Forum: PC-Programmierung OpenCL Matrix-Vektor-Multiplikation


von Rüdiger Knörig (Gast)


Lesenswert?

Zum Erlernen von OpenCL habe ich mir eine Vektor-Matrix-Multiplikation 
geschrieben, bei der ich mir aber nicht sicher bin, inwieweit die 
dahinterstehenden Überlegungen richtig sind.

Prinzipiell verstehe ich Workgroups so, daß mit diesen das Gesamtproblem 
in von dem jeweiligen Gerät gleichzeitig ausführbare Häppchen zerlegt 
wird.

Deshalb habe ich die elementweise Zeilenvektor/Vektormultiplikation 
durch je eine Workgroup ausführen lassen, wobei erst einmal die erste 
Einheit der Workgroup den Produktvektor aufsummiert.

Somit wäre die "Global Size" die Größe der Matrix und die "Local Size" 
die Anzahl der Zeilenvektoren / Produktvektorgröße.

Kann ich generell (bei mir funktioniert das) den Kernel dann so 
parameterisieren:
1
 cl::NDRange globalSize(A.getNumberOfRows()*A.getNumberOfColumns());
2
 cl::NDRange localSize(A.getNumberOfColumns());
3
 rcpp::KernelFunctor vektorSquareFunc(matrixMultiplicationKernel,queue,globalSize,localSize);
4
        vektorSquareFunc(cl::Buffer(A),
5
                         cl::Buffer(x),
6
                         cl::Buffer(y),
7
                         A.getNumberOfRows(),
8
                         A.getNumberOfColumns(),
9
                         rcpp::KernelFunctor::createLocalMemoryBuffer<double>(A.getNumberOfColumns()),
10
                         rcpp::KernelFunctor::createLocalMemoryBuffer<double>(A.getNumberOfColumns()));

Den Kernel selbst habe ich so geschrieben, wobei mich momentan der 
Verdacht überkommt, daß das "Cachen" des Produktvektors in einen lokalen 
Puffer unnötig ist - es sei denn, die physische Arbeitsgruppe wird 
wieder rangenommen:
1
/**
2
 * @brief Matrix multiplication kernel.
3
 * @param A The matrix as concencated row vectors.
4
 * @param x Multiplicant vector (size: number of columns in A)
5
 * @param y Result vector A*x (size: number of rows in A)
6
 * @param nRows Number of rows in the matrix.
7
 * @param nCols Number of columns in the matrix.
8
 * @param xbuffer Local memory buffer for the multiplicant vector.
9
 */
10
11
 
12
13
__kernel void matrixMultiplication(__global double *A,__global double *x,__global double *y,unsigned int nRows,unsigned int nCols,__local double *xbuffer,__local double *resultBuffer)
14
{
15
    int column=get_local_id(0); // equals the column number
16
    int row=get_group_id(0); // fetch the workgroup number - should be the row number
17
    int globalID=get_global_id(0);
18
19
    xbuffer[column]=x[column];
20
21
    barrier(CLK_LOCAL_MEM_FENCE);
22
23
    resultBuffer[column]=xbuffer[column]*A[globalID];
24
25
    barrier(CLK_LOCAL_MEM_FENCE);
26
27
    double sum=0;
28
29
    if(column==0)
30
    {
31
        for(int k=0;k<nCols;k++) sum += resultBuffer[k];
32
        y[row]=sum;
33
    }
34
35
}

von Olga (Gast)


Lesenswert?

Hm, welche obskure Verschwörungstheorie möchtest du denn damit beweisen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.