libMesh
Loading...
Searching...
No Matches
kokkos_tensor_ops_oracle_fixtures.h
Go to the documentation of this file.
1#ifndef KOKKOS_TENSOR_OPS_ORACLE_FIXTURES_H
2#define KOKKOS_TENSOR_OPS_ORACLE_FIXTURES_H
3
4// Fixtures for the Kokkos tensor-ops oracle tests: input data plus
5// host-side reference implementations. As with the vector oracle, the
6// runners recompute each quantity on the device through Kokkos
7// storage-backed refs and compare against these host references (see
8// kokkos_vector_ops_oracle_fixtures.h for the overall strategy).
9
10#include "libmesh/libmesh.h"
11#include "libmesh/point.h"
12#include "libmesh/tensor_value.h"
13#include "libmesh/type_n_tensor.h"
14#include "libmesh/vector_value.h"
16#include "gpu/kokkos_storage.h"
18
20
21#include <type_traits>
22#include <vector>
23
24namespace libMeshTest
25{
26namespace KokkosTensorOracle
27{
28
29using libMesh::Real;
30
31static constexpr double tol = 2.0e-13;
32
35
36// The make_host_* builders below take up-to-3D data and quietly drop
37// components beyond LIBMESH_DIM, so the same fixtures serve 1D/2D/3D
38// builds.
39
40inline oracle_vector
41make_host_vector(const Real x, const Real y = 0, const Real z = 0)
42{
44 v.zero();
45 v(0) = x;
46#if LIBMESH_DIM > 1
47 v(1) = y;
48#endif
49#if LIBMESH_DIM > 2
50 v(2) = z;
51#endif
52 return v;
53}
54
55inline oracle_tensor
56make_host_tensor(const Real xx,
57 const Real xy = 0,
58 const Real xz = 0,
59 const Real yx = 0,
60 const Real yy = 0,
61 const Real yz = 0,
62 const Real zx = 0,
63 const Real zy = 0,
64 const Real zz = 0)
65{
67 T.zero();
68 T(0, 0) = xx;
69#if LIBMESH_DIM > 1
70 T(0, 1) = xy;
71 T(1, 0) = yx;
72 T(1, 1) = yy;
73#endif
74#if LIBMESH_DIM > 2
75 T(0, 2) = xz;
76 T(1, 2) = yz;
77 T(2, 0) = zx;
78 T(2, 1) = zy;
79 T(2, 2) = zz;
80#endif
81 return T;
82}
83
84// Each case pairs a full tensor with the leading block size its
85// det()/inverse() calls should act on, checking that only the leading
86// dim x dim block participates in those operations. In the cases
87// where dim < LIBMESH_DIM, the trailing rows/columns are nonzero on
88// purpose: they must not leak into a leading-block result.
90{
92 unsigned int dim;
93 const char * name;
94};
95
96static const tensor_dim_case dim_cases[] = {
97 { make_host_tensor(1.7, -0.2, 0.5,
98 0.3, 1.1, -0.4,
99 -0.6, 0.8, 0.9),
100 1,
101 "leading_1d" },
102#if LIBMESH_DIM > 1
103 { make_host_tensor(2.5, -0.75, 0.4,
104 1.2, 1.8, -0.6,
105 -0.3, 0.9, 1.4),
106 2,
107 "leading_2d" },
108#endif
109#if LIBMESH_DIM > 2
110 { make_host_tensor(9.08973348886179e-01, 3.36455579239923e-01, 5.16389236893863e-01,
111 9.44156071777472e-01, 1.35610910092516e-01, 1.49881119060538e-02,
112 1.15988384086146e-01, 6.79845197685518e-03, 3.77028969454745e-01),
113 3,
114 "leading_3d" }
115#endif
116};
117
118inline oracle_tensor
119build_identity_tensor(const unsigned int dim)
120{
122 I.zero();
123 for (unsigned int i = 0; i < dim; ++i)
124 I(i, i) = Real(1);
125 return I;
126}
127
128// Host references for the leading-block determinant and inverse:
129// closed forms for dim 1 and 2, and delegation to the trusted
130// TypeTensor::det()/inverse() for the dim == 3 case - where the gpu/
131// implementations under test use their own closed forms instead.
132
133inline Real
134host_leading_determinant(const oracle_tensor & J, const unsigned int dim)
135{
136 if (dim == 0)
137 return Real(1);
138 if (dim == 1)
139 return J(0, 0);
140 if (dim == 2)
141 return J(0, 0) * J(1, 1) - J(0, 1) * J(1, 0);
142#if LIBMESH_DIM > 2
143 return J.det();
144#else
145 return Real(0);
146#endif
147}
148
149inline oracle_tensor
150host_leading_inverse(const oracle_tensor & J, const unsigned int dim)
151{
152 oracle_tensor inv;
153 inv.zero();
154
155 if (dim == 1)
156 {
157 inv(0, 0) = Real(1) / J(0, 0);
158 return inv;
159 }
160
161 if (dim == 2)
162 {
163 const Real det = host_leading_determinant(J, dim);
164 inv(0, 0) = J(1, 1) / det;
165 inv(0, 1) = -J(0, 1) / det;
166 inv(1, 0) = -J(1, 0) / det;
167 inv(1, 1) = J(0, 0) / det;
168 return inv;
169 }
170
171#if LIBMESH_DIM > 2
172 return oracle_tensor(J.inverse());
173#else
174 return inv;
175#endif
176}
177
178} // namespace KokkosTensorOracle
179} // namespace libMeshTest
180
181#endif
unsigned int dim
TypeTensor< T > inverse() const
LIBMESH_DEVICE_INLINE void zero()
Set all entries of the tensor to 0.
LIBMESH_DEVICE_INLINE void zero()
Set all entries of the vector to 0.
oracle_tensor host_leading_inverse(const oracle_tensor &J, const unsigned int dim)
oracle_vector make_host_vector(const Real x, const Real y=0, const Real z=0)
oracle_tensor make_host_tensor(const Real xx, const Real xy=0, const Real xz=0, const Real yx=0, const Real yy=0, const Real yz=0, const Real zx=0, const Real zy=0, const Real zz=0)
oracle_tensor build_identity_tensor(const unsigned int dim)
Real host_leading_determinant(const oracle_tensor &J, const unsigned int dim)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real