2016-03-02 215 views
5

我想从我的Go代码调用CUDA函数。 我有以下三个文件。Golang调用CUDA库

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()) 
} 

我CUDA代码编译有:

nvcc -m64 -arch=sm_20 -o libtest.so --shared -Xcompiler -fPIC test.cu 

所有三个文件 - test.h,test.cu和test.go都在同一个目录中。 我尝试使用go进行构建时遇到的错误是“未定义的对test_add的引用”。

我对C/C++有很少的经验,并且是CUDA的总新手。

我一直在试图解决我的问题两天,现在将是 非常感谢任何输入。

谢谢。

+3

我不熟悉走,但它可能是一个C与C++连接的问题。尝试将'test_add()'原型封装在'extern“C”{...}' –

+0

@RobertCrovella:你在哪里看到C代码? CUDA是基于C++的。 – Olaf

+1

@Olaf我在哪里说“我看到C代码”。 ?我知道CUDA使用C++风格的链接。如果碰巧('C'的导入期望函数提供C风格链接](https://golang.org/cmd/cgo/#hdr-Go_references_to_C),那么你会遇到这个问题。这只是一个猜测。 –

回答

2

看来,至少在这种情况下,那是the go import of C is expecting the function to be provided with C style linkage

CUDA(即NVCC)主要如下:C++模式和默认为C++式链接(包括功能名称重整等)

它可以强制用C而不是C被从外部提供的代码部分提供++风格联动使用extern "C" {...code...}。这是一种C++语言功能,并非特定于CUDA或nvcc。

因此,出现问题可以通过以下修改的test.cu解决:

extern "C" { int test_add(void) { ... code ... }; } 
+0

对于我来说,如果我在test.cu文件中使用'extern“C”{... code ...}',解决方案就可以工作。但是,如果我在头文件test.h中包含'extern“C”',我会得到一个错误'./test.h:1:8:错误:期望的标识符或'('在字符串常量之前'),所以我将使用'extern “C”在cuda文件(.cu)中似乎适用于我。再次感谢您的帮助。 –

+1

谢谢。我更新了答案以反映您的用法。我不是这方面的专家,但我认为您的问题可能对未来的读者有用,作为规范的“如何连接到CUDA”类型的问题。 –