<div dir="ltr">Hi Justin,<div class="gmail_extra"><br><div class="gmail_quote">2016-03-04 14:34 GMT-05:00 Justin Lebar via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>> This has two objectives. One is to avoid the creation of actions that are programming model specific. The other is to remove complexity from the action creation that would have to mix phases and different programming models DAG requirements<br>
<br>
</span>As I understand this, we're saying that we'll build up an action<br>
graph, but it is sort of a lie, in that it does not encapsulate all of<br>
the logic we're interested in.  Then, when we convert the actions into<br>
jobs, we'll postprocess them using language-specific logic to make the<br>
jobs do what we want.<br>
<br>
I am not in favor of this approach, as I understand it.  Although I<br>
acknowledge that it would simplify building the Action graph itself,<br>
it does so by moving this complexity into a "shadow Action graph" --<br>
the DAG that *actually* describes what we're going to do (which may<br>
never be explicitly constructed, but still exists in our minds).  I<br>
don't think this is actually a simplification.<br>
<br>
If, as you say, building the Action graph for CUDA and OpenMP is<br>
complicated, I think we should fix that.  Then we'll be able to<br>
continue using our existing tools to e.g. inspect the Action graph<br>
generated by the driver.<br></blockquote><div><br></div><div>Ok, I guess we had different a interpretation of what an Action and a Job mean in this context, which is fine. I was seeing "action" as "what has to be done for each file" and jobs as "what each toolchain does to make that happen under a given programming model". If we don't have a distinction like this, it makes it a little harder for me to understand why we need Action and then Jobs (maybe because of the bound arch?), instead of doing everything at once.   </div><div><br></div><div>In terms of the actions generation, OpenMP adds a little more complexity because a device action depends on a host action and then a host action depends on a device action. So the actions for host and device would have to be generated in lock step. So it wouldn't be as clean as the way you have it today for CUDA. Adding separate compilation will make things a little messier and adding other programming models with different requirements would make things even worse.</div><div><br></div><div>Doing this with the support of the CachedResult during the generation of the jobs would be almost trivial, non-intrusive, and would avoid having to create actions that are programming model specific.<br></div><div><br></div><div>In any case, I see why you would prefer to work on the actions - it would be nice to see the graph to diagnose problems - and I'm fine with trying to find a way to generalize the creation of the action for  different programming models.</div><div><br></div><div>So, in your opinion, should we create an action for each programing model or should we have a generic one?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span><br>
> I see the driver already as a wrapper, so I don't think it is not appropriate to use it.<br>
<br>
</span>You and I, being compiler hackers, understand that the driver is a<br>
wrapper.  However, to a user, the driver is the compiler.  No build<br>
system invokes clang -cc1 directly.<br>
<span><br>
> However, I think the creation of the blob should be done by an external tool, say, as it was a linker.<br>
<br>
</span>Sure, but this isn't the difference I was getting at.  What I was<br>
trying to say is that the creation of the blob should be done by a<br>
tool which is external to the compiler *from the perspective of the<br>
user*.  Meaning that, the driver should not invoke this tool.  If the<br>
user wants it, they can invoke it explicitly (as they might use tar to<br>
bundle their object files).<br></blockquote><div><br></div><div>I'm not sure what is your point here. Maybe something that I said was misleading. I guess that, from a user viewpoint, this is what we have:</div><div><br></div><div>I have some application that I've been compiling with clang, and I usually just run "make". Now I read somewhere that a new release of clang has  support for CUDA and I happen to have a nice loop that I could implement with CUDA. So, I add a new file with the new implementation, then I run "make", it compiles but when I run it crashes. The reason it crashes is that I was using separate compilation and know I need to change all my makefile rules to forward a new kind of file, that I may not even know what it is.</div><div><br></div><div>I don't think that what you are suggesting is what the users are expecting from the compiler (the driver from our perspective). If you think about that, what NVCC does is more along the lines of what I propose: the user doesn't see any device files and do not have to understand what is a device file. </div><div><br></div><div>If the user, or a developer like you and me, wants to see the host and device files, he would use -save-temps, and I could use my debug tools on it.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span><br>
> I'd put it in this way: an bundled file should work as a normal host  file, regardless of what device code it embeds.<br>
<br>
</span>OK, but this still makes all existing tools useless if I want to<br>
inspect device code.  If you give me a .o file and tell me that it's<br>
device code, I can inspect it, disassemble it, or whatever using<br>
existing tools.  If it's a bundle in a file format we made up here on<br>
this list, there's very little chance existing tools are going to let<br>
me get the device code out in a sensible way.<br>
<br>
Again, I don't think that inventing file formats -- however simple --<br>
is a business that we should be getting into.<br>
<span><br>
> Even for ELF, I agree putting the code in some section is more elegant. I'll investigate the possibilities to implement that.<br>
<br>
</span>Maybe, but unless there's a way to annotate that section and say "this<br>
section contains code for architecture foo", then objdump isn't going<br>
to work sensibly on that section, and I think that's basically game<br>
over.<br></blockquote><div> </div><div>We can make the name of the section as descriptive as we want. Why, wouldn't that be sufficient?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span><br>
> In other side, we have text files. My opinion is that we should have something that is easy to read and edit. How would a bundled text file look like in your opinion?<br>
<br>
</span>Similarly, this will not interoperate with any existing tools, and I<br>
think that's job zero.<br></blockquote><div><br></div><div>Well, there is no single tool that would today understand two separate files that happen to be related. When using offloading, a device only makes sense if is going to be used with that specific host file. If I want to use the files individually (because I happen to now those formats well and I am a compiler hacker) I'd use save-temps, or even unbundle with some tool that comes with clang.</div><div><br></div><div>If someone wants to check the IR, or assembly I think we should give him an easy way to do it without having to track which file matches this other file. Don't you think?</div><div><br></div><div>Thanks!</div><div>Samuel</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><div><br>
On Fri, Mar 4, 2016 at 11:06 AM, Samuel F Antao <<a href="mailto:sfantao@us.ibm.com" target="_blank">sfantao@us.ibm.com</a>> wrote:<br>
> Hi Justin,<br>
><br>
> It's great to have your feedback!<br>
><br>
> 2016-03-03 17:09 GMT-05:00 Justin Lebar via cfe-dev<br>
> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>:<br>
>><br>
>> Hi, I'm one of the people working on CUDA in clang.<br>
>><br>
>> In general I agree that the support for CUDA today is rather ad-hoc; it<br>
>> can<br>
>> likely be improved.  However, there are many points in this proposal that<br>
>> I do<br>
>> not understand.  Inasmuch as I think I understand it, I am concerned that<br>
>> it's<br>
>> adding a new abstractions instead of fixing the existing ones, and that<br>
>> this<br>
>> will result in a lot of additional complexity.<br>
>><br>
>> > a) Create toolchains for host and offload devices before creating the<br>
>> > actions.<br>
>> ><br>
>> > The driver has to detect the employed programming models through the<br>
>> > provided<br>
>> > options (e.g. -fcuda or -fopenmp) or file extensions. For each host and<br>
>> > offloading device and programming model, it should create a toolchain.<br>
>><br>
>> Seems sane to me.<br>
>><br>
>> > b) Keep the generation of Actions independent of the program model.<br>
>> ><br>
>> > In my view, the Actions should only depend on the compile phases<br>
>> > requested by<br>
>> > the user and the file extensions of the input files. Only the way those<br>
>> > actions are interpreted to create jobs should be dependent on the<br>
>> > programming<br>
>> > model.  This would avoid complicating the actions creation with<br>
>> > dependencies<br>
>> > that only make sense to some programming models, which would make the<br>
>> > implementation hard to scale when new programming models are to be<br>
>> > adopted.<br>
>><br>
>> I don't quite understand what you're proposing here, or what you're trying<br>
>> to<br>
>> accomplish with this change.<br>
>><br>
>> Perhaps it would help if you could give a concrete example of how this<br>
>> would<br>
>> change e.g. CUDA or Mac universal binary compilation?<br>
>><br>
>> For example, in CUDA compilation, we have an action which says "compile<br>
>> everything below here as cuda arch sm_35".  sm_35 comes from a<br>
>> command-line<br>
>> flag, so as I understand your proposal, this could not be in the action<br>
>> graph,<br>
>> because it doesn't come from the filename or the compile phases requested<br>
>> by<br>
>> the user.  So, how will we express this notion that some actions should be<br>
>> compiled for a particular arch?<br>
><br>
><br>
> This has two objectives. One is to avoid the creation of actions that are<br>
> programming model specific. The other is to remove complexity from the<br>
> action creation that would have to mix phases and different programming<br>
> models DAG requirements - currently CUDA only requires one single dependency<br>
> but if you have more programming models with different requirements and add<br>
> separate compilation on top of that, the action generation will become<br>
> complex and hard to scale. Just to clarify, I am not saying that creating<br>
> actions for each programming model won't work, I just thing that doing this<br>
> differently will ensure that adding new programming models will be less<br>
> disruptive as the programming model specifics will be contained in a single<br>
> place.<br>
><br>
> The way I see it is that an action just packs some information processed<br>
> from a bunch of input info. However, creating an action specific for a<br>
> programming model does not prevent you from having to have dedicated logic<br>
> to deal with  it when the jobs are created. So, given that the input info<br>
> that results in an action is also available when the jobs are created, what<br>
> I propose it to do all the programming model specifics in a single place. We<br>
> already have a cache of results in the jobs builder that could help navigate<br>
> the dependences and, even better, the queries this cache can provide can be<br>
> completely agnostic of the programming model.<br>
><br>
> Let me try to give you an example on how this proposal would affect CUDA:<br>
><br>
> - Lets assume that the actions are generated the same way they are for the<br>
> host. And that we already have in the driver the host toolchain and also the<br>
> nvptx toolchain, each marked with a new toolchain kind "CUDA" (these<br>
> toolchain were inferred from the options used to invoke the driver and/or<br>
> file extensions).<br>
><br>
> - The jobs start to be created for the host as usual.<br>
><br>
> - Before the any job is constructed there would be a post-processing of the<br>
> results, so that extra results could be appended if required by the<br>
> programming model.<br>
><br>
> - This is what would happen in the post-processing function:<br>
> {<br>
>   if (!isThisCUDAHostToolChain)<br>
>     return;<br>
><br>
>   if (!ActionIsCompile)<br>
>     return;<br>
><br>
>   if (InputActionDependence.type != TY_CUDA)<br>
>     return;<br>
><br>
>   //Make checks currently in buildCudaActions()<br>
><br>
>   DevTC = getDeviceToolChainOfKind(CUDA);<br>
>   Action *Asm = CachedResults().giveMeDependentAsmAction();<br>
><br>
>   for (c : CUDAComputeCapabilities ) {<br>
>     NewResult = BuildJobsForAction(DevTC, Asm)<br>
>     // Or maybe better<br>
>     NewResult = BuildJobsForAction(DevTC, LinkAction(Asm))<br>
><br>
>     Results.push_back(NewResult);<br>
>   }<br>
> }<br>
><br>
> CachedResults would offer some extra functionality that is not programming<br>
> model specific, and this would provide the same functionality the CUDA<br>
> action is providing. Adding a new programming model would only require<br>
> adding an instance of this post-process ( apart from the creation of the<br>
> toolchains that would occur before anything starts to be done).<br>
><br>
> I agree these things are complicated to fully understand/explain based a<br>
> summary in a email. I'll try to come up with a proposal-patch early next<br>
> week so that we have something more concrete to discuss.<br>
><br>
>><br>
>><br>
>> > c) Use unbundling and bundling tools agnostic of the programming model.<br>
>> ><br>
>> > I propose a single change in the action creation and that is the<br>
>> > creation of<br>
>> > a “unbundling” and "bundling” action whose goal is to prevent the user<br>
>> > to<br>
>> > have to deal with multiple files generated from multiple toolchains<br>
>> > (host<br>
>> > toolchain and offloading devices’ toolchains) if he uses separate<br>
>> > compilation<br>
>> > in his build system.<br>
>><br>
>> I'm not sure I understand what "separate compilation" is here.  Do you<br>
>> mean, a<br>
>> compilation strategy which outputs logically separate machine code for<br>
>> each<br>
>> architecture, only to have this code combined at link time?  (In contrast<br>
>> to<br>
>> how we currently compile CUDA, where the device code for a file is<br>
>> integrated<br>
>> into the host code for that file at compile time?)<br>
><br>
><br>
> That's correct. With separate compilation I also mean the ability to link<br>
> device side code, using a device linker (nvlink for CUDA).<br>
><br>
>><br>
>> If that's right, then what I understand you're proposing here is that,<br>
>> instead<br>
>> of outputting N different object files -- one for the host, and N-1 for<br>
>> all our<br>
>> device architectures -- we'd just output one blob which clang would<br>
>> understand<br>
>> how to handle.<br>
><br>
><br>
> Correct.<br>
><br>
>><br>
>><br>
>> For my part, I am highly wary of introducing a new file format into<br>
>> clang's<br>
>> output.  Historically, clang (along with other compilers) does not output<br>
>> proprietary blobs.  Instead, we output object files in well-understood,<br>
>> interoperable formats, such as ELF.  This is beneficial because there are<br>
>> lots<br>
>> of existing tools which can handle these files.  It also allows e.g. code<br>
>> compiled with clang to be linked with g++.<br>
>><br>
>> Build tools are universally awful, and I sympathize with the urge not to<br>
>> change<br>
>> them.  But I don't think this is a business we want the compiler to be in.<br>
>> Instead, if a user wants this kind of "fat object file", they could obtain<br>
>> one<br>
>> by using a simple wrapper around clang.  If this wrapper's output format<br>
>> became<br>
>> widely-used, we could then consider supporting it directly within clang,<br>
>> but<br>
>> that's a proposition for many years in the future.<br>
><br>
><br>
> I see the driver already as a wrapper, so I don't think it is not<br>
> appropriate to use it. However, I think the creation of the blob should be<br>
> done by an external tool, say, as it was a linker. I have an initial<br>
> proposal in<br>
> <a href="http://lists.llvm.org/pipermail/cfe-dev/2016-February/047548.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/cfe-dev/2016-February/047548.html</a>, but based<br>
> on your input and also Jonas, I have to rethink a few things.<br>
><br>
> I agree when you say that you would like to have the blob working well with<br>
> other tools. Jonas in some previous email also expressed  this concern. I'd<br>
> put it in this way: an bundled file should work as a normal host  file,<br>
> regardless of what device code it embeds.<br>
><br>
> For ELF files this works just fine:<br>
><br>
> clang a.c -c -o a.o<br>
> echo "Some offloading bytes" >> a.o<br>
> clang a.o -o a.out<br>
> a.out<br>
><br>
> However for other binary formats, we need to wrap in a different. Even for<br>
> ELF, I agree putting the code in some section is more elegant. I'll<br>
> investigate the possibilities to implement that.<br>
><br>
> In other side, we have text files. My opinion is that we should have<br>
> something that is easy to read and edit. How would a bundled text file look<br>
> like in your opinion?<br>
><br>
> Do you think have all the device code guarded as a comment in the bottom is<br>
> acceptable? That would work well as a host file.<br>
><br>
>><br>
>><br>
>> > d) Allow the target toolchain to request the host toolchain to be used<br>
>> > for a given action.<br>
>><br>
>> Seems sane to me.<br>
>><br>
>> > e)  Use a job results cache to enable sharing results between device and<br>
>> > host toolchains.<br>
>><br>
>> I don't understand why we need a cache for job results.  Why can we not<br>
>> set up<br>
>> the Action graph such that each node has the correct inputs?  (You've<br>
>> actually<br>
>> sketched exactly what I think the Action graph should look like, for CUDA<br>
>> and<br>
>> OpenMP compilations.)<br>
><br>
><br>
> I think what I explain above covers this one. If not, please let me know.<br>
> Just to summarize, I'm not saying expressing things in Actions won't work, I<br>
> just think that will be more complex if we have multiple programming models<br>
> (all potentially used in the same compile) and separate compilation in<br>
> place. We already have a cache in the jobs builder, I was just planing to<br>
> leverage that.<br>
><br>
>><br>
>><br>
>> > f) Intercept the jobs creation before the emission of the command.<br>
>> ><br>
>> > In my view this is the only change required in the driver (apart from<br>
>> > the<br>
>> > obvious toolchain changes) that would be dependent on the programming<br>
>> > model.<br>
>> > A job result post-processing function could check that there are<br>
>> > offloading<br>
>> > toolchains to be used and spawn the jobs creation for those toolchains<br>
>> > as<br>
>> > well as append results from one toolchain to the results of some other<br>
>> > accordingly to the programming model implementation needs.<br>
>><br>
>> Again it's not clear to me why we cannot and should not represent this in<br>
>> the<br>
>> Action graph.  It's that graph that's supposed to tell us what we're going<br>
>> to<br>
>> do.<br>
><br>
><br>
> I guess  covered this above, if not let me know.<br>
><br>
>><br>
>><br>
>> > g) Reflect the offloading programming model in the naming of the<br>
>> > save-temps files.<br>
>><br>
>> We already do this somewhat; e.g. for CUDA with save-temps, we'll output<br>
>> foo.s<br>
>> and foo-sm_35.s.  Extending this to be more robust (e.g. including the<br>
>> triple)<br>
>> seems fine.<br>
><br>
><br>
> Yes, programming model, host/device (in openmp same triple can be used for<br>
> both host and device), and bound arch will make sure we get unique names.<br>
><br>
>><br>
>><br>
>> > h) Use special options -target-offload=<triple> to specify offloading<br>
>> > targets and delimit options meant for a toolchain.<br>
>><br>
>> I think I agree that we should generalize the flags we're using.<br>
>><br>
>> I'm not sold on the name or structure (I'm not aware of any other flags<br>
>> that<br>
>> affect *all* flags following them?), but we can bikeshed about that<br>
>> separately.<br>
><br>
><br>
> I guess we only have -Xblah and friends to change how the next option is<br>
> used. I agree, this is issue is in many ways orthogonal to everything else<br>
> in this proposal, we can address it separately.<br>
><br>
>><br>
>><br>
>> > i) Use the offload kinds in the toolchain to drive the commands<br>
>> > generation by Tools.<br>
>><br>
>> I'm not sure exactly what this means, but it doesn't sound<br>
>> particularly contentious.  :)<br>
><br>
><br>
> Sorry about that... My explanations get convoluted sometimes...<br>
><br>
> What I mean is that, instead of relying on a file input, or attributes of an<br>
> action, a command can be generated by looking at the offloading kind of the<br>
> toolchain.<br>
><br>
> E.g.<br>
><br>
> isCuda = isToolChainKind(Toolchain:OFFLOAD_KINDS_CUDA).<br>
><br>
> or<br>
><br>
> if(isHostToolChainKind(Toolchain:OFFLOAD_KINDS_CUDA))<br>
>  AuxTriple = getDeviceToolChain(Toolchain:OFFLOAD_KINDS_CUDA)<br>
><br>
> This would allow a programming model to tune things here an there. Remember,<br>
> that the same toolchain can, in general, be used by different programming<br>
> models, and simultaneously by host and devices. So being able to do things<br>
> based on a kind simplifies things a lot.<br>
><br>
>><br>
>><br>
>> > 3. We are willing to help with implementation of CUDA-specific parts<br>
>> > when<br>
>> > they overlap with the common infrastructure; though we expect that<br>
>> > effort to<br>
>> > be driven also by other contributors specifically interested in CUDA<br>
>> > support<br>
>> > that have the necessary know-how (both on CUDA itself and how it is<br>
>> > supported<br>
>> > in Clang / LLVM).<br>
>><br>
>> Given that this is work that doesn't really help CUDA (the driver works<br>
>> fine<br>
>> for us as-is), I am not sure we'll be able to devote significant resources<br>
>> to<br>
>> this project.  Of course we'll be available to assist with code relevant<br>
>> reviews and give advice.<br>
>><br>
>> I think like any other change to clang, the responsibility will rest on<br>
>> the<br>
>> authors not to break existing functionality, at the very least inasmuch as<br>
>> is<br>
>> checked by existing unit tests.<br>
>><br>
><br>
> Sure, having your feedback/suggestions and help with code review is all we<br>
> ask for! We will try not to break anything (and if for some reason we do<br>
> will fix it right away). Also, if we find opportunities to improve the CUDA<br>
> support we will be happy to contribute that as well.<br>
><br>
> I hope I addressed the concerns you expressed initially. Let me know any<br>
> other thoughts you may have.<br>
><br>
> Thanks again!<br>
> Samuel<br>
><br>
>><br>
>> Regards,<br>
>> -Justin<br>
>><br>
>> On Thu, Mar 3, 2016 at 12:03 PM, Samuel F Antao via cfe-dev<br>
>> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
>> > Hi Chris,<br>
>> ><br>
>> > I agree with Andrey when he says this should be a separate discussion.<br>
>> ><br>
>> > I think that aiming at having a library that would support any possible<br>
>> > programming model would take a long time, as it requires a lot of<br>
>> > consensus<br>
>> > namely from who is maintaining programming models already in clang (e.g.<br>
>> > CUDA). We should try to have something incremental.<br>
>> ><br>
>> > I'm happy to discuss and know more about the design and code you would<br>
>> > like<br>
>> > to contribute to this, but I think you should post it in a different<br>
>> > thread.<br>
>> ><br>
>> > Thanks,<br>
>> > Samuel<br>
>> ><br>
>> > 2016-03-03 11:20 GMT-05:00 C Bergström <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>:<br>
>> >><br>
>> >> On Thu, Mar 3, 2016 at 10:19 PM, Ronan Keryell <<a href="mailto:ronan@keryell.fr" target="_blank">ronan@keryell.fr</a>><br>
>> >> wrote:<br>
>> >> >>>>>> On Thu, 3 Mar 2016 18:19:43 +0700, C Bergström via cfe-dev<br>
>> >> >>>>>> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> said:<br>
>> >> ><br>
>> >> >     C> On Thu, Mar 3, 2016 at 5:50 PM, Ronan KERYELL via cfe-dev<br>
>> >> >     C> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
>> >> ><br>
>> >> >     >> Just to be sure to understand: you are thinking about being<br>
>> >> > able<br>
>> >> >     >> to outline several "languages" at once, such as CUDA *and*<br>
>> >> >     >> OpenMP, right ?<br>
>> >> >     >><br>
>> >> >     >> I think it is required for serious applications. For example,<br>
>> >> > in<br>
>> >> >     >> the HPC world, it is common to have hybrid multi-node<br>
>> >> >     >> heterogeneous applications that use MPI+OpenMP+OpenCL for<br>
>> >> >     >> example. Since MPI and OpenCL are just libraries, there is<br>
>> >> > only<br>
>> >> >     >> OpenMP to off-load here. But if we move to OpenCL SYCL instead<br>
>> >> >     >> with MPI+OpenMP+SYCL then both OpenMP and SYCL have to be<br>
>> >> > managed<br>
>> >> >     >> by the Clang off-loading infrastructure at the same time and<br>
>> >> > be<br>
>> >> >     >> sure they combine gracefully...<br>
>> >> >     >><br>
>> >> >     >> I think your second proposal about (un)bundling can already<br>
>> >> >     >> manage this.<br>
>> >> >     >><br>
>> >> >     >> Otherwise, what about the code outlining itself used in the<br>
>> >> >     >> off-loading process? The code generation itself requires to<br>
>> >> >     >> outline the kernel code to some external functions to be<br>
>> >> > compiled<br>
>> >> >     >> by the kernel compiler. Do you think it is up to the<br>
>> >> > programmer<br>
>> >> >     >> to re-use the recipes used by OpenMP and CUDA for example or<br>
>> >> > it<br>
>> >> >     >> would be interesting to have a third proposal to abstract more<br>
>> >> >     >> the outliner to be configurable to handle globally OpenMP,<br>
>> >> > CUDA,<br>
>> >> >     >> SYCL...?<br>
>> >> ><br>
>> >> >     C> Some very good points above and back to my broken record..<br>
>> >> ><br>
>> >> >     C> If all offloading is done in a single unified library -<br>
>> >> >     C> a. Lowering in LLVM is greatly simplified since there's<br>
>> >> > ***1***<br>
>> >> >     C> offload API to be supported A region that's outlined for SYCL,<br>
>> >> >     C> CUDA or something else is essentially the same thing. (I do<br>
>> >> >     C> realize that some transformation may be highly target<br>
>> >> > specific,<br>
>> >> >     C> but to me that's more target hw driven than programming model<br>
>> >> >     C> driven)<br>
>> >> ><br>
>> >> >     C> b. Mixing CUDA/OMP/ACC/Foo in theory may "just work" since the<br>
>> >> >     C> same runtime will handle them all. (With the limitation that<br>
>> >> > if<br>
>> >> >     C> you want CUDA to *talk to* OMP or something else there needs<br>
>> >> > to<br>
>> >> >     C> be some glue.  I'm merely saying that 1 application with<br>
>> >> > multiple<br>
>> >> >     C> models in a way that won't conflict)<br>
>> >> ><br>
>> >> >     C> c. The driver doesn't need to figure out do I link against<br>
>> >> > some<br>
>> >> >     C> or a multitude of combining/conflicting libcuda, libomp,<br>
>> >> >     C> libsomething - it's liboffload - done<br>
>> >> ><br>
>> >> > Yes, a unified target library would help.<br>
>> >> ><br>
>> >> >     C> The driver proposal and the liboffload proposal should imnsho<br>
>> >> > be<br>
>> >> >     C> tightly coupled and work together as *1*. The goals are<br>
>> >> >     C> significantly overlapping and relevant. If you get the<br>
>> >> > liboffload<br>
>> >> >     C> OMP people to make that more agnostic - I think it simplifies<br>
>> >> > the<br>
>> >> >     C> driver work.<br>
>> >> ><br>
>> >> > So basically it is about introducing a fourth unification:<br>
>> >> > liboffload.<br>
>> >> ><br>
>> >> > A great unification sounds great.<br>
>> >> > My only concern is that if we tie everything together, it would<br>
>> >> > increase<br>
>> >> > the entry cost: all the different components should be ready in<br>
>> >> > lock-step.<br>
>> >> > If there is already a runtime available, it would be easier to start<br>
>> >> > with and develop the other part in the meantime.<br>
>> >> > So from a pragmatic agile point-of-view, I would prefer not to impose<br>
>> >> > a<br>
>> >> > strong unification.<br>
>> >><br>
>> >> I think may not be explaining clearly - let me elaborate by example a<br>
>> >> bit<br>
>> >> below<br>
>> >><br>
>> >> > In the proposal of Samuel, all the parts seem independent.<br>
>> >> ><br>
>> >> >     C>   ------ More specific to this proposal - device<br>
>> >> >     C> linker vs host linker. What do you do for IPA/LTO or whole<br>
>> >> >     C> program optimizations? (Outside the scope of this project.. ?)<br>
>> >> ><br>
>> >> > Ouch. I did not think about it. It sounds like science-fiction for<br>
>> >> > now. :-) Probably outside the scope of this project..<br>
>> >><br>
>> >> It should certainly not be science fiction or an after-thought. I<br>
>> >> won't go into shameless self promotion, but there are certainly useful<br>
>> >> things you can do when you have a "whole device kernel" perspective.<br>
>> >><br>
>> >> To digress into the liboffload component of this (sorry)<br>
>> >> what we have today is basically liboffload/src/all source files mucked<br>
>> >> together<br>
>> >><br>
>> >> What I'm proposing would look more like this<br>
>> >><br>
>> >> liboffload/src/common_middle_layer_glue # to start this may be "best<br>
>> >> effort"<br>
>> >> liboffload/src/omp # This code should exist today, but ideally should<br>
>> >> build on top of the middle layer<br>
>> >> liboffload/src/ptx # this may exist today - not sure<br>
>> >> liboffload/src/amd_gpu # probably doesn't exist, but<br>
>> >> wouldn't/shouldn't block anything<br>
>> >> liboffload/src/phi # may exist in some form<br>
>> >> liboffload/src/cuda # may exist in some form outside of the OMP work<br>
>> >><br>
>> >> The end result would be liboffload.<br>
>> >><br>
>> >> Above and below the common middle layer API are programming model or<br>
>> >> hardware specific. To add a new hw backend you just implement the<br>
>> >> things the middle layer needs. To add a new programming model you<br>
>> >> build on top of the common layer. I'm not trying to force<br>
>> >> anyone/everyone to switch to this now - I'm hoping that by being a<br>
>> >> squeaky wheel this isolation of design and layers is there from the<br>
>> >> start - even if not perfect. I think it's sloppy to not consider this<br>
>> >> actually. LLVM's code generation is clean and has a nice separation<br>
>> >> per target (for the most part) - why should the offload library have<br>
>> >> bad design which just needs to be refactored later. I've seen others<br>
>> >> in the community beat up Intel to force them to have higher quality<br>
>> >> code before inclusion... some of this may actually be just minor<br>
>> >> refactoring to come close to the target. (No pun intended)<br>
>> >> -------------<br>
>> >> If others become open to this design - I'm happy to contribute more<br>
>> >> tangible details on the actual middle API.<br>
>> >><br>
>> >> the objects which the driver has to deal with may and probably do<br>
>> >> overlap to some extent with the objects the liboffload has to load or<br>
>> >> deal with. Is there an API the driver can hook into to magically<br>
>> >> handle that or is it all per-device and 1-off..<br>
>> >> _______________________________________________<br>
>> >> cfe-dev mailing list<br>
>> >> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
>> >> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>> ><br>
>> ><br>
>> ><br>
>> > _______________________________________________<br>
>> > cfe-dev mailing list<br>
>> > <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
>> > <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
>> ><br>
>> _______________________________________________<br>
>> cfe-dev mailing list<br>
>> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
><br>
><br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div></div>