2016-03-02 10 views
5

Sto provando a chiamare una funzione CUDA dal mio codice Go. Ho i seguenti tre file.Golang chiama la libreria 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()) 
} 

sto compilare il codice CUDA con:

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

Tutti e tre i file - test.h, test.cu e test.go si trovano nella stessa directory. L'errore che ottengo quando provo a creare con go è "riferimento non definito a` test_add '".

Ho poca esperienza con C/C++ e sono un novizio totale in CUDA.

Ho cercato di risolvere il mio problema per due giorni e sarei lo molto grato per qualsiasi input.

Grazie.

+3

Non ho familiarità con go, ma può essere un C vs C++ problema di collegamento. Prova a inserire il prototipo 'test_add()' in 'extern" C "{...}' –

+0

@RobertCrovella: dove vedi il codice C? CUDA è basato su C++. – Olaf

+1

@Olaf dove ho detto "Vedo codice C". ? Sono consapevole che CUDA utilizza il collegamento in stile C++. Se per caso [l'importazione di go di 'C' si aspetta che la funzione sia fornita con il linkage in stile C] (https://golang.org/cmd/cgo/#hdr-Go_references_to_C), allora ti imbatterai in questo problema. È solo una supposizione. –

risposta

2

Appare, almeno in questo caso, che the go import of C is expecting the function to be provided with C style linkage.

CUDA (cioè nvcc) segue sostanzialmente modelli C++ e fornisce di default C++ linkage stile (compresi nome della funzione mangling, ecc)

È possibile forzare una sezione di codice da prevedere esternamente utilizzando C invece di C++ collegamento stile utilizzando extern "C" {...code...}. Questa è una funzione in linguaggio C++ e non specifica per CUDA o nvcc.

Pertanto sembra che il problema può essere risolto tramite la seguente modifica al test.cu:

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

Per me la soluzione funziona se uso 'extern" C "{... code ...}' nel file test.cu. Ma se includo "extern" C "' nell'intestazione test.h, ricevo un errore './test.h:1:8: errore: identificatore atteso o '(' prima della costante di stringa '. Quindi andrò con' extern "C" 'nei file cuda (.cu) che sembra funzionare per me.Grazie ancora per dare una mano. –

+1

Grazie Ho aggiornato la risposta per riflettere il tuo utilizzo Non sono un esperto in questo, ma penso che il tuo la domanda potrebbe essere utile per i futuri lettori come una domanda tipo "come connetterti vai in CUDA". –