3

I am struggling to link my CUDA kernel with my Rust project using a build.rs file with the crate cc:

build.rs

extern crate cc;

fn main() {
    println!("cargo:rustc-link-lib=cuda");
    println!("cargo:rustc-link-lib=cudart");
    println!("cargo:rustc-link-lib=cudnn");

    cc::Build::new()
        .cuda(true)
        .flag("-cudart=shared")
        .flag("-gencode")
        .flag("arch=compute_61,code=sm_61")
        .file("kernel.cu")
        .compile("kernel");
}

I get this error:

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183.1y16o1qfye96o7m0.rcgu.o" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183.3rngp6bm2u2q5z0y.rcgu.o" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183.3vhdzx0ywzealo7m.rcgu.o" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183.4xq48u46a1pwiqn7.rcgu.o" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183.8xzrsc1ux72v29j.rcgu.o" "-o" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183.crate.allocator.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "-L" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps" "-L" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/build/rust_cudnn-df924982e63c2363/out" "-L" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-l" "cudart" "-l" "cudnn" "-l" "cuda" "-Wl,-Bstatic" "-Wl,--whole-archive" "-l" "kernel" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "-l" "stdc++" "-Wl,-Bstatic" "/home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/liblibc-dca5860987df25ef.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-0006dc6e9901bcad.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-8d1c3982c0670998.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_jemalloc-2a12cd93029b9807.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-a5d3ff19e13d9f37.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_system-c5f69e7df1f06d84.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-e2e7ce88a6c41eea.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-3d7473d271611dc2.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_unicode-58e7a51af24928de.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-6806ae6018eec5e7.rlib" "/home/ltei/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-85fd2d595ec0faf9.rlib" "-Wl,-Bdynamic" "-l" "util" "-l" "util" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "pthread" "-l" "gcc_s" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util" "-l" "util"
  = note: /home/ltei/Dev/Workspaces/rust_cudnn/target/debug/deps/rust_cudnn-c2a0c7c98bc21183.3vhdzx0ywzealo7m.rcgu.o : In fonction « rust_cudnn::main » :
          /home/ltei/Dev/Workspaces/rust_cudnn/src/main.rs:213 : undefined reference to « Kernel_test »
          /home/ltei/Dev/Workspaces/rust_cudnn/target/debug/build/rust_cudnn-df924982e63c2363/out/libkernel.a(kernel.o) : In fonction « __sti____cudaRegisterAll_41_tmpxft_0000098e_00000000_7_kernel_cpp1_ii_a9220a05() » :
          /tmp/tmpxft_0000098e_00000000-4_kernel.cudafe1.stub.c:7 : undefined reference to « __cudaRegisterFatBinary »
          /home/ltei/Dev/Workspaces/rust_cudnn/target/debug/build/rust_cudnn-df924982e63c2363/out/libkernel.a(kernel.o) : In fonction « __cudaUnregisterBinaryUtil() » :
          /usr/include/crt/host_runtime.h:238 : undefined reference to « __cudaUnregisterFatBinary »
          collect2: error: ld returned 1 exit status

Apparently, that is what happens when you don't link cudart, but I thought I did. Maybe I did it wrong? The error only occurs when I try to compile and link my CUDA kernel. When I don't, it works and I can use CUDA functions like cudaMalloc from Rust

Here is my kernel.cu file:

#include "kernel.h"

__global__ void vectorAdd_ker(float* vector, int len, float value) {
      int tid = blockIdx.x * blockDim.x + threadIdx.x;
      if (tid < len) { vector[tid] += value; }
}

void Kernel_vectorAdd(float* vector, int len, float value) {
   dim3 gridDim;
   dim3 blockDim;

   blockDim.x = 1024;
   gridDim.x = (len + blockDim.x - 1) / blockDim.x;

  vectorAdd_ker <<<gridDim, blockDim>>> (vector, len, value);
}

