Заметки по программированию CUDA (3)


предисловие

Обнаружение ошибок при запуске программы CUDA

1. Обнаружение ошибок при работе программы CUDA

Обнаружение неправильных заголовочных файлов

Как и в некоторых файлах журналов, при общем обнаружении ошибок записывается файл заголовка, содержащий код для запуска API обнаружения ошибок. При обнаружении ошибок в работе базового API-интерфейса программы cuda мы узнали, что возвращаемое значение практически всех API-интерфейсов cuda имеет информацию о флаге структуры cudaError_t, успешно ли она используется, и успешный вызов возвращает cudaSuccess. Следовательно, в соответствии с возвращаемым значением в заголовочном файле может быть определена функция макроса, чтобы проверить, работает ли программа cuda неправильно.

#pragma once
#include<stdio.h>

#define CHECK(call) \
do                  \
{
      
      \
    const cudaError_t error_code = call; \
    if(error_code != cudaSuccess) \   
    {
    
    \
        printf("cuda error"); \
        printf("  File:   %s\n",__FILE__); \
        printf("  Line:   %d\n",__LINE__); \
        printf("  Error code: %d\n",error_code); \
        printf("  Error text: %s\n",cudaGetErrorString(error_code)); \
        exit(1); \
    }\
} while(0)

(1) #pragma Once — это инструкция предварительной обработки, которая имеет ту же функцию, что и команда условной компиляции #ifndef, но более краткая.
(2) Параметром функции макроса CHECK является функция API среды выполнения cuda.
(3) Прекомпилятор имеет предопределенные макросы:

    __FILE__ // 获取当前文件名
    __func__ // 获取当前函数名
    __LINE__ // 获取当前行号
    __DATE__ // 获取当前日期
    __TIME__ // 获取当前时间
    __WORDSIZE // 获取当前编译器的位数,适合用来显示警告、错误信息。

(4) Также можно не использовать оператор do while в макрофункции, но в некоторых случаях это небезопасно. С помощью функции макроса точка с запятой будет добавлена ​​автоматически при компиляции и импорте в исходный код, поэтому нет необходимости добавлять точку с запятой после while(0) .

Проверьте функции API CUDA во время выполнения.

Включите записанный файл заголовка в исходную программу, имя файла заголовка программы cuda, обычно называемое xxx.cuh. Просто передайте функцию API, которая вызывает среду выполнения cuda в качестве параметра, в макрофункцию CHECK файла заголовка, например:

    // 分配设备内存
    double *d_x,*d_y,*d_z;
    // printf("%p",d_x);
    CHECK(cudaMalloc((void **)&d_x,M));
    CHECK(cudaMalloc((void **)&d_y,M));
    CHECK(cudaMalloc((void **)&d_z,M));
    // 将某些数据从主机复制到设备上
    CHECK(cudaMemcpy(d_x,h_x,M,cudaMemcpyHostToDevice));
    CHECK(cudaMemcpy(d_y,h_y,M,cudaMemcpyHostToDevice));

    // 数组求和
    const int block_size = 128;
    const int gride_size = N/block_size;
    add<<<gride_size,block_size>>>(d_x,d_y,d_z);
    CHECK(cudaMemcpy(h_z,d_z,M,cudaMemcpyHostToDevice));

Если программа сообщает об ошибке, будет отображена следующая информация:
вставьте сюда описание изображения

Проверьте функцию ядра CUDA во время выполнения.

Вышеупомянутый метод нельзя использовать напрямую, как указано выше, потому что функция ядра не имеет возвращаемого значения. В API cuda есть способ отлавливать ошибки, которые могут возникнуть в функции ядра.
cudaGetLastError():
вставьте сюда описание изображения
ПРИМЕЧАНИЕ. Эта функция также может возвращать коды ошибок из предыдущих асинхронных запусков.
Поэтому при последующей проверке также проверьте, синхронизированы ли хост и устройство, например:

    // 数组求和
    const int block_size = 1240;  // 最大限制是1024
    const int gride_size = N/block_size;
    add<<<gride_size,block_size>>>(d_x,d_y,d_z);
    // 检查核函数的调用
    CHECK(cudaGetLastError());
    CHECK(cudaDeviceSynchronize());  // 可用可不用,后面的隐式的起到了同步主机与设备的作用
    // 将某些数据从设备复制到主机上,这个数据传输函数隐式的起到了同步主机与设备的作用,所以后面用不用cudaDeviceSynchronize都可以
    CHECK(cudaMemcpy(h_z,d_z,M,cudaMemcpyDeviceToHost));
    check(h_z,N);

Используя cudaDeviceSynchronize() отображаемого узла синхронизации и устройства, местоположение ошибки становится более точным.
Проверьте неправильное сообщение об ошибке:
вставьте сюда описание изображения

CUDA-MEMCHECKИнструменты

cuda предоставляет набор инструментов CUDA-MEMCHECK, который используется для проверки ошибок памяти с помощью команды cuda-memcheck.
Через -h можно узнать, что главное проверить память:
вставьте сюда описание изображения

Подведем итог

Основной метод проверки ошибок программы cuda
Ссылка:
Если содержание блога нарушает авторские права, вы можете связаться и вовремя удалить его!
Программирование CUDA: основы и практика
https://docs.nvidia.com/cuda/
https://docs.nvidia.com/cuda/cuda-runtime-api
https://github.com/brucefan1983/CUDA-Programming

Supongo que te gusta

Origin blog.csdn.net/weixin_41311686/article/details/128720882
Recomendado
Clasificación