Skip to content

Add function to stringify tensor shapes #7943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 6, 2025
Merged

Conversation

swolchok
Copy link
Contributor

First step toward fixing #7902

[ghstack-poisoned]
[ghstack-poisoned]
@swolchok
Copy link
Contributor Author

swolchok commented Jan 24, 2025

Copy link

pytorch-bot bot commented Jan 24, 2025

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/7943

Note: Links to docs will display an error until the docs builds have been completed.

❗ 1 Active SEVs

There are 1 currently active SEVs. If your PR is affected, please view them below:

✅ No Failures

As of commit 61e79ce with merge base 62e49ce (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jan 24, 2025
@swolchok swolchok requested review from dbort and Gasoonjia January 24, 2025 19:03
Base automatically changed from gh/swolchok/202/head to main January 28, 2025 16:01
* works whether or not ATen mode is active.
*/
void tensor_shape_to_c_string(
char out[kTensorShapeStringSizeLimit],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried about the safety of this, since a caller could pass in any size despite the sized parameter:

% cat main.cpp
void test(char c[15]) {}

int main() {
  char b[7];
  test(b);
  return 0;
}

% clang++ --std=c++17 -Wall main.cpp
(no output; success)

A char* and size_t size or a Span<char> would make it more explicit.

Or if you wanted to stick with a fixed size array you could use std::array<char, kTensorShapeStringSizeLimit> which is enforced:

% cat main.cpp
#include <array>

void test(std::array<int, 15>c) {}

int main() {
  std::array<int, 7> b;
  test(b);
  return 0;
}


% clang++ --std=c++17 -Wall main.cpp
main.cpp:8:3: error: no matching function for call to 'test'
    8 |   test(b);
      |   ^~~~
main.cpp:3:6: note: candidate function not viable: no known conversion from 'array<[...], 7>' to 'array<[...], 15>' for 1st argument
    3 | void test(std::array<int, 15>c) {
      |      ^    ~~~~~~~~~~~~~~~~~~~~
1 error generated.

[ghstack-poisoned]
Copy link
Contributor

@dbort dbort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new function signature looks great

* works whether or not ATen mode is active.
*/
std::array<char, kTensorShapeStringSizeLimit> tensor_shape_to_c_string(
executorch::aten::ArrayRef<executorch::aten::SizesType> shape) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're trying to get away from ArrayRef for non-aten-compatible APIs; could you use executorch::runtime::Span for this?

[ghstack-poisoned]
@swolchok swolchok requested a review from dbort February 3, 2025 18:09
Copy link
Contributor

@dbort dbort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all of the changes here. I know I'm being paranoid but we really need to be extra paranoid in the core runtime.

A few final requests but looks good.

Comment on lines 25 to 28
static constexpr char kLimitExceededError[] =
"(ERR: tensor ndim exceeds limit, can't happen)";
static_assert(sizeof(kLimitExceededError) <= kTensorShapeStringSizeLimit);
std::memcpy(p, kLimitExceededError, sizeof(kLimitExceededError));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could simplify things with snprintf()

And "can't happen" isn't true: I could create a PTE file where this does happen. Right now there's a dangerous assumption across the kernel libraries that dim is always <= kTensorDimensionLimit.

for (const auto elem : shape) {
if (elem < 0 || elem > internal::kMaximumPrintableTensorShapeElement) {
static_assert(
internal::kMaximumPrintableTensorShapeElement > 99999,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took me a minute to understand where >99999 came from: please add a comment pointing out that it's the same number of digits as "ERR, " with the NUL

// we want.
p += snprintf(
p,
kTensorShapeStringSizeLimit - (p - out.data()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a -1 in here to account for the NUL byte? Not sure

[ghstack-poisoned]
@swolchok
Copy link
Contributor Author

swolchok commented Feb 5, 2025

had to move the function into kernels/portable/cpu/util to fix an apparent layering violation -- portable_kernels failed to link because it needed to depend on executorch_core for this new function, but executorch_core already depends on portable_kernels

@swolchok swolchok merged commit 4a1bf29 into main Feb 6, 2025
45 checks passed
@swolchok swolchok deleted the gh/swolchok/203/head branch February 6, 2025 02:24
@swolchok
Copy link
Contributor Author

swolchok commented Feb 6, 2025

apparent layering violation -- portable_kernels failed to link because it needed to depend on executorch_core for this new function, but executorch_core already depends on portable_kernels

I'll send a diff to move this back to runtime/core. portable_kernels really should be able to use code from runtime/core and either I was wrong or we should dig into why not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. topic: not user facing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants