Skip to content

Commit

Permalink
Add initial Linux support.
Browse files Browse the repository at this point in the history
  • Loading branch information
theComputeKid committed Jun 3, 2023
1 parent 2efcd7f commit 48b452c
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 22 deletions.
23 changes: 23 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#* Makefile to build premake-core for tests on windows
PREMAKE_OUT := vendor/premake-core/bin/release/premake5

#* Runs the tests.
all: build
@echo Testing debug config
@cd test/out/bin/debug && ./ExampleProjectExe && ./ExampleProjectExeNonCUDA
@echo Testing release config
@cd test/out/bin/release && ./ExampleProjectExe && ./ExampleProjectExeNonCUDA

build: premake
@cd test/out && $(MAKE) config=debug
@cd test/out && $(MAKE) config=release

premake: $(PREMAKE_OUT)
@$(PREMAKE_OUT) --file=test/premake5.lua gmake2

$(PREMAKE_OUT):
@cd vendor/premake-core && $(MAKE) -f Bootstrap.mak linux PLATFORM=x64

clean:
@rm -f $(PREMAKE_OUT)
@rm -rf test/out
64 changes: 47 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,61 @@
<div align="center">
<p>a premake5 extension for cuda</p>
<h1><small>premake5</small><strong>CUDA</strong></h1>
<h1><small>premake5-</small><strong>CUDA</strong></h1>
</div>

Compiles CUDA code using the Visual Studio CUDA Toolkit extension. Enabled macros (listed in `src/cuda-exported-variables.lua`):
- `cudaFiles` (Table) -> list of files to be compiled by NVCC to binary (relative path from solution root)
- `cudaPTXFiles` (Table) -> list of files to be compiled by NVCC to PTX (relative path from solution root)
- `cudaRelocatableCode` (Bool) -> triggers -rdc=true
- `cudaExtensibleWholeProgram` (Bool) -> triggers extensible whole program compilation
- `cudaCompilerOptions` (Table) -> passed to nvcc
- `cudaLinkerOptions` (Table) -> passed to nvlink
- `cudaFastMath` (Bool) -> triggers fast math optimizations
- `cudaVerbosePTXAS` (Bool) -> triggers code gen verbosity
- `cudaMaxRegCount` (String) -> number to determine the max used registers
- `cudaKeep` (Bool) -> keeps preprocessed output
- `cudaPath` (String) -> custom CUDA install path to override the VS integration plugin
- `cudaGenLineInfo` (Bool) -> generates line info

Files specified by the premake5 options `files` are compiled by the MSVC and not nvcc.
Compiles CUDA code using the Visual Studio CUDA Toolkit extension on Windows and `nvcc` on Linux. Enabled macros (listed in `src/cuda-exported-variables.lua`):
- `cudaFiles` (Table) -> list of files to be compiled by NVCC to binary (relative path from solution root).
- `cudaPTXFiles` (Table) -> list of files to be compiled by NVCC to PTX (relative path from solution root) - Windows only.
- `cudaRelocatableCode` (Bool) -> triggers -rdc=true.
- `cudaExtensibleWholeProgram` (Bool) -> triggers extensible whole program compilation.
- `cudaCompilerOptions` (Table) -> passed to nvcc.
- `cudaLinkerOptions` (Table) -> passed to nvlink.
- `cudaFastMath` (Bool) -> triggers fast math optimizations.
- `cudaVerbosePTXAS` (Bool) -> triggers code gen verbosity.
- `cudaMaxRegCount` (String) -> number to determine the max used registers.
- `cudaKeep` (Bool) -> keeps preprocessed output.
- `cudaPath` (String) -> custom CUDA install path.
- `cudaGenLineInfo` (Bool) -> generates line info.

----------------
Notes for Windows:
----------------

Files specified by `files` are compiled by `cl` and not `nvcc`.

An example is provided in the test folder where a CUDA executable project containing C++, PTX and CUDA files is linked against a CUDA shared library project. If you clone this repo recursively (i.e. with `-recursive`), it will also pull the premake5 repo, which can be used via the makefile to build premake and then the tests (e.g. via the `nmake` command). You do not need the premake5 repo unless you want to build the tests.

To use:
- Install the CUDA toolkit, along with its Visual Studio integration.
- Copy the premake5-cuda folder to your project
- Copy the premake5-cuda folder to your project.
- Include it in your premake5.lua file as shown in the example.

Tested with Visual Studio 2022 (toolkit v143) with CUDA toolkit 12.1 VS integration.

Note: If PTX is requested, it will be found in the output object folder, with the .obj extension, though, it can be opened with a text editor for inspection.

----------------
Notes for Linux:
----------------

This extension was primarily made for VS on Windows, with the CUDA toolkit extension. Linux is a work in progress and does not have feature parity with Windows yet. Differences are:
- toolset must be set as `"nvcc"`.
- rules must be set to `'cu'`.
- `cudaPTXFiles` not supported.
- the list of cuda files must be provided in `files` instead of `cudaFiles`.
- unlike Windows, the whole project is compiled by `nvcc` and not just the `.cu` files.

See test premake5 file for how linux config differs. The differences are summarised here:

```
if os.target() == "windows" then
cudaFiles { "exe/cu/**.cu" } -- files to be compiled into binaries by VS CUDA.
cudaPTXFiles { "exe/ptx/**.cu" } -- files to be compiled into ptx, Windows only.
else
toolset "nvcc"
files { "exe/cu/**.cu" }
rules {"cu"}
end
```

