[cfe-dev] [RFC] Re-use OpenCL address space attributes for SYCL

John McCall via cfe-dev cfe-dev at lists.llvm.org
Thu Aug 6 12:50:57 PDT 2020


On 6 Aug 2020, at 15:11, Anastasia Stulova wrote:
> Just to make it clear - C++ libraries or any existing C++ code doesn't
> necessarily stop to compile if address space attributes are being 
> used. It only
> fails on illegal use of address spaces defined by Embedded C spec from 
> where
> the implementation originates.

Alexey is correct that C and C++ require that if a variable `x` has type
`T`, the expression `&x` must have type `T *`.  Anything else is not
strictly conformant, whether it compiles or not.  OpenCL is therefore
not strictly conformant to the C/C++ specification, and that’s fine
because OpenCL is an independent language, not just a language 
extension;
it happens to be defined using C/C++ as a base specification, but its
modifications are always authoritative.  But as I understand it, Alexey
just wants a conformant C++ implementation on a different target, and
so needs to follow the rules.

It’s good that libc++ is broadly permissive about types qualified
with address spaces, but that doesn’t really change anything.

John.

>
> For example, we have made an evaluation by running type trait tests 
> from libcxx
> with a standard header in OpenCL mode and only a few tests failed due 
> to
> the address spaces. None of those required changes in the libcxx code. 
> Instead,
> they have revealed bugs in clang (that were fixed in release 11 btw) 
> and issues in
> tests due to illegal behavior. These issues are expected for the 
> address space
> attributes as there are extra restriction and rules on types 
> attributed by the
> address spaces that come from Embedded C. If these restrictions are 
> not desirable
> I feel the desirable behavior might be significantly different from 
> the intended use
> of address space attributes and therefore it might be better to look 
> at alternative
> approaches including adding a dedicated attribute that doesn't 
> propagate into a type
> qualifier at all.
>
>> casting a names address space pointer to "generic" pointer is valid 
>> operation
> in all GPGPU programming models I'm aware of (including OpenCL)
>
> I would like to highlight that generic address space and address space
> conversions have only been added in OpenCL 2.0. Furthermore, generic 
> address
> space is becoming optional functionality in OpenCL 3.0.
>
> Cheers,
> Anastasia
>
> ________________________________
> From: Bader, Alexey <alexey.bader at intel.com>
> Sent: 30 July 2020 20:51
> To: David Rector <davrecthreads at gmail.com>; Anastasia Stulova 
> <Anastasia.Stulova at arm.com>
> Cc: cfe-dev (cfe-dev at lists.llvm.org) <cfe-dev at lists.llvm.org>; 
> rjmccall at apple.com <rjmccall at apple.com>; nd <nd at arm.com>
> Subject: RE: [cfe-dev] [RFC] Re-use OpenCL address space attributes 
> for SYCL
>
>
> David's understanding is right. We would like to be able to call 
> existing C++
>
> functions from SYCL applications as much as possible.
>
>
>
> I don't know if analogy with the "const" qualifier is a perfect match 
> here, but
>
> casting a names address space pointer to "generic" pointer is valid 
> operation in
>
> all GPGPU programming models I'm aware of (including OpenCL). 
> "generic" means
>
> that memory can be allocation in any address space, so compiler can't 
> assume any
>
> specific address space and must generate code which is valid for any 
> address
>
> space. Usually it implies runtime overhead on checking the value of 
> "generic"
>
> pointer to handle it properly.
>
>
>
>> Alexey et al's alternative to prevent this breakage, if I understand
>
>> correctly, is to remove the type qualifier, and instead handle all 
>> address
>
>> space semantics in CodeGen (I believe this is what you refer to as 
>> keeping the
>
>> address space "flat").
>
>
>
> Not exactly. It works as what you described below - "the ideal". We 
> keep address
>
> space qualifier if user explicitly applied it, but the difference with 
> OpenCL
>
> mode is that "implicit" address space is the same as in regular C++ 
> (i.e.
>
> default) and we allow conversion to "default" C++ address spaces from 
> explicitly
>
> set named address spaces. C++ "default" is treated as "generic" w/o 
> changing C++
>
> default address space to OpenCL "generic" address space in Sema type 
> system.
>
> When SYCL users access memory though SYCL library API memory pointers 
> will be
>
> annotated with address space attributes to ensure good performance. 
> Users can
>
> obtain a "raw" pointer from SYCL objects to pass it to some generic 
> C++ function
>
> and this use case is enabled by the patch 
> https://reviews.llvm.org/D80932.
>
>
>
>> It seems to me that approach is not ideal, though, because
>
>>   a) it seems they would lose the type-checking benefits of 
>> implementing as a
>
>>  type qualifier (e.g. imagine if "const" qualifiers were removed and 
>> handled
>
>>  instead in CodeGen), and
>
>>  b) I think it really is important for the AST to maintain a clear
>
>>   representation of all target-independent semantics, including 
>> address
>
>>   spaces, so that users can easily reason about their code in AST 
>> matchers
>
>>   etc.
>
>
>
> Address space attributes are preserved in AST if they are applied 
> explicitly on
>
> source code, but they are not implicitly applied to all types.
>
> Type-checking is performed for OpenCL address space attributes (e.g. 
> casts
>
> between "named" address spaces are not allowed) and C++ type 
> qualifiers like
>
> "const" are respected.
>
>
>
>> So the ideal, it seems to me, for everyone’s sake, would be for 
>> OpenCL
>
>> qualifiers to behave more like "const" — there would be a default, 
>> a la
>
>> "non-const", that is applied to all types not explicitly qualified, 
>> so that
>
>> one could enable OpenCL mode and regular code would still work by 
>> default.
>
>
>
> I believe it's what we have in our implementation.
>
>
>
>> In reality though, I imagine this has all already been thought over
>
>> thoroughly, and it has been determined it really is unavoidable to 
>> break
>
>> standard C++ semantics in order to support address spaces; that there 
>> really
>
>> is no default that could be inferred for arbitrary types like those 
>> used in
>
>> template arguments.
>
>
>
>> But perhaps it is worthwhile to think it through one more time, to 
>> question
>
>> whether there may be some way to deduce type qualifiers properly in 
>> every
>
>> case, because the issue that Alexey et al raise is a good one I 
>> think.
>
>
>
> There is LLVM transformation pass which infers address space 
> information at LLVM
>
> IR level: https://llvm.org/doxygen/InferAddressSpaces_8cpp_source.html
>
> It helps to avoid performance overhead for regular C++ code called 
> from SYCL
>
> annotated parts.
>
>
>
> From: David Rector <davrecthreads at gmail.com>
> Sent: Thursday, July 30, 2020 2:33 AM
> To: Anastasia Stulova <Anastasia.Stulova at arm.com>
> Cc: Bader, Alexey <alexey.bader at intel.com>; cfe-dev 
> (cfe-dev at lists.llvm.org) <cfe-dev at lists.llvm.org>; rjmccall at apple.com; 
> nd <nd at arm.com>
> Subject: Re: [cfe-dev] [RFC] Re-use OpenCL address space attributes 
> for SYCL
>
>
>
> If I understand their proposal correctly, from the discussion Alexey 
> linked to in https://reviews.llvm.org/D80932#2073542, the primary 
> motivation for their implementation — its main distinction from 
> OpenCL’s approach -- is that they want to support address spaces in 
> such a way that existing C++ files without any address space markings 
> can still compile as is.
>
>
>
> That definitely seems like a worthy goal if it could be properly 
> accomplished.
>
>
>
> Take, for instance, the "const" qualifier.  Code which never uses it 
> whatsoever still works by default; only when we start adding "const" 
> into our code could we possibly start breaking other code.  That is 
> the ideal way to introduce a language feature: old code still works, 
> but now people can opt in to the new stuff.
>
>
>
> If instead const-ness had been implemented by allowing each type to be 
> either "const" or (let’s say) "mutable" *or neither*, and what is 
> more we implicitly added "mutable" when no such marking was provided 
> to some *but not all* types, then the users would not have the option 
> of ignoring it altogether, it would be a real headache.
>
>
>
> This seems to be how OpenCL is implemented, as Alexey et al identify 
> in the discussion linked above: certain VarDecl types get an implicit 
> __private qualifier, but e.g. template argument types, and certain 
> other types (they give another example beyond std::is_same which 
> presents problems) get no such implicit qualifier, resulting in 
> possible breakage in any code whose address spaces have not been 
> closely considered.
>
>
>
> Alexey et al's alternative to prevent this breakage, if I understand 
> correctly, is to remove the type qualifier, and instead handle all 
> address space semantics in CodeGen (I believe this is what you refer 
> to as keeping the address space "flat").
>
>
>
> It seems to me that approach is not ideal, though, because
>
>   a) it seems they would lose the type-checking benefits of 
> implementing as a type qualifier (e.g. imagine if "const" qualifiers 
> were removed and handled instead in CodeGen), and
>
>   b) I think it really is important for the AST to maintain a clear 
> representation of all target-independent semantics, including address 
> spaces, so that users can easily reason about their code in AST 
> matchers etc.
>
>
>
> So the ideal, it seems to me, for everyone’s sake, would be for 
> OpenCL qualifiers to behave more like "const" — there would be a 
> default, a la "non-const", that is applied to all types not explicitly 
> qualified, so that one could enable OpenCL mode and regular code would 
> still work by default.
>
>
>
> In reality though, I imagine this has all already been thought over 
> thoroughly, and it has been determined it really is unavoidable to 
> break standard C++ semantics in order to support address spaces; that 
> there really is no default that could be inferred for arbitrary types 
> like those used in template arguments.
>
>
>
> But perhaps it is worthwhile to think it through one more time, to 
> question whether there may be some way to deduce type qualifiers 
> properly in every case, because the issue that Alexey et al raise is a 
> good one I think.
>
>
>
> On Jul 29, 2020, at 5:42 PM, Anastasia Stulova 
> <Anastasia.Stulova at arm.com<mailto:Anastasia.Stulova at arm.com>> wrote:
>
>
>
>> I am not well-versed in this, but just thinking about these as 
>> arbitrary type qualifiers: could the issue be simply that the 
>> implicitly-generated address space qualifiers are *only* being added 
>> to the types of VarDecls, rather than to *every* type, including 
>> pointee types, template argument types, etc.?
>
>
>
> It is a little bit more complex than that. Most of the types used with 
> objects in OpenCL will get an address space deduced including pointer 
> types. This is because OpenCL is a language dialect for memory 
> segmented architectures and the memory segments pose some limitations 
> resulting in extra language rules. Clang strictly follows OpenCL 
> language spec and  I don't see any issue in the examples Alexey has 
> referred to. If the types differ by address space is_same is expected 
> to return false.
>
> What I struggle to understand how does this affects SYCL at all? The 
> deduction of address spaces is guarded by OpenCL language mode and it 
> is not set for SYCL as far as I am aware.
>
>
>
>> If it did, I believe those examples would all compile, and code would 
>> only break when the user specified began specifying non-default 
>> address spaces
>
>
>
> If I understand the design Alexey is proposing correctly the 
> user-specified address spaces are cast to the default address spaces 
> "hiddenly" and the AST always ends up to be in flat address space. 
> This is why I don't see the address space as a good fit. However, I am 
> not sure this is explained explicitly in the RFC, I might have 
> remembered this from some other discussions.
>
>
>
> ________________________________
>
> From: David Rector 
> <davrecthreads at gmail.com<mailto:davrecthreads at gmail.com>>
> Sent: 27 July 2020 22:32
> To: Bader, Alexey 
> <alexey.bader at intel.com<mailto:alexey.bader at intel.com>>
> Cc: Anastasia Stulova 
> <Anastasia.Stulova at arm.com<mailto:Anastasia.Stulova at arm.com>>; cfe-dev 
> (cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>) 
> <cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>>; 
> rjmccall at apple.com<mailto:rjmccall at apple.com> 
> <rjmccall at apple.com<mailto:rjmccall at apple.com>>; nd 
> <nd at arm.com<mailto:nd at arm.com>>
> Subject: Re: [cfe-dev] [RFC] Re-use OpenCL address space attributes 
> for SYCL
>
>
>
> On Jul 27, 2020, at 12:18 PM, Bader, Alexey via cfe-dev 
> <cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>> wrote:
>
>>> I don't think (2) deal with language semantics. I assume we both 
>>> talking about
>
>>> the same case when variable declaration is not explicitly annotated 
>>> with address
>
>>> space attribute. According to language semantics such objects are 
>>> allocated in
>
>>> generic address space, but the problem is that most OpenCL 
>>> implementations have
>
>>> problems with consuming SPIR-V files with global variables in 
>>> generic address
>
>>> space. As an alternative to CodeGen changes we can consider handling 
>>> this issue
>
>>> in SPIR-V translator tool.
>
>>
>
>>
>
>> I am not really a CodeGen expert, maybe it will be ok. I think it's 
>> better if you discuss
>
>> it with John McCall or someone who is more experienced with CodeGen 
>> architecture.
>
>>
>
>> Why don't you just do regular address space deduction in Sema and 
>> then cast the
>
>> deduced address space to generic straight after? You already add 
>> similar casts for
>
>> pointers that are annotated with address spaces through the user 
>> code, right?
>
>> This approach will probably allow to reuse the logic from OpenCL and 
>> simplify CodeGen.
>
>
>
> I don't see how it can be done without breaking C++ semantics 
> demonstrated in
>
> https://reviews.llvm.org/D80932#2073542.
>
>
>
> I am not well-versed in this, but just thinking about these as 
> arbitrary type qualifiers: could the issue be simply that the 
> implicitly-generated address space qualifiers are *only* being added 
> to the types of VarDecls, rather than to *every* type, including 
> pointee types, template argument types, etc.?
>
>
>
> I.e., referring to the examples linked to above: perhaps the problem 
> is *not* that that OpenCL changes `int var` to `__private int var`, 
> but rather that it does not *also* change `int* ptr1 = &var` to 
> `__private int* __private ptr1 = &var` (or whatever the proper default 
> qualifiers are) and `std::is_same<T, int>` to `std::is_same<T, 
> __private int>` when in OpenCL (or SYCL) mode.
>
>
>
> If it did, I believe those examples would all compile, and code would 
> only break when the user specified began specifying non-default 
> address spaces, i.e. when they actually used the feature in their 
> code.  In this way, the non-standard semantics could be represented in 
> the AST without affecting the standard semantics.
>
>
>
> In any case that is the form of the ideal solution: sure, don’t 
> break the standard C++ semantics, but also, try to keep a clear 
> representation of any supported-but-non-standard semantics in the AST, 
> I think.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200806/4102a987/attachment-0001.html>


More information about the cfe-dev mailing list