Матрица Кубласа LU Разложение

У меня возникли проблемы с вызовом dgetrf в cuda. Из того, что я нашел, я могу назвать только пакетную версию (http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-getrfbatched). Когда я его вызываю, я получаю возвращаемое значение ошибки 7, для которого я не смог найти соответствующее перечисление для этого кода ошибки. Ниже мой код, любая помощь будет очень признательна;

void cuda_matrix_inverse (int m, int n, double* a){

    cublasHandle_t handle;
    cublasStatus_t status;
    double **devPtrA = 0;
    double **devPtrA_dev = NULL;
    int *d_pivot_array;
    int *d_info_array;
    int rowsA = m;
    int colsA = n;
    int matrixSizeA;
    cudaError_t error;

    fprintf(stderr,"starting cuda inverse\n");

    error = cudaMalloc((void **)&d_pivot_array, sizeof(int));
    if (error != cudaSuccess) fprintf(stderr,"\nError: %s\n",cudaGetErrorString(error));
    error = cudaMalloc((void **)&d_info_array, sizeof(int));
    if (error != cudaSuccess) fprintf(stderr,"\nError: %s\n",cudaGetErrorString(error));

    fprintf(stderr,"malloced pivot and info\n");

    status = cublasCreate(&handle);
    if (status != CUBLAS_STATUS_SUCCESS) fprintf(stderr,"error %i\n",status);

    matrixSizeA = rowsA * colsA;

    devPtrA =(double **)malloc(1 * sizeof(*devPtrA));

    fprintf(stderr,"malloced devPtrA\n");

    error = cudaMalloc((void **)&devPtrA[0], matrixSizeA * sizeof(devPtrA[0][0]));
    if (error != cudaSuccess) fprintf(stderr,"\nError: %s\n",cudaGetErrorString(error));

    error = cudaMalloc((void **)&devPtrA_dev, 1 * sizeof(*devPtrA));
    if (error != cudaSuccess) fprintf(stderr,"\nError: %s\n",cudaGetErrorString(error));

    fprintf(stderr,"malloced device variables\n");

    error = cudaMemcpy(devPtrA_dev, devPtrA, 1 * sizeof(*devPtrA), cudaMemcpyHostToDevice);
    if (error != cudaSuccess) fprintf(stderr,"\nError: %s\n",cudaGetErrorString(error));

    fprintf(stderr,"copied from devPtrA to d_devPtrA\n");

    status = cublasSetMatrix(rowsA, colsA, sizeof(a[0]), a, rowsA, devPtrA[0], rowsA);
    if (status != CUBLAS_STATUS_SUCCESS) fprintf(stderr,"error %i\n",status);


    status = cublasDgetrfBatched(handle, m, devPtrA_dev,m,d_pivot_array,d_info_array,1); //cannot get this to work
    if (status != CUBLAS_STATUS_SUCCESS) fprintf(stderr,"error in dgetrf %i\n",status);


    fprintf(stderr,"done with cuda inverse\n");
}

person David    schedule 19.03.2014    source источник


Ответы (1)


Код ошибки 7 cublas означает CUBLAS_STATUS_INVALID_VALUE. Инверсия матриц в кублах возможна только для квадратных матриц, поэтому я предполагаю, что m == n в вашем случае. При этом функции cublas<t>getrfBatched требуют, чтобы сводной массив имел длину n для каждой матрицы, поэтому вы должны выделить d_pivot_array как:

error = cudaMalloc((void **)&d_pivot_array, n * sizeof(int));

Чтобы быть более общим, он распределяется как:

error = cudaMalloc((void **)&d_pivot_array, n * batchSize * sizeof(int));

Вот код инверсии квадратной матрицы, который я написал во время тестирования CUBLAS работает. Ввод и вывод функции представляют собой квадратные матрицы типа float, расположенные на устройстве.

person sgarizvi    schedule 19.03.2014
comment
Что такое spitch и dpitch в данном случае? Кроме того, если бы я хотел, чтобы он был автономным, мог бы я просто добавить cudaMalloc src_d, а затем cudaMemcpy из a в src_d, чтобы все, что передается, было моей исходной матрицей? - person David; 20.03.2014
comment
spitch и dpitch — это шаг матрицы в случае, если матрицы были выделены с использованием cudaMallocPitch. В противном случае он будет просто равен n * sizeof(dataType). - person sgarizvi; 20.03.2014
comment
Да, чтобы сделать его автономным, вы можете создать выделение матриц устройства внутри этой функции. - person sgarizvi; 20.03.2014