/** * \brief Returns a cuda context against the handle in the argument. * * If a cuda_context is not present for a handle, it is created * and associated with this handle and the context is returned * in the argument. If a cuda_context is already present for * a handle, it is returned. * * \param p_context Pointer to a cuda context instance that should be updated * with a cuda context. * \param cuda_profile The cuda profile, supplied as a string. * \param handle A unique handle which identifies a module. Obtained from * a call to SCCudaHlGetUniqueHandle(). * * \retval 0 On success. * \retval -1 On failure. */ int SCCudaHlGetCudaContext(CUcontext *p_context, char *cuda_profile, int handle) { SCCudaHlModuleData *data = NULL; SCCudaDevices *devices = NULL; if (p_context == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments. " "p_context NULL"); return -1; } /* check if the particular module that wants a CUDA context * is already registered or not. If it is not registered * log a warning and get out of here */ if ( (data = SCCudaHlGetModuleData(handle)) == NULL) { SCLogDebug("Module not registered. You can't create a CUDA context " "without registering a module first. To use this " "registration facility, first register a module using " "SCCudaHlRegisterModule(), and then register " "a cuda context with that module hanle using " "SCCudaHlGetCudaContext(), after which you can call this " "function "); return -1; } if (data->cuda_context != 0) { p_context[0] = data->cuda_context; return 0; } int device_id = SC_CUDA_DEFAULT_DEVICE; if (cuda_profile != NULL) { /* Get default log level and format. */ MpmCudaConf *profile = SCCudaHlGetProfile(cuda_profile); if (profile != NULL) { if (SCCudaIsCudaDeviceIdValid(profile->device_id)) { device_id = profile->device_id; } else { SCLogError(SC_ERR_CUDA_ERROR, "Invalid device id \"%d\" supplied. " "Using the first device.", profile->device_id); } } } /* Get the device list for this CUDA platform and create a new cuda context */ devices = SCCudaGetDeviceList(); if (SCCudaCtxCreate(p_context, 0, devices->devices[device_id]->device) == -1) goto error; data->cuda_context = p_context[0]; return 0; error: return -1; }
CUcontext CudaHandlerModuleGetContext(const char *name, int device_id) { SCMutexLock(&mutex); CudaHandlerModule *module = cudahl_modules; while (module != NULL && strcasecmp(module->name, name) != 0) module = module->next; if (module != NULL) { if (module->device_id != device_id) { SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Module already " "registered, but the new device_id is different " "from the already registered device_id."); exit(EXIT_FAILURE); } SCMutexUnlock(&mutex); return module->context; } CudaHandlerModule *new_module = SCMalloc(sizeof(CudaHandlerModule)); if (new_module == NULL) exit(EXIT_FAILURE); memset(new_module, 0, sizeof(CudaHandlerModule)); new_module->device_id = device_id; new_module->name = SCStrdup(name); if (new_module->name == NULL) exit(EXIT_FAILURE); if (cudahl_modules == NULL) { cudahl_modules = new_module; } else { new_module->next = cudahl_modules; cudahl_modules = new_module; } if (no_of_cuda_contexts <= device_id) { cuda_contexts = SCRealloc(cuda_contexts, sizeof(CUcontext) * (device_id + 1)); if (cuda_contexts == NULL) exit(EXIT_FAILURE); memset(cuda_contexts + no_of_cuda_contexts, 0, sizeof(CUcontext) * ((device_id + 1) - no_of_cuda_contexts)); no_of_cuda_contexts = device_id + 1; } if (cuda_contexts[device_id] == 0) { SCCudaDevices *devices = SCCudaGetDeviceList(); if (SCCudaCtxCreate(&cuda_contexts[device_id], CU_CTX_SCHED_BLOCKING_SYNC, devices->devices[device_id]->device) == -1) { SCLogDebug("ctxcreate failure."); exit(EXIT_FAILURE); } } new_module->context = cuda_contexts[device_id]; SCMutexUnlock(&mutex); return cuda_contexts[device_id]; }
int CudaHandlerGetCudaModule(CUmodule *p_module, const char *ptx_image) { #define CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE 15 int i = 0; /* select the ptx image based on the compute capability supported by all * devices (i.e. the lowest) */ char *image = SCMalloc(strlen(ptx_image) + CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE); if (unlikely(image == NULL)) { exit(EXIT_FAILURE); } memset(image, 0x00, strlen(ptx_image) + CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE); int major = INT_MAX; int minor = INT_MAX; SCCudaDevices *devices = SCCudaGetDeviceList(); for (i = 0; i < devices->count; i++){ if (devices->devices[i]->major_rev < major){ major = devices->devices[i]->major_rev; minor = devices->devices[i]->minor_rev; } if (devices->devices[i]->major_rev == major && devices->devices[i]->minor_rev < minor){ minor = devices->devices[i]->minor_rev; } } snprintf(image, strlen(ptx_image) + CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE, "%s_sm_%u%u", ptx_image, major, minor); /* we don't have a cuda module associated with this module. Create a * cuda module, update the module with this cuda module reference and * then return the module refernce back to the calling function using * the argument */ SCLogDebug("Loading kernel module: %s\n",image); if (SCCudaModuleLoadData(p_module, (void *)SCCudaPtxDumpGetModule(image)) == -1) goto error; SCFree(image); return 0; error: SCFree(image); return -1; #undef CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE }
/** * \brief Returns a cuda_module against the handle in the argument. * * If a cuda_module is not present for a handle, it is created * and associated with this handle and the cuda_module is returned * in the argument. * * \param p_module The loaded CUmodule that is returned. * \param ptx_image Name of the module source file, w/o the .cu extension * \param handle A unique handle which identifies a module. Obtained from * a call to SCCudaHlGetUniqueHandle(). * * \retval A unique handle within the module that is associated with the * loaded CUmodule. Needed for future API calls. * \retval -1 on failure. */ int SCCudaHlGetCudaModule(CUmodule *p_module, const char *ptx_image, int handle) { SCCudaHlModuleData *data = NULL; SCCudaHlModuleCUmodule *new_module_cumodule = NULL; SCCudaHlModuleCUmodule *module_cumodules = NULL; if (p_module == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments" "p_module NULL"); return -1; } /* check if the particular module that wants a CUDA module is already * registered or not. If it is registered, check if a context has * been associated with the module. If yes, then we can go ahead and * create a cuda module and associate it with the module referenced by * the handle in the functions arguments. If no, log warning and get * out of here */ if ( ((data = SCCudaHlGetModuleData(handle)) == NULL) || (data->cuda_context == 0)) { SCLogDebug("Module not registered or no cuda context associated with " "this module. You can't create a CUDA module without" "associating a context with a module first. To use this " "registration facility, first register a module using " "context using SCCudaHlRegisterModule(), and then register " "a cuda context with that module using " "SCCudaHlGetCudaContext(), after which you can call this " "function "); return -1; } /* Register new CUmodule in the module */ new_module_cumodule = SCMalloc(sizeof(SCCudaHlModuleCUmodule)); if (unlikely(new_module_cumodule == NULL)) { exit(EXIT_FAILURE); } memset(new_module_cumodule, 0, sizeof(SCCudaHlModuleCUmodule)); /* select the ptx image based on the compute capability supported by all * devices (i.e. the lowest) */ char* image = SCMalloc(strlen(ptx_image)+15); if (unlikely(image == NULL)) { exit(EXIT_FAILURE); } memset(image, 0x0, strlen(ptx_image)+15); int major = INT_MAX; int minor = INT_MAX; SCCudaDevices *devices = SCCudaGetDeviceList(); int i=0; for (; i<devices->count; i++){ if (devices->devices[i]->major_rev < major){ major = devices->devices[i]->major_rev; minor = devices->devices[i]->minor_rev; } if (devices->devices[i]->major_rev == major && devices->devices[i]->minor_rev < minor){ minor = devices->devices[i]->minor_rev; } } snprintf(image, strlen(ptx_image) + 15, "%s_sm_%u%u", ptx_image, major, minor); /* we don't have a cuda module associated with this module. Create a * cuda module, update the module with this cuda module reference and * then return the module refernce back to the calling function using * the argument */ SCLogDebug("Loading kernel module: %s\n",image); if (SCCudaModuleLoadData(p_module, (void *)SCCudaPtxDumpGetModule(image)) == -1) goto error; SCFree(image); new_module_cumodule->cuda_module = p_module[0]; new_module_cumodule->cuda_module_handle = SCCudaHlGetUniqueHandle(); /* insert it into the cuda_modules list for the module instance */ if (data->cuda_modules == NULL) { data->cuda_modules = new_module_cumodule; return new_module_cumodule->cuda_module_handle; } module_cumodules = data->cuda_modules; while (module_cumodules->next != NULL) module_cumodules = module_cumodules->next; module_cumodules->next = new_module_cumodule; return new_module_cumodule->cuda_module_handle; error: SCFree(image); return -1; }