Vinculación del proyecto CDA Mixed C
Pregunta
Tengo un gran proyecto en C y estoy tratando de integrar algunos núcleos CUDA en él. Estoy compilando mis archivos C con "GCC -C Main.c" y mis archivos .cu con "NVCC -C CUDA_GMRES.CU" e luego intento vincular los 2 archivos de objetos con NVCC: "NVCC -O Main. o CUDA_GMRES.O "y reciba el siguiente error:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: en función_start':
(.text+0x20): undefined reference to
Main 'Collect2: LD devuelve 1 Estado de salida
Es la primera vez que intento combinar CUDA con archivos C y podría haber hecho algo mal. Puede que alguien me ayude por favor. Estoy en un clúster de GPU con Rocks OS.
Mi archivo main.c:
#include <stdio.h>
#include <math.h>
#include "cuda_wrapper.h" //header containing wrapper function
//cuda_GMRES that calls the kernel cuda_dot
int main (int argc,char* argv[])
{
//content
//bla bla bla
//cuda Function call
cuda_GMRES(50);
return 0;
}
Mi archivo cuda_wrapper.h:
#ifndef Cuda_GMRES_cuda_wrapper_h
#define Cuda_GMRES_cuda_wrapper_h
//wrapper function declaration
void cuda_GMRES(double a);
#endif
Mi archivo cuda_gmres.cu que contiene la función de llamadas del núcleo:
#include <stdio.h>
#include "cuda_wrapper.h"
#include "cuda_dot.cu"
//kernel declaration
__global__ void cuda_dot();
//kernel calling function
extern "C"
void cuda_GMRES(double a)
{
double b;
double *dev_a;
double *res;
cudaMemcpy(dev_a, &a, sizeof(double), cudaMemcpyHostToDevice );
cuda_dot<<< 1, 1 >>>(*dev_a, res );
cudaMemcpy(&b, res, sizeof(double), cudaMemcpyDeviceToHost );
}
Mi archivo cuda_dot.cu que contiene el kernel:
__global__ void cuda_dot(double a, double *help)
{
*help=2*a;
}
Solución
Su comando de enlace parece contener un error fatal. Suponiendo que primero compile dos objetos como este:
gcc -c main.c
nvcc -c cuda_GMRES.cu
Debe tener dos archivos de objetos main.o
y cuda_GMRES.o
. Entonces haces esto:
nvcc -o main.o cuda_GMRES.o
Este comando dice "Enlace un archivo de programa llamado main.o usando cuda_gmres.o", es decir. Sobrescribir Main.O. Es por esta razón que el enlazador se queja de una subrutina principal faltante, no está suministrando uno (y está destruyendo el archivo de objeto que contiene uno al mismo tiempo).
Quieres algo como esto:
nvcc -o executable main.o cuda_GMRES.o
dónde executable
es el nombre del programa final vinculado, o
nvcc main.o cuda_GMRES.o
que emitirá un programa vinculado predeterminado llamado a.out