-
Notifications
You must be signed in to change notification settings - Fork 754
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
[SYCL] Add support for union types as kernel parameter #2285
Conversation
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
@erichkeane, I have not added any tests yet. I am working on it. This patch adds the changes from PR #2270 and adds a separate handler SyclKernelUnionBodyChecker for the diagnostic. Could you please review this change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks right to me. When writing the union tests, make sure you use one in an array to make sure it is properly passed. Also, a struct-with-an-array-of-unions, and a array-of-struct-with-a-union.
Otherwise, LGTM once we get sufficient tests.
Thanks Erich for the review and comments. The following test compiles fine. I am passing accessor array as a member inside union. @erichkeane any thought? smanna@scsel-cfl-05:/export/iusers/smanna/myworkws/llvm/clang/test/SemaSYCL$ cat test.cpp #include <sycl.hpp> using namespace cl::sycl; template <typename name, typename Func> int main() { using Accessor = union union_acc_t { a_kernel( |
Hmm... do you perhaps also have to handle the array-element function? Or is that not properly visiting its types? @elizabethandrews : Do you know why the visitor wouldn't be visiting the elements of an array? |
I don't know why it wouldn't visit the elements. I haven't had a chance to look at Erich's template changes properly. I need to actually step through it to understand what is happening. It is quite complicated. Array elements are handled in VisitElement. Am I right in understanding that the call to 'handleSyclAccessorType' here should call the handler defined in SyclKernelUnionBodyChecker? |
I don't think my union changes really matter here. I'd expect the visitor to visit the elements themselves (via VisitUnion?), then each of the sub-elements to it. VisitElement calls VisitUnion in this patch, so I'd expect that to work? Or did I screw up the visiting there or something? Perhaps we need a bit of time to be debugging. |
The handlers in VisitElement are to handle individual elements of an array. For example, add __init calls for each accessor element. I don't fully understand your patch yet. I need to step through it but I think VisitUnion here means you're handling an array of unions. |
Ah, I might have it :) The union-checker is never added in ConstructOpenCLKernel as a new visitor! Add it after 'checker'. |
I see that we have added " SyclKernelFieldChecker" in two places: I have not added "SyclKernelUnionBodyChecker " anywhere in the patch. This might cause the issue here. |
You need it in the ConstructOpenCLKernel function (see my response right above yours :) ) |
Yes, i missed this. Thanks Erich. |
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, this needs a test to show the diagnostics happening.
Yes, i am missing diagnostic tests. UnionBodyChecker seems like not working properly. I am debugging this issue. The following test expects to fail since we are trying to pass accessor array inside union. This test generates no diagnostic. Same is happening with sampler/stream.
// RUN: %clang_cc1 -I %S/Inputs -fsycl -fsycl-is-device -fcxx-exceptions -verify -fsyntax-only %s
#include <sycl.hpp>
using namespace cl::sycl;
template <typename name, typename Func>
attribute((sycl_kernel)) void a_kernel(Func kernelFunc) {
kernelFunc();
}
int main() {
using Accessor =
accessor<int, 1, access::mode::read_write, access::target::global_buffer>;
union union_acc_t {
Accessor member_acc[2];
} union_acc;
a_kernel(
= {
union_acc.member_acc[2].use();
});
}
clang/lib/Sema/SemaSYCL.cpp
Outdated
// A type to Create and own the FunctionDecl for the kernel. | ||
class SyclKernelDeclCreator : public SyclKernelFieldHandler { | ||
FunctionDecl *KernelDecl; | ||
llvm::SmallVector<ParmVarDecl *, 8> Params; | ||
SyclKernelFieldChecker &ArgChecker; | ||
SyclKernelUnionBodyChecker &ArgChecker1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably call this 'UnionChecker'. Additionally, note that #2289 makes this part unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I will change that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, looking again, adding ArgChecker1 is completely unnecessary. ArgChecker itself is completely unnecessary here too (and likely should be removed). I remove it in #2289 (depending on when that gets in), but it seems to be a leftover from when it was necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like only place we can add this handler "SyclKernelUnionBodyChecker checker1(*this)" to ConstructOpenCLKernel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I thought you would have noticed trying to debug why diagnostics weren't working right, but it needs to be added to these two lines instead:
Visitor.VisitRecordBases(KernelObj, checker, kernel_decl, kernel_body,
int_header);
Visitor.VisitRecordFields(KernelObj, checker, kernel_decl, kernel_body,
int_header);
// CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = { | ||
// CHECK-NEXT: //--- _ZTSZZ5test0vENK3$_0clERN2cl4sycl7handlerEE8MyKernel | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 0 }, | ||
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 12, 16 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is right, is it? 'S' is just the union, right? We should be capturing that as a single std_layout, not as however many these are.
} | ||
} | ||
|
||
// CHECK MyKernel parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elizabethandrews can you take a look at this? The union should be a simple un-decomposed value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the Sema tests below, it looks like parameters are being passed individually as well? This in incorrect right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the test seems incorrect. I will update the test. Thanks Erich and Elizabeth.
// Check kernel_A parameters | ||
// CHECK: FunctionDecl {{.*}}kernel_A{{.*}} 'void (union union_acc_t, int, int)' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_ 'union union_acc_t':'union_acc_t' | ||
// CHECK-NEXT: ParmVarDecl {{.*}} used _arg_member_acc 'int' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks decomposition is happening ? member_acc is the union array. This should not be passed as individual parameters right? It looks like you are passing the 'not-decomposed' union as well as it's fields?
|
||
typedef float realw; | ||
|
||
typedef union dpct_type_54e08f { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add more than one field in this union? Also why do we need the typedefs? A simple test with 2-3 non-array fields will be best to check basic functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! I also want to see an:
array of unions. (should be 1 union per element)
Array of structs-with-unions. (should be decomposed structs, but unions still only a single).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update tests.
clang/lib/Sema/SemaSYCL.cpp
Outdated
// A type to check the validity of passing union with accessor/sampler/stream | ||
// member as a kernel argument types. | ||
class SyclKernelUnionBodyChecker : public SyclKernelFieldHandler { | ||
static constexpr const bool VisitUnionBody = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your problem is that SyclKernelFieldHandler needs this line as well, except =false instead.
I think that results in the union-filtering not actually doing anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think that results in the union-filtering not actually doing anything.
Yes, Thanks Erich.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find where it is done, that might be the reason why everything is decomposed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it should be in the base class, not just the other checker. WHich is why the tests are still wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I NEED us to be able to catch that missed constexpr variable, so please change the visitor to be like this: Changes: This will prevent silently missing that the flag is missing. EDIT: Disregard the printf statements I added in that :) Those were for my own debugging. |
I tried this simple union test without array. The AST looks like this. union MyUnion { template <typename name, typename Func> int main() { a_kernel( @erichkeane, Are we expecting this AST syntax ? FunctionDecl 0x55d691256088 <line:26:7, > col:7 _ZTSZ4mainE6kernel 'void (MyUnion, int, char, float)' |
No, arg_x, arg_y, and arg_cuda shouldn't end up in there. For some reason, this is still visiting places it shouldn't. Do you have the latest patch up that someone can take a look at? I will check with Maria and Elizabeth tomorrow and I will upload latest patch. |
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Sorry for the multiple submissions. Clang format took wrong patches. This is fixed now. |
@elizabethandrews , @Fznamznon,, @premanandrao could you please review the support? Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of minors in tests, otherwise looks ok
#include <sycl.hpp> | ||
|
||
using namespace cl::sycl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see usage of this include. Let's remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
#include <sycl.hpp> | ||
|
||
using namespace cl::sycl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Signed-off-by: Soumi Manna <soumi.manna@intel.com>
Thanks everyone for the reviews. |
Preserve DIExpression in DIGlobalVariableExpression. Preserving DIExpressions is necessary because of this change in LLVM: commit 638a839 Author: Michael Buch michaelbuch12@gmail.com Date: Mon Nov 13 06:04:27 2023 +0000 Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (#71780) Original commit: KhronosGroup/SPIRV-LLVM-Translator@9edf714
This patch adds support for union types kernel arguments.
- Add 'VisitUnion' function.
- Add separate handler to implement a diagnostic on attempt to pass union with accessor/sampler/stream member
as a kernel argument.
- Add CodeGen/Sema/Intengreation header/runtime tests.
Signed-off-by: Soumi Manna soumi.manna@intel.com