Has anyone yet used CUDA in a project that is built with autotools? If so, can you please post your build system files here. I’m integrating CUDA into an existing open source program, but this autotools detection stuff is driving me crazy. (like, for example, how to add a --cuda-path variable to configure)
I got it to work on my own already…
Can you explain how?
I made a libtool-like program that calls nvcc and generates the necessary libtool description file, then in Makefile.am I added
.cu.lo:
$(top_builddir)/cudalt.py $@ $(NVCC) -c $(NVCCFLAGS) $<
Now it recognizes .cu files automatically in SOURCES and calls the script. Let me know if you need the script.
can you send me the program, I just begin to program with nvcc, perhaps it is needed…
thank you
You can find it in the tarball of my GPU accelerated Dirac codec:
[url=“http://www.cs.rug.nl/~wladimir/sc-cuda/sc-cuda-1.tar.gz”]http://www.cs.rug.nl/~wladimir/sc-cuda/[/url]
Thanks, that helps figuring things out.
Actually, your particular project doesn’t build for me on Ubuntu 7.04 so I’ve got a quick queston – what Autotools version are you using?
Can you be more specific in “doesn’t build”?
:) Yes, sorry. The autotools barf, not recognizing some stuff in the Makefile.am’s. I think I have the wrong Autotools version. I’ll post the error codes when I get back to school, but can you tell me in the meantime what Autotools ver. you have so I can start by trying an upgrade? The errors looked like all the other bad-autotools-version errors I’ve seen in my carreer.
OK, here’s what happens with a freshly unwrapped sc-cuda tarball:
gx280:~/src/sc-new$ aclocal
/usr/share/aclocal/smpeg.m4:13: warning: underquoted definition of AM_PATH_SMPEG
run info '(automake)Extending aclocal'
or see http://sources.redhat.com/automake/automake.html#Extending-aclocal
aclocal:configure.ac:128: warning: macro `AM_PATH_CHECK' not found in library
gx280:~/src/sc-new$ autoheader
gx280:~/src/sc-new$ automake
testsuite/prototype/Makefile.am:2: HAVE_I386 does not appear in AM_CONDITIONAL
gx280:~/src/sc-new$ autoconf
configure.ac:5: error: possibly undefined macro: AS_NANO
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
configure.ac:30: error: possibly undefined macro: AS_AUTOTOOLS_ALTERNATE
configure.ac:60: error: possibly undefined macro: AS_COMPILER_FLAG
configure.ac:134: error: possibly undefined macro: AM_PATH_CHECK
configure.ac:139: error: possibly undefined macro: AS_HOST_DEFINES
gx280:~/src/sc-new$ ./configure
./configure: line 1975: syntax error near unexpected token `SCHRO_CVS=no,SCHRO_CVS=yes'
./configure: line 1975: `AS_NANO(SCHRO_CVS=no,SCHRO_CVS=yes)'
gx280:~/src/sc-new$
Hmm I don’t recognize those at all. I don’t know what versions I have, but it’s the most recent ones provided by ubuntu at the moment.
Also make sure that you have gtkdoc-tools installed as it provides some m4 stuff it will otherwise complain about.
OK, I was missing the libgstreamer development package. That fixed the weird Autotools errors. Thanks for the help!
edit: no wait, it wasn’t libgstreamer that fixed it, but rather using ‘autoreconf’ instead of that other Autotools stuff. Man I hate Autotools. Autoreconf creates an OK configure script, but now I get this when compiling:
gx280:~/src/sc-new$ make
cp schroedinger-uninstalled.pc schroedinger-0.9-uninstalled.pc
make all-recursive
make[1]: Entering directory `/home/krilli/src/sc-new'
Making all in cuda
make[2]: Entering directory `/home/krilli/src/sc-new/cuda'
../cudalt.py init.lo nvcc -c -O2 -use_fast_math init.cu
../cudalt.py cudawavelet.lo nvcc -c -O2 -use_fast_math cudawavelet.cu
../cudalt.py haar_iwt.lo nvcc -c -O2 -use_fast_math haar_iwt.cu
../cudalt.py haar_iiwt.lo nvcc -c -O2 -use_fast_math haar_iiwt.cu
make[2]: *** No rule to make target `frame.lo', needed by `libdcuda.la'. Stop.
make[2]: Leaving directory `/home/krilli/src/sc-new/cuda'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/krilli/src/sc-new'
make: *** [all] Error 2
Wumpus, thanks for your precious indications !
Thanks to you I managed to build a small cuda test of mine with autotools (I’m beginning cuda development).
Nevertheless, your workaround only supports shared libraries, so I improved your script and added a line in my makefile to make it work for executables and static libraries.
I also implemented a switch for emulation mode support in the configure (but it does not use the emulation version of other libraries like fft, cublas, …)
For anyone that may be interested, here is what is needed to make it work:
Makefile.am (insert these lines anywhere in the file):
.cu.o:
�   $(NVCC) -o $@ -c $< $(NVCCFLAGS)
.cu.lo:
�   $(top_srcdir)/cudalt.py $@ $(NVCC) -c $(NVCCFLAGS) $<
configure.ac (the “nvcc flags setup” part assumes we already have a DEBUG variable defined by a AC_ARG_ENABLE([debug]…). These lines should be inserted anywhere after the AC_ARG_ENABLE([debug] call.
By the way, I am planning to write an m4 script to properly detect CUDA.
# ------------------------------------------------------------------------------
# Setup CUDA paths
# ------------------------------------------------------------------------------
AC_ARG_WITH([cuda],
   [  --with-cuda=PATH  �  �    prefix where cuda is installed [default=auto]])
if test -n "$with_cuda"
then
   CUDA_CFLAGS="-I$with_cuda/include"
   CUDA_LIBS="-L$with_cuda/lib -lcuda -lcudart"
   NVCC="$with_cuda/bin/nvcc"
else
   CUDA_CFLAGS="-I/usr/local/cuda/include"
   CUDA_LIBS="-L/usr/local/cuda/lib -lcuda -lcudart"
   NVCC="nvcc"
fi
AC_SUBST(CUDA_CFLAGS)
AC_SUBST(CUDA_LIBS)
AC_SUBST(NVCC)
AC_ARG_ENABLE([emu],
   [  --enable-emu    Turn on device emulation for CUDA],
   [case "${enableval}" in
 �  �    yes) EMULATION=true;;
 �  �    no)  EMULATION=false;;
 �  �    *) AC_MSG_ERROR([bad value ${enableval} for --enable-emu]);;
   esac],
   [EMULATION=false]
)
# ------------------------------------------------------------------------------
# Setup nvcc flags
# ------------------------------------------------------------------------------
if test x$DEBUG = xtrue
then
   NVCCFLAGS="-g"
else
   NVCCFLAGS="-O3 -use_fast_math"
fi
if test x$EMULATION = xtrue
then
   NVCCFLAGS+=" -deviceemu"
fi
AC_SUBST(NVCCFLAGS)
cudalt.py (complete file):
#!/usr/bin/python
# libtoolish hack: compile a .cu file like libtool does
import sys
import os
lo_filepath = sys.argv[1]
o_filepath = lo_filepath.replace(".lo", ".o")
try:
  i = o_filepath.rindex("/")
  lo_dir = o_filepath[0:i+1]
  o_filename = o_filepath[i+1:]
except ValueError:
  lo_dir = ""
  o_filename = o_filepath
local_pic_dir = ".libs/"
local_npic_dir = ""
pic_dir = lo_dir + local_pic_dir
npic_dir = lo_dir + local_npic_dir
pic_filepath = pic_dir + o_filename
npic_filepath = npic_dir + o_filename
local_pic_filepath = local_pic_dir + o_filename
local_npic_filepath = local_npic_dir + o_filename
# Make lib dir
try:
   os.mkdir(pic_dir)
except OSError:
   pass
# generate the command to compile the .cu for shared library
args = sys.argv[2:]
args.extend(["-Xcompiler","-fPIC"]) # position indep code
args.append("-o")
args.append(pic_filepath)
command = " ".join(args)
print command
# compile the .cu
rv = os.system(command)
if rv != 0:
  sys.exit(1)
# generate the command to compile the .cu for static library
args = sys.argv[2:]
args.append("-o")
args.append(npic_filepath)
command = " ".join(args)
print command
# compile the .cu
rv = os.system(command)
if rv != 0:
  sys.exit(1)
# get libtool version
fd = os.popen("libtool --version")
libtool_version = fd.readline()
fd.close()
# generate the .lo file
f = open(lo_filepath, "w")
f.write("# " + Â lo_filepath + " - a libtool object file\n")
f.write("# Generated by " + libtool_version + "\n")
f.write("#\n")
f.write("# Please DO NOT delete this file!\n")
f.write("# It is necessary for linking the library.\n\n")
f.write("# Name of the PIC object.\n")
f.write("pic_object='" + local_pic_filepath + "'\n\n")
f.write("# Name of the non-PIC object.\n")
f.write("non_pic_object='" + local_npic_filepath + "'\n")
f.close()
sys.exit(0)
Hello,
My friend and I, here, are trying to port an open source math library to CUDA. We managed to edit the configure.ac to set appropriate compiler options. Our aim is to generate a shared library file as an output. But the linking fails when libtool passes -Wl, -soname, --whole-archive etc as options which are not recognized by nvcc, Any idea how we can fix this? Thanks
Don’t use nvcc for linking, use the normal system tool (i.e. gcc). Although I cannot offer any help on how to configure this with autotools as I am not familiar with it.
Thank you both! I now final managed to build my CUDA shared library with autotools. I find it useful to modify the .cu compiling lines on automake file:
$(top_srcdir)/cudalt.py $@ $(NVCC) $(NVCC_CFLAGS) --compiler-options=\"$(CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS)\" -c $<
To get proper includes and cflags. With this setup nvcc_cflags is used to pass only flags to nvcc, but gcc called by nvcc gets all the same flags as normal .c files.
Hi,
I know it is not good style to dig out a three years old thread, but I want to add my solution here to spare others the way through autohell and this thread was the only reference I found on the topic.
############################################
# NVIDIA Cuda Compiler detection and setup #
############################################
# If cuda is requested to be enabled
AC_ARG_ENABLE(cuda,
AS_HELP_STRING([--enable-cuda=ARCH], [Enable cuda based modules for architecture ARCH (see nvcc option -arch).]),[
# Search nvcc compiler
AC_PATH_PROG(NVCC, nvcc, "no")
AS_IF([test "x$NVCC" = "xno"],[
AC_MSG_ERROR([NVCC compiler not found!])
])
# Check nvcc version, should be 3.0
AS_IF([nvcc --version | grep -q "release 3.0"],
[],
[AC_MSG_WARN([NVCC compiler version is NOT 3.0!])
])
# If $with_cuda is not empty, set to CUDA_ARCH to
# supplied value, else set to value sm_11
AS_IF([test "x$enableval" = "xyes"],[
CUDA_ARCH=" -arch=sm_11"
],[
CUDA_ARCH=" -arch=$enableval"
])
# Set CUDA_CFLAGS to $NVCC, where substring "bin/nvcc"
# is substituted by "include".
CUDA_CFLAGS=" -I${NVCC/'bin/nvcc'/include}"
#Set CUDA_CFLAGS to $NVCC, where substring "bin/nvcc"
#is substituted by "lib".
CUDA_LIBS=" -L${NVCC/'bin/nvcc'/lib}"
# If $build_cpu contains "_64", append "64" to CUDA_LIBS
AS_IF([echo $build_cpu | grep -q "_64"],
[CUDA_LIBS+="64"])
# Append " -lcudart" to CUDA_LIBS
CUDA_LIBS+=" -lcudart"
# Symbolize that cuda is wanted
with_cuda=$enableval
# Make variables available in Makefile.am
AC_SUBST(CUDA_CFLAGS)
AC_SUBST(CUDA_LIBS)
AC_SUBST(NVCC)
])
# Set this conditional if cuda is wanted
AM_CONDITIONAL([WANT_CUDA], [test -n "$with_cuda"])
# Check whether to use device emulation mode for cuda (if no cuda capable gpu is available)
AC_ARG_ENABLE([emu],
AS_HELP_STRING([--enable-emu], [Enable device emulation for cuda modules (nvcc version <= 3.0 only).]),
[EMULATION=true],
[EMULATION=false])
# Set up compilation flags for cuda compiler nvcc, if with_cuda is set
AS_IF([test -n "$with_cuda"],[
# If debug flag is set apply debugging compilation flags, otherwise build compilation flags
AS_IF([test "x$DEBUG" = "xtrue"],
[NVCCFLAGS="-g --compiler-options -fno-strict-aliasing --compiler-options -fno-inline"],
[NVCCFLAGS="-O3 -use_fast_math --compiler-options -fno-strict-aliasing --compiler-options -fno-inline"])
# Add architecture to flags
NVCCFLAGS+=" $CUDA_ARCH"
# If device emulation was set, add deviceemu flag
AS_IF([test "x$EMULATION" = "xtrue"],
[NVCCFLAGS+=" -deviceemu"])
])
# Make NVCCFLAGS available in Makefile.am
AC_SUBST(NVCCFLAGS)
This code allows the conditional compilation of cuda files. It automatically detects the cuda compiler and all library and include paths. For compilation, the libtool like script from above was used. To add files for conditional compilation you can add them to the Makefile.am:
if WANT_CUDA
<yourtarget>_SOURCES += <yoursources>.cpp
All other stuff was handled with the make targets and libtool like python script above. I know this code is easy to break, but it is the best solution I have found so far for conditional compilation.
Have a nice day,
Kwyjibo
Hi,
I know it is not good style to dig out a three years old thread, but I want to add my solution here to spare others the way through autohell and this thread was the only reference I found on the topic.
############################################
# NVIDIA Cuda Compiler detection and setup #
############################################
# If cuda is requested to be enabled
AC_ARG_ENABLE(cuda,
AS_HELP_STRING([--enable-cuda=ARCH], [Enable cuda based modules for architecture ARCH (see nvcc option -arch).]),[
# Search nvcc compiler
AC_PATH_PROG(NVCC, nvcc, "no")
AS_IF([test "x$NVCC" = "xno"],[
AC_MSG_ERROR([NVCC compiler not found!])
])
# Check nvcc version, should be 3.0
AS_IF([nvcc --version | grep -q "release 3.0"],
[],
[AC_MSG_WARN([NVCC compiler version is NOT 3.0!])
])
# If $with_cuda is not empty, set to CUDA_ARCH to
# supplied value, else set to value sm_11
AS_IF([test "x$enableval" = "xyes"],[
CUDA_ARCH=" -arch=sm_11"
],[
CUDA_ARCH=" -arch=$enableval"
])
# Set CUDA_CFLAGS to $NVCC, where substring "bin/nvcc"
# is substituted by "include".
CUDA_CFLAGS=" -I${NVCC/'bin/nvcc'/include}"
#Set CUDA_CFLAGS to $NVCC, where substring "bin/nvcc"
#is substituted by "lib".
CUDA_LIBS=" -L${NVCC/'bin/nvcc'/lib}"
# If $build_cpu contains "_64", append "64" to CUDA_LIBS
AS_IF([echo $build_cpu | grep -q "_64"],
[CUDA_LIBS+="64"])
# Append " -lcudart" to CUDA_LIBS
CUDA_LIBS+=" -lcudart"
# Symbolize that cuda is wanted
with_cuda=$enableval
# Make variables available in Makefile.am
AC_SUBST(CUDA_CFLAGS)
AC_SUBST(CUDA_LIBS)
AC_SUBST(NVCC)
])
# Set this conditional if cuda is wanted
AM_CONDITIONAL([WANT_CUDA], [test -n "$with_cuda"])
# Check whether to use device emulation mode for cuda (if no cuda capable gpu is available)
AC_ARG_ENABLE([emu],
AS_HELP_STRING([--enable-emu], [Enable device emulation for cuda modules (nvcc version <= 3.0 only).]),
[EMULATION=true],
[EMULATION=false])
# Set up compilation flags for cuda compiler nvcc, if with_cuda is set
AS_IF([test -n "$with_cuda"],[
# If debug flag is set apply debugging compilation flags, otherwise build compilation flags
AS_IF([test "x$DEBUG" = "xtrue"],
[NVCCFLAGS="-g --compiler-options -fno-strict-aliasing --compiler-options -fno-inline"],
[NVCCFLAGS="-O3 -use_fast_math --compiler-options -fno-strict-aliasing --compiler-options -fno-inline"])
# Add architecture to flags
NVCCFLAGS+=" $CUDA_ARCH"
# If device emulation was set, add deviceemu flag
AS_IF([test "x$EMULATION" = "xtrue"],
[NVCCFLAGS+=" -deviceemu"])
])
# Make NVCCFLAGS available in Makefile.am
AC_SUBST(NVCCFLAGS)
This code allows the conditional compilation of cuda files. It automatically detects the cuda compiler and all library and include paths. For compilation, the libtool like script from above was used. To add files for conditional compilation you can add them to the Makefile.am:
if WANT_CUDA
<yourtarget>_SOURCES += <yoursources>.cpp
All other stuff was handled with the make targets and libtool like python script above. I know this code is easy to break, but it is the best solution I have found so far for conditional compilation.
Have a nice day,
Kwyjibo
Not sure I want to post my m4 script just yet, but here are some tricks others may appreciate.
Add this to Makefile.am so you don’t need the libtool-python hack. The -static flag keeps libtool from trying to add in harmful PIC flags. (Tested with Libtool 2.4 – 1.x users really should upgrade.)
.cu.lo:
$(LIBTOOL) --tag=CC --mode=compile $(NVCC) --compile $(NVCC_FLAGS) -o $@ $^ -static
Also in Makefile.am, if your library only uses cuda sources, add in the following to appease automake (tell it to treat the library as C sources).
nodist_EXTRA_libmycuda_la_SOURCES = dummy.c
Final trick: This can be useful in configure scripts that detect the -arch and -code flags supported by $NVCC.
touch conftest.cu
NVCC_FLAGS="--dryrun -c conftest.cu -o conftest.o" # --dryrun for a significant speedup
$NVCC $NVCC_FLAGS -arch=compute_10 >/dev/null 2>&1
if test $? -eq 0 ...
$NVCC $NVCC_FLAGS -arch=compute_10 -code=sm_11 >/dev/null 2>&1
if test $? -eq 0 ...
rm -f conftest.cu conftest.o
Not sure I want to post my m4 script just yet, but here are some tricks others may appreciate.
Add this to Makefile.am so you don’t need the libtool-python hack. The -static flag keeps libtool from trying to add in harmful PIC flags. (Tested with Libtool 2.4 – 1.x users really should upgrade.)
.cu.lo:
$(LIBTOOL) --tag=CC --mode=compile $(NVCC) --compile $(NVCC_FLAGS) -o $@ $^ -static
Also in Makefile.am, if your library only uses cuda sources, add in the following to appease automake (tell it to treat the library as C sources).
nodist_EXTRA_libmycuda_la_SOURCES = dummy.c
Final trick: This can be useful in configure scripts that detect the -arch and -code flags supported by $NVCC.
touch conftest.cu
NVCC_FLAGS="--dryrun -c conftest.cu -o conftest.o" # --dryrun for a significant speedup
$NVCC $NVCC_FLAGS -arch=compute_10 >/dev/null 2>&1
if test $? -eq 0 ...
$NVCC $NVCC_FLAGS -arch=compute_10 -code=sm_11 >/dev/null 2>&1
if test $? -eq 0 ...
rm -f conftest.cu conftest.o