Skip to content

[TorchTidy] Adding support for accessing strides and scalars#80072

Closed
Gamrix wants to merge 12 commits intogh/gamrix/77/basefrom
gh/gamrix/77/head
Closed

[TorchTidy] Adding support for accessing strides and scalars#80072
Gamrix wants to merge 12 commits intogh/gamrix/77/basefrom
gh/gamrix/77/head

Conversation

@Gamrix
Copy link
Contributor

@Gamrix Gamrix commented Jun 22, 2022

@facebook-github-bot
Copy link
Contributor

facebook-github-bot commented Jun 22, 2022

🔗 Helpful links

✅ No Failures (0 Pending)

As of commit f370cf0 (more details on the Dr. CI page):

Expand to see more

💚 💚 Looks good so far! There are no failures yet. 💚 💚


This comment was automatically generated by Dr. CI (expand for details).

Please report bugs/suggestions to the (internal) Dr. CI Users group.

Click here to manually regenerate this comment.

@Gamrix Gamrix marked this pull request as draft June 22, 2022 19:50
Gamrix added a commit that referenced this pull request Jun 22, 2022
@Gamrix Gamrix requested review from robieta and removed request for albanD and soulitzer June 22, 2022 22:06
@Gamrix Gamrix marked this pull request as ready for review June 22, 2022 22:07
Gamrix added a commit that referenced this pull request Jun 22, 2022
Copy link
Contributor

@robieta robieta left a comment

Choose a reason for hiding this comment

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

I have a couple nits, but overall looks good. Can you run the overhead benchmark to A/B test and see what the additional info costs?

buck build @mode/opt-clang //caffe2/caffe2/fb/high_perf_models/pytorch/benchmark_framework_overheads:cpp_benchmark
./buck-out/gen/caffe2/caffe2/fb/high_perf_models/pytorch/benchmark_framework_overheads/cpp_benchmark --useOutOfPlace --kinetoInputShapes

(Which, by the way, we should totally open source.)

} else if (value.isScalar()) {
tags_.emplace_back(Tag::Scalar);
// Scalars are small enough to store as IValues
ivalues_.emplace_back(value);
Copy link
Contributor

Choose a reason for hiding this comment

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

How does the perf of holding an IValue compare to storing the Scalar directly? In theory the latter should be cheaper, but if its not meaningfully different obviously IValue has a bunch of advantages.

Copy link
Contributor Author

@Gamrix Gamrix Jun 23, 2022

Choose a reason for hiding this comment

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

For trivially copyable datatypes (which includes all scalars), the only difference in performance between an IValue and a Scalar would be an extra check on the tag to see if it is trivially copyable, which should not be meaningfully different.

Both of them are tagged unions.

union Payload {
// We use a nested union here so that we can make the copy easy
// and efficient in the non-tensor (i.e., trivially copyable)
// case. Specifically, we do not have to do a switch-on-tag to
// figure out which union member to assign; we can just use
// TriviallyCopyablePayload::operator=.
union TriviallyCopyablePayload {
TriviallyCopyablePayload() : as_int(0) {}
int64_t as_int;
double as_double;
bool as_bool;
// Invariant: never nullptr; null state is represented as
// c10::UndefinedTensorImpl::singleton() for consistency of
// representation with Tensor.
c10::intrusive_ptr_target* as_intrusive_ptr;
struct {
DeviceType type;
DeviceIndex index;
} as_device;
} u;
at::Tensor as_tensor;
Payload() : u() {}
~Payload() {}
};

return next_++;
}