int Kernel_test() {
  return 7;
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ltei
  • 425
  • 1
  • 6
  • 14
  • You aren't linking cudart. The output in your question shows you anren"t – talonmies Mar 18 '18 at 15:22
  • I have this "-l" "cudart" in the command, but indeed it looks like I isn't linked, I wonder why – Ltei Mar 18 '18 at 15:33
  • Does it work if you specify dynamic linkage explicitly, eg. `cargo:rustc-link-lib=dylib=cuda` ? – harmic Mar 19 '18 at 01:13
  • No, the same error appears – Ltei Mar 19 '18 at 01:26
  • Could you paste "kernel.cu"? Your "build.rs" works with sample/vectorAdd.cu on my env. – termoshtt Mar 21 '18 at 14:05
  • I added my kernel.cu file to the post. Also I tried to build with vectorAdd.cu instead of my kernel.cu, but it gives me the same error! I think there is something I forgot to do in my Rust project – Ltei Mar 21 '18 at 14:58
  • @XavierP: I have added a community wiki entry to replace the answer you added and which was moderator deleted. If you could be so kind as to modify it as you see fit and accept the answer, this question will fall off the unaswered queues for the CUDA and rust tags. – talonmies Jul 01 '20 at 11:57

1 Answers1

1

The original poster diagnosed that this was a path issue and was able to modify build.rs to this (taken from here):

extern crate cc;
use std::env;


fn main() {

    if let Ok(cuda_path) = env::var("CUDA_HOME") {
        println!("cargo:rustc-link-search=native={}/lib64", cuda_path);
    } else {
        println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64");
    }

    println!("cargo:rustc-link-lib=dylib=cuda");
    println!("cargo:rustc-link-lib=dylib=cudart");
    println!("cargo:rustc-link-lib=dylib=cublas");
    println!("cargo:rustc-link-lib=dylib=curand");

    cc::Build::new().cuda(true)
        .flag("-gencode").flag("arch=compute_52,code=sm_52") // Generate code for Maxwell (GTX 970, 980, 980 Ti, Titan X).
        .flag("-gencode").flag("arch=compute_53,code=sm_53") // Generate code for Maxwell (Jetson TX1).
        .flag("-gencode").flag("arch=compute_61,code=sm_61") // Generate code for Pascal (GTX 1070, 1080, 1080 Ti, Titan Xp).
        .flag("-gencode").flag("arch=compute_60,code=sm_60") // Generate code for Pascal (Tesla P100).
        .flag("-gencode").flag("arch=compute_62,code=sm_62") // Generate code for Pascal (Jetson TX2).
        .file("kernels/vectorfragment.cu").compile("libvectorfragment.a");
    cc::Build::new().cuda(true).cpp_link_stdlib(None)
        .flag("-gencode").flag("arch=compute_52,code=sm_52")
        .flag("-gencode").flag("arch=compute_53,code=sm_53")
        .flag("-gencode").flag("arch=compute_61,code=sm_61")
        .flag("-gencode").flag("arch=compute_60,code=sm_60")
        .flag("-gencode").flag("arch=compute_62,code=sm_62")
        .file("kernels/vectorpacked.cu").compile("libvectorpacked.a");
    cc::Build::new().cuda(true).cpp_link_stdlib(None)
        .flag("-gencode").flag("arch=compute_52,code=sm_52")
        .flag("-gencode").flag("arch=compute_53,code=sm_53")
        .flag("-gencode").flag("arch=compute_61,code=sm_61")
        .flag("-gencode").flag("arch=compute_60,code=sm_60")
        .flag("-gencode").flag("arch=compute_62,code=sm_62")
        .file("kernels/matrix.cu").compile("libmatrix.a");
}

This apparently worked where the original did not.

[Note: this answer added as a community wiki from comments and a now deleted answer to get this question off the unanswered question queue for the CUDA tag.]

talonmies
  • 70,661
  • 34
  • 192
  • 269