Skip to content

Refactor out headeronly ArrayRef#164991

Closed
janeyx99 wants to merge 8 commits intogh/janeyx99/314/basefrom
gh/janeyx99/314/head
Closed

Refactor out headeronly ArrayRef#164991
janeyx99 wants to merge 8 commits intogh/janeyx99/314/basefrom
gh/janeyx99/314/head

Conversation

@janeyx99
Copy link
Copy Markdown
Contributor

@janeyx99 janeyx99 commented Oct 8, 2025

@pytorch-bot
Copy link
Copy Markdown

pytorch-bot Bot commented Oct 8, 2025

🔗 Helpful Links

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

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

❌ 1 New Failure, 2 Unrelated Failures

As of commit e5ab10c with merge base d7e2d0a (image):

NEW FAILURE - The following job has failed:

BROKEN TRUNK - The following job failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

UNSTABLE - The following job is marked as unstable, possibly due to flakiness on trunk:

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

janeyx99 added a commit that referenced this pull request Oct 8, 2025
ghstack-source-id: 73ed751
Pull Request resolved: #164991
@janeyx99 janeyx99 added the release notes: cpp release notes category label Oct 8, 2025
janeyx99 added a commit that referenced this pull request Oct 9, 2025
ghstack-source-id: 5ede5cb
Pull Request resolved: #164991
@janeyx99 janeyx99 marked this pull request as ready for review October 9, 2025 18:29
Comment thread torch/headeronly/util/HOArrayRef.h Outdated
Comment thread c10/util/ArrayRef.h Outdated
/// value.
///
/// NOTE: We have refactored out the headeronly parts of the ArrayRef struct
/// into HOArrayRef. As adding `virtual` will change the performance of the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: s/will/would

Comment thread c10/util/ArrayRef.h Outdated
Comment on lines 53 to 57
void debugCheckNullptrInvariant() {
TORCH_INTERNAL_ASSERT_DEBUG_ONLY(
Data != nullptr || Length == 0,
this->Data != nullptr || this->Length == 0,
"created ArrayRef with nullptr and non-zero length! std::optional relies on this being illegal");
}
Copy link
Copy Markdown
Contributor

@swolchok swolchok Oct 10, 2025

Choose a reason for hiding this comment

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

you can delete this function. "std::optional relies on this being illegal" is false. Relevant history here:

  1. [PyTorch] RFC: optimize c10::optional<ArrayRef<T>> #59333 (by yours truly) added this debug check, together with a specialization of c10::optionalc10::ArrayRef to reduce its size.
  2. [PyTorch] Redirect c10::optional to std::optional #101995 (by yours truly) removed the c10::optional and replaced it with a simple redirect to std::optional, "intentionally dropping the c10::optionalc10::ArrayRef size optimization" (with a note that it wasn't as important anymore). I forgot that this debug check was here, oops! sorry.
  3. [codemod] c10:optional -> std::optional #126135 find/replaced this message from c10::optional to std::optional.

I haven't specifically checked whether someone has tried to reintroduce this optimization, but if they had it would be undefined behavior -- you can't specialize std-namespaced things unless they explicitly allow you to, and I don't see any mention of specialization on https://en.cppreference.com/w/cpp/utility/optional.html .

if this check was important, I would instead ask you to guarantee it in HOArrayRef as well.

After you delete this function, you can get rid of all the constructor implementations that just call into HOArrayRef's constructors and simply write using HOArrayRef::HOArrayRef.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

lol ok, got it!!

Comment thread c10/util/ArrayRef.h Outdated
}

/// front - Get the first element.
/// We deviate from HOArrayRef by using TORCH_CHECK instead of STD_TORCH_CHECK
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is STD_TORCH_CHECK really so bad? if so, why is it always correct to call HOArrayRef functions instead? Is there some set of unwritten rules people have to be aware of about when it's OK for them to use HOArrayRef?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

From what I understand, c10::Error does some traceback handling to present the error in a nice way to the user. STD_TORCH_CHECK just calls std::runtime_error so it's less full. STD_TORCH_CHECK still checks properly though, but it scores fewer points in "user understandability", so it's not "incorrect", but not as ideal.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How do you propose avoiding the creation of a perceived mess where people don't understand when they should use HeaderOnlyArrayRef vs ArrayRef?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm now wondering if we can get STD_TORCH_CHECK to do the right thing -- throw c10::Error when linking with libtorch, but throw std::runtime_error when not linking with libtorch. I suspect we might be able to get the job done with weak symbols. Let me see if I can get a PR up...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

weak symbols will do the job on macOS (and presumably Linux), but Googling seems to suggest that there isn't an equivalent for Windows.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm now wondering if we can get STD_TORCH_CHECK to do the right thing

per offline discussion, 1) @janeyx99 is concerned about code in headeronly changing its behavior depending on whether libtorch is linked 2) it is definitely unclear how to do this for windows, and we care about windows. therefore it is not clear that the behavior I proposed is the "right thing", shelving it.