T* emplace_list(c10::ArrayRef<T> arg_list) {
Copy link
Contributor

Choose a reason for hiding this comment

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

A related follow up is directly using SizesAndStrides. (https://github.com/pytorch/pytorch/blob/master/c10/core/impl/SizesAndStrides.h) That, combined with a vectorized emplace would mean that most of the time we could store sizes and strides in a single memcpy.

}

T* emplace_list(c10::ArrayRef<T> arg_list) {
// TODO: Optimize this frther at a future date
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: further

AppendOnlyList<TensorMetadata, IO_ENCODER_DEFAULT_BLOCK_SIZE>
tensor_metadata_;
AppendOnlyList<int64_t, IO_ENCODER_DEFAULT_BLOCK_SIZE> tensor_sizes_;
AppendOnlyList<int64_t, IO_ENCODER_DEFAULT_BLOCK_SIZE> tensor_strides_;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason not to store sizes and strides in the same container? They're guaranteed to have the same size, so it's unambiguous during post processing. (And it should have modestly better cache behavior.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see any reason not to, but I will likely refactor into using SizesAndStrides as you suggested above.

# The second argument to the add gets promotoed to a zerodim Tensor
self.assertEqual(node.extra_fields.inputs.dtypes, ['float', 'double', 'Scalar'])
self.assertEqual(node.extra_fields.inputs.shapes, [[5, 5], [], []])
self.assertEqual(node.extra_fields.inputs.ivalues, [None, None, alpha])
Copy link
Contributor

Choose a reason for hiding this comment

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

Test for layout as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will pull the layout stuff into a separate diff, I need to expose the TensorMetadata struct to Python.

[](const Inputs& inputs) {
py::list list;
for (auto& v : inputs.ivalues_) {
list.append(torch::jit::toPyObject(v));
Copy link
Contributor

Choose a reason for hiding this comment

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

TIL

Gamrix added a commit that referenced this pull request Jun 30, 2022
@Gamrix
Copy link
Contributor Author

Gamrix commented Jul 1, 2022

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

Gamrix added a commit that referenced this pull request Jul 8, 2022
pytorchmergebot pushed a commit that referenced this pull request Jul 21, 2022
TensorMetadata will be used later to hold various metadata fields including sizes and strides.

This is basically me separating the following diff into its logical components after they all got smushed together
#80072
Pull Request resolved: #81155
Approved by: https://github.com/robieta
facebook-github-bot pushed a commit that referenced this pull request Jul 22, 2022
#81155)

Summary:
TensorMetadata will be used later to hold various metadata fields including sizes and strides.

This is basically me separating the following diff into its logical components after they all got smushed together
#80072

Pull Request resolved: #81155
Approved by: https://github.com/robieta

Test Plan: contbuild & OSS CI, see https://hud.pytorch.org/commit/pytorch/pytorch/74c795871704114ef4a3c898dd388da84759d925

Reviewed By: jeanschmidt

Differential Revision: D38066982

Pulled By: jeanschmidt

fbshipit-source-id: a583ea42e0a3ed438923a1bd4ccd9c16e2ab9f69
@Gamrix
Copy link
Contributor Author

Gamrix commented Aug 8, 2022

Reopening this commit. In #81824 we concluded we would not do SizesAndStrides and go back to this method instead.

@Gamrix Gamrix marked this pull request as ready for review August 8, 2022 19:31
@Gamrix Gamrix requested review from aaronenyeshi and robieta August 8, 2022 21:48
@Gamrix
Copy link
Contributor Author

Gamrix commented Aug 10, 2022

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

Copy link
Contributor

@robieta robieta left a comment

Choose a reason for hiding this comment

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

LGTM.

@Gamrix
Copy link
Contributor Author

Gamrix commented Aug 16, 2022

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

@facebook-github-bot
Copy link
Contributor

@pytorchbot merge

(Initiating merge automatically since Phabricator Diff has merged)

@pytorchmergebot
Copy link
Collaborator

@pytorchbot successfully started a merge job. Check the current status here.
The merge job was triggered without a flag. This means that your change will be merged once all checks on your PR have passed (ETA: 0-4 Hours). If this is not the intended behavior, feel free to use some of the other merge options in the wiki.
Please reach out to the PyTorch DevX Team with feedback or questions!

@github-actions
Copy link
Contributor

Hey @Gamrix.
You've committed this PR, but it does not have both a 'release notes: ...' and 'topics: ...' label. Please add one of each to the PR. The 'release notes: ...' label should represent the part of PyTorch that this PR changes (fx, autograd, distributed, etc) and the 'topics: ...' label should represent the kind of PR it is (not user facing, new feature, bug fix, perf improvement, etc). The list of valid labels can be found here for the 'release notes: ...' and here for the 'topics: ...'.
For changes that are 'topic: not user facing' there is no need for a release notes label.

facebook-github-bot pushed a commit that referenced this pull request Aug 17, 2022
Summary: Pull Request resolved: #80072

Test Plan: Imported from OSS

Reviewed By: robieta

Differential Revision: D37571570

Pulled By: Gamrix

fbshipit-source-id: 2ea2056b6a498b2a6aea77bece57090845580503
@facebook-github-bot facebook-github-bot deleted the gh/gamrix/77/head branch August 20, 2022 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants