можно ли выделить общую память для ядра (внутри или снаружи) и использовать ее в других функциях устройства, вызываемых из ядра? Особенно интересно для меня будет, если/как я могу использовать его как возвращаемый параметр/массив.
Кажется, не проблема использовать общую память в качестве входного параметра в функциях устройства (по крайней мере, я не получаю проблем, ошибок или неожиданных результатов.
Когда я использую его как возвращаемый параметр, у меня возникает несколько проблем:
Я могу запустить программу, когда она была построена из конфигурации отладки.
Но я не могу его отладить -> он падает в функциях устройства, когда я использую общую память
Также я получаю ошибки с
cuda-memchecker
-> неверным чтением__global__
, потому что адрес выходит за пределы и он читается из общего адресного пространства.
Так можно ли использовать разделяемую память для возврата массивов из функций устройства в ядро?
РЕДАКТИРОВАТЬ:
Я написал очень простой пример, чтобы исключить другие ошибки, сделанные мной.
#define CUDA_CHECK_RETURN(value) { \
cudaError_t _m_cudaStat = (value); \
if (_m_cudaStat != cudaSuccess) { \
printf( "Error %s at line %d in file %s\n", \
cudaGetErrorString(_m_cudaStat), __LINE__, __FILE__); \
exit(-1); \
} }
__device__ void Function( const int *aInput, volatile int *aOutput )
{
for( int i = 0; i < 10; i++ )
aOutput[i] = aInput[i] * aInput[i];
}
__global__ void Kernel( int *aInOut )
{
__shared__ int aShared[10];
for(int i=0; i<10; i++)
aShared[i] = i+1;
Function( aShared, aInOut );
}
int main( int argc, char** argv )
{
int *hArray = NULL;
int *dArray = NULL;
hArray = ( int* )malloc( 10*sizeof(int) );
CUDA_CHECK_RETURN( cudaMalloc( (void**)&dArray, 10*sizeof(int) ) );
for( int i = 0; i < 10; i++ )
hArray[i] = i+1;
CUDA_CHECK_RETURN( cudaMemcpy( dArray, hArray, 10*sizeof(int), cudaMemcpyHostToDevice ) );
cudaMemcpy( dArray, hArray, 10*sizeof(int), cudaMemcpyHostToDevice );
Kernel<<<1,1>>>( dArray );
CUDA_CHECK_RETURN( cudaMemcpy( hArray, dArray, 10*sizeof(int), cudaMemcpyDeviceToHost ) );
cudaMemcpy( hArray, dArray, 10*sizeof(int), cudaMemcpyDeviceToHost );
free( hArray );
CUDA_CHECK_RETURN( cudaFree( dArray ) );
cudaFree( dArray );
return 0;
}
Я запускаю ядро по одному блоку потоков и по одному потоку на блок. Собрать программу и запустить ее не проблема. Я получаю ожидаемые результаты. Но если программа тестируется cuda-memchecker, она завершает работу ядра и появляется следующий журнал.
Error unspecified launch failure at line 49 in file ../CuTest.cu
========= Invalid __global__ read of size 4
========= at 0x00000078 in /home/strautz/Develop/Software/CuTest/Debug/../CuTest.cu:14:Function(int const *, int volatile *)
========= by thread (0,0,0) in block (0,0,0)
========= Address 0x01000000 is out of bounds
========= Device Frame:/home/strautz/Develop/Software/CuTest/Debug/../CuTest.cu:25:Kernel(int*) (Kernel(int*) : 0xd0)
========= Saved host backtrace up to driver entry point at kernel launch time
========= Host Frame:/usr/lib/libcuda.so (cuLaunchKernel + 0x34b) [0x55d0b]
========= Host Frame:/usr/lib/libcudart.so.5.0 [0x8f6a]
=========
========= Program hit error 4 on CUDA API call to cudaMemcpy
========= Saved host backtrace up to driver entry point at error
========= Host Frame:/usr/lib/libcuda.so [0x24e129]
========= Host Frame:/usr/lib/libcudart.so.5.0 (cudaMemcpy + 0x2bc) [0x3772c]
========= Host Frame:[0x5400000]
=========
========= ERROR SUMMARY: 2 errors
Должна ли разделяемая память выравниваться, нужно ли делать что-то еще или ее можно игнорировать - не думаю?