Skip to content

Commit 5b0df51

Browse files
committed
Fix Issue #179
1 parent d7b4789 commit 5b0df51

12 files changed

Lines changed: 601 additions & 1 deletion

docs/web/functions.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ Multi-component values can be stored:
197197
+-----------++-----------++---------++-----------+------+-----------++-----------++---------++-----------+
198198
~~~~
199199

200+
Non interleaved storage allows coalescent memory accesses, which may be
201+
beneficial on some architectures, including GPUs.
202+
200203
In a element-major pattern, values usually are stored as follows:
201204

202205
~~~~
@@ -274,3 +277,39 @@ The `FunctionView` class has two template parameters:
274277
The `FunctionView` class matches the `FunctionEvaluator` concept (See
275278
Section @sec:mgis:function:overview and [this page](evaluators.html) for
276279
details).
280+
281+
## Tensorial functions
282+
283+
### The `TensorView` class
284+
285+
The `TensorView` class allows to make views which returns tensorial
286+
objects from functions returning data in contiguous memory.
287+
288+
A `TensorView` is generally created by combining a `FunctionView` which
289+
a modifier such as `as_stensor` (See [this page](evaluators.html) for
290+
details).
291+
292+
### The `CoalescedMemoryAccessTensorView` class
293+
294+
Coalescent memory access refers to an access pattern where each
295+
components of a function is accessed through its dedicated memory
296+
location (see the non-interleaved storage pattern described previously).
297+
298+
The `CoalescedMemoryAccessTensorView` class allows to make a tensorial
299+
function view from scalar function view on each components, as follows:
300+
301+
~~~~{.cxx}
302+
real values[8] = {1, 10, // components XX
303+
2, 20, // components YY
304+
3, 30, // components ZZ
305+
4, 40}; // components XY
306+
const auto ne = size_type { 2 };
307+
auto space = BasicLinearSpace{ne};
308+
auto c_xx = ScalarFunctionView{space, std::span{values, ne}};
309+
auto c_yy = ScalarFunctionView{space, std::span{values + ne, ne}};
310+
auto c_zz = ScalarFunctionView{space, std::span{values + 2 * ne, ne}};
311+
auto c_xy = ScalarFunctionView{space, std::span{values + 3 * ne, ne}};
312+
auto f = CoalescedMemoryAccessTensorView<BasicLinearSpace,
313+
tfel::math::stensor<2, real>>{
314+
std::array{c_xx, c_yy, c_zz, c_xy}};
315+
~~~~

