Well, the end goal is to incorporate hand written cuda kernels in openacc accelerated C/C++ sources and build everything with cmake. We’re not sure if it’s a cmake or a cuda issue, to be fair. My approach was to just write a simple, modern cmake file, my colleague also tried to hack together some of the link lines and so on to try to solve the issues, though ideally that should not be necessary. In any case, building with cmake does not work, but it can be built by hand.
For reference, saxpy_cuda.cu:
__global__
void saxpy_kernel(int n, float a, float *x, float *y)
{
int i = blockDim.x * blockIdx.x + threadIdx.x;
if ( i < n )
y[i] += a * x[i];
}
extern "C" void saxpy(int n ,float a, float *x, float *y)
{
dim3 griddim, blockdim;
blockdim = dim3(128,1,1);
griddim = dim3(n/blockdim.x,1,1);
saxpy_kernel<<<griddim,blockdim>>>(n,a,x,y);
}
and openacc_c_main.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
extern void saxpy(int,float,float*,float*);
int main(int argc, char **argv)
{
float *x, *y;
int n = 1<<20, i;
x = (float*)malloc(n*sizeof(float));
y = (float*)malloc(n*sizeof(float));
#pragma acc data create(x[0:n]) copyout(y[0:n])
{
#pragma acc kernels
{
for( i = 0; i < n; i++)
{
x[i] = 1.0f;
y[i] = 0.0f;
}
}
#pragma acc host_data use_device(x,y)
{
saxpy(n, 2.0, x, y);
}
}
fprintf(stdout, "y[0] = %f\n",y[0]);
return 0;
}
To compile and run on Ubuntu 20 and the HPC SDK 23.9 and it’s embedded nvcc
nvcc -gencode arch=compute_80,code=sm_80 -c saxpy_cuda.cu
nvc -fast -acc -gpu=cc80 -c openacc_c_main.c
nvc++ -o openacc_c_main -fast -acc -gpu=cc80 saxpy_cuda.o openacc_c_main.o -cuda
./openacc_c_main
y[0] = 2.000000
But not with cmake and this CMakeLists.txt:
cmake_minimum_required(VERSION 3.25)
project(openacc_cuda_interop)
enable_language(CUDA)
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
find_package(OpenACC REQUIRED)
add_library(saxpy_cuda src/saxpy_cuda.cu)
add_executable(openacc_c_main src/openacc_c_main.c)
target_link_libraries(openacc_c_main PRIVATE OpenACC::OpenACC_C)
target_link_libraries(openacc_c_main PRIVATE saxpy_cuda)
Building with cmake looks like this:
$ CC=nvc CXX=nvc++ cmake -B build . --fresh --warn-uninitialized -DCMAKE_BUILD_TYPE=Debug && cmake --build build/ --config Debug --verbose
Warn about uninitialized values.
-- The C compiler identification is NVHPC 23.9.0
-- The CXX compiler identification is NVHPC 23.9.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- The CUDA compiler identification is NVIDIA 12.2.91
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Check for working CUDA compiler: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvcc - skipped
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- Found OpenACC_C: -acc
-- Found OpenACC_CXX: -acc
-- Configuring done (5.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/user/git/openacc-cuda-interop/build
Change Dir: '/home/user/git/openacc-cuda-interop/build'
Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile
/usr/bin/cmake -S/home/user/git/openacc-cuda-interop -B/home/user/git/openacc-cuda-interop/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/user/git/openacc-cuda-interop/build/CMakeFiles /home/user/git/openacc-cuda-interop/build//CMakeFiles/progress.marks
/usr/bin/make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/user/git/openacc-cuda-interop/build'
/usr/bin/make -f CMakeFiles/saxpy_cuda.dir/build.make CMakeFiles/saxpy_cuda.dir/depend
make[2]: Entering directory '/home/user/git/openacc-cuda-interop/build'
cd /home/user/git/openacc-cuda-interop/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/user/git/openacc-cuda-interop /home/user/git/openacc-cuda-interop /home/user/git/openacc-cuda-interop/build /home/user/git/openacc-cuda-interop/build /home/user/git/openacc-cuda-interop/build/CMakeFiles/saxpy_cuda.dir/DependInfo.cmake "--color="
make[2]: Leaving directory '/home/user/git/openacc-cuda-interop/build'
/usr/bin/make -f CMakeFiles/saxpy_cuda.dir/build.make CMakeFiles/saxpy_cuda.dir/build
make[2]: Entering directory '/home/user/git/openacc-cuda-interop/build'
[ 25%] Building CUDA object CMakeFiles/saxpy_cuda.dir/src/saxpy_cuda.cu.o
/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvcc -forward-unknown-to-host-compiler -g "--generate-code=arch=compute_52,code=[compute_52,sm_52]" -MD -MT CMakeFiles/saxpy_cuda.dir/src/saxpy_cuda.cu.o -MF CMakeFiles/saxpy_cuda.dir/src/saxpy_cuda.cu.o.d -x cu -c /home/user/git/openacc-cuda-interop/src/saxpy_cuda.cu -o CMakeFiles/saxpy_cuda.dir/src/saxpy_cuda.cu.o
[ 50%] Linking CUDA static library libsaxpy_cuda.a
/usr/bin/cmake -P CMakeFiles/saxpy_cuda.dir/cmake_clean_target.cmake
/usr/bin/cmake -E cmake_link_script CMakeFiles/saxpy_cuda.dir/link.txt --verbose=1
/usr/bin/ar qc libsaxpy_cuda.a CMakeFiles/saxpy_cuda.dir/src/saxpy_cuda.cu.o
/usr/bin/ranlib libsaxpy_cuda.a
make[2]: Leaving directory '/home/user/git/openacc-cuda-interop/build'
[ 50%] Built target saxpy_cuda
/usr/bin/make -f CMakeFiles/openacc_c_main.dir/build.make CMakeFiles/openacc_c_main.dir/depend
make[2]: Entering directory '/home/user/git/openacc-cuda-interop/build'
cd /home/user/git/openacc-cuda-interop/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/user/git/openacc-cuda-interop /home/user/git/openacc-cuda-interop /home/user/git/openacc-cuda-interop/build /home/user/git/openacc-cuda-interop/build /home/user/git/openacc-cuda-interop/build/CMakeFiles/openacc_c_main.dir/DependInfo.cmake "--color="
make[2]: Leaving directory '/home/user/git/openacc-cuda-interop/build'
/usr/bin/make -f CMakeFiles/openacc_c_main.dir/build.make CMakeFiles/openacc_c_main.dir/build
make[2]: Entering directory '/home/user/git/openacc-cuda-interop/build'
[ 75%] Building C object CMakeFiles/openacc_c_main.dir/src/openacc_c_main.c.o
/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc -g -O0 -acc -MD -MT CMakeFiles/openacc_c_main.dir/src/openacc_c_main.c.o -MF CMakeFiles/openacc_c_main.dir/src/openacc_c_main.c.o.d -o CMakeFiles/openacc_c_main.dir/src/openacc_c_main.c.o -c /home/user/git/openacc-cuda-interop/src/openacc_c_main.c
[100%] Linking CUDA executable openacc_c_main
/usr/bin/cmake -E cmake_link_script CMakeFiles/openacc_c_main.dir/link.txt --verbose=1
/usr/bin/g++ @CMakeFiles/openacc_c_main.dir/objects1.rsp -o openacc_c_main @CMakeFiles/openacc_c_main.dir/linkLibs.rsp -L"/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/cuda/12.2/lib64" -L"/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/math_libs/12.2/lib64" -L"/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/12.2/nccl/lib" -L"/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/12.2/nvshmem/lib" -L"/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/cuda/12.2/targets/x86_64-linux/lib/stubs" -L"/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/cuda/12.2/targets/x86_64-linux/lib"
/usr/bin/ld: CMakeFiles/openacc_c_main.dir/src/openacc_c_main.c.o: in function `main':
/home/user/git/openacc-cuda-interop/src/openacc_c_main.c:24: undefined reference to `__pgi_uacc_enter'
/usr/bin/ld: /home/user/git/openacc-cuda-interop/src/openacc_c_main.c:18: undefined reference to `__pgi_uacc_computestart2'
/usr/bin/ld: /home/user/git/openacc-cuda-interop/src/openacc_c_main.c:19: undefined reference to `__pgi_uacc_launch'
/usr/bin/ld: /home/user/git/openacc-cuda-interop/src/openacc_c_main.c:24: undefined reference to `__pgi_uacc_computedone'
/usr/bin/ld: /home/user/git/openacc-cuda-interop/src/openacc_c_main.c:24: undefined reference to `__pgi_uacc_noversion'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_cooperlake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_get_l3_cachesize'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_rocketlake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_remainder'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_haswell'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_icelake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dbessel_j1'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_znver4'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_tigerlake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_avx2'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_bessel_y0'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_avx512vl'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_znver3'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dbessel_j0'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dremainder'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_get_threads_per_socket'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dround'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_sandybridge'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_bessel_y1'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_gh_b'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_znver2'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dbessel_y1'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_intel'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dbessel_jn'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_sapphirerapids'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_znver1'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dbessel_y0'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_bessel_jn'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_cascadelake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_skylake_xeon'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_avx512f'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_skylake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_dbessel_yn'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_alderlake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_fma'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_ivybridge'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_graniterapids'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_bessel_j0'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_cannonlake'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_bessel_j1'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_skylake_client'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_around'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__mth_i_bessel_yn'
/usr/bin/ld: /opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/lib/libnvc.so: undefined reference to `__Cpuid_is_broadwell'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/openacc_c_main.dir/build.make:100: openacc_c_main] Error 1
make[2]: Leaving directory '/home/user/git/openacc-cuda-interop/build'
make[1]: *** [CMakeFiles/Makefile2:111: CMakeFiles/openacc_c_main.dir/all] Error 2
make[1]: Leaving directory '/home/user/git/openacc-cuda-interop/build'
make: *** [Makefile:91: all] Error 2
Any idea what is going on and how to fix this on the cmake side? It looks like it’s using g++ and ld for linking, does that make sense? Is cmake maybe confused what the link language should be for linking a cuda library and a C executable?