Моя матрица работает для первых нескольких результатов, затем выводит 0 - PullRequest
0 голосов
/ 28 апреля 2020

Если честно, я использую матричное умножение для умножения матрицы 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;
}

Любые предложения будут оценены.

...