5{%
for item in NAMESPACE -%}
13void {{gemm}}(
const double* A,
const double* B,
double* C);
15void {{gemm}}(
const float* A,
const float* B,
float* C);
17void {{gemm}}(
const long double* A,
const long double* B,
long double* C);
21{% endif %}{# USE_LIBXSMM #}
23{%
for item in NAMESPACE -%}
27{% macro gemm(gemm_key, A, B, C, A_shift, B_shift, C_shift, true_alpha=
"", true_B=
"", force_coeff_matrix=False) %}
29 C =
alpha * A * B + beta * C
30 (M x N) (
M x K) (K x N)
31 The gemms (fetched through gemm_key)
contains M,
N, K, LDA, LDB, LDC,
alpha and beta
33 String gemm_key :
name of the associated GEMMS
37 String A_shift : shift to the zero of A
38 String B_shift : shift to the zero of B
39 String C_shift : shift to the zero of C
42 String true_B :
true array B, B must
b a true matrix, not
a tensor
slice
43 String true_alpha :
true value of the coefficent
alpha (note: it will be multiplied by the GEMMS
alpha, /!\
sign error)
44 bool force_coeff_matrix : only when using true_B, true_alpha, force the no libxsmm case to also generate the coeff
matrix.
46 If true_B is used,
a temporary array true_alpha*true_B is
generated
49{% set gemms = GEMMS[gemm_key] %}
51{%
if true_B is not defined or true_B ==
"" %}
53 {% set use_true_B =
False %}
55 {% set use_true_B =
True %}
58{%
if force_coeff_matrix is not defined %}
59 {% set force_coeff_matrix =
False %}
62{# set arrays
' name for pragma by removing eventual index #}
63{% set Ap = (A.split("["))[0] %}
64{% set Bp = (B.split("["))[0] %}
65{% set Cp = (C.split("["))[0] %}
66{% set true_Bp = (true_B.split("["))[0] %}
67{% set M = GEMMS[gemm_key].M %}
68{% set N = GEMMS[gemm_key].N %}
69{% set K = GEMMS[gemm_key].K %}
70{% set LDA = GEMMS[gemm_key].LDA %}
71{% set LDB = GEMMS[gemm_key].LDB %}
72{% set LDC = GEMMS[gemm_key].LDC %}
73{% set alpha = GEMMS[gemm_key].alpha %}
74{% set beta = GEMMS[gemm_key].beta %}
76{% set precision = GEMMS[gemm_key].precision[0] %}
77{% if precision == "DP" %}
78 {% set precision_prefix = "d" %}
79 {% set precision_type = "double" %}
80{% elif precision == "SP" %}
81 {% set precision_prefix = "s" %}
82 {% set precision_type = "float" %}
85{% if GEMMS[gemm_key].alignment_A == 1 %}
86 {% set alignment_A = "Aligned" %}
88 {% set alignment_A = "Unaligned" %}
91{% if GEMMS[gemm_key].alignment_C == 1 %}
92 {% set alignment_C = "Aligned" %}
94 {% set alignment_C = "Unaligned" %}
98 {{gemms.baseroutinename}}({{A}}{% if A_shift != '0
' %}+{{A_shift}}{% endif %}, {{B}}{% if B_shift != '0
' %}+{{B_shift}}{% endif %}, {{C}}{% if C_shift != '0
' %}+{{C_shift}}{% endif %});
100{% if force_coeff_matrix %}
101 double {{B}}[{{gemms.LDB*gemms.K}}] __attribute__((aligned({{ALIGNMENT}})));
103 #pragma omp simd aligned({{Bp}},{{true_Bp}}:{{ALIGNMENT}})
105 for (int it = 0; it < {{gemms.LDB*gemms.K}}; it++) {
106 {{B}}[it] = {{true_alpha}} * {{true_B}}[it];
111{% if gemms.beta == 0 %}
113 for (int it_1 = 0; it_1 < {{gemms.N}}; it_1++) {
115 #pragma omp simd aligned({{Cp}}:{{ALIGNMENT}})
117 for (int it_3 = 0; it_3 < {{gemms.M}}; it_3++) {
118 {{C}}[{{C_shift}} + it_1 * {{gemms.LDC}} + it_3] = 0.0;
123for (int it_1 = 0; it_1 < {{gemms.N}}; it_1++) {
124 for (int it_2 = 0; it_2 < {{gemms.K}}; it_2++) {
126 #pragma omp simd aligned({{Cp}},{{Ap}},{{true_Bp}}:{{ALIGNMENT}})
128 for (int it_3 = 0; it_3 < {{gemms.M}}; it_3++) {
129 {{C}}[{{C_shift}} + it_1 * {{gemms.LDC}} + it_3] {{ '+
' if gemms.alpha == 1 else '-
' }}= {{A}}[{{A_shift}} + it_2 * {{gemms.LDA}} + it_3]
130 * {% 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];
134{% endif %} {# USE_LIBXSMM #}
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)