2013-03-28 4 views
0

Я думаю, что массив может быть выделен на gpu ex. __device__ int device_array[100]; без использования cudaMalloc, поскольку длина известна. Но когда я запускаю следующий код, отображаются некоторые нерелевантные числа. Я изучил популярную книгу для cuda, и все примеры там используют cudaMalloc. Можно использовать массив фиксированного размера, например, или он должен быть выделен cudaMalloc?cuda фиксированный размер глобальный массив

__device__ int device_array[100]; 

__global__ void kernel() { 

    device_array[blockIdx.x] = blockIdx.x; 
} 

void call_kernel(int *host_array) { 

    kernel<<<100,1>>>(); 

    cudaMemcpy(host_array, device_array, 100 * sizeof(int), cudaMemcpyDeviceToHost); 
} 

int main() { 

    int host_array[100]; 

    call_kernel(host_array); 

    for (int i = 0; i < 100; i++) 
     cout << host_array[i] << endl; 
} 
+0

В вашем коде отсутствует проверка ошибок. Вероятно, что вызов 'cudaMemcpy' терпит неудачу, но вы просто этого не знаете, потому что вы не проверяете статус возврата. Как только вы подтвердите, что ошибка возникает во время выполнения, источник проблемы станет очевидным. – talonmies

+0

Подробнее [clues] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-variable-qualifier). Как сделать проверку ошибок хорошо обсуждается [здесь] (http://stackoverflow.com/questions/14038589/what-is-the-canonical-way-to-check-for-errors-using-the-cuda-runtime- апи). –

ответ

1

Как Роберт упомянул в своем комментарии, вы должны использовать cudaMemcpyFromSymbol при доступе к __device__ символ на хосте. Таким образом, ваш вызов cudaMemcpy в его нынешнем виде должен давать ошибку в строке «недопустимый аргумент». Если вы хотите, чтобы убедиться в этом, попробуйте изменить cudaMemcpy строку:

cudaError_t cuda_status = cudaMemcpy(...); 
std::cout << cudaGetErrorString(cuda_status) << std::endl; 

В любом случае, если вы хотите, чтобы получить правильный ответ, вы должны изменить свою cudaMemcpy линию, чтобы быть:

cudaMemcpyFromSymbol(host_array, device_array, 100 * sizeof(int), 0, cudaMemcpyDeviceToHost); 

Сигнатура для cudaMemcpyFromSymbol является:

cudaError_t cudaMemcpyFromSymbol (void* dst, const void* symbol, size_t count, size_t offset = 0, cudaMemcpyKind kind = cudaMemcpyDeviceToHost) 

смещение по умолчанию 0 и копирования памяти направления по умолчанию cudaMemcpyDeviceToHost, так что те технич в вашем случае не обязательно. Основной вывод из всего этого - всегда проверять возвращаемые значения вашего cuda-call, поскольку они обычно ведут вас в правильном направлении.

+0

Если вы хотите копировать с хоста на устройство таким же образом, вам лучше воспользоваться функцией «cudaMemcpyToSymbol». Я бы посоветовал взглянуть на доступные функции API выполнения CUDA по адресу http://docs.nvidia.com/cuda/cuda-runtime-api/index.html#group__CUDART__MEMORY – alrikai

Смежные вопросы