Comment thread torch/headeronly/util/HOArrayRef.h Outdated
Comment thread torch/headeronly/util/HOArrayRef.h Outdated
Comment thread torch/headeronly/util/HOArrayRef.h Outdated
// nullptr Data and nonzero length in the following constructors: from a pointer
// and length, from a range, from a templated Container with .data() and .size().
// HOArrayRef does not make that check for any constructor.
/// 2. ArrayRef can be constructed from a SmallVector. HOArrayRef cannot.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: you can still make a HOArrayRef given a SmallVector, you just don't get the convenience constructor

@janeyx99 janeyx99 requested a review from swolchok October 14, 2025 02:59
Comment thread c10/util/ArrayRef.h
/// into HeaderOnlyArrayRef. As adding `virtual` would change the performance of
/// the underlying constexpr calls, we rely on apparent-type dispatch for
/// inheritance. This should be fine because their memory format is the same,
/// and it is never incorrect for ArrayRef to call HeaderOnlyArrayRef methods.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we should probably add something like "However, you should prefer to use ArrayRef when possible, because its use of TORCH_CHECK will lead to better user-facing error messages."

/// 1. ArrayRef has an extra convenience constructor for SmallVector.
/// 2. ArrayRef uses TORCH_CHECK. HeaderOnlyArrayRef uses header-only
/// STD_TORCH_CHECK,
/// which will output a std::runtime_error vs a c10::Error.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

and here, something like "Consequently, you should use ArrayRef when possible and HeaderOnlyArrayRef only when necessary to support headeronly code."

Comment thread c10/util/ArrayRef.h Outdated
: Data(data), Length(length) {
debugCheckNullptrInvariant();
}
// Inherits all constructors from HeaderOnlyArrayRef<T>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't love comments that explain C++ language features


/// slice(n, m) - Take M elements of the array starting at element N
constexpr HeaderOnlyArrayRef<T> slice(size_t N, size_t M) const {
STD_TORCH_CHECK(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it occurs to me that having to repeat these error messages isn't great. if you wanted to cut that out, you could

#define ARRAY_REF_SLICE(check, class_name, N, M) \
  check( \
    N + M <= this->size(), \
// ...
#class_name ": invalid slice, N = ", \
// ...

up to you whether the macro ugliness is worth the deduplication, though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

eh

@pytorchmergebot
Copy link
Copy Markdown
Collaborator

Starting merge as part of PR stack under #165152

1 similar comment
@pytorchmergebot
Copy link
Copy Markdown
Collaborator

Starting merge as part of PR stack under #165152

@clee2000
Copy link
Copy Markdown
Contributor

@pytorchbot revert -m "breaking internal tests D84961075" -c ghfirst

@pytorchmergebot
Copy link
Copy Markdown
Collaborator

@pytorchbot successfully started a revert job. Check the current status here.
Questions? Feedback? Please reach out to the PyTorch DevX Team

pytorchmergebot added a commit that referenced this pull request Oct 20, 2025
…165152)"

This reverts commit e445494.

Reverted #165152 on behalf of https://github.com/clee2000 due to breaking internal tests D84961075 ([comment](#164991 (comment)))
pytorchmergebot added a commit that referenced this pull request Oct 20, 2025
This reverts commit 3806e97.

Reverted #164991 on behalf of https://github.com/clee2000 due to breaking internal tests D84961075 ([comment](#164991 (comment)))
@janeyx99
Copy link
Copy Markdown
Contributor Author

@janeyx99 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@pytorch-bot pytorch-bot Bot added the ciflow/trunk Trigger trunk jobs on your pull request label Oct 20, 2025
@janeyx99
Copy link
Copy Markdown
Contributor Author

@janeyx99 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Chao1Han pushed a commit to Chao1Han/pytorch that referenced this pull request Oct 21, 2025
Chao1Han pushed a commit to Chao1Han/pytorch that referenced this pull request Oct 21, 2025
Chao1Han pushed a commit to Chao1Han/pytorch that referenced this pull request Oct 21, 2025
Chao1Han pushed a commit to Chao1Han/pytorch that referenced this pull request Oct 21, 2025
This reverts commit 3806e97.

Reverted pytorch#164991 on behalf of https://github.com/clee2000 due to breaking internal tests D84961075 ([comment](pytorch#164991 (comment)))
zhudada0120 pushed a commit to zhudada0120/pytorch that referenced this pull request Oct 22, 2025
zhudada0120 pushed a commit to zhudada0120/pytorch that referenced this pull request Oct 22, 2025
zhudada0120 pushed a commit to zhudada0120/pytorch that referenced this pull request Oct 22, 2025
zhudada0120 pushed a commit to zhudada0120/pytorch that referenced this pull request Oct 22, 2025
This reverts commit 3806e97.

Reverted pytorch#164991 on behalf of https://github.com/clee2000 due to breaking internal tests D84961075 ([comment](pytorch#164991 (comment)))
@pytorchmergebot
Copy link
Copy Markdown
Collaborator

Starting merge as part of PR stack under #165152

1 similar comment
@pytorchmergebot
Copy link
Copy Markdown
Collaborator

Starting merge as part of PR stack under #165152

pytorchmergebot pushed a commit that referenced this pull request Nov 5, 2025
pytorchmergebot pushed a commit that referenced this pull request Nov 5, 2025
pytorchmergebot pushed a commit that referenced this pull request Nov 7, 2025
Some important notes:
a) Just like IValues steal the ownership of ArrayRefs and any std::vectors in order to convert the inner elements into IValues, we do the same thing with StableIValue. This O(N) traverse is ineluctable.
b) As a result, since StableIValues are owning and our contract is that to<T>(StableIValue) transfers ownership, you cannot ever convert from StableIValue to a nonowning HeaderOnlyArrayRef<V>.

