Skip to content
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

Clean up index type handling #2570

Merged
merged 10 commits into from
Mar 10, 2023
Merged

Clean up index type handling #2570

merged 10 commits into from
Mar 10, 2023

Conversation

naoyam
Copy link
Collaborator

@naoyam naoyam commented Mar 10, 2023

This is a cleanup PR of the code around the kernel index mode/type.

  • FusionExecutor::compileFusion respects the optional index type parameter if given. Previously, it wasn't used at all. The index type is now used as long as it doesn't conflict with the required index type for the given kernel inputs. More specifically, if the index type is int32, but the kernel inputs need int64, it throws an error. On the other hand, int64 index type is allowed even when the kernel inputs are small enough to use int32.
  • FusionExecutor::runFusion also has an option, CompileParams, which includes an index type. It's just unused before. It's now an error if a different index type is passed since the index type of a Kernel is immutable.
  • The index type of Kernel must not be DataType::Index and must be either Int or Int32. Currently we assume the index type is resolved at the time when a Fusion is lowered to a Kernel and then it's immutable. We could relax this restriction, but that's not part of this PR.
  • Previously, both a SchedulerEntry and its HeuristicParams have index type info. It seems the one of HeuristicParams wasn't used. Removed the one from SchedulerEntry, and made sure the one of HeuristicParams is used.

I'm sure we could do more, but I'll stop here for now.

Note that this does not address the issues @mmigdal-nv attempted to fix (#2522). Notably, these remain:

  1. We only look at kernel inputs to determine index type. Intermediate and output tensors are not considered, which can result in underestimate.
  2. Once a Fusion is lowered to a Kernel, its index type cannot be changed. I believe we could relax this constraint, but it's unclear how important it would be. We don't want to compile back and forth between int32 and int64, so we would need to keep two compiled kernel images of a single Kernel. This would certainly reduce the overhead of lowering a Fusion to a Kernel as it would need to be done just once for both int32 and int64, but the nvrtc compilation still needs to be done twice. And it only matters when the (rest of) scheduler heuristics are the same for problem sizes that range from small enough to use int32 and to large enough to use int64.

I think issue 1 is important and should be fixed, but the second one doesn't seem that urgent.

@naoyam naoyam marked this pull request as ready for review March 10, 2023 19:08
@naoyam
Copy link
Collaborator Author

naoyam commented Mar 10, 2023

All tests are green.

I was concerned if there would be any change with the benchmarks, but I confirmed all of the generated CUDA kernels (i.e., __tmp_kernel*.cu) are exactly the same as before, so I'm pretty confident nothing changes.

@naoyam naoyam requested a review from zasdfgbnm March 10, 2023 19:10
@naoyam naoyam changed the title [WIP] Clean up index type handling Clean up index type handling Mar 10, 2023
Copy link
Collaborator

@zasdfgbnm zasdfgbnm left a comment

Choose a reason for hiding this comment

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

Thank you for the cleanup! Left some minor comments.

third_party/nvfuser/csrc/executor_params.h Outdated Show resolved Hide resolved
third_party/nvfuser/test/test_gpu3.cpp Outdated Show resolved Hide resolved
at::Tensor t0 = at::randn({999}, options);
std::vector<c10::IValue> small_inputs = {t0, t0};

at::Tensor t0_large = at::randn({std::numeric_limits<int>::max()}, options);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it be safer to use (int64_t)std::numeric_limits<int>::max() + 1? In theory std::numeric_limits<int>::max() is still indexable with 32bit indexing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This assumes how we determine the index mode, i.e., we only allow up to half of the int32 max. If this assumption breaks, the TORCH_ERROR about large_inputs should break, so this should be fine.

third_party/nvfuser/csrc/executor.cpp Outdated Show resolved Hide resolved
@@ -135,7 +135,8 @@ bool PointerOf::operator==(const PointerOf& other) const {

enum class KernelIndexMode { INT32, INT64 };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not blocking this PR because this PR is already making the logic much more clear, but I think we should consider completely remote KernelIndexMode and just use PrimDataType wherever KernelIndexMode was used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Generally agreed, and I did consider it as well, but technically speaking, KernelIndexModel would allow something more than just always int32 or int64, although I don't have any specific idea.

@naoyam naoyam merged commit 3c4b3da into devel Mar 10, 2023
@zasdfgbnm zasdfgbnm deleted the index_type_validation branch March 10, 2023 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants