flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
bench_bottom_factor.cpp
Go to the documentation of this file.
1
15#include <algorithm>
16#include <cmath>
17#include <cstdio>
18#include <cstdlib>
19#include <cstring>
20#include <Kokkos_Core.hpp>
21#include <string>
22#include <type_traits>
23#include <vector>
24
25#include "mac_cutcell_mg.hpp"
26
27using namespace peclet::flow;
28
29namespace {
30
31template <class V>
32std::vector<char> bytes(const V& v) {
33 auto h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), v);
34 const char* p = reinterpret_cast<const char*>(h.data());
35 return std::vector<char>(p, p + h.span() * sizeof(typename V::value_type));
36}
37std::vector<char> storage(const BottomDirect<float>& D) {
38 std::vector<char> out;
39 for (const auto& b : {bytes(D.Q), bytes(D.Y), bytes(D.e), bytes(D.s), bytes(D.stat)})
40 out.insert(out.end(), b.begin(), b.end());
41 return out;
42}
43
44} // namespace
45
46int main(int argc, char** argv) {
47 Kokkos::initialize(argc, argv);
48 {
49 const int reps = argc > 1 ? std::atoi(argv[1]) : 20;
50 const std::string cname = argc > 2 ? argv[2] : "walls-y";
51 const char* dump = (argc > 3 && std::strcmp(argv[3], "-") != 0) ? argv[3] : nullptr;
52 std::vector<int> Ts;
53 for (int a = 4; a < argc; ++a)
54 Ts.push_back(std::atoi(argv[a]));
55 if (Ts.empty())
56 Ts = {1, 2, 4, 8, 16, 24};
57 int bc[6] = {0, 0, 1, 1, 0, 0};
58 if (cname == "periodic")
59 bc[2] = bc[3] = 0;
60 const int nx = 32, ny = 24, nz = 16;
61 CutcellMG mg;
63 mg.init(nx, ny, nz, 2);
65 const C3 e{nx + 2, ny + 2, nz + 2};
66 const std::size_t n = (std::size_t)e.x * e.y * e.z;
67 std::vector<double> hx(n), hy(n), hz(n);
68 const double lr = std::log(50.0), k = 2.0 * M_PI;
69 for (int z = 0; z < e.z; ++z) // test_bottom_direct's openness (ratio 50)
70 for (int y = 0; y < e.y; ++y)
71 for (int x = 0; x < e.x; ++x) {
72 const std::size_t i = x + (std::size_t)y * e.x + (std::size_t)z * e.x * e.y;
73 const double s = 0.5 + 0.5 * std::sin(k * x / nx) * std::cos(k * (y + 0.5 * z) / ny);
74 const double t = 0.5 + 0.5 * std::cos(k * (x + z) / nz);
75 hx[i] = std::exp(lr * s) / 50.0;
76 hy[i] = std::exp(lr * t) / 50.0;
77 hz[i] = std::exp(lr * (1.0 - s)) / 50.0;
78 }
79 auto dev = [](const std::vector<double>& v, const char* name) {
80 CCField f(name, v.size());
81 auto h = Kokkos::create_mirror_view(f);
82 for (std::size_t i = 0; i < v.size(); ++i)
83 h(i) = v[i];
84 Kokkos::deep_copy(f, h);
85 return f;
86 };
87 CCField ox = dev(hx, "ox"), oy = dev(hy, "oy"), oz = dev(hz, "oz");
88 mg.setOpenness(CCConst(ox), CCConst(oy), CCConst(oz), 1.0, 1.0, 1.0);
90 const BottomPlanes pl = mg.directPlanes();
91 printf("bench_bottom_factor %s: P = %d, b = %d, border %d, %d reps, concurrency %d\n",
92 cname.c_str(), pl.P, pl.b, pl.border, reps, (int)CCExec().concurrency());
93 std::vector<char> ref;
94 const bool host = std::is_same_v<CCMem, Kokkos::HostSpace>;
95 for (int alg = 0; alg < (host ? 2 : 1); ++alg)
96 for (int T : Ts) {
97 const bool team = alg == 1; // on a host backend: 0 = the host schedule, 1 = the team one
98 int Tu = 0;
100 if (T != 0 && Tu != T) {
101 printf(" T %3d: not available (ran %d), skipped\n", T, Tu);
102 continue;
103 }
104 for (int w = 0; w < 3; ++w)
105 mg.launchDirectFactor(D, Tu, kBottomPivotTol, /*probe=*/false, team);
106 Kokkos::fence();
107 std::vector<double> ms;
108 for (int r = 0; r < reps; ++r) {
109 Kokkos::Timer tm;
110 mg.launchDirectFactor(D, Tu, kBottomPivotTol, /*probe=*/false, team);
111 Kokkos::fence();
112 ms.push_back(tm.seconds() * 1e3);
113 }
114 std::sort(ms.begin(), ms.end());
115 const std::vector<char> st = storage(D);
116 const char* same = "reference";
117 if (ref.empty()) {
118 ref = st;
119 if (dump) {
120 FILE* f = std::fopen(dump, "wb");
121 std::fwrite(ref.data(), 1, ref.size(), f);
122 std::fclose(f);
123 }
124 } else {
125 same = (st == ref) ? "bitwise identical" : "DIFFERS";
126 }
127 printf(" %s T %3d: factor min %8.3f ms median %8.3f ms max %8.3f ms (%s)\n",
128 host ? (team ? "team" : "host") : "team", Tu, ms.front(), ms[ms.size() / 2],
129 ms.back(), same);
130 }
131 }
132 Kokkos::finalize();
133 return 0;
134}
int launchDirectFactor(const BottomDirect< FR > &D, int team, double tauPiv0, bool probe=true, bool teamAlgorithm=false)
const BottomPlanes & directPlanes() const
void setOpenness(CCConst ox, CCConst oy, CCConst oz, double idx2, double idy2, double idz2)
void setBoundaryConditions(const int bc[6])
void setAgglomerationMode(int mode)
void init(int nx, int ny, int nz, int nLevels)
BottomDirect< FR > directFactorForTest(int team, double tauPiv0=kBottomPivotTol, int *Tused=nullptr, bool teamAlgorithm=false)
int main()
Definition dbg_scene.cpp:13
flow — portable (Kokkos) geometric multigrid for the cut-cell (variable-openness) pressure Poisson.
Kokkos::View< double *, CCMem > CCField
constexpr double kBottomPivotTol
Kokkos::DefaultExecutionSpace CCExec
Kokkos::View< const double *, CCMem > CCConst
int D
Definition tracers.py:128
static bool same(double a, double b)