Quiero entender cómo se crea un contexto de cuda y se asocia con un kernel en las aplicaciones API de tiempo de ejecución de cuda?Creación de contexto cuda y asociación de recursos en aplicaciones de API de tiempo de ejecución
Sé que las API del controlador lo hacen bajo el capó. Pero me gustaría entender la línea de tiempo de la creación.
Para empezar, sé que cudaRegisterFatBinary es la primera llamada hecha de cuda api y registra un archivo fatbin con el tiempo de ejecución. Le siguen un puñado de API de registro de funciones de cuda que llaman cuModuleLoad en la capa de controladores. Pero luego, si mi aplicación de API Cuda en tiempo de ejecución invoca cudaMalloc, ¿cómo se proporciona el puntero a esta función asociada con el contexto, que creo que debería haberse creado de antemano? ¿Cómo se maneja este contexto ya creado y se asocian las futuras llamadas API de tiempo de ejecución con él? Por favor desmitificar el funcionamiento interno.
Para citar la documentación de NVIDIA en este
CUDA API de ejecución llamadas operan en el CUcontext API controlador CUDA, que está obligado a el hilo host actual.
Si no existe CUDA CUcontext API conductor unido a la actual hilo en el momento de una llamada API de CUDA en tiempo de ejecución que requiere un CUcontext entonces el tiempo de ejecución de CUDA implícitamente crear un nuevo CUcontext antes de ejecutar la llamada.
Si el tiempo de ejecución de CUDA crea una CUcontext entonces el CUcontext habrá creado usando los parámetros especificados por la API de tiempo de ejecución de CUDA funciones cudaSetDevice, cudaSetValidDevices, cudaSetDeviceFlags, cudaGLSetGLDevice, cudaD3D9SetDirect3DDevice, cudaD3D10SetDirect3DDevice y cudaD3D11SetDirect3DDevice. Tenga en cuenta que estas funciones fallarán con cudaErrorSetOnActiveProcess si son llamadas cuando un CUcontext está vinculado al hilo de host actual.
La vida útil de un CUcontext se gestiona mediante un mecanismo de recuento de referencias . El recuento de referencia de un CUcontext se establece inicialmente en 0, y se incrementa en cuCtxAttach y disminuye en cuCtxDetach.
Si un CUcontext es creado por el tiempo de ejecución de CUDA, entonces el tiempo de ejecución de CUDA disminuirá el número de referencias de ese CUcontext en la función cudaThreadExit. Si un CUcontext es creado por la API de controlador de CUDA ( es creado por una instancia separada de la biblioteca API de CUDA Runtime), entonces el CUDA Runtime no incrementará o disminuirá el recuento de referencia de ese CUcontext.
Todos los estados de API CUDA Runtime (por ejemplo, direcciones de variables globales y valores ) viajan con su CUcontext subyacente. En particular, si un CUcontext se mueve de un hilo a otro (usando cuCtxPopCurrent y cuCtxPushCurrent), entonces todo el estado de la API CUDA Runtime se moverá a también.
Pero lo que no entiendo es cómo crea el contexto el tiempo de ejecución de cuda? ¿Qué llamadas API se utilizan para esto? ¿El compilador nvcc inserta algunas llamadas API para hacer esto en tiempo de compilación o se hace completamente en tiempo de ejecución? Si lo primero es cierto, ¿qué API de tiempo de ejecución se utilizan para esta gestión de contexto? Lo último es cierto cómo exactamente se hace?
Si un contexto está asociado con un hilo de host, ¿cómo obtenemos acceso a este contexto? ¿Está asociado automáticamente con todas las variables y referencias de puntero tratadas por el hilo?
¿cómo se realiza finalmente la carga de un módulo en el contexto?
Intenté usar cudaFree (0). Pero todavía no tengo un contexto. CuCtxPop devolvió un nulo. ¿Por que es esto entonces? – ash
Definitivamente debe tener un contexto actual después de un cudaFree exitoso (0). ¿Revisaste el valor de retorno? – ArchaeaSoftware
Entonces, después de analizar el problema, descubrí que CudaFree (0) me está dando un error de manejo de recurso Inválido. ¿Tienes alguna idea de por qué? – ash