2012-02-23 75 views
36

Estoy buscando ayuda para comenzar con un proyecto que involucra a CUDA. Mi objetivo es tener un proyecto que pueda compilar en el compilador g ++ nativo pero que use el código CUDA. Entiendo que tengo que compilar mi código CUDA en el compilador nvcc, pero desde mi entendimiento, de alguna manera puedo compilar el código CUDA en un archivo cubin o en un archivo ptx.¿Cómo puedo compilar el código CUDA y luego vincularlo a un proyecto C++?

Aquí están mis preguntas:

  1. ¿Cómo uso NVCC para compilar en un archivo o un archivo cubin PTX? ¿No necesito una -c o algo así?
  2. ¿Qué tipo de archivo quiero usar?
  3. ¿Qué son los comandos g ++ para compilar correctamente y vincular el proyecto?

Supongamos lo siguiente:

  1. tengo un archivo llamado "main.cpp" que tiene una función principal en ella e incluye cuda.h.
  2. Tengo otro archivo llamado "cudaFunc.cu" que tiene código CUDA. Digamos, por ejemplo, que quiero agregar dos matrices de enteros que existen en main.cpp.

Respuesta

39

Pude resolver mi problema con un par de publicaciones diferentes, incluidas estas. ¡No olvide que si está utilizando una máquina de 64 bits para vincularla a la biblioteca de 64 bits! Se ve algo obvio, pero para los payasos como yo, eso es algo que olvidé. Aquí está el archivo make que ahora uso ... si puedes digerir este archivo make, deberías poder hacer lo que estaba tratando de hacer, que era una compilación separada del código cuda y otro código G ++. También hay que tener en cuenta que usted tiene que tener el gcc, g compiladores ++ en ciertas versiones (estoy usando g ++ - 4,4 y se está trabajando para mí) De todos modos, aquí está el archivo make ...

all: program 

program: cudacode.o 
    g++ -o program -L/usr/local/cuda/lib64 -lcuda -lcudart main.cpp cudacode.o 

cudacode.o: 
    nvcc -c -arch=sm_20 cudacode.cu 

clean: rm -rf *o program 

Con suerte Puedo ver que lo primero que hago es compilar el cudacode (que se ha guardado como .cu) utilizando el compilador nvcc y la opción -c (también tenga en cuenta que es posible que desee eliminar el -arch = sm_20). Esto creó un cudacode.o. A continuación, uso el compilador g ++ con la opción -o y el enlace a la biblioteca lib64 y enlace los archivos lcuda y lcudart junto con la compilación de mi main.cpp y luego el cudacode.o. ¡Espero que esto ayude a alguien!

+0

¿También puede proporcionar un mínimo de archivos '.cu' y' .cpp' con los que haya probado? Curioso sobre el incluye usado, cpp, en particular, cómo ver las funciones '__global__' del kernel de' .cu'. –

+1

Ten cuidado, tu objetivo limpio eliminará todos los archivos que terminen con 'o'. Probablemente desee 'clean: rm -rf * .o program' – gerowam

+1

Gracias [Matthew] (https://stackoverflow.com/users/1226843/matthew), esto fue muy útil. – SRG

8

Mi respuesta to this recent question probablemente describa lo que necesita.

Un par de notas adicionales:

  1. No es necesario para compilar sus .cu a un .cubin o archivo .ptx. Debe compilarlo en un archivo de objeto .o y luego vincularlo con los archivos de objeto .o de sus archivos .cpp compilados con g ++.
  2. Además de poner su código de kernel en cudaFunc.cu, también necesita poner una función envoltura C o C++ en ese archivo que inicia el núcleo (a menos que esté usando la API del controlador CUDA, que es poco probable y no se recomienda) También agregue un archivo de encabezado con el prototipo de esta función de contenedor para que pueda incluirlo en su código C++ que necesita llamar al código CUDA. A continuación, vincula los archivos con su línea de enlace g ++ estándar.

Estoy empezando a repetir mi other answer, entonces recomiendo simplemente leerlo. :)

+0

Harrism, gracias por su respuesta. Estoy mucho más cerca ahora. Puedo compilar muy bien utilizando el compilador nvcc y el archivo .cu (que renombré a cudacode.cu) y tengo un objeto cudacode.o, pero ahora cuando intento compilar en el g ++ obtengo cudacode.o: en función 'wrapper (int *, int *, int *, int) ': tmpxft_00000d3a_00000000-1_cudacode.cudafe1.cpp :(. text + 0x30): referencia indefinida a' cudaMalloc' – Matthew

+0

Debe vincular libcudart. Primero averigüe dónde está libcudart.so - de manera predeterminada, creo que va a/usr/local/bin/cuda, pero eso varía según la instalación. Una vez que encuentre la ruta, agregue esto a su línea de enlace: '-L -lcudart'. – harrism

+0

¡eres mi héroe! gracias. un problema adicional que estaba teniendo era que estoy en una máquina de 64 bits, así que tuve que vincular al archivo lib64. Hace solo tres horas no sabía cómo usar g ++, no sabía qué era un archivo make, y no sabía cómo vincularlo. Supongo que eso es lo que obtengo por crecer en Windows. – Matthew

7

Encontré que vincular el código compilado del objeto cuda con g ++ puede ser problemático. Intente compilarlo así:

all: 
nvcc cudafile.cu mainfile.cpp -o executable 

clean: rm -rf *.o 
+0

Usaría rm -f en lugar de rm -rf, porque los archivos * .o deberían ser archivos regulares y tengo miedo de cometer un error fatal: https://www.theregister.co.uk/2015/01/17/scary_code_of_the_week_steam_cleans_linux_pcs / –

Cuestiones relacionadas