This is an archive of the discontinued LLVM Phabricator instance.

[CUDA][OpenMP] Add a generic offload action builder
ClosedPublic

Authored by sfantao on Mar 14 2016, 6:33 PM.

Details

Summary

This patch proposes a new class to generate and record action dependences related with offloading. The builder provides three main functionalities:

  • Add device dependences to host actions.
  • Add host dependence to device actions.
  • Register device top-level actions.

The constructor of the builder detect the programming models that should be supported, and generates a specialized builder for each. If a new programming model is to be added in the future, only a new specialized builder has to be implemented.

When the specialized builder is generated, it produces programming-model-specific diagnostics.

A CUDA specialized builder is proposed in the patch that mostly consists of the partition of the current buildCudaAction by the three different functionalities.

Diff Detail

Event Timeline

sfantao updated this revision to Diff 50690.Mar 14 2016, 6:33 PM
sfantao retitled this revision from to [CUDA][OpenMP] Add a generic offload action builder.
sfantao updated this object.
sfantao added reviewers: ABataev, jlebar, tra, echristo, hfinkel.
mkuron added a subscriber: mkuron.Mar 19 2016, 1:42 AM
sfantao updated this revision to Diff 52881.Apr 6 2016, 6:56 PM
sfantao updated this object.

Rebase.

sfantao updated this revision to Diff 60604.Jun 13 2016, 2:10 PM
  • Rebase.
sfantao updated this revision to Diff 62231.Jun 29 2016, 9:28 AM
  • Rebase.
ABataev edited edge metadata.Jun 29 2016, 9:31 PM

No '\brief's

lib/Driver/Driver.cpp
1802
  1. 'final'
  2. default initializers for fields
1846

default initializer

1895

'final'

sfantao updated this revision to Diff 62438.Jun 30 2016, 4:23 PM
sfantao marked 3 inline comments as done.
sfantao edited edge metadata.
  • Fix comments, annotate classes with final, and add default initializers.

Hi Alexey,

Thanks for the review! Addressed your comments in the new diff.

I'll wait for your response on my question in http://reviews.llvm.org/D18172 to address the issue with \brief properly.

Thanks again,
Samuel

jlebar edited edge metadata.Jun 30 2016, 4:34 PM

Alexey, it seems that you're asking for "final" on all classes that are not inherited from. Forgive my ignorance, but would you mind pointing me to the document that talks about our position on "final" in LLVM source? I don't see it in the style guide, but I may be missing something.

The style guide does talk a good bit about writing concise and generally not-misleading code. My concern is that adding "final" everywhere paints an inaccurate picture and will mislead readers. Specifically, "final" is useful as a signal to readers that a class cannot safely be inherited from. "Don't even think about it, buster." But here we're adding "final" to a lot of classes that, as far as I can tell, aren't distinctive except in that they have no subclasses today. The problem with this is that, if we use "final" in this way, it dilutes the first "don't even try" meaning. Now when I see a class with "final" that I want to subclass, I'm just going to rip the "final" off, because chances are, I can do so safely. Now "final" does not serve as a warning to me that I shouldn't do this.

Sorry to focus on a superficial issue, but I think this really does matter for usability.

sfantao updated this revision to Diff 62462.Jun 30 2016, 8:59 PM
sfantao edited edge metadata.
  • Remove \brief.

Alexey, it seems that you're asking for "final" on all classes that are not inherited from. Forgive my ignorance, but would you mind pointing me to the document that talks about our position on "final" in LLVM source? I don't see it in the style guide, but I may be missing something.

The style guide does talk a good bit about writing concise and generally not-misleading code. My concern is that adding "final" everywhere paints an inaccurate picture and will mislead readers. Specifically, "final" is useful as a signal to readers that a class cannot safely be inherited from. "Don't even think about it, buster." But here we're adding "final" to a lot of classes that, as far as I can tell, aren't distinctive except in that they have no subclasses today. The problem with this is that, if we use "final" in this way, it dilutes the first "don't even try" meaning. Now when I see a class with "final" that I want to subclass, I'm just going to rip the "final" off, because chances are, I can do so safely. Now "final" does not serve as a warning to me that I shouldn't do this.

Sorry to focus on a superficial issue, but I think this really does matter for usability.

Hi Justin,
There are no strict rules on using 'final'. But I believe that it is better to protect developers from unintended use of code and if language allows to do it we should do it. If some class is not intended to be used as a base class, it is better to mark it as 'final' to be sure that nobody will inherit from it for sure. Consider it as an additional contract of the class.

