Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add ScalarType -> shim conversion, add stable::Tensor.scalar_type#160557

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
janeyx99 wants to merge6 commits intogh/janeyx99/300/basefromgh/janeyx99/300/head

Conversation

@janeyx99
Copy link
Contributor

@janeyx99janeyx99 commentedAug 13, 2025
edited by mikaylagawarecki
Loading

TL;DR: Moving to ScalarType in user extensions and removing deprecated dtypes.

This changemodifies the from/to behavior between ScalarType and StableValue! Whereas before, user extensions could only in abstract pass around obfuscated dtypes appearing as int32_ts, now, users can confidently use torch::headeronly::ScalarType in their extensions for major scalar types. This PR enables ABI stability by adding a translation layer through the shim, so that even if the ScalarType enum values change in the future, user extensions need not fear.

Then we add a Tensor scalar_type API which reuses the from/to logic to return to the user a nice ScalarType (vs an abstracted int32_t).

I then changed the test to test the scalar_type API.

This code change required some refactoring because of circular dependencies.

BC Breaking note

This commit is (narrowly) BC-breaking for unpopular dtypes:quint*s,qint*s,Bits*,dummy_uint*s,dummy_int*s,Float8_e8m0fnu, andFloat4_e2m1fn_x2 in the narrow use case where an extension retrieves a Tensor dtype of the above and passes it intoaoti_torch_call_dispatcher. As of now, I believe there are 0 users of this use case, so the benefits of this change significantly justify BC-breaking this API.

Stack fromghstack (oldest at bottom):

@pytorch-bot
Copy link

pytorch-botbot commentedAug 13, 2025
edited
Loading

🔗 Helpful Links

🧪 See artifacts and rendered test results athud.pytorch.org/pr/160557

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

✅ No Failures

As of commitf12f9d1 with merge basea44a0d3 (image):
💚 Looks good so far! There are no failures yet. 💚

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

janeyx99 added a commit that referenced this pull requestAug 13, 2025
@janeyx99janeyx99 added the release notes: buildrelease notes category labelAug 13, 2025

stack[0] =from(t);
stack[1] =from(std::optional(t_dtype));// dtype
stack[1] =from(std::optional(t.scalar_type()));// dtype
Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

For testing

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

The to/from logic of this file got moved to utils.h

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

This file got split into tensor-struct.h which has everything before the PR, and tensor-inl.h which implements scalar_type as it relies on from/to. The reason for the code split is to allow the code to build without circular dependencies. Without the split, tensor.h would depend on library.h (for to/from) and library.h would depend on tensor.h (cuz to/from Tensor needs a Tensor def).

Now, utils.h (which has to/from) depends on tensor-struct.h, tensor-inl.h depends on both utils.h and tensor-struct.h, and users depend on tensor.h still, which depends on all of the above.

