2014-11-12 11 views
6

Sto tentando di collegare un kernel CUDA a un progetto di autotools C++, ma non riesco a passare la fase di collegamento.Creazione di una libreria CUDA statica da collegare a un programma C++

Ho un file GPUFloydWarshall.cu che contiene il kernel e una funzione wrapper C che vorrei inserire in una libreria libgpu.a. Questo sarà coerente con il resto del progetto. È possibile?

In secondo luogo, la libreria dovrebbe quindi essere collegata a circa dieci altre librerie per l'eseguibile principale che al momento utilizza mpicxx.

Attualmente sto usando/generare il seguito i comandi per compilare e creare la libreria libgpu.a

nvcc -rdc=true -c -o temp.o GPUFloydWarshall.cu 
nvcc -dlink -o GPUFloydWarshall.o temp.o -L/usr/local/cuda/lib64 -lcuda -lcudart 
rm -f libgpu.a 
ar cru libgpu.a GPUFloydWarshall.o 
ranlib libgpu.a 

Quando questo è tutto legato al eseguibile principale ottengo il seguente errore

problem/libproblem.a(libproblem_a-UTRP.o): In function `UTRP::evaluate(Solution&)': 
UTRP.cpp:(.text+0x1220): undefined reference to `gpu_fw(double*, int)' 

La funzione gpu_fw è la mia funzione wrapper.

risposta

3

È possibile?

Sì, è possibile. E la creazione di una funzione wrapper (non CUDA) attorno ad essa rende ancora più semplice. Puoi semplificarti la vita se ti affidi al collegamento C++ in tutto (fai riferimento a una funzione wrapper C). mpicxx è un alias di compilatore/linker C++ e i file cuda (.cu) seguono il comportamento del compilatore/linker C++ per impostazione predefinita. Here's una domanda molto semplice che tratta della costruzione di codice cuda (incapsulato in una funzione wrapper) in una libreria statica.

In secondo luogo, la libreria dovrebbe quindi essere collegata a circa dieci altre librerie per l'eseguibile principale che al momento utilizza mpicxx.

Una volta esposto un wrapper C/C++ (non CUDA) nella libreria, il collegamento non deve essere diverso dal normale collegamento delle librerie ordinarie. Potresti ancora aver bisogno di passare le librerie di runtime di cuda e qualsiasi altra libreria di cuda che potresti usare nella fase di collegamento, ma questa è la stessa concettualità di tutte le altre librerie da cui il tuo progetto può dipendere.

EDIT:

Non è chiaro è necessario utilizzare dispositivo di collegamento per quello che si vuole fare. (Ma è accettabile, semplicemente complica un po 'le cose.) Comunque, la tua costruzione della libreria non è del tutto corretta, ora che hai mostrato la sequenza dei comandi. Il comando link del dispositivo produce un oggetto collegabile al dispositivo, che non include tutti i pezzi host necessari. Per ottenere tutto in un'unica posizione, desideriamo aggiungere alla libreria sia GPUFloydWarshall.o (che ha i pezzi collegati alla periferica) E temp.o (che ha i pezzi del codice host).

Ecco un esempio completamente lavorato:

$ cat GPUFloydWarshall.cu 
#include <stdio.h> 

__global__ void mykernel(){ 
    printf("hello\n"); 
} 

void gpu_fw(){ 
    mykernel<<<1,1>>>(); 
    cudaDeviceSynchronize(); 
} 


$ cat main.cpp 
#include <stdio.h> 

void gpu_fw(); 

int main(){ 

    gpu_fw(); 
} 

$ nvcc -rdc=true -c -o temp.o GPUFloydWarshall.cu 
$ nvcc -dlink -o GPUFloydWarshall.o temp.o -lcudart 
$ rm -f libgpu.a 
$ ar cru libgpu.a GPUFloydWarshall.o temp.o 
$ ranlib libgpu.a 
$ g++ main.cpp -L. -lgpu -o main -L/usr/local/cuda/lib64 -lcudart 
$ ./main 
hello 
$ 
+0

io non sono molto sicuro di capire principalmente a causa autotools che generano la libreria per me. Ho modificato la mia domanda originale per includere dettagli aggiuntivi che dovrebbero, se tutto va bene, rendere le cose un po 'più chiare. –

+0

Seguendo questo approccio ora posso compilare il codice con successo. Durante l'esecuzione, tuttavia, viene generato il seguente errore. Msgstr "Errore funzione del dispositivo non valido sulla riga 84 nel file GPUFloydWarshall.cu". Questo significa che il kernel non viene compilato?So che il kernel è corretto poiché l'ho testato esternamente. –

+0

SO non è davvero una chat room. Hai un problema diverso ora. Si consiglia di pubblicare una nuova domanda. Il kernel è compilato, ma l'architettura/destinazione non corrisponde alla GPU su cui viene eseguita. Avrebbero bisogno di altre specifiche come il comando di compilazione attuale, la GPU su cui si sta eseguendo, la versione CUDA, ecc. –

Problemi correlati