Ошибка неверного дескриптора ресурса CUDA при выделении буфера памяти графического процессора - PullRequest
0 голосов
/ 03 августа 2020

Я столкнулся с ошибкой неверного дескриптора ресурса cuda при выделении буфера на GPU.

1, я загружаю код из git clone https://github.com/Funatiq/gossip.git.

2, я построил этот проект в сплетнях каталог: git submodule update --init && make. Затем я получил здесь двоичный файл компиляции.

3, затем я генерирую план разброса и сбора для моего основного графического процессора, здесь это 0.

$python3 scripts/plan_from_topology_asynch.py gather 0

$python3 scripts/plan_from_topology_asynch.py scatter 0

, затем он генерирует scatter_plan. json и gather_plan. json.

4, наконец, я выполняю план: ./execute scatter_gather scatter_plan.json gather_plan.json

Ошибка указывала на эти строки code :

std::vector<size_t> bufs_lens_scatter = scatter.calcBufferLengths(table[main_gpu]);
    print_buffer_sizes(bufs_lens_scatter);

    std::vector<data_t *> bufs(num_gpus);
    std::vector<size_t> bufs_lens(bufs_lens_scatter);
    TIMERSTART(malloc_buffers)
    for (gpu_id_t gpu = 0; gpu < num_gpus; ++gpu) {
        cudaSetDevice(context.get_device_id(gpu)); CUERR
        cudaMalloc(&bufs[gpu], sizeof(data_t)*bufs_lens[gpu]); CUERR
    }
    TIMERSTOP(malloc_buffers)

Подробная информация об ошибке отображается как:

RUN: scatter_gather
INFO: 32768 bytes (scatter_gather)
TIMING: 0.463872 ms (malloc_devices)
TIMING: 0.232448 ms (zero_gpu_buffers)
TIMING: 0.082944 ms (init_data)
TIMING: 0.637952 ms (multisplit)

Partition Table:
470 489 534 553 514 515 538 483
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

Required buffer sizes:
0 538 717 604 0 344 0 687

TIMING: 3.94455e-31 ms (malloc_buffers)
CUDA error: invalid resource handle : executor.cuh, line 405

Для справки я приложил полный отчет об ошибке сюда . Любопытно то, что автор не может воспроизвести эту ошибку на своем сервере. Но когда я запустил его на рабочей станции DGX с 8 графическими процессорами. Эта ошибка возникает. Я сомневаюсь, что это ошибка программирования cuda или проблемы со средой c.

1 Ответ

0 голосов
/ 04 августа 2020

Код имеет дефект при обработке cudaEventRecord(), который используется в макросах TIMERSTART и TIMERSTOP, определенных здесь и используемых здесь malloc_buffers label).

События CUDA имеют ассоциацию устройств , неявно определяемую при их создании. Это означает, что они связаны с устройством, выбранным последним вызовом cudaSetDevice(). Как указано в руководстве по программированию:

cudaEventRecord () завершится ошибкой, если входное событие и входной поток связаны с разными устройствами.

(обратите внимание, что каждое устройство имеет свои собственный нулевой поток - эти события записываются в нулевой поток)

И если мы запустим код с cuda-memcheck, мы заметим, что ошибка неверного дескриптора ресурса действительно возвращается вызовом cudaEventRecord() .

Конкретно ссылаясь на код здесь :

...
std::vector<size_t> bufs_lens(bufs_lens_scatter);
TIMERSTART(malloc_buffers)
for (gpu_id_t gpu = 0; gpu < num_gpus; ++gpu) {
    cudaSetDevice(context.get_device_id(gpu)); CUERR
    cudaMalloc(&bufs[gpu], sizeof(data_t)*bufs_lens[gpu]); CUERR
}
TIMERSTOP(malloc_buffers)

Макрос TIMERSTART определяет и создает 2 события cuda, одно из которых он немедленно записывает (начало мероприятие). Макрос TIMERSTOP использует событие остановки таймера, которое было создано в макросе TIMERSTART. Однако мы можем видеть, что промежуточный код, вероятно, изменил устройство с того, которое действовало, когда были созданы эти два события (из-за вызова cudaSetDevice в for-l oop). Следовательно, вызовы cudaEventRecordcudaEventElapsedTime) не работают из-за этого недопустимого использования.

В качестве доказательства, когда я добавляю вызовы cudaSetDevice в определения макросов следующим образом:

    #define TIMERSTART(label)                                                  \
        cudaEvent_t timerstart##label, timerstop##label;                       \
        float timerdelta##label;                                               \
        cudaSetDevice(0); \
        cudaEventCreate(&timerstart##label);                                   \
        cudaEventCreate(&timerstop##label);                                    \
        cudaEventRecord(timerstart##label, 0);
#endif

#ifndef __CUDACC__
    #define TIMERSTOP(label)                                                   \
        stop##label = std::chrono::system_clock::now();                        \
        std::chrono::duration<double>                                          \
            timerdelta##label = timerstop##label-timerstart##label;            \
        std::cout << "# elapsed time ("<< #label <<"): "                       \
                  << timerdelta##label.count()  << "s" << std::endl;
#else
    #define TIMERSTOP(label)                                                   \
            cudaSetDevice(0); \
            cudaEventRecord(timerstop##label, 0);                              \
            cudaEventSynchronize(timerstop##label);                            \
            cudaEventElapsedTime(                                              \
                &timerdelta##label,                                            \
                timerstart##label,                                             \
                timerstop##label);                                             \
            std::cout <<                                                       \
                "TIMING: " <<                                                  \
                timerdelta##label << " ms (" <<                                \
                #label <<                                                      \
                ")" << std::endl;
#endif

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

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