Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
linalg/cpu/gemm.hpp
Go to the documentation of this file.
1#pragma once
2
13
14#include <concepts>
15#include <type_traits>
16
17namespace uni20::linalg::cpu
18{
19
21template <class OutputMdspan, class Scalar, class LhsMdspan, class RhsMdspan>
25 std::same_as<std::remove_cv_t<typename std::remove_cvref_t<OutputMdspan>::element_type>, Scalar> &&
26 std::same_as<std::remove_cv_t<typename std::remove_cvref_t<LhsMdspan>::element_type>, Scalar> &&
27 std::same_as<std::remove_cv_t<typename std::remove_cvref_t<RhsMdspan>::element_type>, Scalar> &&
28 requires(OutputMdspan& output, LhsMdspan& lhs, RhsMdspan& rhs,
29 typename std::remove_cvref_t<OutputMdspan>::index_type index, Scalar value) {
30 static_cast<Scalar>(output.operator[](index, index));
31 static_cast<Scalar>(lhs.operator[](index, index));
32 static_cast<Scalar>(rhs.operator[](index, index));
33 output.operator[](index, index) = value;
34 value += value * value;
35 { value == Scalar{} } -> std::convertible_to<bool>;
36 };
37
39template <class OutputMdspan, uni20::Scalar Scalar, class LhsMdspan, class RhsMdspan>
41void gemm(OutputMdspan&& output, Scalar alpha, LhsMdspan&& lhs, RhsMdspan&& rhs, Scalar beta)
42{
43 using output_type = std::remove_cvref_t<OutputMdspan>;
44 using index_type = typename output_type::index_type;
45
46 CHECK_EQUAL(lhs.extent(1), rhs.extent(0));
47 CHECK_EQUAL(output.extent(0), lhs.extent(0));
48 CHECK_EQUAL(output.extent(1), rhs.extent(1));
49
50 index_type const rows = static_cast<index_type>(output.extent(0));
51 index_type const cols = static_cast<index_type>(output.extent(1));
52 index_type const inner = static_cast<index_type>(lhs.extent(1));
53
54 if (alpha == Scalar{} || inner == 0)
55 {
56 if (beta == Scalar{1}) return;
57
58 for (index_type row = 0; row < rows; ++row)
59 {
60 for (index_type col = 0; col < cols; ++col)
61 {
62 if (beta == Scalar{})
63 output[row, col] = Scalar{};
64 else
65 output[row, col] = beta * static_cast<Scalar>(output[row, col]);
66 }
67 }
68 return;
69 }
70
71 for (index_type row = 0; row < rows; ++row)
72 {
73 for (index_type col = 0; col < cols; ++col)
74 {
76 for (index_type k = 0; k < inner; ++k)
77 {
78 product += static_cast<Scalar>(lhs[row, k]) * static_cast<Scalar>(rhs[k, col]);
79 }
80
81 if (beta == Scalar{})
82 {
83 output[row, col] = alpha * product;
84 }
85 else
86 {
87 output[row, col] = beta * static_cast<Scalar>(output[row, col]) + alpha * product;
88 }
89 }
90 }
91}
92
93} // namespace uni20::linalg::cpu
A mutable mdspan-like type with a specified static rank.
Definition mdspan/concepts.hpp:494
An mdspan-like type with a specified static rank.
Definition mdspan/concepts.hpp:447
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
Report whether resolved mdspans support reference CPU GEMM expressions.
Definition linalg/cpu/gemm.hpp:22
locale_t value
Definition data_table.cpp:49
Mdspan concept and accessor extensions for Uni20.
T product(std::vector< T > const &values)
Definition mpreal_exact_example.cpp:13
Definition strided_transform.hpp:20
void gemm(OutputMdspan &&output, Scalar alpha, LhsMdspan &&lhs, RhsMdspan &&rhs, Scalar beta)
Execute reference CPU GEMM on resolved mdspans.
Definition linalg/cpu/gemm.hpp:41
std::ptrdiff_t index_type
Definition types.hpp:19
mpreal beta(mpreal const &a, mpreal const &x)
Real Beta function; positive rational/integer pairs retain exact values.
Definition mpreal_special.hpp:164
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309