/*! \brief Helper function for reporting GPU usage information
 * in the mdrun log file
 *
 * \param[in] gpu_info    Pointer to per-node GPU info struct
 * \param[in] gpu_opt     Pointer to per-node GPU options struct
 * \param[in] numPpRanks  Number of PP ranks per node
 * \return                String to write to the log file
 * \throws                std::bad_alloc if out of memory */
static std::string
makeGpuUsageReport(const gmx_gpu_info_t *gpu_info,
                   const gmx_gpu_opt_t  *gpu_opt,
                   size_t                numPpRanks)
{
    int ngpu_use  = gpu_opt->ncuda_dev_use;
    int ngpu_comp = gpu_info->ncuda_dev_compatible;

    /* Issue a note if GPUs are available but not used */
    if (ngpu_comp > 0 && ngpu_use < 1)
    {
        return gmx::formatString("%d compatible GPU%s detected in the system, but none will be used.\n"
                                 "Consider trying GPU acceleration with the Verlet scheme!\n",
                                 ngpu_comp, (ngpu_comp > 1) ? "s" : "");
    }

    std::string output;
    if (!gpu_opt->bUserSet)
    {
        // gpu_opt->cuda_dev_compatible is only populated during auto-selection
        std::string gpuIdsString =
            formatAndJoin(gmx::constArrayRefFromArray(gpu_opt->cuda_dev_compatible,
                                                      gpu_opt->ncuda_dev_compatible),
                          ",", gmx::StringFormatter("%d"));
        bool bPluralGpus = gpu_opt->ncuda_dev_compatible > 1;
        output += gmx::formatString("%d compatible GPU%s %s present, with ID%s %s\n",
                                    gpu_opt->ncuda_dev_compatible,
                                    bPluralGpus ? "s" : "",
                                    bPluralGpus ? "are" : "is",
                                    bPluralGpus ? "s" : "",
                                    gpuIdsString.c_str());
    }

    {
        std::vector<int> gpuIdsInUse;
        for (int i = 0; i < ngpu_use; i++)
        {
            gpuIdsInUse.push_back(get_gpu_device_id(gpu_info, gpu_opt, i));
        }
        std::string gpuIdsString =
            formatAndJoin(gpuIdsInUse, ",", gmx::StringFormatter("%d"));
        int         numGpusInUse = gmx_count_gpu_dev_unique(gpu_info, gpu_opt);
        bool        bPluralGpus  = numGpusInUse > 1;

        output += gmx::formatString("%d GPU%s %sselected for this run.\n"
                                    "Mapping of GPU ID%s to the %d PP rank%s in this node: %s\n",
                                    numGpusInUse, bPluralGpus ? "s" : "",
                                    gpu_opt->bUserSet ? "user-" : "auto-",
                                    bPluralGpus ? "s" : "",
                                    numPpRanks,
                                    (numPpRanks > 1) ? "s" : "",
                                    gpuIdsString.c_str());
    }

    return output;
}
Beispiel #2
0
OPENCL_EXPERIMENTS_EXPORT
cl_int opencl_plugin_create(opencl_plugin *plugin_out)
{
    cl_int err = CL_SUCCESS;
    opencl_plugin plugin;
    cl_int i;
    cl_int num_queues = 50;

    assert(plugin_out != NULL);

    plugin = calloc(1, sizeof(*plugin));
    CHECK_ALLOCATION(plugin);

    if (get_desired_platform("NVIDIA", &plugin->selected_platform, &err))
        goto error;

    if (get_gpu_device_id(plugin->selected_platform, &plugin->selected_device,
                          CL_TRUE, &err))
        goto error;

    if (create_context(plugin->selected_platform, plugin->selected_device,
                       &plugin->context, &err))
        goto error;

    if (build_program_from_file("program.cl", NULL, plugin->context,
                                plugin->selected_device, &plugin->program, &err))
        goto error;

    plugin->queue = clCreateCommandQueue(plugin->context, plugin->selected_device, 0, &err);
    CHECK_CL_ERROR(err);

    plugin->num_queues = num_queues;
    plugin->queues = calloc(num_queues, sizeof(cl_command_queue));
    CHECK_ALLOCATION(plugin->queues);

    for (i = 0; i < num_queues; i++) {
        plugin->queues[i] = clCreateCommandQueue(plugin->context, plugin->selected_device, 0, &err);
        CHECK_CL_ERROR(err);
    }

    plugin->voxelize_kernel = clCreateKernel(plugin->program, "voxelize", &err);
    CHECK_CL_ERROR(err);

    *plugin_out = plugin;
    return 0;
error:
    if (plugin) {
        if (plugin->voxelize_kernel)
            clReleaseKernel(plugin->voxelize_kernel);
        if (plugin->queue)
            clReleaseCommandQueue(plugin->queue);
        if (plugin->queues) {
            for (i = 0; i < num_queues; i++) {
                if (plugin->queues[i])
                    clReleaseCommandQueue(plugin->queues[i]);
            }
            free(plugin->queues);
        }
        if (plugin->context)
            clReleaseContext(plugin->context);
        free(plugin);
    }
    return -1;
}