9{%
for item in NAMESPACE -%}
18void {{gemm}}(
const double* A,
const double* B,
double* C);
20void {{gemm}}(
const float* A,
const float* B,
float* C);
22void {{gemm}}(
const long double* A,
const long double* B,
long double* C);
27{% endif %}{# USE_LIBXSMM #}
29{%
for item in NAMESPACE -%}
33{% macro gemm(gemm_key, A, B, C, A_shift, B_shift, C_shift, true_alpha=
"", true_B=
"", force_coeff_matrix=False) %}
35 C =
alpha * A * B + beta * C
36 (M x N) (
M x K) (K x N)
37 The gemms (fetched through gemm_key)
contains M,
N, K, LDA, LDB, LDC,
alpha and beta
39 String gemm_key :
name of the associated GEMMS
43 String A_shift : shift to the zero of A
44 String B_shift : shift to the zero of B
45 String C_shift : shift to the zero of C
48 String true_B :
true array B, B must
b a true matrix, not
a tensor
slice
49 String true_alpha :
true value of the coefficent
alpha (note: it will be multiplied by the GEMMS
alpha, /!\
sign error)
50 bool force_coeff_matrix : only when using true_B, true_alpha, force the no libxsmm case to also generate the coeff
matrix.
52 If true_B is used,
a temporary array true_alpha*true_B is
generated
55{% set gemms = GEMMS[gemm_key] %}
57{%
if true_B is not defined or true_B ==
"" %}
59 {% set use_true_B =
False %}
61 {% set use_true_B =
True %}
64{%
if force_coeff_matrix is not defined %}
65 {% set force_coeff_matrix =
False %}
68{# set arrays
' name for pragma by removing eventual index #}
69{% set Ap = (A.split("["))[0] %}
70{% set Bp = (B.split("["))[0] %}
71{% set Cp = (C.split("["))[0] %}
72{% set true_Bp = (true_B.split("["))[0] %}
73{% set M = GEMMS[gemm_key].M %}
74{% set N = GEMMS[gemm_key].N %}
75{% set K = GEMMS[gemm_key].K %}
76{% set LDA = GEMMS[gemm_key].LDA %}
77{% set LDB = GEMMS[gemm_key].LDB %}
78{% set LDC = GEMMS[gemm_key].LDC %}
79{% set alpha = GEMMS[gemm_key].alpha %}
80{% set beta = GEMMS[gemm_key].beta %}
82{% set precision = GEMMS[gemm_key].precision[0] %}
83{% if precision == "DP" %}
84 {% set precision_prefix = "d" %}
85 {% set precision_type = "double" %}
86{% elif precision == "SP" %}
87 {% set precision_prefix = "s" %}
88 {% set precision_type = "float" %}
91{% if GEMMS[gemm_key].alignment_A == 1 %}
92 {% set alignment_A = "Aligned" %}
94 {% set alignment_A = "Unaligned" %}
97{% if GEMMS[gemm_key].alignment_C == 1 %}
98 {% set alignment_C = "Aligned" %}
100 {% set alignment_C = "Unaligned" %}
103{% if force_coeff_matrix %}
104 double {{B}}[{{gemms.LDB*gemms.K}}] __attribute__((aligned({{ALIGNMENT}})));
106 #pragma omp simd aligned({{Bp}},{{true_Bp}}:{{ALIGNMENT}})
108 for (int it = 0; it < {{gemms.LDB*gemms.K}}; it++) {
109 {{B}}[it] = {{true_alpha}} * {{true_B}}[it];
114{% if gemms.beta == 0 %}
116 for (int it_1 = 0; it_1 < {{gemms.N}}; it_1++) {
118 #pragma omp simd aligned({{Cp}}:{{ALIGNMENT}})
120 for (int it_3 = 0; it_3 < {{gemms.M}}; it_3++) {
121 {{C}}[{{C_shift}} + it_1 * {{gemms.LDC}} + it_3] = 0.0;
126for (int it_1 = 0; it_1 < {{gemms.N}}; it_1++) {
127 for (int it_2 = 0; it_2 < {{gemms.K}}; it_2++) {
129 #pragma omp simd aligned({{Cp}},{{Ap}},{{true_Bp}}:{{ALIGNMENT}})
131 for (int it_3 = 0; it_3 < {{gemms.M}}; it_3++) {
132 {{C}}[{{C_shift}} + it_1 * {{gemms.LDC}} + it_3] {{ '+
' if gemms.alpha == 1 else '-
' }}= {{A}}[{{A_shift}} + it_2 * {{gemms.LDA}} + it_3]
133 * {% if (use_true_B and not force_coeff_matrix) %}{{true_alpha}} * {% endif %}{{true_B}}[{% if B_shift != '0
' %}{{B_shift}}+{% endif %}it_1 * {{gemms.LDB}} + it_2];
Vector< SizeLhs, Scalar > slice(const Vector< SizeRhs, Scalar > &vector, int fromIndex, int stride=1)
Returns subpart of the vector.
int sign(double value, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
bool contains(const Vector< Size, Scalar > &vector, const Scalar &value)