18int main(
int argc,
char** argv) {
19 Kokkos::initialize(argc, argv);
22 const int ex = 12, ey = 12, ez = 12;
23 const std::size_t n = (std::size_t)ex * ey * ez;
24 const double beta = 0.7, idiag = 3.0;
25 const float u_bc = 0.25f;
30 std::uniform_int_distribution<int> ic(2, 9);
31 std::uniform_real_distribution<float> uc(0.05f, 0.95f), us(-0.95f, -0.05f), uf(0.05f, 0.95f),
33 std::vector<int> cidx;
34 std::vector<float> sc(M);
35 std::vector<float> sn((std::size_t)M * 6);
36 std::vector<char> used(n, 0);
37 for (
int i = 0; i < M;) {
38 int x = ic(rng), y = ic(rng), z = ic(rng);
39 std::size_t c = (std::size_t)x + (std::size_t)y * ex + (std::size_t)z * ex * ey;
43 cidx.push_back((
int)c);
45 bool sw = u01(rng) < 0.3f;
46 for (
int k = 0; k < 6; ++k) {
47 bool solid = (sw && k < 2) || (u01(rng) < 0.5f);
48 sn[(std::size_t)i * 6 + k] = solid ? us(rng) : uf(rng);
53 auto mkF = [&](
const char* nm) {
57 FV AC = mkF(
"AC"), AW = mkF(
"AW"), AE = mkF(
"AE"), AS = mkF(
"AS"), AN = mkF(
"AN"),
58 AB = mkF(
"AB"), AT = mkF(
"AT");
59 DV inhom(
"inhom", n), rscale(
"rscale", n);
60 ibmBuildDiffusion(
AC, AW, AE, AS, AN, AB, AT, ex, ey, ez, beta, idiag);
64 Kokkos::View<int*, IMem>(
"ci", M), Kokkos::View<int*, IMem>(
"nb", M),
65 Kokkos::View<float*, IMem>(
"dr", M), Kokkos::View<int*, IMem>(
"dc", (std::size_t)M * 6),
66 FV(
"K", (std::size_t)M * 6),
FV(
"Mv", (std::size_t)M * 6),
67 FV(
"X", (std::size_t)M * 6),
FV(
"Nbc", (std::size_t)M * 6),
68 FV(
"R", (std::size_t)M * 6)};
69 Kokkos::View<int*, IMem> dci(
"dci", M);
71 auto m = Kokkos::create_mirror_view(dci);
72 for (
int i = 0; i < M; ++i)
74 Kokkos::deep_copy(dci, m);
78 auto m = Kokkos::create_mirror_view(dsc);
79 for (
int i = 0; i < M; ++i)
81 Kokkos::deep_copy(dsc, m);
83 FV dsn(
"dsn", (std::size_t)M * 6);
85 auto m = Kokkos::create_mirror_view(dsn);
86 for (std::size_t i = 0; i < (std::size_t)M * 6; ++i)
88 Kokkos::deep_copy(dsn, m);
91 "bo", Kokkos::RangePolicy<DSpace>(0, M), KOKKOS_LAMBDA(
int i) {
93 for (
int k = 0; k < 6; ++k)
94 s6[k] = dsn((std::size_t)i * 6 + k);
95 ibmFillEntry<0>(ov, i, dci(i), dsc(i), s6, 0);
98 ibmModifyStencil(
AC, AW, AE, AS, AN, AB, AT, inhom, rscale, ov, M, u_bc);
100 auto gf = [&](
FV v) {
101 std::vector<float> o(n);
102 auto m = Kokkos::create_mirror_view(v);
103 Kokkos::deep_copy(m, v);
104 for (std::size_t i = 0; i < n; ++i)
108 auto gd = [&](
DV v) {
109 std::vector<double> o(n);
110 auto m = Kokkos::create_mirror_view(v);
111 Kokkos::deep_copy(m, v);
112 for (std::size_t i = 0; i < n; ++i)
116 auto GAC = gf(
AC), GAW = gf(AW), GAE = gf(AE), GAS = gf(AS), GAN = gf(AN), GAB = gf(AB),
118 auto GIN = gd(inhom), GRS = gd(rscale);
121 std::vector<float> hAC(n), hAW(n), hAE(n), hAS(n), hAN(n), hAB(n), hAT(n);
122 std::vector<double> hin(n, 0), hrs(n, 0);
123 float nb = (float)(-beta), cc = (float)(idiag + 6.0 * beta);
124 for (std::size_t i = 0; i < n; ++i) {
134 HOV h{Kokkos::View<int*, Kokkos::HostSpace>(
"hci", M),
135 Kokkos::View<int*, Kokkos::HostSpace>(
"hnb", M),
136 Kokkos::View<float*, Kokkos::HostSpace>(
"hdr", M),
137 Kokkos::View<int*, Kokkos::HostSpace>(
"hdc", (std::size_t)M * 6),
138 Kokkos::View<float*, Kokkos::HostSpace>(
"hK", (std::size_t)M * 6),
139 Kokkos::View<float*, Kokkos::HostSpace>(
"hM", (std::size_t)M * 6),
140 Kokkos::View<float*, Kokkos::HostSpace>(
"hX", (std::size_t)M * 6),
141 Kokkos::View<float*, Kokkos::HostSpace>(
"hNbc", (std::size_t)M * 6),
142 Kokkos::View<float*, Kokkos::HostSpace>(
"hR", (std::size_t)M * 6)};
143 for (
int i = 0; i < M; ++i) {
145 for (
int k = 0; k < 6; ++k)
146 s6[k] = sn[(std::size_t)i * 6 + k];
147 ibmFillEntry<0>(h, i, cidx[i], sc[i], s6, 0);
149 const int OPP[6] = {1, 0, 3, 2, 5, 4};
150 for (
int li = 0; li < M; ++li) {
151 int c = h.cell_index(li);
152 float descale = h.D_rescale(li);
154 double orig[6] = {hAE[c], hAW[c], hAN[c], hAS[c], hAT[c], hAB[c]};
155 double aC = (double)hAC[c] * (
double)descale;
156 double mod[6] = {0, 0, 0, 0, 0, 0};
158 for (
int k = 0; k < 6; ++k) {
159 float K = h.K_val(li * 6 + k), Mv = h.M_val(li * 6 + k), X = h.X_val(li * 6 + k),
160 Nbc = h.Nbc_val(li * 6 + k);
161 double vnb = orig[k];
163 inh += (double)Nbc * u_bc * vnb;
164 mod[k] += vnb * ((double)descale * Mv - 1.0);
165 mod[OPP[k]] += vnb * X;
168 hAE[c] = (float)(orig[0] + mod[0]);
169 hAW[c] = (float)(orig[1] + mod[1]);
170 hAN[c] = (float)(orig[2] + mod[2]);
171 hAS[c] = (float)(orig[3] + mod[3]);
172 hAT[c] = (float)(orig[4] + mod[4]);
173 hAB[c] = (float)(orig[5] + mod[5]);
180 auto cf = [&](
float a,
float b) {
181 return std::fabs((
double)a - (
double)b) <= 2e-3 * (1.0 + std::fabs((
double)b));
183 auto cd = [&](
double a,
double b) {
return std::fabs(a - b) <= 2e-3 * (1.0 + std::fabs(b)); };
186 auto rel = [&](
double a,
double b) {
187 double r = std::fabs(a - b) / (1.0 + std::fabs(b));
191 for (std::size_t i = 0; i < n; ++i) {
196 if (!cf(GAC[i], hAC[i]) || !cf(GAW[i], hAW[i]) || !cf(GAE[i], hAE[i]) ||
197 !cf(GAS[i], hAS[i]) || !cf(GAN[i], hAN[i]) || !cf(GAB[i], hAB[i]) || !cf(GAT[i], hAT[i]))
199 if (!cd(GIN[i], hin[i]) || !cd(GRS[i], hrs[i]))
203 std::fprintf(stderr,
"FAIL: %d modified-stencil cells differ (max rel diff %.3e)\n", bad,
208 "[ibm_apply] PASS: build+overlay+modify stencil (%d cut cells) matches host (exec: %s)\n",