Content |
GEMM Macro Kernel
Der Macro Kernel soll für einen gepackten \(m_c \times k_c\) Matrixblock \(\tilde{A}\) und einen gepackten \(k_c \times n_c\) Matrixblock \(\tilde{B}\) das Matrix-Matrix Produkt \(C \leftarrow \beta C + \alpha \; \tilde{A} \cdot \tilde{B}\) berechnen.
Algorithmus
Geht die Folien durch, nehmt Papier und Bleistift...
Aufgabe
Implementiert den Macro-Kernel. Unten gibt es wieder ein Grundgerüst mit einem Mini-Test im Hauptprogramm:
-
Ihr könnt zunächst davon ausgehen, dass dir gepackten Blöcke keine Rand-Blöcke sind. Also die Maximale Größe haben. Im Hauptprogramm wird dgemm_macro_kernel deshlab auch zunächst mit den Konstanten MC, NC und KC aufgerufen.
-
Was wird im Hauptprogramm genau berechnet bzw. getestet?
-
Ihr könnt wieder mit Matlab nachrechnen ob euer Ergebnis stimmt.
-
Verwendet wieder verschiedene Werte für \(\alpha\) und \(\beta\).
#include <stdio.h>
#define M 14
#define K 15
#define N 16
#define MC 8
#define KC 11
#define NC 12
#define MR 4
#define NR 6
double A[M*K];
double B[K*N];
double C[M*N];
double _A[MC*KC];
double _B[KC*NC];
void
initMatrix(int m, int n, double *X, int ldX, int counter)
{
// ... your code here ...
}
void
printMatrix(int m, int n, const double *X, int ldX)
{
// ... your code here ...
}
void
pack_MRxk(int k, const double *A, int incRowA, int incColA, double *buffer)
{
// ... your code here ...
}
void
pack_A(int mc, int kc, const double *A, int incRowA, int incColA,
double *buffer)
{
// ... your code here ...
}
void
pack_kxNR(int k, const double *B, int incRowB, int incColB, double *buffer)
{
// ... your code here ...
}
void
pack_B(int kc, int nc, const double *B, int incRowB, int incColB,
double *buffer)
{
// ... your code here ...
}
void
dgemm_micro_kernel(int kc,
double alpha, const double *A, const double *B,
double beta,
double *C, int incRowC, int incColC)
{
// ... your code here ...
}
void
dgemm_macro_kernel(int mc,
int nc,
int kc,
double alpha,
double beta,
double *C,
int incRowC,
int incColC)
{
// ... your code here ...
}
int
main()
{
int i, j, mc, kc, nc;
initMatrix(M, K, A, M, 1);
initMatrix(K, N, B, K, M*K+1);
printf("A = \n");
printMatrix(M, K, A, M);
printf("B = \n");
printMatrix(K, N, B, K);
pack_A(MC, KC, A, 1, M, _A);
pack_B(KC, NC, B, 1, K, _B);
printf("Buffer: _A = \n");
printMatrix(MR, KC*MC/MR, _A, MR);
printf("Buffer: _B = \n");
printMatrix(NR, KC*NC/NR, _B, NR);
dgemm_macro_kernel(MC, NC, KC, 1.0, _A, _B, 0.0, C, 1, M);
printf("C = \n");
printMatrix(M, N, C, M);
return 0;
}