Skip to content
Snippets Groups Projects
Commit 833861db authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

Merge branch 'rf/cudacxxflags' into 'master'

RF: New CUDACXXFLAGS

See merge request !34
parents 11d69616 09a2e9c5
No related branches found
Tags 2111.6
1 merge request!34RF: New CUDACXXFLAGS
Pipeline #11585 passed
# FSL base project changelog # FSL base project changelog
## 2111.6 (Friday 19th November 2021)
* New convention for compiling C++ files which are part of a CUDA library or
executable, using `${CUDACXXFLAGS}`.
## 2111.5 (Friday 19th November 2021) ## 2111.5 (Friday 19th November 2021)
* Set `-std=c++14` for `nvcc`-compiled code, as CUDA 11.0 is the first version * Set `-std=c++14` for `nvcc`-compiled code, as CUDA 11.0 is the first version
......
...@@ -18,6 +18,57 @@ behaviour of various aspects of the `base` project. All tests are written ...@@ -18,6 +18,57 @@ behaviour of various aspects of the `base` project. All tests are written
in Python, and are executed with `pytest`. in Python, and are executed with `pytest`.
## Standard conventions for C/C++/CUDA projects.
Commands for compilation of intermediate object files should have the
form:
$(CC) $(CFLAGS) <input/output files> # for .c files
$(CXX) $(CXXFLAGS) <input/output files> # for .cc files
$(CXX) $(CUDACXXFLAGS) <input/output files> # for .cc files which are to
# be linked into CUDA
# libraries/executables
$(NVCC) $(NVCCFLAGS) <input/output files> # for .cu files
And commands for compilation and linking of executables and libraries
should have the form:
$(CC) $(CFLAGS) <input/output files> ${LDFLAGS} # for c libs/exes
$(CXX) $(CXXFLAGS) <input/output files> ${LDFLAGS} # for c++ exes
$(CXX) $(CXXFLAGS) -shared <input/output files> ${LDFLAGS} # for c++ libs
$(NVCC) $(NVCCFLAGS) -shared <input/output files> ${NVCCLDFLAGS} # for CUDA libs
$(NVCC) $(NVCCFLAGS) <input/output files> ${NVCCLDFLAGS} # for CUDA exes
`LDFLAGS` *must* come at the end, to ensure proper linking.
An example C++ `Makefile` might look like this:
```
include ${FSLCONFDIR}/default.mk
PROJNAME = myproject
SOFILES = libmylib.so
XFILES = myexe1 myexe2
# Instead of explicitly defining this rule,
# We could instead rely on implicit Make
# rules for generating *.o files from *.cc
# files.
%.o: %.cc
$(CXX) $(CXXFLAGS) -c -o $@ $<
libmylib.so: myobj1.o myobj2.o
$(CXX) $(CXXFLAGS) -shared -o $@ $^ $(LDFLAGS)
myexe1: myexe1.o myobj1.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
myexe2: myexe2.o myobj2.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
```
## Building FSL CUDA projects. ## Building FSL CUDA projects.
Some FSL projects (e.g. [`fsl/eddy`(https://git.fmrib.ox.ac.uk/fsl/eddy) use Some FSL projects (e.g. [`fsl/eddy`(https://git.fmrib.ox.ac.uk/fsl/eddy) use
...@@ -42,3 +93,21 @@ using static linking: ...@@ -42,3 +93,21 @@ using static linking:
The `Makefile` for each FSL CUDA project may provide additional options for The `Makefile` for each FSL CUDA project may provide additional options for
controlling compilation. controlling compilation.
An example `Makefile` for a C++/CUDA project might look like this:
```
include ${FSLCONFDIR}/default.mk
PROJNAME = myproject
XFILES = myexe
%.o: %.cu
$(NVCC) $(NVCCFLAGS) -c -o $@ $<
%.o: %.cc
$(CXX) $(CUDACXXFLAGS) -c -o $@ $<
myexe:
$(NVCC) $(NVCCFLAGS) -o $@ $< $(NVCCLDFLAGS)
```
...@@ -65,6 +65,9 @@ ARCHLIBS = ...@@ -65,6 +65,9 @@ ARCHLIBS =
# armadillo structures may have different byte-alignment # armadillo structures may have different byte-alignment
# to equivalent g++-compiled structures (see # to equivalent g++-compiled structures (see
# include/armadillo_bits/compiler_setup.hpp) # include/armadillo_bits/compiler_setup.hpp)
#
# - Set -std=c++14. This is the newest C++ standard
# supported by nvcc for CUDA<11.0.
ARCHNVCCFLAGS = -DARMA_ALLOW_FAKE_GCC -std=c++14 ARCHNVCCFLAGS = -DARMA_ALLOW_FAKE_GCC -std=c++14
# Linker flags for CUDA projects. # Linker flags for CUDA projects.
...@@ -171,13 +174,14 @@ ifneq (${NVCC}, ) ...@@ -171,13 +174,14 @@ ifneq (${NVCC}, )
# "-ccbin" rather than "--compiler-bindir" here, # "-ccbin" rather than "--compiler-bindir" here,
# because the conda-forge nvcc wrapper checks for # because the conda-forge nvcc wrapper checks for
# -ccbin, and adds its own if not present. # -ccbin, and adds its own if not present.
NVCCFLAGS ?= -I${CUDA_HOME}/include \ CUDACXXFLAGS ?= -I${CUDA_HOME}/include
${GENCODEFLAGS} \ NVCCFLAGS ?= ${GENCODEFLAGS} \
-ccbin $(CXX) -ccbin $(CXX) \
NVCCLDFLAGS ?= -L${CUDA_HOME}/lib \ ${CUDACXXFLAGS}
-L${CUDA_HOME}/lib64 \ NVCCLDFLAGS ?= -L${CUDA_HOME}/lib \
-L${CUDA_HOME}/lib/stubs \ -L${CUDA_HOME}/lib64 \
-L${CUDA_HOME}/lib64/stubs -L${CUDA_HOME}/lib/stubs \
-L${CUDA_HOME}/lib64/stubs
# Link CUDA libraries statically, if compilation # Link CUDA libraries statically, if compilation
# was invoked with "make CUDA_STATIC=1". # was invoked with "make CUDA_STATIC=1".
...@@ -197,10 +201,10 @@ ifneq (${NVCC}, ) ...@@ -197,10 +201,10 @@ ifneq (${NVCC}, )
# cublas_Lt_static, in addition to culibos # cublas_Lt_static, in addition to culibos
ifeq ($(patsubst 9.%,,${CUDA_VER}),) ifeq ($(patsubst 9.%,,${CUDA_VER}),)
CUBLAS_STATIC = -lcublas_static -lculibos CUBLAS_STATIC = -lcublas_static -lculibos
NVCCFLAGS += --cudart=static NVCCLDFLAGS += --cudart=static
else else
CUBLAS_STATIC = -lcublas_static -lcublasLt_static -lculibos CUBLAS_STATIC = -lcublas_static -lcublasLt_static -lculibos
NVCCFLAGS += --cudart=static --cudadevrt=static NVCCLDFLAGS += --cudart=static --cudadevrt=static
endif endif
# Other CUDA toolkit components will # Other CUDA toolkit components will
...@@ -209,9 +213,9 @@ ifneq (${NVCC}, ) ...@@ -209,9 +213,9 @@ ifneq (${NVCC}, )
$(subst -lcurand,-lcurand_static,${CUDALIBS})) $(subst -lcurand,-lcurand_static,${CUDALIBS}))
else else
ifeq ($(patsubst 9.%,,${CUDA_VER}),) ifeq ($(patsubst 9.%,,${CUDA_VER}),)
NVCCFLAGS += --cudart=shared NVCCLDFLAGS += --cudart=shared
else else
NVCCFLAGS += --cudart=shared --cudadevrt=static NVCCLDFLAGS += --cudart=shared --cudadevrt=static
endif endif
_CUDALIBS += ${CUDALIBS} _CUDALIBS += ${CUDALIBS}
endif endif
......
...@@ -22,13 +22,13 @@ PROJNAME = ...@@ -22,13 +22,13 @@ PROJNAME =
USRLDFLAGS = # Linker flags USRLDFLAGS = # Linker flags
USRINCFLAGS = # Include directories USRINCFLAGS = # Include directories
USRCFLAGS = # Compiler flags for C projects USRCFLAGS = # Compiler flags for C files
USRCXXFLAGS = # Compiler flags for C++ projects USRCXXFLAGS = # Compiler flags for C++ files
USRCPPFLAGS = # Preprocessor flags USRCPPFLAGS = # Preprocessor flags
LIBS = # Libraries to link against for C and C++ projects - LIBS = # Libraries to link against for C and C++ projects -
# these are incorporated into the final LDFLAGS, below. # these are incorporated into the final LDFLAGS, below.
USRNVCCFLAGS = # Compiler flags for CUDA projects USRNVCCFLAGS = # Compiler flags for CUDA files
USRNVCCLDFLAGS = # Linker flags for CUDA projects USRNVCCLDFLAGS = # Linker flags for CUDA libraries/executables
CUDALIBS = # CUDA libraries to link against (e.g. curand, cublas, etc) - CUDALIBS = # CUDA libraries to link against (e.g. curand, cublas, etc) -
# these are incorporated into the final NVCCLDFLAGS, below. # these are incorporated into the final NVCCLDFLAGS, below.
# -lcuda and -lcudart are automatically added, so do not # -lcuda and -lcudart are automatically added, so do not
...@@ -84,20 +84,25 @@ INCFLAGS = ${USRINCFLAGS} -I. -I${DEVINCDIR} -I${INCDIR} ...@@ -84,20 +84,25 @@ INCFLAGS = ${USRINCFLAGS} -I. -I${DEVINCDIR} -I${INCDIR}
# All projects must use these flags for compilation/linking. # All projects must use these flags for compilation/linking.
# Commands for compilation of intermediate object files # Commands for compilation of intermediate object files
# should have the form: # should have the form:
#
# $(CC) $(CFLAGS) <input/output files> # $(CC) $(CFLAGS) <input/output files> # for .c files
# $(CXX) $(CXXFLAGS) <input/output files> # $(CXX) $(CXXFLAGS) <input/output files> # for .cc files
# $(NVCC) $(NVCCFLAGS) <input/output files> # $(CXX) $(CUDACXXFLAGS) <input/output files> # for .cc files which are to
# # be linked into CUDA
# # libraries/executables
# $(NVCC) $(NVCCFLAGS) <input/output files> # for .cu files
# #
# And commands for compilation and linking of executables # And commands for compilation and linking of executables
# and libraries should have the form: # and libraries should have the form:
# #
# $(CC) $(CFLAGS) <input/output files> ${LDFLAGS} # $(CC) $(CFLAGS) <input/output files> ${LDFLAGS} # for c libs/exes
# $(CXX) $(CXXFLAGS) <input/output files> ${LDFLAGS} # $(CXX) $(CXXFLAGS) <input/output files> ${LDFLAGS} # for c++ exes
# $(NVCC) $(NVCCFLAGS) <input/output files> ${NVCCLDFLAGS} # $(CXX) $(CXXFLAGS) -shared <input/output files> ${LDFLAGS} # for c++ libs
# $(NVCC) $(NVCCFLAGS) -shared <input/output files> ${NVCCLDFLAGS} # for CUDA libs
# $(NVCC) $(NVCCFLAGS) <input/output files> ${NVCCLDFLAGS} # for CUDA exes
#
# `LDFLAGS` *must* come at the end, to ensure proper linking.
# #
# LDFLAGS *must* come at the end, to ensure proper linking.
# The order in which the final FLAGS variables are # The order in which the final FLAGS variables are
# constructed here is important: # constructed here is important:
# #
...@@ -113,12 +118,13 @@ INCFLAGS = ${USRINCFLAGS} -I. -I${DEVINCDIR} -I${INCDIR} ...@@ -113,12 +118,13 @@ INCFLAGS = ${USRINCFLAGS} -I. -I${DEVINCDIR} -I${INCDIR}
# the default options specified in buildSettings.mk, # the default options specified in buildSettings.mk,
# which in turn can override options provided by the # which in turn can override options provided by the
# environment. # environment.
CPPFLAGS += ${ARCHCPPFLAGS} ${USRCPPFLAGS} CPPFLAGS += ${ARCHCPPFLAGS} ${USRCPPFLAGS}
CFLAGS += ${CPPFLAGS} ${ARCHCFLAGS} ${USRCFLAGS} ${INCFLAGS} CFLAGS += ${CPPFLAGS} ${ARCHCFLAGS} ${USRCFLAGS} ${INCFLAGS}
CXXFLAGS += ${CPPFLAGS} ${ARCHCXXFLAGS} ${USRCXXFLAGS} ${INCFLAGS} CXXFLAGS += ${CPPFLAGS} ${ARCHCXXFLAGS} ${USRCXXFLAGS} ${INCFLAGS}
LDFLAGS += ${ARCHLDFLAGS} ${USRLDFLAGS} \ CUDACXXFLAGS += ${CXXFLAGS} ${USRNVCCFLAGS}
-L. -L${DEVLIBDIR} -L${LIBDIR} \ LDFLAGS += ${ARCHLDFLAGS} ${USRLDFLAGS} \
${LIBS} ${ARCHLIBS} -L. -L${DEVLIBDIR} -L${LIBDIR} \
${LIBS} ${ARCHLIBS}
# Remove any -std=c++ options, as we are already setting # Remove any -std=c++ options, as we are already setting
# -std in ARCHNVCCFLAGS (seee buildSettings.mk), and # -std in ARCHNVCCFLAGS (seee buildSettings.mk), and
# passing another one via --compiler-options will confuse # passing another one via --compiler-options will confuse
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment