Peano
Loading...
Searching...
No Matches
Gemms.template.h
Go to the documentation of this file.
1// This file is part of the ExaHyPE2 project. For conditions of distribution and
2// use, please see the copyright notice at www.peano-framework.org
3#pragma once
4
5{% for item in NAMESPACE -%}
6namespace {{ item }} {
7{%- endfor %}
8
9{% if USE_LIBXSMM %}
10
11{% for gemm,precision in GEMM_LIST %}
12{% if precision == "DP" %}
13void {{gemm}}(const double* A, const double* B, double* C);
14{% elif precision == "SP"%}
15void {{gemm}}(const float* A, const float* B, float* C);
16{% else %}
17void {{gemm}}(const long double* A, const long double* B, long double* C);
18{% endif %}
19{% endfor %}
20
21{% endif %}{# USE_LIBXSMM #}
22
23{% for item in NAMESPACE -%}
24}
25{%- endfor %}
26
27{% macro gemm(gemm_key, A, B, C, A_shift, B_shift, C_shift, true_alpha="", true_B="", force_coeff_matrix=False) %}
28{#
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
32
33 String gemm_key : name of the associated GEMMS
34 String A : name of A
35 String B : name of B
36 String C : name of C
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
40
41 optional
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.
45
46 If true_B is used, a temporary array true_alpha*true_B is generated
47#}
48{% with %}
49{% set gemms = GEMMS[gemm_key] %}
50
51{% if true_B is not defined or true_B == "" %}
52 {% set true_B = B %}
53 {% set use_true_B = False %}
54{% else %}
55 {% set use_true_B = True %}
56{% endif %}
57
58{% if force_coeff_matrix is not defined %}
59 {% set force_coeff_matrix = False %}
60{% endif %}
61
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 %}
75
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" %}
83{% endif %}
84
85{% if GEMMS[gemm_key].alignment_A == 1 %}
86 {% set alignment_A = "Aligned" %}
87{% else %}
88 {% set alignment_A = "Unaligned" %}
89{% endif %}
90
91{% if GEMMS[gemm_key].alignment_C == 1 %}
92 {% set alignment_C = "Aligned" %}
93{% else %}
94 {% set alignment_C = "Unaligned" %}
95{% endif %}
96
97{% if USE_LIBXSMM %}
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 %});
99{% else %}
100{% if force_coeff_matrix %}
101 double {{B}}[{{gemms.LDB*gemms.K}}] __attribute__((aligned({{ALIGNMENT}})));
102 #ifdef SharedOMP
103 #pragma omp simd aligned({{Bp}},{{true_Bp}}:{{ALIGNMENT}})
104 #endif
105 for (int it = 0; it < {{gemms.LDB*gemms.K}}; it++) {
106 {{B}}[it] = {{true_alpha}} * {{true_B}}[it];
107 }
108 {% set true_B = B %}
109{% endif %}
110
111{% if gemms.beta == 0 %}
112 // Reset {{C}}
113 for (int it_1 = 0; it_1 < {{gemms.N}}; it_1++) {
114 #ifdef SharedOMP
115 #pragma omp simd aligned({{Cp}}:{{ALIGNMENT}})
116 #endif
117 for (int it_3 = 0; it_3 < {{gemms.M}}; it_3++) {
118 {{C}}[{{C_shift}} + it_1 * {{gemms.LDC}} + it_3] = 0.0;
119 }
120 }
121{% endif %}
122
123for (int it_1 = 0; it_1 < {{gemms.N}}; it_1++) {
124 for (int it_2 = 0; it_2 < {{gemms.K}}; it_2++) {
125 #ifdef SharedOMP
126 #pragma omp simd aligned({{Cp}},{{Ap}},{{true_Bp}}:{{ALIGNMENT}})
127 #endif
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];
131 }
132 }
133}
134{% endif %} {# USE_LIBXSMM #}
135{% endwith %}
136{% endmacro %}
137{#
str precision
Definition LOH.py:12
float M
Definition csv_plot.py:10
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)