如何用 Go 语言的 cgo 编译 Cuda 源代码?

Posted

技术标签:

【中文标题】如何用 Go 语言的 cgo 编译 Cuda 源代码?【英文标题】:how to compile Cuda source with Go language's cgo? 【发布时间】:2015-09-15 14:51:06 【问题描述】:

我用 cuda-c 写了一个简单的程序,它可以在 eclipse nsight 上运行。这是源代码:

#include <iostream>
#include <stdio.h>


__global__ void add( int a,int b, int *c)
*c = a + b;


int main(void)

int c;
int *dev_c;

cudaMalloc((void**)&dev_c, sizeof(int));

add <<<1,1>>>(2,7,dev_c);

cudaMemcpy(&c, dev_c, sizeof(int),cudaMemcpyDeviceToHost);

printf("\n2+7= %d\n",c);
cudaFree(dev_c);

return 0;

现在我正在尝试将此代码与 Go 语言和 cgo 一起使用!!! 所以我写了这个新代码:

package main

//#include "/usr/local/cuda-7.0/include/cuda.h"
//#include "/usr/local/cuda-7.0/include/cuda_runtime.h"
//#cgo LDFLAGS: -lcuda
//#cgo LDFLAGS: -lcurand
////default location:
//#cgo LDFLAGS: -L/usr/local/cuda-7.0/lib64 -L/usr/local/cuda-7.0/lib
//#cgo CFLAGS: -I/usr/local/cuda-7.0/include/
//
//
//
//
//
//
//
//
//
//
/*

#include <stdio.h>

__global__ void add( int a,int b, int *c)
    *c = a + b;


int esegui_somma(void)

    int c;
    int *dev_c;

    cudaMalloc((void**)&dev_c, sizeof(int));
    add <<<1,1>>> (2,7,dev_c);
    cudaMemcpy(&c, dev_c, sizeof(int),cudaMemcpyDeviceToHost);

    cudaFree(dev_c);
    return c;

*/
import "C"
import "fmt"

func main()
    fmt.Printf("il risultato è %d",C.esegui_somma)

但它不起作用! 我读到了这个错误信息:

cgo_cudabyexample_1/main.go:34:8: error: expected expression before '<' token
add <<<1,1>>> (2,7,dev_c);
      ^

我认为我必须为 cgo 而不是 gcc 设置 nvcc cuda 编译器。 我该怎么做?我可以更改 CC 环境变量吗? 最好的问候

【问题讨论】:

您是否尝试过仅使用标准 CC anc CXX 环境变量? (我不知道在这种情况下 cgo 是否可以与 cuda 一起使用,但应该很容易尝试) 您好,感谢您的回复。在 /etc/profile 文件中我添加了这个: export PATH=$PATH:/usr/local/cuda-7.0/bin export CC=nvcc 现在这是错误消息:nvcc fatal : Unknown option 'dM' 我不确定 cuda 编译器是如何工作的,但它显然不是标准的 CC 替代品。我认为您需要在 Go 程序之外编译 cuda 代码。 (顺便说一句,你不需要编辑全局配置文件来设置环境变量,如果你用命令定义它,你甚至不需要导出它)。 【参考方案1】:

我终于想出了如何做到这一点。最大的问题是nvcc 不遵循gcc 标准标志,并且与clang 不同,它不会默默地忽略它们。 cgo 通过添加一堆用户未明确指定的标志来触发问题。

为了使这一切正常工作,您需要将设备代码和直接调用它的函数分离到单独的文件中,并使用nvcc 直接将它们编译/打包到共享库 (.so) 中。然后,您将使用 cgo 使用系统上的任何默认链接器来链接此共享库。您唯一需要添加的是 -lcudart 到您的 LDFLAGS(链接器标志)以链接 CUDA 运行时。

【讨论】:

以上是关于如何用 Go 语言的 cgo 编译 Cuda 源代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何用Go语言开发Android应用

CGO类型转换

CGO类型转换

[Go语言]cgo用法演示

Go命令教程13. go tool cgo

cgo 和 Go 语言是两码事