CUDA and autotools configure.ac, makefile.am, ...

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:

http://www.cs.rug.nl/~wladimir/sc-cuda/

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