Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
PatchDataToPy.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
21#include <pybind11/numpy.h>
22#include <pybind11/pybind11.h>
23
24namespace shamrock {
25 template<class T>
26 class VecToNumpy;
27
28 template<class T>
29 class VecToNumpy {
30 public:
31 static py::array_t<T> convert(std::vector<T> vec) {
32
33 u32 len = vec.size();
34
35 py::array_t<T> ret({len});
36 auto r = ret.mutable_unchecked();
37
38 for (u32 i = 0; i < len; i++) {
39 r(i) = vec[i];
40 }
41
42 return std::move(ret);
43 }
44 };
45
46 template<class T>
47 class VecToNumpy<sycl::vec<T, 2>> {
48 public:
49 static py::array_t<T> convert(std::vector<sycl::vec<T, 2>> vec) {
50
51 u32 len = vec.size();
52
53 py::array_t<T> ret({len, 2U});
54 auto r = ret.mutable_unchecked();
55
56 for (u32 i = 0; i < len; i++) {
57 r(i, 0) = vec[i].x();
58 r(i, 1) = vec[i].y();
59 }
60 return std::move(ret);
61 }
62 };
63
64 template<class T>
65 class VecToNumpy<sycl::vec<T, 3>> {
66 public:
67 static py::array_t<T> convert(std::vector<sycl::vec<T, 3>> vec) {
68
69 u32 len = vec.size();
70
71 py::array_t<T> ret({len, 3U});
72 auto r = ret.mutable_unchecked();
73
74 for (u32 i = 0; i < len; i++) {
75 r(i, 0) = vec[i].x();
76 r(i, 1) = vec[i].y();
77 r(i, 2) = vec[i].z();
78 }
79 return std::move(ret);
80 }
81 };
82
83 template<class T>
84 class VecToNumpy<sycl::vec<T, 4>> {
85 public:
86 static py::array_t<T> convert(std::vector<sycl::vec<T, 4>> vec) {
87
88 u32 len = vec.size();
89
90 py::array_t<T> ret({len, 4U});
91 auto r = ret.mutable_unchecked();
92
93 for (u32 i = 0; i < len; i++) {
94 r(i, 0) = vec[i].x();
95 r(i, 1) = vec[i].y();
96 r(i, 2) = vec[i].z();
97 r(i, 3) = vec[i].w();
98 }
99 return std::move(ret);
100 }
101 };
102
103 template<class T>
104 class VecToNumpy<sycl::vec<T, 8>> {
105 public:
106 static py::array_t<T> convert(std::vector<sycl::vec<T, 8>> vec) {
107
108 u32 len = vec.size();
109
110 py::array_t<T> ret({len, 8U});
111 auto r = ret.mutable_unchecked();
112
113 for (u32 i = 0; i < len; i++) {
114 r(i, 0) = vec[i].s0();
115 r(i, 1) = vec[i].s1();
116 r(i, 2) = vec[i].s2();
117 r(i, 3) = vec[i].s3();
118 r(i, 4) = vec[i].s4();
119 r(i, 5) = vec[i].s5();
120 r(i, 6) = vec[i].s6();
121 r(i, 7) = vec[i].s7();
122 }
123 return std::move(ret);
124 }
125 };
126
127 template<class T>
128 class VecToNumpy<sycl::vec<T, 16>> {
129 public:
130 static py::array_t<T> convert(std::vector<sycl::vec<T, 16>> vec) {
131
132 u32 len = vec.size();
133
134 py::array_t<T> ret({len, 16U});
135 auto r = ret.mutable_unchecked();
136
137 for (u32 i = 0; i < len; i++) {
138 r(i, 0) = vec[i].s0();
139 r(i, 1) = vec[i].s1();
140 r(i, 2) = vec[i].s2();
141 r(i, 3) = vec[i].s3();
142 r(i, 4) = vec[i].s4();
143 r(i, 5) = vec[i].s5();
144 r(i, 6) = vec[i].s6();
145 r(i, 7) = vec[i].s7();
146 r(i, 8) = vec[i].s8();
147 r(i, 9) = vec[i].s9();
148 r(i, 10) = vec[i].sA();
149 r(i, 11) = vec[i].sB();
150 r(i, 12) = vec[i].sC();
151 r(i, 13) = vec[i].sD();
152 r(i, 14) = vec[i].sE();
153 r(i, 15) = vec[i].sF();
154 }
155
156 return std::move(ret);
157 }
158 };
159
160 template<class T>
161 void append_to_map(
162 std::string key,
163 std::vector<std::reference_wrapper<shamrock::patch::PatchDataLayer>> ref_lst,
164 py::dict &dic_out) {
165
166 std::vector<T> vec;
167
168 auto appender = [&](auto &field) {
169 if (field.get_name() == key) {
170
171 logger::debug_ln("PatchDataToPy", "appending field", key);
172
173 {
174 auto acc = field.get_buf().copy_to_stdvec();
175 u32 len = field.get_val_cnt();
176
177 for (u32 i = 0; i < len; i++) {
178 vec.push_back(acc[i]);
179 }
180 }
181 }
182 };
183
184 for (auto &pdat_ref : ref_lst) {
185 auto &pdat = pdat_ref.get();
186 if (pdat.get_obj_cnt() > 0) {
187 pdat.for_each_field<T>([&](auto &field) {
188 appender(field);
189 });
190 }
191 }
192
193 if (!vec.empty()) {
194 auto arr = VecToNumpy<T>::convert(vec);
195
196 logger::debug_ln("PatchDataToPy", "adding -> ", key);
197
198 if (dic_out.contains(key.c_str())) {
199 throw shambase::make_except_with_loc<std::runtime_error>("the key already exists");
200 } else {
201 dic_out[key.c_str()] = arr;
202 }
203 }
204 }
205
206 template<class T>
207 void append_to_map(
208 std::string key,
209 std::vector<std::unique_ptr<shamrock::patch::PatchDataLayer>> &lst,
210 py::dict &dic_out) {
211
212 std::vector<std::reference_wrapper<shamrock::patch::PatchDataLayer>> ref_lst;
213 for (auto &pdat : lst) {
214 if (pdat) {
215 ref_lst.push_back(*pdat);
216 }
217 }
218
219 append_to_map<T>(key, ref_lst, dic_out);
220 }
221
222 inline py::dict pdat_to_dic(shamrock::patch::PatchDataLayer &pdat) {
223 py::dict dic_out;
224
225 std::reference_wrapper<shamrock::patch::PatchDataLayer> ref_pdat = pdat;
226
227 using namespace shamrock;
228
229 for (auto fname : pdat.pdl().get_field_names()) {
230 append_to_map<f32>(fname, {ref_pdat}, dic_out);
231 append_to_map<f32_2>(fname, {ref_pdat}, dic_out);
232 append_to_map<f32_3>(fname, {ref_pdat}, dic_out);
233 append_to_map<f32_4>(fname, {ref_pdat}, dic_out);
234 append_to_map<f32_8>(fname, {ref_pdat}, dic_out);
235 append_to_map<f32_16>(fname, {ref_pdat}, dic_out);
236 append_to_map<f64>(fname, {ref_pdat}, dic_out);
237 append_to_map<f64_2>(fname, {ref_pdat}, dic_out);
238 append_to_map<f64_3>(fname, {ref_pdat}, dic_out);
239 append_to_map<f64_4>(fname, {ref_pdat}, dic_out);
240 append_to_map<f64_8>(fname, {ref_pdat}, dic_out);
241 append_to_map<f64_16>(fname, {ref_pdat}, dic_out);
242 append_to_map<u32>(fname, {ref_pdat}, dic_out);
243 append_to_map<u64>(fname, {ref_pdat}, dic_out);
244 append_to_map<u32_3>(fname, {ref_pdat}, dic_out);
245 append_to_map<u64_3>(fname, {ref_pdat}, dic_out);
246 append_to_map<i64_3>(fname, {ref_pdat}, dic_out);
247 }
248
249 return dic_out;
250 }
251} // namespace shamrock
std::uint32_t u32
32 bit unsigned integer
PatchDataLayer container class, the layout is described in patchdata_layout.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
namespace for the main framework
Definition __init__.py:1
Pybind11 include and definitions.