I am trying to call a CUDA function from my Go code. I have the following three files.
test.h:
int test_add(void);
test.cu:
__global__ void add(int *a, int *b, int *c){
*c = *a + *b;
}
int test_add(void) {
int a, b, c; // host copies of a, b, c
int *d_a, *d_b, *d_c; // device copies of a, b, c
int size = sizeof(int);
// Allocate space for device copies of a, b, c
cudaMalloc((void **)&d_a, size);
cudaMalloc((void **)&d_b, size);
cudaMalloc((void **)&d_c, size);
// Setup input values
a = 2;
b = 7;
// Copy inputs to device
cudaMemcpy(d_a, &a, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, &b, size, cudaMemcpyHostToDevice);
// Launch add() kernel on GPU
add<<<1,1>>>(d_a, d_b, d_c);
// Copy result back to host
cudaMemcpy(&c, d_c, size, cudaMemcpyDeviceToHost);
// Cleanup
cudaFree(d_a); cudaFree(d_b); cudaFree(d_c);
return 0;
}
test.go:
package main
import "fmt"
//#cgo CFLAGS: -I.
//#cgo LDFLAGS: -L. -ltest
//#cgo LDFLAGS: -lcudart
//#include <test.h>
import "C"
func main() {
fmt.Printf("Invoking cuda library...\n")
fmt.Println("Done ", C.test_add())
}
I am compiling CUDA code with:
nvcc -m64 -arch=sm_20 -o libtest.so --shared -Xcompiler -fPIC test.cu
All three files - test.h, test.cu and test.go are in the same directory. The error I am getting when I try to build with go is "undefined reference to `test_add'".
I have very little experience with C/C++ and am a total novice in CUDA.
I've been trying to solve my problem for two days now and would be very grateful for any input.
Thanks.
It appears, at least in this case, that the go import of C
is expecting the function to be provided with C style linkage.
CUDA (i.e. nvcc) mainly follows C++ patterns and provides by default C++ style linkage (including function name mangling, etc.)
It's possible to force a section of code to be provided externally using C rather than C++ style linkage using extern "C" {...code...}
. This is a C++ language feature and not specific to CUDA or nvcc.
Therefore it appears the problem can be solved via the following modification to the test.cu:
extern "C" { int test_add(void) { ... code ... }; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With