Как я могу смешать API драйвера CUDA с API времени выполнения CUDA? - PullRequest
1 голос
/ 09 февраля 2020

Из cuda-документа в нем говорится:

  1. Если контекст создается и обновляется с помощью API драйвера, последующие вызовы времени выполнения выбирают этот контекст вместо создания нового один.
  2. Если среда выполнения инициализирована (неявно, как указано в CUDA Runtime), cuCtxGetCurrent () можно использовать для получения контекста, созданного во время инициализации. Этот контекст может использоваться последующими вызовами API драйвера.

Я могу заставить работать 1-е очко. Я могу создать контекст из драйвера CUDA. тогда я могу использовать функции времени выполнения cuda без вызова cudaSetDevice(), который неявно создает новый первичный контекст.

Однако я хочу работать через 2-й вариант. То есть сначала инициализируйте среду выполнения, затем выполните cuCtxGetCurrent() и используйте ее в API драйвера cuda. Это не работает вообще. Я всегда выдвигаю ошибку, говоря, что контекст был уничтожен или недействителен. Что я сделал не так?

Вот мой пример кодов:

#define CUDA_DRIVER_API
#include <cuda.h>
#include <cuda_runtime.h>
#include <helper_cuda.h>
#include <iostream>
CUcontext check_current_ctx()
{
    CUcontext context{0};
    unsigned int api_ver;
    checkCudaErrors(cuCtxGetCurrent(&context));
    fprintf(stdout, "current context=%p\n", context);
    checkCudaErrors( cuCtxGetApiVersion(context, &api_ver));
    fprintf(stdout, "current context api version = %d\n", api_ver);
    return context;
}
auto inital_runtime_context()
{
    int current_device = 0;
    int device_count = 0;
    int devices_prohibited = 0;
    CUcontext current_ctx{0};

    cudaDeviceProp deviceProp;
    checkCudaErrors(cudaGetDeviceCount(&device_count));;
    if (device_count == 0) {
        fprintf(stderr, "CUDA error: no devices supporting CUDA.\n");
        exit(EXIT_FAILURE);
    }

    // Find the GPU which is selected by Vulkan
    while (current_device < device_count) {
        cudaGetDeviceProperties(&deviceProp, current_device);
        if ((deviceProp.computeMode != cudaComputeModeProhibited)) {
            checkCudaErrors(cudaSetDevice(current_device));
            checkCudaErrors(cudaGetDeviceProperties(&deviceProp, current_device));
            printf("GPU Device %d: \"%s\" with compute capability %d.%d\n\n",
                current_device, deviceProp.name, deviceProp.major,
                deviceProp.minor);
            CUcontext current_ctx;
            cuCtxGetCurrent(&current_ctx);
            std::cout << "current_ctx=" << current_ctx << "\n";
            return current_device;

        } else {
            devices_prohibited++;
        }

        current_device++;
    }

    if (devices_prohibited == device_count) {
        fprintf(stderr,
            "CUDA error:"
            " No Vulkan-CUDA Interop capable GPU found.\n");
        exit(EXIT_FAILURE);
    }

    return -1;
}
void test_runtime_driver_op()
{
    inital_runtime_context();
    check_current_ctx();

}

Он сообщает:

GPU Device 0: "GeForce RTX ..." with compute capability 7.5

current_ctx=0x6eb220
current context=0x6eb220
CUDA error at ... code=201(CUDA_ERROR_INVALID_CONTEXT) "cuCtxGetApiVersion(context, &api_ver)" 

1 Ответ

3 голосов
/ 09 февраля 2020

Причина, по которой вы получаете ошибку, заключается в том, что, по крайней мере, в этом случае, создание ленивого контекста API времени выполнения не происходило при попытке привязки к контексту с API драйвера. Канонический способ обеспечить получение контекста, созданного во время выполнения, всегда был

cudaSetDevice(current_device);
cudaFree(0);

. В этом отношении документация всегда была неоднозначной, и семантика, казалось, со временем немного изменилась, но этот вызов всегда работал для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...