Alexey, it seems that you're asking for "final" on all classes that are not inherited from. Forgive my ignorance, but would you mind pointing me to the document that talks about our position on "final" in LLVM source? I don't see it in the style guide, but I may be missing something.

The style guide does talk a good bit about writing concise and generally not-misleading code. My concern is that adding "final" everywhere paints an inaccurate picture and will mislead readers. Specifically, "final" is useful as a signal to readers that a class cannot safely be inherited from. "Don't even think about it, buster." But here we're adding "final" to a lot of classes that, as far as I can tell, aren't distinctive except in that they have no subclasses today. The problem with this is that, if we use "final" in this way, it dilutes the first "don't even try" meaning. Now when I see a class with "final" that I want to subclass, I'm just going to rip the "final" off, because chances are, I can do so safely. Now "final" does not serve as a warning to me that I shouldn't do this.

Sorry to focus on a superficial issue, but I think this really does matter for usability.

Hi Justin,

Thanks for the comment!

I understand both interpretations can be useful for different purposes, i.e. "don't inherit, it is not safe" vs "feel free to change this class without worrying with subclasses". I tend to think that the latter (which I believe is what Alexey has in mind) can, in general, be more useful in the sense that a class is usually safe to extend - you can always add features that are somewhat orthogonal to what the parent class is doing. I can, of course, imagine cases where your argument is valid - you can have an implementation that allocates memory based on the type of the parent therefore it does not observe the extra storage required by derived classes. However, I think these cases are less common.

I also look at the programming guidelines and couldn't find a clear answer to the issue you raised.

I don't have a strong opinion about this, just giving my two cents.

Thanks again!
Samuel

jlebar added a subscriber: jlebar.Jul 1 2016, 12:31 AM

Yeah, I'd say that in the absence of a rule, consistency with surrounding
code is king. Otherwise we're sending a message when we don't mean to be.

I'm not at my machine, but my recollection is that most of the driver uses
final sparingly. But whatever the convention is we should do that, I think.

sfantao updated this revision to Diff 62506.Jul 1 2016, 10:07 AM
  • Use double instead of triple slash in one comment.

Yeah, I'd say that in the absence of a rule, consistency with surrounding
code is king. Otherwise we're sending a message when we don't mean to be.

I'm not at my machine, but my recollection is that most of the driver uses
final sparingly. But whatever the convention is we should do that, I think.

True, final is not widely used in the driver. Again, I don't feel strongly about doing this one way or the other. For the moment, I'll update the diffs according to what Alexey requested. If you guys decide that I should do that differently, I'm happy to go to back to each review and update it accordingly.

Thanks again!
Samuel

sfantao updated this revision to Diff 62573.Jul 1 2016, 4:53 PM
  • Rebase
sfantao updated this revision to Diff 63681.Jul 12 2016, 8:16 AM
  • Rebase.
sfantao updated this revision to Diff 66016.Jul 28 2016, 2:48 PM
  • Remove redundant phases from cuda-phases.cu and use DAG check.
  • Rebase.

Any more comments on this patch or depending ones?

Thanks!
Samuel

Any more comments on this patch or depending ones?

Thanks!
Samuel

I can report that the latest patches are working for me and that they fix all points that I previously raised.
That said they look good from a user perspective but @jlebar and @ABataev have been driving the reviews so far.

Regards,
Jonas

sfantao updated this revision to Diff 72117.Sep 21 2016, 3:45 PM
  • Rebase.
hfinkel accepted this revision.Sep 28 2016, 8:40 AM
hfinkel edited edge metadata.

A nice abstraction and cleanup. LGTM.

lib/Driver/Driver.cpp
1611

use -> uses

This revision is now accepted and ready to land.Sep 28 2016, 8:40 AM
This revision was automatically updated to reflect the committed changes.
sfantao marked an inline comment as done.

Hi, Samuel.

This change introduced a new crash / assertion failure in the driver.

$ echo | llvm-run clang -emit-llvm -c -x cuda - -o /dev/null

Before this patch, we get an error (perhaps not as helpful as we might want, but still):

clang-3.8: error: cannot specify -o when generating multiple output files

After this patch, we get an assertion failure:

