This function generates a write function for graph entity properties.
The generated lambda function can then be called on each write specification in the adaptor tuple. It writes the specified data to a new dataset and adds attributes, fire-and-forget. Depending on the shape of the write specifications 1d or 2d datasets are written, see Utopia::DataIO::save_graph_entity_properties for more detail. Only relying on the given iterator pair, this function allows to handle vertex and edge iterations equivalently.
139{
140 static_assert(entity_kind == EntityKind::vertex or
141 entity_kind == EntityKind::edge,
142 "Error, 'entity_kind' has to be either 'vertex' or 'edge'");
143
144 return
145 [&g,
146 nw_grp{std::forward<NWGroup>(nw_grp)},
147 label{std::move(label)},
148 it_pair{std::forward<ItPair>(it_pair)},
149 num_entities{std::move(num_entities)}] (auto&& write_spec)
150
151
152 {
153
154 std::string prop_prefix;
155
156 if constexpr (entity_kind == EntityKind::vertex) {
157 prop_prefix = "vertex";
158 }
159 else {
160 prop_prefix = "edge";
161 }
162
163 const auto grp =
164 nw_grp->open_group(std::get<0>(write_spec));
165
166
167
168
169 if constexpr (Utils::is_callable_v<std::tuple_element_t<1,
170 std::decay_t<decltype(write_spec)>>>)
171 {
172 const auto dset = grp->open_dataset(label, { num_entities });
173
174 dset->write(it_pair.first, it_pair.second,
175 [&](auto&& desc) {
176 return std::get<1>(write_spec)(desc, g);
177 }
178 );
179
180 dset->add_attribute("dim_name__0", prop_prefix + "_idx");
181 dset->add_attribute("coords_mode__"s + prop_prefix + "_idx",
182 "trivial");
183 }
184
185
186
187
188
189 else {
190
191 static_assert(Utils::is_string_v<std::tuple_element_t<1,
192 std::decay_t<decltype(write_spec)>>>,
193 "Error, the name of dimension 0 has to be s string");
194
195
196 const auto adaptor_pairs =
tuple_tail(write_spec);
197
198
199
200
201 constexpr auto num_adaptors = std::tuple_size_v<std::decay_t<
202 decltype(adaptor_pairs)>>;
203
204
205 const auto dset = grp->open_dataset(label,
206 {num_adaptors, num_entities});
207
208
209 using WriteSpecT = std::decay_t<decltype(write_spec)>;
210 using FirstTupElementT = std::tuple_element_t<2, WriteSpecT>;
211 using CoordT = std::tuple_element_t<0, FirstTupElementT>;
212
213
214 auto coords = coords_container<CoordT>();
215
216
217
218 auto apply_adaptor = [&](auto&& adaptor_pair){
219
220 dset->write(it_pair.first, it_pair.second,
221 [&](auto&& desc) {
222 return std::get<1>(adaptor_pair)(desc, g);
223 }
224 );
225
226 static_assert(
227
228 std::is_same_v<
229 std::tuple_element_t<0,
230 std::decay_t<decltype(adaptor_pair)>>,
231 CoordT>,
232 "Error, coordinate types do not match! Check that all "
233 "coordinates are of the same type");
234
235 coords.push_back(std::get<0>(adaptor_pair));
236 };
237
238 boost::hana::for_each(adaptor_pairs, apply_adaptor);
239
240
241 const std::string dim0_name = std::get<1>(write_spec);
242
243
244 dset->add_attribute("dim_name__0", dim0_name);
245 dset->add_attribute("coords_mode__"s + dim0_name, "values");
246 dset->add_attribute("coords__"s + dim0_name, coords);
247
248 dset->add_attribute("dim_name__1", prop_prefix + "_idx");
249 dset->add_attribute("coords_mode__"s + prop_prefix + "_idx",
250 "trivial");
251 }
252 };
253}
constexpr std::tuple< Tail... > tuple_tail(const std::tuple< First, Second, Tail... > &t)
Builds new tuple containing all elements but the first two.
Definition graph_utils.hh:81