Admittedly, Linux support is a bit clunky but it should get the job done.
2 changes: 2 additions & 0 deletions premake5-cuda.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ require("src/cuda-exported-variables")

if os.target() == "windows" then
dofile("src/premake5-cuda-vs.lua")
elseif os.target() == "linux" then
dofile("src/premake5-cuda-nvcc.lua")
end
100 changes: 100 additions & 0 deletions src/premake5-cuda-nvcc.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
--* Creates an NVCC toolset for Linux.

rule 'cu'
fileExtension { ".cu" }
buildoutputs { "$(OBJDIR)/%{file.objname}.cu.o" }
buildmessage '$(notdir $<)'
buildcommands {'$(CXX) %{premake.modules.gmake2.cpp.fileFlags(cfg, file)} $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"'}

premake.tools.nvcc = {}

local nvcc = premake.tools.nvcc
local gcc = premake.tools.gcc

nvcc.getcflags = gcc.getcflags
nvcc.getcppflags = gcc.getcppflags
nvcc.getforceincludes = gcc.getforceincludes
nvcc.getdefines = gcc.getdefines
nvcc.getundefines = gcc.getundefines
nvcc.getrunpathdirs = gcc.getrunpathdirs
nvcc.getincludedirs = gcc.getincludedirs
nvcc.getLibraryDirectories = gcc.getLibraryDirectories
nvcc.getlinks = gcc.getlinks
nvcc.getmakesettings = gcc.getmakesettings

nvcc.cxxflags = {
cudaRelocatableCode = {
On = "-rdc=true",
Off = "-rdc=false"
},
cudaExtensibleWholeProgram = {
On = "-ewp"
},
cudaFastMath = {
On = "-use_fast_math"
},
cudaVerbosePTXAS = {
On = "--ptxas-options=--verbose"
},
cudaKeep = {
On = "-keep"
},
cudaGenLineInfo = {
On = "-lineinfo"
},
kind = {
SharedLib = "-fpic"
}
}

function nvcc.gettoolname (cfg, tool)

local prefix = ""
if cfg.project.cudaPath == nil then
prefix = "/usr/local/cuda/bin/"
else
prefix = cfg.project.cudaPath .. "/bin/"
end

if tool == "cc" then
name = prefix .. "nvcc"
elseif tool == "cxx" then
name = prefix .. "nvcc"
elseif tool == "ar" then
name = "ar"
else
name = nil
end
return name
end

function nvcc.getcxxflags(cfg)
local flags = premake.config.mapFlags(cfg, nvcc.cxxflags)
local gccFlags = premake.config.mapFlags(cfg, gcc.cxxflags)
flags = table.join(flags,gccFlags)
flags = table.join({"-forward-unknown-to-host-compiler"}, flags)

if cfg.cudaCompilerOptions ~= nil then
local cudaFlags = cfg.cudaCompilerOptions
flags = table.join(flags, cudaFlags)
end

if cfg.cudaMaxRegCount ~= nil then
flags = table.join(flags, { "--maxrregcount " .. cfg.cudaMaxRegCount})
end

return flags
end

function nvcc.getldflags(cfg)
local flags = premake.config.mapFlags(cfg, gcc.ldflags)
flags = table.join({"-forward-unknown-to-host-compiler"}, flags)
flags = table.join({"-Xlinker=-rpath,'$$ORIGIN'"}, flags)

if cfg.cudaLinkerOptions ~= nil then
local cudaFlags = cfg.cudaLinkerOptions
flags = table.join(flags, cudaFlags)
end

return flags
end
26 changes: 21 additions & 5 deletions test/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,17 @@ project "ExampleProjectExe"
buildcustomizations "BuildCustomizations/CUDA 12.1"

externalwarnings "Off" -- thrust gives a lot of warnings
cudaFiles { "exe/cu/**.cu" } -- files to be compiled into binaries
cudaPTXFiles { "exe/ptx/**.cu" } -- files to be compiled into ptx

if os.target() == "windows" then
cudaFiles { "exe/cu/**.cu" } -- files to be compiled into binaries by VS CUDA.
cudaPTXFiles { "exe/ptx/**.cu" } -- files to be compiled into ptx, Windows only.
else
toolset "nvcc"
cudaPath "/usr/local/cuda"
files { "exe/cu/**.cu" }
rules {"cu"}
end

cudaKeep "On" -- keep temporary output files
cudaFastMath "On"
cudaRelocatableCode "On"
Expand All @@ -74,10 +83,17 @@ project "ExampleProjectDLL"

buildcustomizations "BuildCustomizations/CUDA 12.1"

-- Just in case we want the VS CUDA extension to use a custom version of CUDA
cudaPath "$(CUDA_PATH)"
if os.target() == "windows" then
-- Just in case we want the VS CUDA extension to use a custom version of CUDA
cudaPath "$(CUDA_PATH)"
cudaFiles { "lib/**.cu" }
else
toolset "nvcc"
cudaPath "/usr/local/cuda"
files { "lib/**.cu" }
rules {"cu"}
end

cudaFiles { "lib/**.cu" }
cudaRelocatableCode "On"

defines { "PREMAKE_CUDA_EXPORT_API" }
Expand Down

0 comments on commit 48b452c

Please sign in to comment.