Инициализация данных CUDA - PullRequest
0 голосов
/ 15 апреля 2019

Что касается руководства по CUDA, большая часть данных отправляется на устройство посредством вызова ядра.Интересно, могу ли я в любом случае выполнить Init Data - Process (s) - очистить вид операции в cuda.Вот мой код, который я пробовал, но, похоже, он не работает.

#include <cuda.h>
#include <stdio.h>
#include <cuda_runtime.h>

#define CUDA_CHECK_VALUE(value, a) {                            \
    cudaError_t _m_cudaStatus = value;                          \
    if(_m_cudaStatus != cudaSuccess) {                          \
        printf("Error &s at line %d in file %s\n",              \
                cudaGetErrorString(_m_cudaStatus),              \
                __LINE__, __FILE__);                            \
        exit(1);                                                \
    } else {printf("Done! - %d\n", a);} }

__constant__
float* data;

__host__ __device__
void initMemory(int size){
    CUDA_CHECK_VALUE(cudaMalloc(&data, sizeof(float) * size), 0);
    float *ha = new float[size];
    for(int i =0; i < size; i++){
        ha[i] = i * 1.0f;
    }
    CUDA_CHECK_VALUE(cudaMemcpyToSymbol(data, ha, sizeof(float) * size, 0, cudaMemcpyHostToDevice), 1);
    CUDA_CHECK_VALUE(cudaDeviceSynchronize(), 2);
}

__host__ __device__
void freeMemory(){
    CUDA_CHECK_VALUE(cudaDeviceSynchronize(), 3);
    cudaFree(data);
}

__global__
void print(int size){
    printf("size = %d\n", size);
    for(int i = 0; i < size; i++){
        printf("data[%d] = %f\n", i, data[i]);
    }
}

int main(){
    int size = 1024;

    initMemory(size);
    printf("1\n");
    print<<<1, 1>>>(size);
    printf("2\n");
    cudaDeviceSynchronize();
    freeMemory();
    printf("3\n");
}

В этом коде я пытаюсь сохранить некоторые данные, инициализированные хостом, один раз, и подготовить процесс ядра к многократному вызову и, наконец, освободить cuda.память методом очистки.Но я не совсем уверен, является ли это правильным способом использования CUDA и как соответствующим образом изменить мой код.

1 Ответ

2 голосов
/ 15 апреля 2019

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

#include <cuda.h>
#include <stdio.h>
#include <cuda_runtime.h>

#define CUDA_CHECK_VALUE(value, a) {                            \
    cudaError_t _m_cudaStatus = value;                          \
    if(_m_cudaStatus != cudaSuccess) {                          \
        printf("Error %s at line %d in file %s\n",              \
                cudaGetErrorString(_m_cudaStatus),              \
                __LINE__, __FILE__);                            \
        exit(1);                                                \
    } else {printf("Done! - %d\n", a);} }

__device__ float* data;

void initMemory(int size){
    float* da;
    CUDA_CHECK_VALUE(cudaMalloc(&da, sizeof(float) * size), 0);
    float *ha = new float[size];
    for(int i =0; i < size; i++){
        ha[i] = i * 1.0f;
    }
    CUDA_CHECK_VALUE(cudaMemcpy(da, ha, sizeof(float) * size, cudaMemcpyHostToDevice), 1);
    CUDA_CHECK_VALUE(cudaMemcpyToSymbol(data, &da, sizeof(da), 0, cudaMemcpyHostToDevice), 2);
    CUDA_CHECK_VALUE(cudaDeviceSynchronize(), 3);
    delete[] ha;
}

void freeMemory(){
    CUDA_CHECK_VALUE(cudaDeviceSynchronize(), 4);
    float* da;
    CUDA_CHECK_VALUE(cudaMemcpyFromSymbol(&da, data, sizeof(da), 0, cudaMemcpyDeviceToHost), 5);
    CUDA_CHECK_VALUE(cudaFree(da), 6);
}

__global__
void print(int size){
    for(int i = 0; i < size; i++){
        printf("data[%d] = %f\n", i, data[i]);
    }
}

int main(){
    int size = 1024;

    initMemory(size);
    printf("1\n");
    print<<<1, 1>>>(size);
    cudaDeviceSynchronize();
    printf("2\n");
    freeMemory();
    printf("3\n");
}

Несколько баллов:

  1. Важно понимать, что initMemory и freeMemory оба работают на хосте в вашем коде. Декорирование кода с помощью __device__ не приводит к автоматическому запуску кода на устройстве. Он только компилирует версию кода как функцию устройства, которая может быть вызвана в ядре. Однако вы ни в коем случае не делаете этого, поэтому весь код выполняется на хосте, потому что именно там вы его назвали.
  2. __shared__ и __constant__ память не может быть динамически выделена из хоста, как вы пытались в двух итерациях вашего кода, которые мы видели
  3. Для ваших вторых реализаций initMemory и freeMemory требуется несколько дополнительных функций API-интерфейса хоста CUDA для правильной работы, что должно быть очевидно из приведенного выше кода.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...