Skip to content

Commit ff23eff

Browse files
authored
Merge branch 'main' into gh/cccclai/31/orig
2 parents 274ee93 + 91c9ffa commit ff23eff

File tree

5 files changed

+39
-144
lines changed

5 files changed

+39
-144
lines changed

backends/xnnpack/partition/config/generic_node_configs.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ def __init__(self, **kwargs):
107107
def supported_precision_types(self) -> List[ConfigPrecisionType]:
108108
return [ConfigPrecisionType.FP32, ConfigPrecisionType.STATIC_QUANT]
109109

110+
def check_constraints(self, node: torch.fx.Node, ep: ExportedProgram) -> bool:
111+
if not self.check_common_constraints(node, ep):
112+
return False
113+
# No support for add nodes with alpha != 1
114+
if "alpha" in node.kwargs and not np.isclose(
115+
node.kwargs["alpha"], 1.0, atol=1e-9, rtol=1e-9
116+
):
117+
why(node, reason="Add node doesn't support alpha != 1")
118+
return False
119+
return True
120+
110121

111122
class ReLUConfig(GenericNodePartitionerConfig):
112123
target_name = "relu.default"

backends/xnnpack/test/ops/test_add.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,27 @@ def forward(self, x, z):
240240
.serialize()
241241
.run_method_and_compare_outputs()
242242
)
243+
244+
class AddWithAlpha(torch.nn.Module):
245+
def forward(self, x, y):
246+
# node with alpha = 1.0 will be partitioned
247+
out1 = torch.add(x, y, alpha=1)
248+
# node with alpha != 1.0 will not be partitioned
249+
out2 = torch.add(x, y, alpha=2)
250+
return out1, out2
251+
252+
def test_add_with_alpha(self):
253+
inputs = (torch.randn(1, 1, 4, 4), torch.randn(1, 1, 4, 4))
254+
(
255+
Tester(self.AddWithAlpha(), inputs)
256+
.export()
257+
.check_count({"torch.ops.aten.add.Tensor": 2})
258+
.to_edge_transform_and_lower()
259+
# unpartitioned node
260+
.check_count({"executorch_exir_dialects_edge__ops_aten_add_Tensor": 1})
261+
# partitioned node
262+
.check_count({"torch.ops.higher_order.executorch_call_delegate": 1})
263+
.to_executorch()
264+
.serialize()
265+
.run_method_and_compare_outputs()
266+
)

extension/data_loader/mmap_data_loader.cpp

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,10 @@ void MunmapSegment(void* context, void* data, size_t size) {
150150
}
151151
} // namespace
152152

