Ошибка в cudaMemcpyToSymbol с использованием CUDA 5
Проблема
Я подготовил один образец кода CUDA с использованием постоянной памяти. Я могу запустить это в cuda 4.2 успешно, но при компиляции с использованием CUDA 5 я получаю "недопустимый символ устройства" .
Здесь я привел пример кода.
Код
#include <iostream>
#include <stdio.h>
#include <cuda_runtime.h>
#include <cuda.h>
struct CParameter
{
int A;
float B;
float C;
float D;
};
__constant__ CParameter * CONSTANT_PARAMETER;
#define PARAMETER "CONSTANT_PARAMETER"
bool ERROR_CHECK(cudaError_t Status)
{
if(Status != cudaSuccess)
{
printf(cudaGetErrorString(Status));
return false;
}
return true;
}
// Kernel that executes on the CUDA device
__global__ void square_array(float *a, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx<N)
{
a[idx] = CONSTANT_PARAMETER->A * a[idx];
}
}
////Main Function/////
int main(void)
{
/////Variable Definition
const int N = 10;
size_t size = N * sizeof(float);
cudaError_t Status = cudaSuccess;
CParameter * m_dParameter;
CParameter * m_hParameter;
float * m_D;
float * m_H;
//Memory Allocation Host
m_hParameter = new CParameter;
m_H = new float[N];
//Memory Allocation Device
cudaMalloc((void **) &m_D, size);
cudaMalloc((void**)&m_dParameter,sizeof(CParameter));
////Data Initialization
for (int i=0; i<N; i++)
m_H[i] = (float)i;
m_hParameter->A = 5;
m_hParameter->B = 3;
m_hParameter->C = 98;
m_hParameter->D = 100;
//Memory Copy from Host To Device
Status = cudaMemcpy(m_D, m_H, size, cudaMemcpyHostToDevice);
ERROR_CHECK(Status);
Status = cudaMemcpy(m_dParameter,m_hParameter,sizeof(CParameter),cudaMemcpyHostToDevice);
ERROR_CHECK(Status);
Status = cudaMemcpyToSymbol(PARAMETER, &m_dParameter, sizeof(m_dParameter));
ERROR_CHECK(Status);
// Do calculation on device:
int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
square_array <<<n_blocks, block_size>>>(m_D,N);
// Retrieve result from device and store it in host array
cudaMemcpy(m_H, m_D, sizeof(float)*N, cudaMemcpyDeviceToHost);
// Print results
for (int i=0; i<N; i++)
printf("%d %f\n", i, m_H[i]);
// Cleanup
free(m_H);
free(m_hParameter);
cudaFree(m_dParameter);
cudaFree(m_D);
return 0;
}
Я пробовал WINDOWS: CUDA 5.0 Production Release, а графическая карта - GTX 590.
Любая помощь будет оценена.
Ответы
Ответ 1
Чтобы избежать "Stringly Typed" , использование символьных строк для обозначения символов устройства было устаревшим в API-интерфейсе CUDA функции в CUDA 4.1 и удалены в CUDA 5.0.
примечания к выпуску CUDA 5:
** Использование символьной строки для обозначения символа устройства, что было возможно с некоторыми функциями API, больше не поддерживается. Вместо этого символ должен быть используется напрямую.
Если вы измените код на следующий, он должен работать.
Status = cudaMemcpyToSymbol(CONSTANT_PARAMETER, &m_dParameter, sizeof(m_dParameter));
ERROR_CHECK(Status);
![enter image description here]()
Ответ 2
Из Замечания по выпуску CUDA 5.0:
** Использование символьной строки для обозначения символа устройства, которое возможно с некоторыми функциями API, больше не поддерживается. Вместо этого символ следует использовать напрямую. "
Эти функции API все еще существуют, но теперь они принимают аргумент символа цели только как голый идентификатор, а не как пустой идентификатор, так и строковый литерал, обозначающий идентификатор. Например.
__ device__ __ constant__ type ident;
main() { cudaMemcpyToSymbol("ident", ...); } // no longer valid, returns cudaErrorInvalidSymbol
main() { cudaMemcpyToSymbol(ident, ...); } // valid
Так избавитесь от этого:
#define PARAMETER "CONSTANT_PARAMETER"
И измените это:
Status = cudaMemcpyToSymbol(PARAMETER, &m_dParameter, sizeof(m_dParameter));
Для этого:
Status = cudaMemcpyToSymbol(CONSTANT_PARAMETER, &m_dParameter, sizeof(m_dParameter));
И я думаю, что это сработает.