include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,6 @@ if(enable-mgis-function)
8484
mgis_header(MGIS/Function/Tensors TensorModifier.ixx)
8585
mgis_header(MGIS/Function Mechanics.hxx)
8686
mgis_header(MGIS/Function Mechanics.ixx)
87+
mgis_header(MGIS/Function CoalescedMemoryAccessFunctionViewBase.hxx)
88+
mgis_header(MGIS/Function CoalescedMemoryAccessFunctionViewBase.ixx)
8789
endif(enable-mgis-function)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*!
2+
* \file MGIS/Function/CoalescedMemoryAccessFunctionViewBase.hxx
3+
* \brief
4+
* \author Thomas Helfer
5+
* \date 26/10/2025
6+
* \copyright (C) Copyright Thomas Helfer 2018.
7+
* Use, modification and distribution are subject
8+
* to one of the following licences:
9+
* - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
10+
* file LGPL-3.0.txt)
11+
* - CECILL-C, Version 1.0 (See accompanying files
12+
* CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
13+
*/
14+
15+
#ifndef LIB_MGIS_FUNCTION_COALESCEDMEMORYACCESSFUNCTIONVIEWBASE_HXX
16+
#define LIB_MGIS_FUNCTION_COALESCEDMEMORYACCESSFUNCTIONVIEWBASE_HXX
17+
18+
#include <span>
19+
#include <array>
20+
#include "MGIS/Config.hxx"
21+
#include "MGIS/Contract.hxx"
22+
#include "MGIS/Function/SpaceConcept.hxx"
23+
#include "MGIS/Function/FunctionConcept.hxx"
24+
#include "MGIS/Function/Function.hxx"
25+
#include "MGIS/Function/Evaluator.hxx"
26+
27+
namespace mgis::function {
28+
29+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable = true>
30+
requires(N > 0) struct CoalescedMemoryAccessFunctionViewBase
31+
: private PreconditionsChecker<
32+
CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>> {
33+
//
34+
using MutableValues = std::array<real*, N>;
35+
//
36+
using ConstValues = std::array<const real*, N>;
37+
38+
//! \brief type of the function view associated with a single component
39+
using ScalarComponentFunctionView =
40+
FunctionView<Space,
41+
FunctionDataLayoutDescription{.data_size = 1,
42+
.data_stride = 1},
43+
is_mutable>;
44+
/*!
45+
* \brief check that the preconditions to build the view are met
46+
* \param[in] eh: error handler.
47+
* \param[in] components: components
48+
*/
49+
[[nodiscard]] static constexpr bool checkPreconditions(
50+
AbstractErrorHandler&,
51+
const std::array<ScalarComponentFunctionView, N>&);
52+
/*!
53+
* \param[in] components: components
54+
*/
55+
constexpr CoalescedMemoryAccessFunctionViewBase(
56+
const std::array<ScalarComponentFunctionView, N>&);
57+
/*!
58+
* \param[in] components: components
59+
*/
60+
template <bool doPreconditionsCheck>
61+
constexpr CoalescedMemoryAccessFunctionViewBase(
62+
const PreconditionsCheck<doPreconditionsCheck>&,
63+
const std::array<ScalarComponentFunctionView, N>&);
64+
/*!
65+
* \return the data associated with an integration point
66+
* \param[in] o: offset associated with the integration point
67+
*/
68+
[[nodiscard]] constexpr MutableValues
69+
getValuesPointers(const size_type) requires(
70+
is_mutable&& LinearElementSpaceConcept<Space> &&
71+
(!hasElementWorkspace<Space>));
72+
/*!
73+
* \return the data associated with an integration point
74+
* \param[in] e: element index
75+
* \param[in] i: quadrature point index
76+
*/
77+
[[nodiscard]] constexpr MutableValues
78+
getValuesPointers(const size_type, const size_type) requires(
79+
is_mutable&& LinearQuadratureSpaceConcept<Space> &&
80+
(!hasCellWorkspace<Space>));
81+
/*!
82+
* \return the data associated with an integration point
83+
* \param[in] o: offset associated with the integration point
84+
*/
85+
[[nodiscard]] constexpr ConstValues getValuesPointers(const size_type) const
86+
requires(LinearElementSpaceConcept<Space> &&
87+
(!hasElementWorkspace<Space>));
88+
/*!
89+
* \return the data associated with an integration point
90+
* \param[in] e: element index
91+
* \param[in] i: quadrature point index
92+
*/
93+
[[nodiscard]] constexpr ConstValues getValuesPointers(const size_type,
94+
const size_type) const
95+
requires(LinearQuadratureSpaceConcept<Space> &&
96+
(!hasCellWorkspace<Space>));
97+
98+
private:
99+
//!
100+
std::array<ScalarComponentFunctionView, N> function_components;
101+
};
102+
103+
} // namespace mgis::function
104+
105+
#include "MGIS/Function/CoalescedMemoryAccessFunctionViewBase.ixx"
106+
107+
#endif /* LIB_MGIS_FUNCTION_COALESCEDMEMORYACCESSFUNCTIONVIEWBASE_HXX */
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*!
2+
* \file MGIS/Function/CoalescedMemoryAccessFunctionViewBase.ixx
3+
* \brief
4+
* \author Thomas Helfer
5+
* \date 26/10/2025
6+
* \copyright (C) Copyright Thomas Helfer 2018.
7+
* Use, modification and distribution are subject
8+
* to one of the following licences:
9+
* - GNU Lesser General Public License (LGPL), Version 3.0. (See accompanying
10+
* file LGPL-3.0.txt)
11+
* - CECILL-C, Version 1.0 (See accompanying files
12+
* CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt).
13+
*/
14+
15+
#ifndef LIB_MGIS_FUNCTION_COALESCEDMEMORYACCESSFUNCTIONVIEWBASE_IXX
16+
#define LIB_MGIS_FUNCTION_COALESCEDMEMORYACCESSFUNCTIONVIEWBASE_IXX
17+
18+
namespace mgis::function {
19+
20+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable>
21+
requires(N > 0) //
22+
constexpr bool CoalescedMemoryAccessFunctionViewBase<Space,
23+
N,
24+
is_mutable>::
25+
checkPreconditions(
26+
AbstractErrorHandler& eh,
27+
const std::array<ScalarComponentFunctionView, N>& components) {
28+
for (int i = 1; i != N; ++i) {
29+
if (!areEquivalent(getSpace(components[0]), getSpace(components[1]))) {
30+
return eh.registerErrorMessage("unmatched spaces");
31+
}
32+
}
33+
for (const auto& c : components) {
34+
if (!check(eh, c)) {
35+
return false;
36+
}
37+
}
38+
return true;
39+
} // end of checkPreconditions
40+
41+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable>
42+
requires(N > 0) //
43+
constexpr CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
44+
CoalescedMemoryAccessFunctionViewBase(
45+
const std::array<ScalarComponentFunctionView, N>& components)
46+
: CoalescedMemoryAccessFunctionViewBase(preconditions_check, components) {
47+
} // end of CoalescedMemoryAccessFunctionViewBase
48+
49+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable>
50+
requires(N > 0) //
51+
template <bool doPreconditionsCheck>
52+
constexpr CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
53+
CoalescedMemoryAccessFunctionViewBase(
54+
const PreconditionsCheck<doPreconditionsCheck>& pcheck,
55+
const std::array<ScalarComponentFunctionView, N>& components)
56+
: PreconditionsChecker<CoalescedMemoryAccessFunctionViewBase>(pcheck,
57+
components),
58+
function_components(components) {
59+
} // end of CoalescedMemoryAccessFunctionViewBase
60+
61+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable>
62+
requires(N > 0) //
63+
constexpr
64+
typename CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
65+
MutableValues
66+
CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
67+
getValuesPointers(const size_type i) requires(
68+
is_mutable&& LinearElementSpaceConcept<Space> &&
69+
(!hasElementWorkspace<Space>)) {
70+
return [ this, i ]<std::size_t... Is>(std::index_sequence<Is...>)
71+
->std::array<real*, N> {
72+
return {&this->function_components[Is](i)...};
73+
}
74+
(std::make_index_sequence<N>());
75+
} // end of getValuesPointers
76+
77+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable>
78+
requires(N > 0) //
79+
constexpr
80+
typename CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
81+
MutableValues
82+
CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
83+
getValuesPointers(const size_type e,
84+
const size_type q) //
85+
requires(is_mutable&& LinearQuadratureSpaceConcept<Space> &&
86+
(!hasCellWorkspace<Space>)) {
87+
return [ this, e, q ]<std::size_t... Is>(std::index_sequence<Is...>)
88+
->std::array<real*, N> {
89+
return {&this->function_components[Is](e, q)...};
90+
}
91+
(std::make_index_sequence<N>());
92+
} // end of getValuesPointers
93+
94+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable>
95+
requires(N > 0) //
96+
constexpr
97+
typename CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
98+
ConstValues
99+
CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
100+
getValuesPointers(const size_type i) const //
101+
requires(LinearElementSpaceConcept<Space> &&
102+
(!hasElementWorkspace<Space>)) {
103+
return [ this, i ]<std::size_t... Is>(std::index_sequence<Is...>)
104+
->std::array<const real*, N> {
105+
return {&this->function_components[Is](i)...};
106+
}
107+
(std::make_index_sequence<N>());
108+
} // end of getValuesPointers
109+
110+
template <FunctionalSpaceConcept Space, size_type N, bool is_mutable>
111+
requires(N > 0) //
112+
constexpr
113+
typename CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
114+
ConstValues
115+
CoalescedMemoryAccessFunctionViewBase<Space, N, is_mutable>::
116+
getValuesPointers(const size_type e, const size_type q) const //
117+
requires(LinearQuadratureSpaceConcept<Space> &&
118+
(!hasCellWorkspace<Space>)) {
119+
return [ this, e, q ]<std::size_t... Is>(std::index_sequence<Is...>)
120+
->std::array<real*, N> {
121+
return {&this->function_components[Is](e, q)...};
122+
}
123+
(std::make_index_sequence<N>());
124+
} // end of getValuesPointers
125+
126+
} // end of namespace mgis::function
127+
128+
#endif /* LIB_MGIS_FUNCTION_COALESCEDMEMORYACCESSFUNCTIONVIEWBASE_IXX */

include/MGIS/Function/Function.hxx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ namespace mgis::function {
147147
FunctionDataLayoutDescription layout =
148148
FunctionDataLayoutDescription{},
149149
bool is_mutable = true>
150-
//
151150
struct FunctionView
152151
: private PreconditionsChecker<FunctionView<Space, layout, is_mutable>>,
153152
public FunctionDataLayout<layout> {

include/MGIS/Function/Tensors.hxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "MGIS/Function/Tensors/TensorConcept.hxx"
2525
#include "MGIS/Function/Tensors/TensorView.hxx"
2626
#include "MGIS/Function/Tensors/TensorModifier.hxx"
27+
#include "MGIS/Function/Tensors/CoalescedMemoryAccessTensorView.hxx"
2728

2829
namespace mgis::function::internals {
2930

0 commit comments

Comments
 (0)