153-
/**
154-
* Validates that file read range is within bounds.
155-
*/
156-
Error MmapDataLoader::validate_input(size_t offset, size_t size) const {
153+
Result<FreeableBuffer> MmapDataLoader::load(
154+
size_t offset,
155+
size_t size,
156+
ET_UNUSED const DataLoader::SegmentInfo& segment_info) const {
157157
ET_CHECK_OR_RETURN_ERROR(
158158
// Probably had its value moved to another instance.
159159
fd_ >= 0,
@@ -173,18 +173,6 @@ Error MmapDataLoader::validate_input(size_t offset, size_t size) const {
173173
InvalidArgument,
174174
"Offset %zu too large for off_t",
175175
offset);
176-
return Error::Ok;
177-
}
178-
179-
Result<FreeableBuffer> MmapDataLoader::load(
180-
size_t offset,
181-
size_t size,
182-
ET_UNUSED const DataLoader::SegmentInfo& segment_info) const {
183-
// Ensure read range is valid.
184-
auto validation_err = validate_input(offset, size);
185-
if (validation_err != Error::Ok) {
186-
return validation_err;
187-
}
188176

189177
// mmap() will fail if the size is zero.
190178
if (size == 0) {
@@ -279,69 +267,5 @@ Result<size_t> MmapDataLoader::size() const {
279267
return file_size_;
280268
}
281269

282-
Error MmapDataLoader::load_into(
283-
size_t offset,
284-
size_t size,
285-
ET_UNUSED const SegmentInfo& segment_info,
286-
void* buffer) const {
287-
ET_CHECK_OR_RETURN_ERROR(
288-
buffer != nullptr, InvalidArgument, "Buffer is null");
289-
290-
// Ensure read range is valid.
291-
auto err = validate_input(offset, size);
292-
if (err != Error::Ok) {
293-
return err;
294-
}
295-
296-
// Nothing to copy.
297-
if (size == 0) {
298-
return Error::Ok;
299-
}
300-
301-
// Find the range of pages that covers the requested region.
302-
Range range =
303-
get_overlapping_pages(static_cast<uintptr_t>(offset), size, page_size_);
304-
305-
size_t map_size = range.size;
306-
if (range.start + map_size > file_size_) {
307-
// Clamp to the end of the file.
308-
//
309-
// The Windows implementation of mmap uses CreateFileMapping which returns
310-
// error STATUS_SECTION_TOO_BIG (0xc0000040) if we try to map past the end
311-
// of the last page of a file mapped in as read-only.
312-
map_size = file_size_ - range.start;
313-
}
314-
315-
// Map the pages read-only. MAP_PRIVATE vs. MAP_SHARED doesn't matter since
316-
// the data is read-only, but use PRIVATE just to further avoid accidentally
317-
// modifying the file.
318-
void* pages = ::mmap(
319-
nullptr,
320-
map_size,
321-
PROT_READ,
322-
MAP_PRIVATE,
323-
fd_,
324-
static_cast<off_t>(range.start));
325-
ET_CHECK_OR_RETURN_ERROR(
326-
pages != MAP_FAILED,
327-
AccessFailed,
328-
"Failed to map %s: mmap(..., size=%zd, ..., fd=%d, offset=0x%zx)",
329-
file_name_,
330-
range.size,
331-
fd_,
332-
range.start);
333-
334-
// Offset into mapped region.
335-
const size_t map_delta = offset - range.start;
336-
337-
// Copy data into caller's buffer.
338-
std::memcpy(buffer, static_cast<uint8_t*>(pages) + map_delta, size);
339-
340-
// Unmap mapped region.
341-
::munmap(pages, map_size);
342-
343-
return Error::Ok;
344-
}
345-
346270
} // namespace extension
347271
} // namespace executorch

extension/data_loader/mmap_data_loader.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,6 @@ class MmapDataLoader final : public executorch::runtime::DataLoader {
9595

9696
ET_NODISCARD executorch::runtime::Result<size_t> size() const override;
9797

98-
ET_NODISCARD
99-
executorch::runtime::Error load_into(
100-
size_t offset,
101-
size_t size,
102-
ET_UNUSED const SegmentInfo& segment_info,
103-
void* buffer) const override;
104-
10598
private:
10699
MmapDataLoader(
107100
int fd,
@@ -120,10 +113,6 @@ class MmapDataLoader final : public executorch::runtime::DataLoader {
120113
MmapDataLoader& operator=(const MmapDataLoader&) = delete;
121114
MmapDataLoader& operator=(MmapDataLoader&&) = delete;
122115

123-
ET_NODISCARD executorch::runtime::Error validate_input(
124-
size_t offset,
125-
size_t size) const;
126-
127116
const char* const file_name_; // String data is owned by the instance.
128117
const size_t file_size_;
129118
const size_t page_size_;

extension/data_loader/test/mmap_data_loader_test.cpp

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -376,56 +376,3 @@ TEST_F(MmapDataLoaderTest, DEPRECATEDFrom) {
376376
ASSERT_EQ(total_size.error(), Error::Ok);
377377
EXPECT_EQ(*total_size, contents_size);
378378
}
379-
380-
// Tests that load_into copies bytes correctly.
381-
TEST_F(MmapDataLoaderTest, LoadIntoCopiesCorrectly) {
382-
// Create a test string.
383-
const char* test_text = "FILE_CONTENTS";
384-
const size_t text_size = std::strlen(test_text);
385-
TempFile tf(test_text);
386-
387-
// Wrap it in a loader.
388-
Result<MmapDataLoader> mdl = MmapDataLoader::from(tf.path().c_str());
389-
ASSERT_EQ(mdl.error(), Error::Ok);
390-
391-
// Destination buffer.
392-
std::vector<uint8_t> dst(text_size);
393-
394-
// Call load_into()
395-
Error err = mdl->load_into(
396-
/*offset=*/0,
397-
/*size=*/text_size,
398-
DataLoader::SegmentInfo(DataLoader::SegmentInfo::Type::Program),
399-
dst.data());
400-
ASSERT_EQ(err, Error::Ok);
401-
402-
// Verify memory copied correctly.
403-
EXPECT_EQ(0, std::memcmp(dst.data(), test_text, text_size));
404-
}
405-
406-
// Tests that load_into copies offset slice correctly.
407-
TEST_F(MmapDataLoaderTest, LoadIntoCopiesOffsetCorrectly) {
408-
// Create a test string.
409-
const char* contents = "ABCDEFGH";
410-
TempFile tf(contents);
411-
412-
// Wrap it in a loader.
413-
Result<MmapDataLoader> mdl = MmapDataLoader::from(tf.path().c_str());
414-
ASSERT_EQ(mdl.error(), Error::Ok);
415-
416-
// Copying 3 bytes starting at offset 2 = "CDE"
417-
const size_t offset = 2;
418-
const size_t size = 3;
419-
uint8_t dst[size];
420-
421-
// Call load_into()
422-
Error err = mdl->load_into(
423-
offset,
424-
size,
425-
DataLoader::SegmentInfo(DataLoader::SegmentInfo::Type::Program),
426-
dst);
427-
ASSERT_EQ(err, Error::Ok);
428-
429-
// Verify memory copied correctly.
430-
EXPECT_EQ(0, std::memcmp(dst, contents + offset, size));
431-
}

0 commit comments

Comments
 (0)