Skip to content

Commit

Permalink
Add support for nvcc & hipcc (cuda/rocm) (nim-lang#23805)
Browse files Browse the repository at this point in the history
I've been working on making some basic cuda examples work, both with
cuda (nvcc) and with AMD HIP (hipcc) https://github.com/monofuel/hippo

- hipcc is just a drop-in replacement for clang and works out of the box
with clang settings in Nim. hipcc is capable of compiling for AMD ROCm
or to CUDA, depending on how HIP_PLATFORM is set.
- nvcc is a little quirky. we can use `-x cu` to tell it to handle nim's
`.cpp` files as if they were `.cu` files. nvcc expects all backend
compiler flags to be wrapped with a special `-Xcompiler=""` flag when
compiling and also when linking.

I manually tested on a linux desktop with amd and a laptop with nvidia.
  • Loading branch information
monofuel authored Jul 8, 2024
1 parent 3f5016f commit dc46350
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
20 changes: 19 additions & 1 deletion compiler/extccomp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,22 @@ compiler vcc:
cppXsupport: "",
props: {hasCpp, hasAssume, hasDeclspec})

# Nvidia CUDA NVCC Compiler
compiler nvcc:
result = gcc()
result.name = "nvcc"
result.compilerExe = "nvcc"
result.cppCompiler = "nvcc"
result.compileTmpl = "-c -x cu -Xcompiler=\"$options\" $include -o $objfile $file"
result.linkTmpl = "$buildgui $builddll -o $exefile $objfiles -Xcompiler=\"$options\""

# AMD HIPCC Compiler (rocm/cuda)
compiler hipcc:
result = clang()
result.name = "hipcc"
result.compilerExe = "hipcc"
result.cppCompiler = "hipcc"

compiler clangcl:
result = vcc()
result.name = "clang_cl"
Expand Down Expand Up @@ -285,7 +301,9 @@ const
envcc(),
icl(),
icc(),
clangcl()]
clangcl(),
hipcc(),
nvcc()]

hExt* = ".h"

Expand Down
2 changes: 1 addition & 1 deletion compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ type

TSystemCC* = enum
ccNone, ccGcc, ccNintendoSwitch, ccLLVM_Gcc, ccCLang, ccBcc, ccVcc,
ccTcc, ccEnv, ccIcl, ccIcc, ccClangCl
ccTcc, ccEnv, ccIcl, ccIcc, ccClangCl, ccHipcc, ccNvcc

ExceptionSystem* = enum
excNone, # no exception system selected yet
Expand Down
22 changes: 22 additions & 0 deletions doc/nimc.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,28 @@ They are:
5. nl_types. No headers for this.
6. As mmap is not supported, the nimAllocPagesViaMalloc option has to be used.

GPU Compilation
===============

Compiling for GPU computation can be achieved with `--cc:nvcc` for CUDA with nvcc, or with `--cc:hipcc` for AMD GPUs with HIP. Both compilers require building for C++ with `nim cpp`.

Here's a very simple CUDA kernel example using emit, which can be compiled with `nim cpp --cc:nvcc --define:"useMalloc" hello_kernel.nim` assuming you have the CUDA toolkit installed.

```nim
{.emit: """
__global__ void add(int a, int b) {
int c;
c = a + b;
}
""".}
proc main() =
{.emit: """
add<<<1,1>>>(2,7);
""".}
main()
```

DLL generation
==============
Expand Down

0 comments on commit dc46350

Please sign in to comment.