case ScalarType::UInt64:
returnfrom(aoti_torch_dtype_uint64());
default:
throwstd::runtime_error(
Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

NOTE!! THIS IS WHERE I WANT REVIEW!! cc@albanD

Prior, if we had an IValue dtype that was qint8, from_ivalue would callfrom(ScalarType::Qint8), and the code would just reinterpret the enum and spit out the int32_t correspondingly. This was okay because ScalarType wasn't exposed to the end user, and all they had to work with was an abstracted int32_t that they would get from the C shim.

However, with this change today,from(ScalarType::Qint8) would error!!!! Because now, ScalarType is allowed to be used by the end user, and they can call this function, and naively reinterpreting the enum is no longer ok if the extension's ScalarType is different from libtorch's ScalarType! I think erroring is acceptable because these other types are infrequently used by people anyway, but maybe I am wrong about that. e.g.,@swolchok are the Bits ScalarTypes used in ET?

Copy link
Contributor

Choose a reason for hiding this comment

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

Answering your specific question:

I haven't (yet?) made any attempt to use PyTorch's ScalarType in ExecuTorch. ExecuTorch hashttps://github.com/pytorch/executorch/blob/52b45e2d2ac244b13a36ddf5d21a9ebe8d8aa17e/runtime/core/portable_type/scalar_type.h#L132

PyTorch's ScalarType will get used in ExecuTorch's ATen mode, though.https://github.com/pytorch/executorch/blob/52b45e2d2ac244b13a36ddf5d21a9ebe8d8aa17e/runtime/core/exec_aten/exec_aten.h#L82

I don't know what the Bits ScalarTypes even are, but ExecuTorch seems to have its own versions of them that it uses:https://github.com/search?q=repo%3Apytorch%2Fexecutorch+ScalarType%3A%3ABits+language%3AC%2B%2B&type=code&l=C%2B%2B

In general: it is not backward compatible to change functionality such that a call that previously succeeded (and really did work fine) is now an error.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I've concluded it is okay to BC break here given that GitHub search yields 0 users for the narrow use case for which this code would break. Updated the PR body consequently.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

this code is a copy pasta EXCEPT for the specializations fortorch::headeronly::ScalarType

…ar_type"This change _modifies_ the from/to behavior between ScalarType and StableValue!Then we add a Tensor scalar_type API which reuses the from/to logic to return to the user a nice ScalarType (vs an abstracted int32_t).I then changed the test to test the scalar_type API.This code change required some refactoring because of circular dependencies.[ghstack-poisoned]
janeyx99 added a commit that referenced this pull requestAug 13, 2025
…ar_type"This change _modifies_ the from/to behavior between ScalarType and StableValue!Then we add a Tensor scalar_type API which reuses the from/to logic to return to the user a nice ScalarType (vs an abstracted int32_t).I then changed the test to test the scalar_type API.This code change required some refactoring because of circular dependencies.[ghstack-poisoned]
janeyx99 added a commit that referenced this pull requestAug 13, 2025
@@ -0,0 +1,342 @@
#pragma once
Copy link
Contributor

Choose a reason for hiding this comment

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

I firmly dislike naming things "utils" because it is synonymous with "stuff" and helps neither predict their current contents nor limit their future contents. Instead I would consider a specific name, like say StableIValueConversions.h .

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

renamed!!!!!! stableivalue_conversions.h

case ScalarType::UInt64:
returnfrom(aoti_torch_dtype_uint64());
default:
throwstd::runtime_error(
Copy link
Contributor

Choose a reason for hiding this comment

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

Answering your specific question:

I haven't (yet?) made any attempt to use PyTorch's ScalarType in ExecuTorch. ExecuTorch hashttps://github.com/pytorch/executorch/blob/52b45e2d2ac244b13a36ddf5d21a9ebe8d8aa17e/runtime/core/portable_type/scalar_type.h#L132

PyTorch's ScalarType will get used in ExecuTorch's ATen mode, though.https://github.com/pytorch/executorch/blob/52b45e2d2ac244b13a36ddf5d21a9ebe8d8aa17e/runtime/core/exec_aten/exec_aten.h#L82

I don't know what the Bits ScalarTypes even are, but ExecuTorch seems to have its own versions of them that it uses:https://github.com/search?q=repo%3Apytorch%2Fexecutorch+ScalarType%3A%3ABits+language%3AC%2B%2B&type=code&l=C%2B%2B

In general: it is not backward compatible to change functionality such that a call that previously succeeded (and really did work fine) is now an error.

…ar_type"This change _modifies_ the from/to behavior between ScalarType and StableValue!Then we add a Tensor scalar_type API which reuses the from/to logic to return to the user a nice ScalarType (vs an abstracted int32_t).I then changed the test to test the scalar_type API.This code change required some refactoring because of circular dependencies.[ghstack-poisoned]
janeyx99 added a commit that referenced this pull requestAug 15, 2025
…ar_type"This change _modifies_ the from/to behavior between ScalarType and StableValue!Then we add a Tensor scalar_type API which reuses the from/to logic to return to the user a nice ScalarType (vs an abstracted int32_t).I then changed the test to test the scalar_type API.This code change required some refactoring because of circular dependencies.[ghstack-poisoned]
@janeyx99janeyx99 added the topic: bc breakingtopic category labelAug 15, 2025
janeyx99 added a commit that referenced this pull requestAug 15, 2025
@janeyx99janeyx99 added the ciflow/trunkTrigger trunk jobs on your pull request labelAug 16, 2025
@janeyx99janeyx99 requested a review frommalfetAugust 18, 2025 14:51
structFromImpl<ScalarType> {
static StableIValuecall(ScalarType val) {
switch (val) {
case ScalarType::Byte:
Copy link
Contributor

Choose a reason for hiding this comment

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

This feels like it can benefit from define of sorts, that iterates over known dtypes (if dtypes are part of stable API...)

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I was trying to figure out a way, but it did not seem worth it for this PR. (Also there's no "is dtype part of stable API" function we can call yet).

auto inner_val = to<T>(*sivp);

// free the memory associated with StableIValue* sivp
delete sivp;
Copy link
Contributor

Choose a reason for hiding this comment

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

This feels very suspicious.. Why not pass the value as unique_ptr?

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 not sure about passing it around as std::unique_ptr, but you could certainly declarestd::unique_ptr<StableIValue> sivp = to<StableIValue*>(val); above and insulate yourself against the innerto<T> throwing an exception.

malfet reacted with thumbs up emoji
Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

will address in a followup

@@ -0,0 +1,342 @@
#pragma once
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: is "stableivalue_conversions.h" really the conventional formatting here? I would've expected "StableIValueConversions.h", as with torch/headeronly/core/ScalarType.h

Copy link
Contributor

Choose a reason for hiding this comment

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

I think in general it would be good to document the header format, as I've seen bothCamelCase.h,snake_case.h andsomething-weird.h (for exampletensor-inl.h in this PR)

For example, aoti follows snake_case

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

idk the conventional format, but I was going under the guise of using Caps when there was a struct definition of the same name, and using lowercase for more thematic naming (like everything in this file relates to ____). And then the -dashes I'm copying from in c10/ Half and Half-inl.h where the dash means it's a continuation of a file, that these files would be together if possible but are broken apart for some other reason.

I'm happy to follow an existing header notation though, if there is one

auto inner_val = to<T>(*sivp);

// free the memory associated with StableIValue* sivp
delete sivp;
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 not sure about passing it around as std::unique_ptr, but you could certainly declarestd::unique_ptr<StableIValue> sivp = to<StableIValue*>(val); above and insulate yourself against the innerto<T> throwing an exception.

malfet reacted with thumbs up emoji
@@ -0,0 +1,342 @@
#pragma once
Copy link
Contributor

Choose a reason for hiding this comment

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

I think in general it would be good to document the header format, as I've seen bothCamelCase.h,snake_case.h andsomething-weird.h (for exampletensor-inl.h in this PR)

For example, aoti follows snake_case

returnfrom(aoti_torch_dtype_uint8());
case ScalarType::Char:
returnfrom(aoti_torch_dtype_int8());
case ScalarType::Short:
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: Why not add unisgned types here?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I was following the convention of the actual enum order

Comment on lines +226 to +227
int32_t shim_scalartype = to<int32_t>(val);
if (shim_scalartype ==aoti_torch_dtype_uint8()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to cast it to some enum and use switch statement? (As it will force devs to add options there when new dtype is added) This statement will be result of never ending series of "Added missing XYZ" here

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Well the whole reason to have this is because the user binary ScalarType baked in isn't necessarily the same enum as the libtorch binary ScalarType, which is why I'm passing ints through the shim.

return ScalarType::Float8_e5m2fnuz;
}elseif (shim_scalartype ==aoti_torch_dtype_float8_e4m3fnuz()) {
return ScalarType::Float8_e4m3fnuz;
}elseif (shim_scalartype ==aoti_torch_dtype_uint16()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you support unisgned dtypes here but not in the previous switch statement?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

They're supported above too

@@ -0,0 +1,24 @@
#pragma once
Copy link
Contributor

Choose a reason for hiding this comment

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

See my above comment. Use either CamelCase or snake_case

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

okay, ill switch to snake case for these

Comment on lines 77 to 93
void*data_ptr()const {
void* data_ptr;
TORCH_ERROR_CODE_CHECK(aoti_torch_get_data_ptr(ath_.get(), &data_ptr));
return data_ptr;
}

int64_tdim()const {
int64_t dim;
TORCH_ERROR_CODE_CHECK(aoti_torch_get_dim(ath_.get(), &dim));
return dim;
}

int64_tnumel()const {
int64_t numel;
TORCH_ERROR_CODE_CHECK(aoti_torch_get_numel(ath_.get(), &numel));
return numel;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Please please use macros to get rid of copy_pasta

Suggested change
void*data_ptr()const {
void*data_ptr;
TORCH_ERROR_CODE_CHECK(aoti_torch_get_data_ptr(ath_.get(),&data_ptr));
returndata_ptr;
}
int64_tdim()const {
int64_tdim;
TORCH_ERROR_CODE_CHECK(aoti_torch_get_dim(ath_.get(),&dim));
returndim;
}
int64_tnumel()const {
int64_tnumel;
TORCH_ERROR_CODE_CHECK(aoti_torch_get_numel(ath_.get(),&numel));
returnnumel;
}
#define_DEF_COSNT_ACCESSOR_METHOD(NAME,DTYPE) \
DTYPENAME()const { \
DTYPErc; \
TORCH_ERROR_CODE_CHECK(aoti_torch_get_##NAME(ath_.get(), &rc)); \
returnrc; \
}
_DEF_CONST_ACCESSOR_METHOD(data_ptr,void*);
_DEF_CONST_ACCESSOR_METHOD(dim,int64_t);
_DEF_CONST_ACCESSOR_METHOD(numel,int64_t);
#undef _DEF_CONST_ACCESSOR_METHOD

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

It is more readable currently to see these APIs as is. If we need to add more, I will consider using a preprocessor macro.

…ar_type"TL;DR: Moving to ScalarType in user extensions and removing deprecated dtypes.This change _modifies_ the from/to behavior between ScalarType and StableValue! Whereas before, user extensions could only in abstract pass around obfuscated dtypes appearing as int32_ts, now, users can confidently use torch::headeronly::ScalarType in their extensions for major scalar types. This PR enables ABI stability by adding a translation layer through the shim, so that even if the ScalarType enum values change in the future, user extensions need not fear.Then we add a Tensor scalar_type API which reuses the from/to logic to return to the user a nice ScalarType (vs an abstracted int32_t).I then changed the test to test the scalar_type API.This code change required some refactoring because of circular dependencies.## BC Breaking noteThis commit is (narrowly) BC-breaking for unpopular dtypes: `quint*`s, `qint*`s, `Bits*`, `dummy_uint*`s, `dummy_int*`s, `Float8_e8m0fnu`, and `Float4_e2m1fn_x2` in the narrow use case where an extension retrieves a Tensor dtype of the above and passes it into `aoti_torch_call_dispatcher`. As of now, I believe there are 0 users of this use case, so the benefits of this change significantly justify BC-breaking this API.[ghstack-poisoned]
janeyx99 added a commit that referenced this pull requestAug 19, 2025
@janeyx99
Copy link
ContributorAuthor

@pytorchbot merge

pytorch-bot[bot] reacted with thumbs up emoji

@pytorchmergebot
Copy link
Collaborator

Merge started

Your change will be merged once all checks pass (ETA 0-4 Hours).

Learn more about merging in thewiki.

Questions? Feedback? Please reach out to thePyTorch DevX Team

Advanced Debugging
Check the merge workflow status
here

pytorchmergebot pushed a commit that referenced this pull requestAug 20, 2025
markc-614 pushed a commit to markc-614/pytorch that referenced this pull requestSep 17, 2025
…torch#160557)TL;DR: Moving to ScalarType in user extensions and removing deprecated dtypes.This change _modifies_ the from/to behavior between ScalarType and StableValue! Whereas before, user extensions could only in abstract pass around obfuscated dtypes appearing as int32_ts, now, users can confidently use torch::headeronly::ScalarType in their extensions for major scalar types. This PR enables ABI stability by adding a translation layer through the shim, so that even if the ScalarType enum values change in the future, user extensions need not fear.Then we add a Tensor scalar_type API which reuses the from/to logic to return to the user a nice ScalarType (vs an abstracted int32_t).I then changed the test to test the scalar_type API.This code change required some refactoring because of circular dependencies.## BC Breaking noteThis commit is (narrowly) BC-breaking for unpopular dtypes: `quint*`s, `qint*`s, `Bits*`, `dummy_uint*`s, `dummy_int*`s, `Float8_e8m0fnu`, and `Float4_e2m1fn_x2` in the narrow use case where an extension retrieves a Tensor dtype of the above and passes it into `aoti_torch_call_dispatcher`. As of now, I believe there are 0 users of this use case, so the benefits of this change significantly justify BC-breaking this API.Pull Requestresolved:pytorch#160557Approved by:https://github.com/mikaylagawarecki,https://github.com/malfet
markc-614 pushed a commit to markc-614/pytorch that referenced this pull requestSep 17, 2025
@github-actionsgithub-actionsbot deleted the gh/janeyx99/300/head branchSeptember 19, 2025 02:11
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@malfetmalfetmalfet approved these changes

@mikaylagawareckimikaylagawareckimikaylagawarecki approved these changes

@albanDalbanDAwaiting requested review from albanD

+1 more reviewer

@swolchokswolchokswolchok left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

ciflow/trunkTrigger trunk jobs on your pull requestMergedrelease notes: buildrelease notes categorytopic: bc breakingtopic category

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

6 participants

@janeyx99@pytorchmergebot@swolchok@malfet@mikaylagawarecki

[8]ページ先頭

©2009-2025 Movatter.jp