CUDA를 사용하여 행렬 곱셈을 구현 한 후. 나는 CUBLAS (포럼의 일부 사람들의 조언 덕분에)로 구현하려고 시도했다.CUBLAS 행렬 곱셈
사각형 행렬을 곱할 수는 있지만 (다시 한 번 ...) 비 사각형 행렬로 작업하는 데 어려움이 있습니다. Matrix A의 너비 (A * B = C)가 다를 때 작동하는 비 정사각 행렬 곱셈의 유일한 유형입니다.
오류가 발생하지 않지만 결과 행렬이 잘못된 값을 반환합니다. 다음은 내 코드입니다 (기본적으로 simpleCUBLAS SDK 예제를 적용한 것입니다).
#include <stdlib.h>
#include <stdio.h>
#include "cublas.h"
#define HA 2
#define WA 9
#define WB 2
#define HB WA
#define WC WB
#define HC HA
#define index(i,j,ld) (((j)*(ld))+(i))
void printMat(float*P,int uWP,int uHP){
//printf("\n %f",P[1]);
int i,j;
for(i=0;i<uHP;i++){
printf("\n");
for(j=0;j<uWP;j++)
printf("%f ",P[index(i,j,uHP)]);
//printf("%f ",P[i*uWP+j]);
}
}
int main (int argc, char** argv) {
cublasStatus status;
int i,j;
cublasInit();
float *A = (float*)malloc(HA*WA*sizeof(float));
float *B = (float*)malloc(HB*WB*sizeof(float));
float *C = (float*)malloc(HC*WC*sizeof(float));
if (A == 0) {
fprintf (stderr, "!!!! host memory allocation error (A)\n");
return EXIT_FAILURE;
}
if (B == 0) {
fprintf (stderr, "!!!! host memory allocation error (A)\n");
return EXIT_FAILURE;
}
if (C == 0) {
fprintf (stderr, "!!!! host memory allocation error (A)\n");
return EXIT_FAILURE;
}
for (i=0;i<HA;i++)
for (j=0;j<WA;j++)
A[index(i,j,HA)] = (float) index(i,j,HA);
for (i=0;i<HB;i++)
for (j=0;j<WB;j++)
B[index(i,j,HB)] = (float) index(i,j,HB);
/*
for (i=0;i<HA*WA;i++)
A[i]=(float) i;
for (i=0;i<HB*WB;i++)
B[i]=(float) i; */
float* AA; float* BB; float* CC;
/*ALLOCATE ON THE DEVICE*/
status=cublasAlloc(HA*WA,sizeof(float),(void**)&AA);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! device memory allocation error (A)\n");
return EXIT_FAILURE;
}
status=cublasAlloc(HB*WB,sizeof(float),(void**)&BB);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! device memory allocation error (A)\n");
return EXIT_FAILURE;
}
status=cublasAlloc(HC*WC,sizeof(float),(void**)&CC);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! device memory allocation error (A)\n");
return EXIT_FAILURE;
}
/*SET MATRIX*/
status=cublasSetMatrix(HA,WA,sizeof(float),A,HA,AA,HA);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! device memory allocation error (A)\n");
return EXIT_FAILURE;
}
status=cublasSetMatrix(HB,WB,sizeof(float),B,HB,BB,HB);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! device memory allocation error (A)\n");
return EXIT_FAILURE;
}
/*KERNEL*/
cublasSgemm('n','n',HA,WB,WA,1,AA,HA,BB,HB,0,CC,HC);
status = cublasGetError();
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! kernel execution error.\n");
return EXIT_FAILURE;
}
cublasGetMatrix(HC,WC,sizeof(float),CC,HC,C,HC);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! device read error (A)\n");
return EXIT_FAILURE;
}
/* PERFORMANCE OUTPUT*/
printf("\nMatriz A:\n");
printMat(A,WA,HA);
printf("\nMatriz B:\n");
printMat(B,WB,HB);
printf("\nMatriz C:\n");
printMat(C,WC,HC);
free(A); free(B); free (C);
status = cublasFree(AA);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! memory free error (A)\n");
return EXIT_FAILURE;
}
status = cublasFree(BB);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! memory free error (B)\n");
return EXIT_FAILURE;
}
status = cublasFree(CC);
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! memory free error (C)\n");
return EXIT_FAILURE;
}
/* Shutdown */
status = cublasShutdown();
if (status != CUBLAS_STATUS_SUCCESS) {
fprintf (stderr, "!!!! shutdown error (A)\n");
return EXIT_FAILURE;
}
if (argc > 1) {
if (!strcmp(argv[1], "-noprompt") ||!strcmp(argv[1], "-qatest"))
{
return EXIT_SUCCESS;
}
}
else
{
printf("\nPress ENTER to exit...\n");
getchar();
}
return EXIT_SUCCESS;
}
어떤 생각이 들었습니까? 또한, 누군가가 CUBLAS에서 작동하는 매트릭스 곱셈 구현을 가지고 있으므로 비교할 수 있습니까? 미리 감사드립니다.
+1 용 cuBLAS'dgemm' 예 :-) – fommil