Если честно, я использую матричное умножение для умножения матрицы 4x4 на матрицу 4x1000 +. Я использую это, чтобы изменить ряд координат x, y, z. Он обеспечивает правильные ответы для первых 268 - 392 потоков, в зависимости от размера набора данных, но затем выдает 0 для остальных. Моя функция cuda выглядит следующим образом:
__global__ void Transformation(float* transMatrix, float* coordinates, float* matrixOut, int transRows, int transCols, int coordRows, int coordCols, int outRows, int outCols)
{
float outValue = 0;
int Row = blockIdx.y * blockDim.y + threadIdx.y;
int Col = blockIdx.x * blockDim.x + threadIdx.x;
if (Row < outRows && Col < outCols)
{
for (int n = 0; n < transCols; ++n)
{
outValue += transMatrix[Row * transCols + n] * coordinates[Col * coordRows + n];
}
}
matrixOut[(blockIdx.y * blockDim.x + threadIdx.y) + (blockIdx.x * blockDim.y + threadIdx.x) * outRows] = outValue;
}
MatrixOut отформатирован так, как мне нужно, чтобы ответы помещались в матрицу для последующего чтения в правильном порядке.
Это выглядит как потоки выходят за границы столбцов и строк, но я не понимаю, почему. Мой размер блока составляет 256. Это должно быть хорошо для подсчета потоков, если умножить на 4, это дает 1024. Но у меня та же проблема с меньшим размером блока.
Нет никаких ошибок. Я не знаю, как поставить точку останова в части cuda.
Основной код функции, который вызывает умножение матриц, выглядит так:
cudaError_t transWithCuda(float* coordinates, float* TransMatrix, int numAtoms)
{
float* dev_coordinates;
float* dev_transMatrix;
float* dev_outputMatrix;
int size = numAtoms;
int outputRows = N;
int outputCols = size;
int transRows = N;
int transCols = N;
int coordRows = N;
int coordCols = size;
cudaError_t cudaStatus;
// Choose which GPU to run on, change this on a multi-GPU system.
cudaStatus = cudaSetDevice(0);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
goto Error;
}
// Allocate GPU buffers
cudaStatus = cudaMallocManaged((void**)&dev_coordinates, coordRows * coordCols * sizeof(float));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "dev_coordinates cudaMalloc failed!");
goto Error;
}
cudaStatus = cudaMallocManaged((void**)&dev_transMatrix, transRows * transCols * sizeof(float));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "dev_transMatrix cudaMalloc failed!");
goto Error;
}
cudaStatus = cudaMallocManaged((void**)&dev_outputMatrix, outputRows * outputCols * sizeof(float));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "dev_transMatrix cudaMalloc failed!");
goto Error;
}
// Copy input vectors from host memory to GPU buffers.
cudaStatus = cudaMemcpy(dev_coordinates, coordinates, N * size * sizeof(float), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "dev_coordinates cudaMemcpy failed!");
goto Error;
}
cudaStatus = cudaMemcpy(dev_transMatrix, TransMatrix, N * N * sizeof(float), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "dev_transMatrix cudaMemcpy failed!");
goto Error;
}
// Launch a kernel on the GPU.
dim3 block_size(256, N, 1);
dim3 grid_size;
grid_size.x = (outputCols + block_size.x - 1) / block_size.x;
grid_size.y = (outputRows + block_size.y - 1) / block_size.y;
cout << "numAtoms: " << size << endl;
cout << "grid size: " << grid_size.x << endl;
cout << "block size: " << block_size.x << endl;
cout << "outputRows: " << outputRows << endl;
cout << "outputCols: " << outputCols << endl;
cout << "transRows: " << transRows << endl;
cout << "transCols: " << transCols << endl;
cout << "coordRows: " << coordRows << endl;
cout << "coordCols: " << coordCols << endl;
Transformation <<<grid_size, block_size >>> (dev_transMatrix, dev_coordinates, dev_outputMatrix, transRows, transCols, coordRows, coordCols, outputRows, outputCols);
// Check for any errors launching the kernel
cudaStatus = cudaGetLastError();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "Transformation launch failed: %s\n", cudaGetErrorString(cudaStatus));
goto Error;
}
// cudaDeviceSynchronize waits for the kernel to finish, and returns
// any errors encountered during the launch.
cudaStatus = cudaDeviceSynchronize();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
goto Error;
}
// Copy output vector from GPU buffer to host memory.
cudaStatus = cudaMemcpy(coordinates, dev_outputMatrix, size * N * sizeof(float), cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "coordinates cudaMemcpy failed!");
goto Error;
}
Error:
cudaFree(dev_coordinates);
cudaFree(dev_transMatrix);
cudaFree(dev_outputMatrix);
return cudaStatus;
}
Любые предложения будут оценены.