Я пытаюсь реализовать одно ядро Cuda, чтобы использовать его непосредственно с Jcuda.
Я хочу сделать векторное произведение двух векторов на N элементов.Я следовал некоторому учебнику онлайн и смог написать код ниже.Я не знаю, что не так с кодом, но я не могу записать результат из графического процессора в память хоста.Ошибка в строке
`
int ThreadPerBlock = 256;
int blockPerGrid = Math.max(32 , ((int) n+ThreadPerBlock-1) / ThreadPerBlock );
float hostResult[] = new float[blockPerGrid];
cuMemcpyDtoH(Pointer.to(hostResult), deviceResult, blockPerGrid * Sizeof.FLOAT);
`
extern "C"
__global__ void Vector_Dot_Product (size_t N, float *V1 , float *V2 , float *V3 )
{
const int ThreadPerBlock = 256;
__shared__ float chache[ThreadPerBlock] ;
float temp ;
unsigned int tid = blockDim.x * blockIdx.x + threadIdx.x ;
unsigned int chacheindex = threadIdx.x ;
while ( tid < N )
{
temp += V1[tid] * V2[tid] ;
tid += blockDim.x * gridDim.x ;
}
chache[chacheindex] = temp ;
__syncthreads () ;
int i = blockDim.x / 2 ;
while ( i!=0 )
{
if ( chacheindex < i )
chache[chacheindex] += chache [chacheindex + i] ;
__syncthreads () ;
i/=2 ;
}
if ( chacheindex == 0 )
V3[blockIdx.x] = chache [0] ;
}
Вот функции Java, которые я вызываю в ядре.
public static float[] VecDotProd(long n, float[] x, float[] y){
// Define the values of blockPerGrid.
int ThreadPerBlock = 256;
int blockPerGrid = Math.max(32 , ((int) n+ThreadPerBlock-1) / ThreadPerBlock );
// Enable exceptions and omit all subsequent error checks
JCudaDriver.setExceptionsEnabled(true);
// Initialize the driver and create a context for the first device.
cuInit(0);
CUdevice device = new CUdevice();
cuDeviceGet(device, 0);
CUcontext context = new CUcontext();
cuCtxCreate(context, 0, device);
// Afterwards, initialize the vector library, which will
// attach to the current context
VecMatOperation.init();
// Allocate the device pointers, and copy the
// host input data to the device
CUdeviceptr deviceX = new CUdeviceptr();
cuMemAlloc(deviceX, n * Sizeof.FLOAT);
cuMemcpyHtoD(deviceX, Pointer.to(x), n * Sizeof.FLOAT);
CUdeviceptr deviceY = new CUdeviceptr();
cuMemAlloc(deviceY, n* Sizeof.FLOAT);
cuMemcpyHtoD(deviceY, Pointer.to(y), n * Sizeof.FLOAT);
CUdeviceptr deviceResult = new CUdeviceptr();
cuMemAlloc(deviceResult, blockPerGrid * Sizeof.FLOAT);
// Calling the add function to perform vector addition.
VecMatOperation.VecDotProd(n, deviceX , deviceY, deviceResult);
// Allocate host output memory and copy the device output
// to the host.
float hostResult[] = new float[blockPerGrid];
// System.out.println(Sizeof(deviceResult));
cuMemcpyDtoH(Pointer.to(hostResult), deviceResult, blockPerGrid * Sizeof.FLOAT);
cuMemFree(deviceX);
cuMemFree(deviceY);
cuMemFree(deviceResult);
VecMatOperation.shutdown();
return hostResult;
}
Я создал интерфейс, который использует функцию вызова для вызова фактической функции из ядра Cuda.Но из кода Java можно предположить, что это просто простой вызов, который включает в себя переданные параметры и ничего более.Полный код действительно большой, и я не могу показать его здесь, поэтому я записал код ядра и фрагмент кода, где я получаю сообщение об ошибке.Ошибка в строке
cuMemcpyDtoH(Pointer.to(hostResult), deviceResult, blockPerGrid * Sizeof.FLOAT);
Он говорит, что не может записать deviceResult в hostResult из-за несоответствия размеров обоих.Я попытался напечатать значения результата из кода ядра, и он имел 49 значений, которые не являются размером hostResult.Но я пробовал 49 как размер массива hostResult и все равно получил ту же ошибку.Так что я не могу записать результат обратно в процессор.запишите
Каким должен быть размер результата от графического процессора?Что не так в коде, если что-то не так?