2017-09-04 6 views
0

Ich versuche Gemm für Matrix-Multiplikation auf Alea GPU verwenden, jedoch gibt dieser Code das falsche Ergebnis.Matrix-Multiplikation mit CuBLAS auf Alea GPU

Gpu gpu = Gpu.Default; 
Blas blas = new Blas(gpu); 

int m=2,n=3; //in dimension and out dimension (output will be mxn matrix) 
int k=4; 

//column major 
float[,] A = new float[4,2] { {100,200},{2,6},{3,7},{4,8} }; //2x4 matrix 
float[,] B = new float[3,4] { {1,4,7,10}, {2,5,8,11}, {3,6,9,12} }; //4x3 matrix 
float[,] C = new float[3,2] { {-1,-1}, {-1,-1}, {-1,-1} }; //2x3 matrix 

var dA = gpu.AllocateDevice<float>(A); 
var dB = gpu.AllocateDevice<float>(B); 
var dC = gpu.AllocateDevice<float>(C); 

blas.Gemm(Operation.N,Operation.N,m,n,k,1f,dA.Ptr,m,dB.Ptr,k,0f,dC.Ptr,m); 

var result = Gpu.Copy2DToHost(dC); 

Dies ist das Ergebnis, das ich bekomme. Es kopiert nur eine Nummer aus der Matrix A. Einige Zahlen in der Matrix C ändern sich nicht gegenüber der Initialisierung.

100 -1 -1 
200 -1 -1 

Gibt es etwas falsch mit dem Code? Bitte helfen Sie.

Ich benutze alea 3.0.3 mit cuda toolkit 8.0.

UPDATE1: Ich habe festgestellt, dass es korrekte Ergebnisse gibt, wenn ich A, B, C-Matrizen zu 1D-Arrays abflachen. Ich möchte jedoch immer noch wissen, was mit 2D-Arrays nicht stimmt.

Antwort

1

Ich habe festgestellt, dass gpu.AllocateDevice für 2D-Array nicht den Platz auf der GPU zuweisen, wie es auf der CPU ist. Der Abstand zwischen den ersten Elementen von 2 aufeinanderfolgenden Spalten (Tonhöhe) ist überraschend groß.

Daher muss der führende Dimensionsparameter geändert werden.

blas.Gemm(Operation.N,Operation.N,m,n,k,1f,dA.Ptr,dA.PitchInElements.ToInt32(),dB.Ptr,dB.PitchInElements.ToInt32(),0f,dC.Ptr,dC.PitchInElements.ToInt32()); 

Jetzt habe ich das richtige Ergebnis. Gibt es jedoch Dokumente, die die Details zeigen, wie die Zuweisung von 2D-Arrays auf GPU wirklich in Alea funktioniert?

Ich kann nur http://www.aleagpu.com/release/3_0_3/api/html/6f0dc687-7191-91ba-6c30-bb379dded567.htm sehen, die keine Erklärung hat.

+0

Höchstwahrscheinlich verwendet es [cudaMallocPitch] (http://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__MEMORY.html#group__CUDART__MEMORY_1g32bd7a39135594788a542ae72217775c). Der Grund für die Tonhöhe ist das Ausrichten von Matrixzeilen mit physikalischen Speicherkanälen für eine bessere Leistung in einigen Kernen. –