Skip to content

[SYCL] Add element size argument to piKernelSetArg #5104

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

Closed
wants to merge 1 commit into from

Conversation

npmiller
Copy link
Contributor

@npmiller npmiller commented Dec 8, 2021

This patch comes from an attempt to fix #5007.

The issue there is that for local kernel argument the CUDA plugin uses
CUDA dynamic shared memory, which gives us a single chunk of shared
memory to work with.

The CUDA plugin then lays out all the local kernel arguments
consecutively in this single chunk of memory.

And this can cause issues because simply laying the arguments out one
after the other can result in misaligned arguments. In #5007 for example
there is an int argument followed by a double4 argument, so the
double4 argument ends up with the wrong alignment, only being aligned
on a 4 bytes boundary following from the int.

It is possible to adjust this and fixup the alignment when laying out
the local kernel arguments in the CUDA plugin, however before this patch
the only information in the plugin would be the total size of local
memory required for the given arguments, which doesn't tell us anything
about the required alignment.

So this patch propagates the size of the elements inside of the
local accessor all the way down to the PI plugin through
piKernelSetArg, and tweaks the local argument layout in the CUDA
plugin to use the type size as alignment for local kernel arguments.

I'm not entirely sure if this is the best approach so feedback on this would be appreciated, this patch may also need to be refined for naming and/or position of the extra argument, however it does fix the issue in #5007

This patch comes from an attempt to fix intel#5007.

The issue there is that for local kernel argument the CUDA plugin uses
CUDA dynamic shared memory, which gives us a single chunk of shared
memory to work with.

The CUDA plugin then lays out all the local kernel arguments
consecutively in this single chunk of memory.

And this can cause issues because simply laying the arguments out one
after the other can result in misaligned arguments. In intel#5007 for example
there is an `int` argument followed by a `double4` argument, so the
`double4` argument ends up with the wrong alignment, only being aligned
on a 4 bytes boundary following from the `int`.

It is possible to adjust this and fixup the alignment when laying out
the local kernel arguments in the CUDA plugin, however before this patch
the only information in the plugin would be the total size of local
memory required for the given arguments, which doesn't tell us anything
about the required alignment.

So this patch propagates the size of the elements inside of the
local accessor all the way down to the PI plugin through
`piKernelSetArg`, and tweaks the local argument layout in the CUDA
plugin to use the type size as alignment for local kernel arguments.
@npmiller npmiller requested review from smaslov-intel and a team as code owners December 8, 2021 14:31

cl::sycl::detail::kernel_param_kind_t MType;
void *MPtr;
int MSize;
int MIndex;
int MElemSize;
Copy link
Contributor

Choose a reason for hiding this comment

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

The patch should break ABI since this structure crosses library boundaries. Breaking ABI is not allowed right now.

@romanovvlad
Copy link
Contributor

I'm not entirely sure if this is the best approach so feedback on this would be appreciated, this patch may also need to be refined for naming and/or position of the extra argument, however it does fix the issue in #5007

Can we use the strictest required alignment for vector operations as a default alignment, which I believe it should be sizeof(double) * 16 ?
It could be optimized for small values like: alignment = min(sizeof(double) * 16, arg_size);

@npmiller
Copy link
Contributor Author

npmiller commented Dec 9, 2021

I'm not entirely sure if this is the best approach so feedback on this would be appreciated, this patch may also need to be refined for naming and/or position of the extra argument, however it does fix the issue in #5007

Can we use the strictest required alignment for vector operations as a default alignment, which I believe it should be sizeof(double) * 16 ? It could be optimized for small values like: alignment = min(sizeof(double) * 16, arg_size);

Yeah, after looking at this a bit more I think you're right, we could use the largest vector size for this, I'll close this PR and open a separate one with a change to that effect.

@npmiller npmiller closed this Dec 9, 2021
npmiller added a commit to npmiller/llvm that referenced this pull request Dec 9, 2021
The issue there is that for local kernel argument the CUDA plugin uses
CUDA dynamic shared memory, which gives us a single chunk of shared
memory to work with.

The CUDA plugin then lays out all the local kernel arguments
consecutively in this single chunk of memory.

And this can cause issues because simply laying the arguments out one
after the other can result in misaligned arguments.

So this patch is changing the argument layout to align them to the
maximum necessary alignment which is the size of the largest vector
type. Additionally if there is a local buffer smaller than this maximum
alignment, the size of that buffer is simply used for alignment.

This fixes the issue in intel#5007.

See also the discussion on intel#5104 for alternative solution, that may be
more efficient but would require a more intrusive ABI changing patch.
bader pushed a commit that referenced this pull request Jan 10, 2022
The issue there is that for local kernel argument the CUDA plugin uses
CUDA dynamic shared memory, which gives us a single chunk of shared
memory to work with.

The CUDA plugin then lays out all the local kernel arguments
consecutively in this single chunk of memory.

And this can cause issues because simply laying the arguments out one
after the other can result in misaligned arguments.

So this patch is changing the argument layout to align them to the
maximum necessary alignment which is the size of the largest vector
type. Additionally if there is a local buffer smaller than this maximum
alignment, the size of that buffer is simply used for alignment.

This fixes the issue in #5007.

See also the discussion on #5104 for alternative solution, that may be
more efficient but would require a more intrusive ABI changing patch.
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.

[SYCL][CUDA][HIP] warp misaligned address on CUDA and results mismatch on HIP
2 participants