Skip to content

Commit 7ebb45f

Browse files
committed
Update
[ghstack-poisoned]
1 parent 0a04883 commit 7ebb45f

File tree

4 files changed

+110
-1
lines changed

4 files changed

+110
-1
lines changed

runtime/core/exec_aten/util/targets.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def define_common_targets():
5050

5151
runtime.cxx_library(
5252
name = "tensor_util" + aten_suffix,
53-
srcs = ["tensor_util_aten.cpp"] if aten_mode else ["tensor_util_portable.cpp"],
53+
srcs = ["tensor_util.cpp"] + (["tensor_util_aten.cpp"] if aten_mode else ["tensor_util_portable.cpp"]),
5454
exported_headers = [
5555
"tensor_util.h",
5656
],
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "tensor_util.h"
2+
3+
/*
4+
* Copyright (c) Meta Platforms, Inc. and affiliates.
5+
* All rights reserved.
6+
*
7+
* This source code is licensed under the BSD-style license found in the
8+
* LICENSE file in the root directory of this source tree.
9+
*/
10+
11+
#include <executorch/runtime/core/exec_aten/util/tensor_util.h>
12+
13+
#include <executorch/runtime/platform/assert.h>
14+
15+
namespace executorch::runtime {
16+
/**
17+
* Shared implementation for tensor_util.h, may only contain code that
18+
* works whether or not ATen mode is active.
19+
*/
20+
void tensor_shape_to_c_string(
21+
char out[kTensorShapeStringSizeLimit],
22+
executorch::aten::ArrayRef<executorch::aten::SizesType> shape) {
23+
char* p = out;
24+
*p++ = '(';
25+
for (const auto elem : shape) {
26+
if (elem < 0 || elem > kMaximumPrintableTensorShapeElement) {
27+
strcpy(p, "ERR, ");
28+
p += strlen("ERR, ");
29+
} else {
30+
// snprintf returns characters *except* the NUL terminator, which is what
31+
// we want.
32+
p += snprintf(
33+
p,
34+
kTensorShapeStringSizeLimit - (p - out),
35+
"%" PRIu32 ", ",
36+
static_cast<uint32_t>(elem));
37+
}
38+
}
39+
*(p - 2) = ')';
40+
*(p - 1) = '\0';
41+
}
42+
43+
} // namespace executorch::runtime

runtime/core/exec_aten/util/tensor_util.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,29 @@ bool extract_scalar_tensor(executorch::aten::Tensor tensor, BOOL_T* out_val) {
11201120
return true;
11211121
}
11221122

1123+
/**
1124+
* Maximum size of a string returned by tensor_shape_to_c_string, for
1125+
* stack allocation.
1126+
*/
1127+
constexpr size_t kTensorShapeStringSizeLimit = 1 + /* opening parenthesis */
1128+
10 * kTensorDimensionLimit + /* maximum digits we will print; update
1129+
* kMaximumPrintableTensorShapeElement
1130+
* if changing */
1131+
2 * kTensorDimensionLimit + /* comma and space after each item,
1132+
* overwritten with closing paren and
1133+
* NUL terminator for last element */
1134+
1; /* padding for temporary NUL terminator for simplicity of implementation
1135+
*/
1136+
1137+
constexpr size_t kMaximumPrintableTensorShapeElement =
1138+
std::is_same_v<executorch::aten::SizesType, int32_t>
1139+
? std::numeric_limits<int32_t>::max()
1140+
: std::numeric_limits<uint32_t>::max();
1141+
1142+
void tensor_shape_to_c_string(
1143+
char out[kTensorShapeStringSizeLimit],
1144+
executorch::aten::ArrayRef<executorch::aten::SizesType> shape);
1145+
11231146
/// These APIs should not be used outside of Executor.cpp.
11241147
namespace internal {
11251148
/**

runtime/core/exec_aten/util/test/tensor_util_test.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <executorch/runtime/platform/runtime.h>
1313
#include <executorch/test/utils/DeathTest.h>
1414
#include <cmath>
15+
#include <cstring>
1516
#include <limits>
1617

1718
using namespace ::testing;
@@ -605,3 +606,45 @@ TEST_F(TensorUtilTest, SameShapesDifferentDimOrder) {
605606
EXPECT_FALSE(tensors_have_same_dim_order(a, c, b));
606607
EXPECT_FALSE(tensors_have_same_dim_order(c, b, a));
607608
}
609+
610+
TEST_F(TensorUtilTest, TensorShapeToCStringBasic) {
611+
char str[executorch::runtime::kTensorShapeStringSizeLimit];
612+
std::array<executorch::aten::SizesType, 3> sizes = {123, 456, 789};
613+
executorch::runtime::tensor_shape_to_c_string(str, sizes);
614+
EXPECT_STREQ(str, "(123, 456, 789)");
615+
616+
std::array<executorch::aten::SizesType, 1> one_size = {1234567890};
617+
executorch::runtime::tensor_shape_to_c_string(str, one_size);
618+
EXPECT_STREQ(str, "(1234567890)");
619+
}
620+
621+
TEST_F(TensorUtilTest, TensorShapeToCStringMaximumLength) {
622+
using executorch::runtime::kMaximumPrintableTensorShapeElement;
623+
using executorch::runtime::kTensorDimensionLimit;
624+
using executorch::runtime::kTensorShapeStringSizeLimit;
625+
using executorch::runtime::tensor_shape_to_c_string;
626+
char str[executorch::runtime::kTensorShapeStringSizeLimit + 1];
627+
std::memset(str, '@', sizeof(str));
628+
629+
std::array<
630+
executorch::aten::SizesType,
631+
executorch::runtime::kTensorDimensionLimit>
632+
sizes;
633+
std::fill(
634+
sizes.begin(),
635+
sizes.end(),
636+
executorch::runtime::kMaximumPrintableTensorShapeElement);
637+
638+
executorch::runtime::tensor_shape_to_c_string(str, sizes);
639+
640+
std::ostringstream expected;
641+
expected << '(' << kMaximumPrintableTensorShapeElement;
642+
for (int ii = 0; ii < kTensorDimensionLimit - 1; ++ii) {
643+
expected << ", " << kMaximumPrintableTensorShapeElement;
644+
}
645+
expected << ')';
646+
auto expected_str = expected.str();
647+
648+
EXPECT_EQ(str[executorch::runtime::kTensorShapeStringSizeLimit], '@');
649+
EXPECT_EQ(expected_str, str);
650+
}

0 commit comments

Comments
 (0)