support for cuda .cu files

82 views
Skip to first unread message

Erik Smith

unread,
Nov 5, 2024, 12:49:28 PM11/5/24
to gn-dev
I'm trying to see how GN can support cuda source in my build.   This is the first time I've used a custom toolchain and it almost worked.  The problem is that nvcc (the CUDA compiler) or clang, which supports calling nvcc, require the source file extension type to be .cu, which a source_set won't accept:

source_set("source") {
  sources = [ "cuda_demo.cu" ]
}

group("cuda") {
  deps = [ ":source(//build//toolchain::nvcc)" ]
}

ERROR: Only source, header, and object files belong in the sources of a source_set.

I could build this out through an action template, but this bypases toolchains entirely. It seems like it would work if the .cu extension was added as a supported extension.

Erik







Dirk Pranke

unread,
Nov 5, 2024, 2:47:47 PM11/5/24
to Erik Smith, gn-dev
Yup, as you say, .cu extensions won't work as part of a source_set(). GN doesn't really have a mechanism for arbitrarily adding different types of files into source_sets and having them do the right thing. 

I think it would be cool if we did have a way to do that, but I suspect designing and building that could be a decent amount of work.

-- Dirk

To unsubscribe from this group and stop receiving emails from it, send an email to gn-dev+un...@chromium.org.

Erik Smith

unread,
Nov 5, 2024, 3:42:16 PM11/5/24
to gn-dev, dpr...@google.com, gn-dev, Erik Smith
I understand that it might be significant work to support it.  However, I was able to get it working with this two line change in GN 's source_file.cc:

     switch (TAG2(str[size - 2], str[size - 1])) {
       case TAG2('c', 'c'):
         return SourceFile::SOURCE_CPP;  // .cc
+      case TAG2('c', 'u'):
+        return SourceFile::SOURCE_CPP;  // .cc


It might benefit from another enum type.  It seems that the only fundamental difference with nvcc and other "C" compilers is the name of the binary and the .cu extension requirement.   Also clang and gcc has support for nvcc passthrough but it still requires the .cu extension.   

It seems like it should just be another supported "C" file type?

Erik


Dirk Pranke

unread,
Nov 5, 2024, 4:31:24 PM11/5/24
to Erik Smith, gn-dev
Yes, sorry, I meant that a general solution might be a fair amount of work. Adding support for a single file type is probably pretty easy. Presumably you'd have to add another `tool` type.

-- Dirk

Erik Smith

unread,
Nov 5, 2024, 5:19:08 PM11/5/24
to gn-dev, dpr...@google.com, gn-dev, Erik Smith
It would probably work fine with the existing cxx tool as clang and gcc do support that extension with the right flags and nvcc is a version of C++ for GPUs.  I'm not sure what the tradeoffs are of defining a specific tool for nvcc. 

Can support for .cu be added?

Dirk Pranke

unread,
Nov 6, 2024, 12:20:10 PM11/6/24
to Erik Smith, gn-dev
Do you have a patch for it that you could post? I'm open to the idea depending on what the details end up looking like.

-- Dirk

Erik Smith

unread,
Nov 7, 2024, 7:09:03 PM11/7/24
to gn-dev, dpr...@google.com, gn-dev, Erik Smith
Here is the patch.   There are just two things here:  support for CUDA source, which must have the the .cu extension, and also support for a .cuh extension for CUDA code in a header.   I don't think any additional tool types are needed as it otherwise works like a clang/gcc compiler and in fact those compilers accept these extensions.  

Erik


diff --git a/src/gn/source_file.cc b/src/gn/source_file.cc
index 319adde9..7191b0f4 100644
--- a/src/gn/source_file.cc
+++ b/src/gn/source_file.cc
@@ -58,6 +58,8 @@ SourceFile::Type GetSourceFileType(const std::string& file) {

     switch (TAG2(str[size - 2], str[size - 1])) {
       case TAG2('c', 'c'):
         return SourceFile::SOURCE_CPP;  // .cc
+      case TAG2('c', 'u'):
+        return SourceFile::SOURCE_CPP;  // .cu
       case TAG2('g', 'o'):
         return SourceFile::SOURCE_GO;  // .go
       case TAG2('h', 'h'):
@@ -87,6 +89,7 @@ SourceFile::Type GetSourceFileType(const std::string& file) {
       case TAG3('i', 'n', 'c'):
       case TAG3('i', 'p', 'p'):
       case TAG3('i', 'n', 'l'):
+      case TAG3('c', 'u', 'h'):
         return SourceFile::SOURCE_H;
       case TAG3('a', 's', 'm'):
         return SourceFile::SOURCE_S;

Nico Weber

unread,
Nov 7, 2024, 8:03:23 PM11/7/24
to Erik Smith, gn-dev, dpr...@google.com
I'd give this its own language type, similar to ObjC. You probably want cflags_cu, etc.
Reply all
Reply to author
Forward
0 new messages