We handle memory similar to AtenTensorHandle, but we have a StableListHandle!

Pull Request resolved: #165953
Approved by: https://github.com/malfet
ghstack dependencies: #164991, #165152, #165153
pytorchmergebot pushed a commit that referenced this pull request Nov 7, 2025
pytorchmergebot pushed a commit that referenced this pull request Nov 15, 2025
This PR moves the implementations of Tensor accessor classes to headeronly with the following modifications:
- Add ArrayRef and IndexBoundsCheck template parameters to refactor out the usages of `IntArrayRef` and `TORCH_CHECK_INDEX` from Tensor accessor implementations.
- Eliminate usage of `c10::irange` as it is not headeronly-compatible.
- Introduce `torch::headeronly::{TensorAccessorBase,TensorAccessor, GenericPackedTensorAccessorBase, GenericPackedTensorAccessor}` that are headeronly-equivalent to `at::{TensorAccessorBase,TensorAccessor, GenericPackedTensorAccessorBase, GenericPackedTensorAccessor}`. Both these sets of template classes use original implementations from `torch::headeronly::detail` that have new template parameters `ArrayRefCls` and `IndexBoundsCheck` to facilitate `at` and `torch::headeronly` implementations of ArrayRef and checking indices.

TODO:
- ~when #164991 lands, eliminate the placeholder class HeaderOnlyArrayRef~ UPDATE: done.

Pull Request resolved: #166855
Approved by: https://github.com/janeyx99
Khanaksahu pushed a commit to Khanaksahu/pytorch that referenced this pull request Nov 17, 2025
ghstack-source-id: 7b6f852
Pull Request resolved: pytorch/pytorch#164991
Silv3S pushed a commit to Silv3S/pytorch that referenced this pull request Nov 18, 2025
Some important notes:
a) Just like IValues steal the ownership of ArrayRefs and any std::vectors in order to convert the inner elements into IValues, we do the same thing with StableIValue. This O(N) traverse is ineluctable.
b) As a result, since StableIValues are owning and our contract is that to<T>(StableIValue) transfers ownership, you cannot ever convert from StableIValue to a nonowning HeaderOnlyArrayRef<V>.

We handle memory similar to AtenTensorHandle, but we have a StableListHandle!

Pull Request resolved: pytorch#165953
Approved by: https://github.com/malfet
ghstack dependencies: pytorch#164991, pytorch#165152, pytorch#165153
Silv3S pushed a commit to Silv3S/pytorch that referenced this pull request Nov 18, 2025
Silv3S pushed a commit to Silv3S/pytorch that referenced this pull request Nov 18, 2025
This PR moves the implementations of Tensor accessor classes to headeronly with the following modifications:
- Add ArrayRef and IndexBoundsCheck template parameters to refactor out the usages of `IntArrayRef` and `TORCH_CHECK_INDEX` from Tensor accessor implementations.
- Eliminate usage of `c10::irange` as it is not headeronly-compatible.
- Introduce `torch::headeronly::{TensorAccessorBase,TensorAccessor, GenericPackedTensorAccessorBase, GenericPackedTensorAccessor}` that are headeronly-equivalent to `at::{TensorAccessorBase,TensorAccessor, GenericPackedTensorAccessorBase, GenericPackedTensorAccessor}`. Both these sets of template classes use original implementations from `torch::headeronly::detail` that have new template parameters `ArrayRefCls` and `IndexBoundsCheck` to facilitate `at` and `torch::headeronly` implementations of ArrayRef and checking indices.

TODO:
- ~when pytorch#164991 lands, eliminate the placeholder class HeaderOnlyArrayRef~ UPDATE: done.

Pull Request resolved: pytorch#166855
Approved by: https://github.com/janeyx99
@github-actions github-actions Bot deleted the gh/janeyx99/314/head branch December 6, 2025 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-no-td Do not run TD on this PR ciflow/inductor ciflow/trunk Trigger trunk jobs on your pull request Merged release notes: cpp release notes category Reverted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants