Exemplo n.º 1
0
/**
 * \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;
}
Exemplo n.º 2
0
/**
 * \brief Pushes a cuda context for the calling thread.
 *
 *        Before calling this function make sure that the cuda context belonging
 *        to the registered module, is floating(not attached to any host thread).
 *
 * \param name Name of the registered module whose cuda context has to be
 *             pushed for the calling thread.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCCudaHlPushCudaContextFromModule(const char *name)
{
    SCCudaHlModuleData *data = SCCudaHlGetModuleData(SCCudaHlGetModuleHandle(name));

    if (data == NULL) {
        SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "No module registered by the "
                   "name \"%s\"", name);
        return -1;
    }

    if (SCCudaCtxPushCurrent(data->cuda_context) == -1) {
        SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Error pushing cuda context from "
                   "module \"%s\" for this calling thread\n", name);
        return -1;
    }

    return 0;
}
Exemplo n.º 3
0
/**
 * \brief Registers a Dispatcher function against this handle.
 *
 * \param SCCudaHlDispFunc Pointer to a dispatcher function to be registered
 *                         for this handle.
 * \param handle           A unique handle which identifies a module.  Obtained
 *                         from a call to SCCudaHlGetUniqueHandle().
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCCudaHlRegisterDispatcherFunc(void *(*SCCudaHlDispFunc)(void *), int handle)
{
    SCCudaHlModuleData *data = NULL;

    if (SCCudaHlDispFunc == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments"
                   "SCCudaHlDispFunc NULL");
        return -1;
    }

    if ( (data = SCCudaHlGetModuleData(handle)) == NULL) {
        SCLogDebug("Module not registered.  To avail the benefits of this "
                   "registration facility, first register a module using "
                   "context using SCCudaHlRegisterModule(), after which you "
                   "can call this function");
        return -1;
    }

    data->SCCudaHlDispFunc = SCCudaHlDispFunc;

    return 0;
}
Exemplo n.º 4
0
/**
 * \brief DeRegister a registered module.
 *
 * \param name Name of the module to deregister.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCCudaHlDeRegisterModule(const char *name)
{
    SCCudaHlModuleData *data = NULL;
    SCCudaHlModuleData *prev_data = NULL;
    SCCudaHlModuleCUmodule *cumodule = NULL;
    SCCudaHlModuleCUmodule *temp_cumodule = NULL;
    SCCudaHlModuleDevicePointer *device_ptr = NULL;
    SCCudaHlModuleDevicePointer *temp_device_ptr = NULL;
    int module_handle = SCCudaHlGetModuleHandle(name);

    /* get the module */
    data = (module_handle == -1) ? NULL : SCCudaHlGetModuleData(module_handle);

    /* a module by this name doesn't exist.  Log Error and return */
    if (data == NULL) {
        SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Module \"%s\" not "
                   "registered", name);
        return -1;
    }

    /* the application must take care to check that the following cuda context
     * which is being freed is floating(not attached to any host thread) */
    if (data->cuda_context != 0)
        SCCudaCtxPushCurrent(data->cuda_context);

    /* looks like we do have a module registered by this name.
     * Go through all CUmodules registered in this module and
     * free cuda device pointers and unload the module.
     */
    cumodule = data->cuda_modules;
    while (cumodule != NULL) {
        /* free all device pointers */
        device_ptr = cumodule->device_ptrs;
        while (device_ptr != NULL) {
            temp_device_ptr = device_ptr;
            device_ptr = device_ptr->next;
            if (SCCudaMemFree(temp_device_ptr->d_ptr) == -1)
                goto error;
            SCFree(temp_device_ptr->name);
            SCFree(temp_device_ptr);
        }
        cumodule->device_ptrs = NULL;

        /* unload the cuda module */
        temp_cumodule = cumodule;
        cumodule = cumodule->next;
        if (SCCudaModuleUnload(temp_cumodule->cuda_module) == -1)
            goto error;
        SCFree(temp_cumodule);
    }
    data->cuda_modules = NULL;

    if (data->name != NULL)
        SCFree((void *)data->name);

    /* clean the dispatcher function registered */
    data->SCCudaHlDispFunc = NULL;

    /* destroy the cuda context */
    if (data->cuda_context != 0) {
        if (SCCudaCtxDestroy(data->cuda_context) == -1)
            goto error;
    }

    /* find the previous module data instance */
    if (module_data == data) {
        module_data = module_data->next;
    } else {
        prev_data = module_data;
        while (prev_data->next != data)
            prev_data = prev_data->next;
        prev_data->next = data->next;
    }

    /* delete the module data instance */
    SCFree(data);

    /* mission accomplished.  let's go */
    return 0;
 error:
    return -1;
}
Exemplo n.º 5
0
/**
 * \brief Frees a Cuda Device Pointer.
 *
 *        If a device pointer by the name \"name\"  is registered for this
 *        handle, it is freed.
 *
 * \param name       Name of the device pointer by which we have to search
 *                   module for its existance.
 * \param handle     A unique handle which identifies a module.  Obtained from
 *                   a call to SCCudaHlGetUniqueHandle().
 * \param cumodule   A handle that identifies the CUmodule within the above module.
 *                   Obtained from a call to SCCudaHlGetCudaModule() or
 *                   SCCudaHlGetCudaModuleFromFile().
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCCudaHlFreeCudaDevicePtr(const char *name, int handle, int cumodule_handle)
{
    SCCudaHlModuleData *data = NULL;
    SCCudaHlModuleCUmodule *cumodule = NULL;
    SCCudaHlModuleDevicePointer *module_device_ptr = NULL;
    SCCudaHlModuleDevicePointer *temp_module_device_ptr = NULL;

    if (name == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments"
                   "device_ptr is NULL or name is NULL");
        goto error;
    }

    /* check if the particular module that wants to free device memory 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
     * free the device memory.
     */
    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 ");
        goto error;
    }

    if ( (cumodule = SCCudaHlGetModuleCUmodule(data, cumodule_handle)) == NULL ) {
        SCLogDebug("CUmodule not registered with the module. Before you can request"
                   "a device pointer for a module you need to load the CUmodule into"
                   "the engine module using SCCudaHlGetCudaModule() or"
                   "SCCudaHlGetCudaModuleFromFile().");
        goto error;
    }

    /* if we do not have a device pointer registered by this name get out */
    if ( (module_device_ptr = SCCudaHlCudaDevicePtrAvailable(cumodule, name)) == NULL) {
        goto error;
    }

    SCCudaMemFree(module_device_ptr->d_ptr);
    module_device_ptr->d_ptr = 0;
    if (module_device_ptr == cumodule->device_ptrs) {
        cumodule->device_ptrs = cumodule->device_ptrs->next;
    } else {
        temp_module_device_ptr = cumodule->device_ptrs;
        while (strcmp(temp_module_device_ptr->next->name, name) != 0) {
            temp_module_device_ptr = temp_module_device_ptr->next;
        }
        temp_module_device_ptr->next = temp_module_device_ptr->next->next;
    }
    free(module_device_ptr->name);
    free(module_device_ptr);

    return 0;

 error:
    return -1;
}
Exemplo n.º 6
0
/**
 * \brief Returns a cuda_device_pointer against the handle in the argument.
 *
 *        If a device pointer by the name \"name\"  is not registered for the
 *        handle, it is created and associated with this handle and cuda mem is
 *        alloted and the cuda_device_pointer is returned in the argument.
 *        If a device pointer by the name \"name\" is already registered with
 *        the handle, the cuda_device_pointer is returned in the argument.
 *
 * \param device_ptr Pointer to the device pointer instance which should be
 *                   with the cuda_device_pointer that has to be returned back.
 * \param name       Name of the device pointer by which we have to search
 *                   module for its existance.
 * \param size       Size of the cuda device memory to be alloted.
 * \param host_ptr   If any host memory has to be transferred to the cuda device
 *                   memory, it can sent using this argument.  host_ptr should
 *                   hold atleast size bytes in memory.
 * \param handle     A unique handle which identifies a module.  Obtained from
 *                   a call to SCCudaHlGetUniqueHandle().
 * \param cumodule_handle   A handle that identifies the CUmodule within the above module.
 *                   Obtained from a call to SCCudaHlGetCudaModule() or
 *                   SCCudaHlGetCudaModuleFromFile().
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SCCudaHlGetCudaDevicePtr(CUdeviceptr *device_ptr, const char *name,
                             size_t size, void *host_ptr, int handle,
                             int cumodule_handle)
{
    SCCudaHlModuleData *data = NULL;
    SCCudaHlModuleCUmodule *cumodule = NULL;
    SCCudaHlModuleDevicePointer *new_module_device_ptr = NULL;
    SCCudaHlModuleDevicePointer *module_device_ptr = NULL;

    if (device_ptr == NULL || name == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENTS, "Error invalid arguments"
                   "device_ptr is NULL or name is NULL");
        goto error;
    }

    /* check if the particular module that wants to allocate device memory 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 the device memory or return the reference to the device memory if
     * we already have the device memory associated with the module.  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 ");
        goto error;
    }

    if ( (cumodule = SCCudaHlGetModuleCUmodule(data, cumodule_handle)) == NULL ) {
        SCLogDebug("CUmodule not registered with the module. Before you can request"
                   "a device pointer for a module you need to load the CUmodule into"
                   "the engine module using SCCudaHlGetCudaModule() or"
                   "SCCudaHlGetCudaModuleFromFile().");
        goto error;
    }

    /* if we already have a device pointer registered by this name return the
     * cuda device pointer instance */
    if ( (module_device_ptr = SCCudaHlCudaDevicePtrAvailable(cumodule, name)) != NULL) {
        device_ptr[0] = module_device_ptr->d_ptr;
        return 0;
    }

    new_module_device_ptr = SCMalloc(sizeof(SCCudaHlModuleDevicePointer));
    if (new_module_device_ptr == NULL)
        goto error;
    memset(new_module_device_ptr, 0, sizeof(SCCudaHlModuleDevicePointer));

    if ( (new_module_device_ptr->name = SCStrdup(name)) == NULL) {
        SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCCudaHlGetCudaDevicePtr. Exiting...");
        exit(EXIT_FAILURE);
    }

    /* allocate the cuda memory */
    if (SCCudaMemAlloc(&new_module_device_ptr->d_ptr, size) == -1)
        goto error;

    /* if the user has supplied a host buffer, copy contents to the device mem */
    if (host_ptr != NULL) {
        if (SCCudaMemcpyHtoD(new_module_device_ptr->d_ptr, host_ptr,
                             size) == -1) {
            goto error;
        }
    }

    /* send the newly assigned device pointer back to the caller */
    device_ptr[0] = new_module_device_ptr->d_ptr;

    /* insert it into the device_ptr list for the module instance */
    if (cumodule->device_ptrs == NULL) {
        cumodule->device_ptrs = new_module_device_ptr;
        return 0;
    }

    module_device_ptr = cumodule->device_ptrs;
    while (module_device_ptr->next != NULL)
        module_device_ptr = module_device_ptr->next;
    module_device_ptr->next = new_module_device_ptr;

    return 0;

 error:
    if (new_module_device_ptr != NULL)
        SCFree(new_module_device_ptr);
    return -1;
}
Exemplo n.º 7
0
/**
 * \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  Pointer to a cuda module instance that should be updated
 *                  with a cuda module.
 * \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 (new_module_cumodule == NULL) {
        exit(EXIT_FAILURE);
    }
    memset(new_module_cumodule, 0, sizeof(SCCudaHlModuleCUmodule));

    /* Create a cuda module, update the module with this cuda module reference
     * and then return the module reference back to the calling function using
     * the argument */
    if (SCCudaModuleLoadData(p_module, (void *)ptx_image) == -1)
        goto error;

    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:
    return -1;
}
Exemplo n.º 8
0
/**
 * \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;
}