如何用Go语言的cgo编译Cuda源码? [英] how to compile Cuda source with Go language's cgo?

查看:880
本文介绍了如何用Go语言的cgo编译Cuda源码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在cuda-c中编写了一个简单的程序,它可以在eclipse中使用。这是源代码:

  #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 > gt;(2,7,dev_c);

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

printf(\\\
2 + 7 =%d\\\
,c);
cudaFree(dev_c);

返回0;
}

现在我试图用cgo使用Go语言来使用此代码! !
所以我写了这个新代码:

  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
////默认位置:
//#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 >>> (2,7,dev_c);
cudaMemcpy(& c,dev_c,sizeof(int),cudaMemcpyDeviceToHost);

cudaFree(dev_c);
return c;

$ /
导入C
导入fmt

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

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

pre code $ cgo_cudabyexample_1 / main.go:34:8:error:expected expression before' <'标记
添加<< 1,1>>> (2,7,dev_c);
$

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

解决方案

我终于想出了如何做到这一点。最大的问题是 nvcc 不符合 gcc 标准标记,而不像 clang 它不会默默地忽略它们。 cgo 通过添加一堆未由用户明确指定的标志触发问题。



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

I wrote a simple program in cuda-c and it works on eclipse nsight. This is source code:

#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;
}

Now I'm trying to use this code with Go language with cgo!!! So I wrote this new code:

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

But it doesn't work!! I read this error message:

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

I think that I must to set nvcc cuda compiler for cgo instead of gcc. How can I do it? Can I change CC environment variable? best regards

解决方案

I finally figured out how to do this. Thing biggest problem is that nvccdoes not follow gcc standard flags and unlike clang it won't silently ignore them. cgo triggers the problem by adding a bunch of flags not explicitly specified by the user.

To make it all work, you'll need to separate out your device code and the functions that directly call it into separate files and compile/package them directly using nvcc into a shared library (.so). Then you'll use cgo to link this shared library using whatever default linker you have on your system. The only thing you'll have to add is -lcudart to your LDFLAGS (linker flags) to link the CUDA runtime.

这篇关于如何用Go语言的cgo编译Cuda源码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