clang: ../clang/lib/Driver/Driver.cpp:1610: virtual (anonymous namespace)::OffloadingActionBuilder::DeviceActionBuilder::ActionBuilderReturnCode (anonymous namespace)::OffloadingActionBuilder::CudaActionBuilder::getDeviceDepences(OffloadAction::DeviceDependences &, phases::ID, phases::ID, PhasesTy &): Assertion `CurPhase < phases::Backend && "Generating single CUDA " "instructions should only occur " "before the backend phase!"' failed.
#0 0x0000000001b07e28 llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1b07e28)
#1 0x0000000001b08566 SignalHandler(int) (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1b08566)
#2 0x00007f4bb7f89330 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
#3 0x00007f4bb6b7cc37 gsignal /build/eglibc-oGUzwX/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
#4 0x00007f4bb6b80028 abort /build/eglibc-oGUzwX/eglibc-2.19/stdlib/abort.c:91:0
#5 0x00007f4bb6b75bf6 __assert_fail_base /build/eglibc-oGUzwX/eglibc-2.19/assert/assert.c:92:0
#6 0x00007f4bb6b75ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
#7 0x0000000001fa809b (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1fa809b)
#8 0x0000000001f99981 clang::driver::Driver::BuildActions(clang::driver::Compilation&, llvm::opt::DerivedArgList&, llvm::SmallVector<std::pair<clang::driver::types::ID, llvm::opt::Arg const*>, 16u> const&, llvm::SmallVector<clang::driver::Action*, 3u>&) const (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1f99981)
#9 0x0000000001f9431c clang::driver::Driver::BuildCompilation(llvm::ArrayRef<char const*>) (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1f9431c)
#10 0x00000000007c0254 main (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x7c0254)
#11 0x00007f4bb6b67f45 __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:321:0
#12 0x00000000007bd9a2 _start (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x7bd9a2)
Stack dump:
0.	Program arguments: /usr/local/google/home/jlebar/llvm/release/bin/clang -emit-llvm -c -x cuda - -o /dev/null 
1.	Compilation construction
2.	Building compilation actions
Aborted (core dumped)

This was reported two weeks ago by Gurunath Kadam on cfe-dev, but I just got around to bisecting it.

Would you mind spinning a fix for this?

Hi Justin

Thanks for letting me know. I'm looking into it.

Thanks again,
Samuel

Hi, Samuel.

This change introduced a new crash / assertion failure in the driver.

$ echo | llvm-run clang -emit-llvm -c -x cuda - -o /dev/null

Before this patch, we get an error (perhaps not as helpful as we might want, but still):

clang-3.8: error: cannot specify -o when generating multiple output files

After this patch, we get an assertion failure:

clang: ../clang/lib/Driver/Driver.cpp:1610: virtual (anonymous namespace)::OffloadingActionBuilder::DeviceActionBuilder::ActionBuilderReturnCode (anonymous namespace)::OffloadingActionBuilder::CudaActionBuilder::getDeviceDepences(OffloadAction::DeviceDependences &, phases::ID, phases::ID, PhasesTy &): Assertion `CurPhase < phases::Backend && "Generating single CUDA " "instructions should only occur " "before the backend phase!"' failed.
#0 0x0000000001b07e28 llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1b07e28)
#1 0x0000000001b08566 SignalHandler(int) (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1b08566)
#2 0x00007f4bb7f89330 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
#3 0x00007f4bb6b7cc37 gsignal /build/eglibc-oGUzwX/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
#4 0x00007f4bb6b80028 abort /build/eglibc-oGUzwX/eglibc-2.19/stdlib/abort.c:91:0
#5 0x00007f4bb6b75bf6 __assert_fail_base /build/eglibc-oGUzwX/eglibc-2.19/assert/assert.c:92:0
#6 0x00007f4bb6b75ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
#7 0x0000000001fa809b (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1fa809b)
#8 0x0000000001f99981 clang::driver::Driver::BuildActions(clang::driver::Compilation&, llvm::opt::DerivedArgList&, llvm::SmallVector<std::pair<clang::driver::types::ID, llvm::opt::Arg const*>, 16u> const&, llvm::SmallVector<clang::driver::Action*, 3u>&) const (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1f99981)
#9 0x0000000001f9431c clang::driver::Driver::BuildCompilation(llvm::ArrayRef<char const*>) (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x1f9431c)
#10 0x00000000007c0254 main (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x7c0254)
#11 0x00007f4bb6b67f45 __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:321:0
#12 0x00000000007bd9a2 _start (/usr/local/google/home/jlebar/llvm/release/bin/clang+0x7bd9a2)
Stack dump:
0.	Program arguments: /usr/local/google/home/jlebar/llvm/release/bin/clang -emit-llvm -c -x cuda - -o /dev/null 
1.	Compilation construction
2.	Building compilation actions
Aborted (core dumped)

This was reported two weeks ago by Gurunath Kadam on cfe-dev, but I just got around to bisecting it.

Would you mind spinning a fix for this?

This should be fixed in r285263.

You should now get the same error message as before.