Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
HDF5Tools.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7
8#pragma once
9
10#include <fstream>
11#include <iostream>
12#include <sstream>
13#include <vector>
14
15#include <alien/utils/Precomp.h>
16
17namespace Alien
18{
19struct HDF5Base
20{
21 typedef enum
22 {
23 ASCII,
24 HDF5,
25 SMART
26 } eFormatType;
27
28 struct FileNode
29 {
30 FileNode(int _level = 0)
31 : name("")
32 , path_name("")
33 , level(_level)
34#ifdef ALIEN_USE_HDF5
35 , h_id(-1)
36#endif
37#ifdef ALIEN_USE_LIBXML2
38 , x_id(NULL)
39#endif
40 {}
41
42 std::string name;
43 std::string path_name;
44 int level;
45
46#ifdef ALIEN_USE_HDF5
47 hid_t h_id;
48#endif
49#ifdef ALIEN_USE_LIBXML2
50 xmlNodePtr x_id;
51#endif
52 };
53
54 class StandardTypes
55 {
56 public:
57 StandardTypes() {}
58 ~StandardTypes() {}
59
60 public:
61#ifdef ALIEN_USE_HDF5
62 hid_t nativeType(float) const
63 {
64 return H5T_NATIVE_FLOAT;
65 }
66 hid_t nativeType(double) const { return H5T_NATIVE_DOUBLE; }
67 hid_t nativeType(long double) const { return H5T_NATIVE_LDOUBLE; }
68 hid_t nativeType(unsigned int) const { return H5T_NATIVE_UINT; }
69 hid_t nativeType(unsigned long) const { return H5T_NATIVE_ULONG; }
70 hid_t nativeType(unsigned long long) const { return H5T_NATIVE_ULLONG; }
71 hid_t nativeType(int) const { return H5T_NATIVE_INT; }
72 hid_t nativeType(long long) const { return H5T_NATIVE_LLONG; }
73 hid_t nativeType(long) const { return H5T_NATIVE_LONG; }
74 hid_t nativeType(char) const { return H5T_NATIVE_CHAR; }
75 hid_t nativeType(unsigned char) const { return H5T_NATIVE_UCHAR; }
76 hid_t nativeType(signed char) const { return H5T_NATIVE_SCHAR; }
77 hid_t nativeType(unsigned short) const { return H5T_NATIVE_USHORT; }
78 hid_t nativeType(short) const { return H5T_NATIVE_SHORT; }
79// hid_t nativeType(eDataType sd) const;
80#endif
81 std::string type(double) const
82 {
83 return "double";
84 }
85 std::string type(float) const { return "float"; }
86 std::string type(int) const { return "int32"; }
87 std::string type(Int64) const { return "int64"; }
88
89 std::string type(char) const { return "char"; }
90
91 public:
92#ifdef ALIEN_USE_HDF5
93 hid_t m_char_id;
94 hid_t m_uchar_id;
95 hid_t m_int_id;
96 hid_t m_long_id;
97 hid_t m_uint_id;
98 hid_t m_ulong_id;
99 hid_t m_real_id;
100#endif
101 };
102
103 HDF5Base(std::string const& name)
104 : name(name)
105 , xfile_name(name + ".xml")
106 , hfile_name(name + ".h5")
107 , format("ascii")
108 , type(HDF5)
109 {}
110
111 std::string name;
112 std::string xfile_name;
113 std::string hfile_name;
114 std::string format;
115 eFormatType type;
116 StandardTypes m_types;
117#ifdef ALIEN_USE_LIBXML2
118 xmlDocPtr doc;
119#endif
120#ifdef ALIEN_USE_HDF5
121 hid_t hfile;
122#endif
123 std::vector<double> rbuffer;
124 std::vector<Int64> i64buffer;
125 std::vector<int> i32buffer;
126};
127
128struct Exporter : public HDF5Base
129{
130 Exporter(std::string const& name, std::string const& out_format, [[maybe_unsed]] int prec,
131 int smart_size_limit = 4)
132 : HDF5Base(name)
133 , m_smart_size_limit(smart_size_limit)
134 , m_write_xml_hdf(false)
135 {
136 if (out_format.compare("ascii") == 0) {
137 format = "xml";
138 type = ASCII;
139 fout.open(xfile_name.c_str());
140 // fout<<std::fixed<<std::setprecision(prec) ;
141 fout << "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>" << std::endl;
142 }
143 if (out_format.compare("hdf5") == 0) {
144 format = "hdf";
145 type = HDF5;
146 if (m_write_xml_hdf) {
147 fout.open(xfile_name.c_str());
148 // fout<<std::fixed<<std::setprecision(prec) ;
149 fout << "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>" << std::endl;
150 }
151#ifdef ALIEN_USE_HDF5
152 hfile = H5Fcreate(hfile_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
153#else
154 throw FatalErrorException(A_FUNCINFO,
155 "hdf5 format requested while there is no support for hdf5 in Alien");
156#endif
157 }
158 if (out_format.compare("smart") == 0) {
159 format = "smart";
160 type = SMART;
161 fout.open(xfile_name.c_str());
162 // fout<<std::fixed<<std::setprecision(prec) ;
163 fout << "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>" << std::endl;
164#ifdef ALIEN_USE_HDF5
165 hfile = H5Fcreate(hfile_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
166#else
167 throw FatalErrorException(A_FUNCINFO,
168 "smart format requested while there is no support for hdf5 in Alien");
169#endif
170 }
171 }
172 ~Exporter()
173 {
174 if (type == ASCII || m_write_xml_hdf || type == SMART) {
175 fout.close();
176 }
177 if (type == HDF5 || type == SMART) {
178#ifdef ALIEN_USE_HDF5
179 H5Fclose(hfile);
180#endif
181 }
182 }
183
184 // create a node at base (without parent)
185 FileNode createFileNode(const std::string& name, int level = 0)
186 {
187 FileNode node;
188 node.name = name;
189 node.path_name = "/" + name;
190 node.level = level;
191 if (type == ASCII || m_write_xml_hdf || type == SMART) {
192 fout << "<" << name << ">" << std::endl;
193 }
194 if (type == HDF5 || type == SMART) {
195#ifdef ALIEN_USE_HDF5
196 node.h_id =
197 H5Gcreate2(hfile, node.name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
198#endif
199 }
200 return node;
201 }
202
203 FileNode createFileNode(FileNode const& parent, const std::string& name)
204 {
205 FileNode node;
206 node.name = name;
207 node.path_name = parent.path_name + "/" + name;
208 node.level = parent.level + 1;
209 if (type == ASCII || m_write_xml_hdf || type == SMART) {
210 _tab(parent.level);
211 fout << "<" << name << ">" << std::endl;
212 }
213 if (type == HDF5 || type == SMART) {
214#ifdef ALIEN_USE_HDF5
215 node.h_id = H5Gcreate2(
216 parent.h_id, node.name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
217#endif
218 }
219 return node;
220 }
221
222 FileNode createFileNode(
223 FileNode const& parent, std::string name, std::string group_name)
224 {
225 FileNode node;
226 node.name = name;
227 node.path_name = parent.path_name + "/" + name;
228 node.level = parent.level + 1;
229 if (type == ASCII || m_write_xml_hdf || type == SMART) {
230 for (int i = 0; i < parent.level; ++i)
231 fout << "\t";
232 fout << "<" << name << " group-name=\"" << group_name << "\">" << std::endl;
233 }
234 if (type == HDF5 || type == SMART) {
235#ifdef ALIEN_USE_HDF5
236 node.h_id = H5Gcreate2(
237 parent.h_id, node.name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
238#endif
239 }
240 return node;
241 }
242
243 FileNode createFileNode(FileNode const& parent, std::string name, std::string att_name,
244 std::string att_kind, bool is_group = false)
245 {
246 FileNode node;
247 node.name = name;
248 if (is_group)
249 node.path_name = parent.path_name + "/" + name + "_" + att_kind + "_" + att_name;
250 else
251 node.path_name = parent.path_name + "/" + att_name;
252
253 node.level = parent.level + 1;
254 if (type == ASCII || m_write_xml_hdf || type == SMART) {
255 _tab(parent.level);
256 fout << "<" << name << " name=\"" << att_name << "\" kind=\"" << att_kind << "\">"
257 << std::endl;
258 }
259 if (type == HDF5 || type == SMART) {
260#ifdef ALIEN_USE_HDF5
261 node.h_id = H5Gcreate2(
262 parent.h_id, att_name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
263#endif
264 }
265 return node;
266 }
267
268 void closeFileNode(FileNode const& group)
269 {
270 if (type == ASCII || m_write_xml_hdf || type == SMART) {
271 _tab(group.level - 1);
272 fout << "</" << group.name << ">" << std::endl;
273 }
274 if (type == HDF5 || type == SMART) {
275#ifdef ALIEN_USE_HDF5
276 H5Gclose(group.h_id);
277#endif
278 }
279 }
280
281 template <typename ValueT>
282 void write(FileNode const& parent_node, const std::string& node_name, const ValueT& val)
283 {
284 switch (type) {
285 case ASCII: {
286 _tab(parent_node.level);
287 fout << "<" << node_name << " format=\"xml\" type=\"" << m_types.type(ValueT())
288 << "\">" << std::endl;
289 fout << val << std::endl;
290 _tab(parent_node.level);
291 fout << "</" << node_name << ">" << std::endl;
292 } break;
293 case HDF5: {
294 if (m_write_xml_hdf) {
295 _tab(parent_node.level);
296 fout << "<" << node_name << " format=\"hdf\" type=\"" << m_types.type(ValueT())
297 << "\">" << std::endl;
298 _tab(parent_node.level);
299 fout << hfile_name << ":" << parent_node.path_name << "/" << node_name
300 << std::endl;
301 _tab(parent_node.level);
302 fout << "</" << node_name << ">" << std::endl;
303 }
304#ifdef ALIEN_USE_HDF5
305 hsize_t dim = 1;
306 hid_t dataspace_id = H5Screate_simple(1, &dim, NULL);
307 hid_t dataset_id =
308 H5Dcreate2(parent_node.h_id, node_name.c_str(), m_types.nativeType(ValueT()),
309 dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
310 herr_t status = H5Dwrite(
311 dataset_id, m_types.nativeType(ValueT()), H5S_ALL, H5S_ALL, H5P_DEFAULT, &val);
312 if (status)
313 std::cerr << "Error while writing HDF5 data set" << std::endl;
314 H5Dclose(dataset_id);
315 H5Sclose(dataspace_id);
316#endif
317 } break;
318 case SMART: {
319 _tab(parent_node.level);
320 fout << "<" << node_name << " format=\"xml\" type=\"" << m_types.type(ValueT())
321 << "\">" << std::endl;
322 fout << val << std::endl;
323 _tab(parent_node.level);
324 fout << "</" << node_name << ">" << std::endl;
325#ifdef ALIEN_USE_HDF5
326 hsize_t dim = 1;
327 hid_t dataspace_id = H5Screate_simple(1, &dim, NULL);
328 hid_t dataset_id =
329 H5Dcreate2(parent_node.h_id, node_name.c_str(), m_types.nativeType(ValueT()),
330 dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
331 herr_t status = H5Dwrite(
332 dataset_id, m_types.nativeType(ValueT()), H5S_ALL, H5S_ALL, H5P_DEFAULT, &val);
333 if (status)
334 std::cerr << "Error while writing HDF5 data set" << std::endl;
335 H5Dclose(dataset_id);
336 H5Sclose(dataspace_id);
337#endif
338 } break;
339 default:
340 std::cerr << "Unknown output format " << std::endl;
341 break;
342 }
343 }
344
345 template <typename ValueT>
346 void write(FileNode const& parent_node, const std::string& node_name,
347 std::vector<ValueT>& buffer, int nb_elems_per_line = 1)
348 {
349 switch (type) {
350 case ASCII: {
351 _tab(parent_node.level);
352 fout << "<" << node_name << " format=\"xml\" type=\"" << m_types.type(ValueT())
353 << "\">" << std::endl;
354
355 int icount = 0;
356 for (std::size_t n = 0; n < buffer.size() / nb_elems_per_line; ++n) {
357 for (int k = 0; k < nb_elems_per_line; ++k)
358 fout << buffer[icount + k] << " ";
359 icount += nb_elems_per_line;
360 fout << std::endl;
361 }
362 _tab(parent_node.level);
363 fout << "</" << node_name << ">" << std::endl;
364 } break;
365 case HDF5: {
366 if (m_write_xml_hdf) {
367 _tab(parent_node.level);
368 fout << "<" << node_name << " format=\"hdf\" type=\"" << m_types.type(ValueT())
369 << "\">" << std::endl;
370 _tab(parent_node.level);
371 fout << hfile_name << ":" << parent_node.path_name << "/" << node_name
372 << std::endl;
373 _tab(parent_node.level);
374 fout << "</" << node_name << ">" << std::endl;
375 }
376#ifdef ALIEN_USE_HDF5
377 hsize_t dim = buffer.size();
378 hid_t dataspace_id = H5Screate_simple(1, &dim, NULL);
379 hid_t dataset_id =
380 H5Dcreate2(parent_node.h_id, node_name.c_str(), m_types.nativeType(ValueT()),
381 dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
382 herr_t status = H5Dwrite(dataset_id, m_types.nativeType(ValueT()), H5S_ALL, H5S_ALL,
383 H5P_DEFAULT, buffer.data());
384 if (status)
385 std::cerr << "Error while writing HDF5 data set" << std::endl;
386 H5Dclose(dataset_id);
387 H5Sclose(dataspace_id);
388#endif
389 } break;
390 case SMART: {
391 if ((int)buffer.size() < m_smart_size_limit) {
392 _tab(parent_node.level);
393 fout << "<" << node_name << " format=\"xml\" type=\"" << m_types.type(ValueT())
394 << "\">" << std::endl;
395
396 int icount = 0;
397 for (std::size_t n = 0; n < buffer.size() / nb_elems_per_line; ++n) {
398 for (int k = 0; k < nb_elems_per_line; ++k)
399 fout << buffer[icount + k] << " ";
400 icount += nb_elems_per_line;
401 fout << std::endl;
402 }
403 _tab(parent_node.level);
404 fout << "</" << node_name << ">" << std::endl;
405 }
406 else {
407 _tab(parent_node.level);
408 fout << "<" << node_name << " format=\"hdf\" type=\"" << m_types.type(ValueT())
409 << "\">" << std::endl;
410 _tab(parent_node.level + 1);
411 fout << hfile_name << ":" << parent_node.path_name << "/" << node_name
412 << std::endl;
413 _tab(parent_node.level);
414 fout << "</" << node_name << ">" << std::endl;
415 }
416#ifdef ALIEN_USE_HDF5
417 hsize_t dim = buffer.size();
418 hid_t dataspace_id = H5Screate_simple(1, &dim, NULL);
419 hid_t dataset_id =
420 H5Dcreate2(parent_node.h_id, node_name.c_str(), m_types.nativeType(ValueT()),
421 dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
422 herr_t status = H5Dwrite(dataset_id, m_types.nativeType(ValueT()), H5S_ALL, H5S_ALL,
423 H5P_DEFAULT, buffer.data());
424 if (status)
425 std::cerr << "Error while writing HDF5 data set" << std::endl;
426 H5Dclose(dataset_id);
427 H5Sclose(dataspace_id);
428#endif
429 } break;
430 default:
431 std::cerr << "Unknown output format " << std::endl;
432 break;
433 }
434 buffer.clear();
435 }
436
437 void write(FileNode const& parent_node, const std::string& node_name,
438 const std::string& buffer)
439 {
440 switch (type) {
441 case ASCII: {
442 _tab(parent_node.level);
443 fout << "<" << node_name << " format=\"xml\" type=\"" << m_types.type(char())
444 << "\">" << std::endl;
445 fout << buffer << std::endl;
446 _tab(parent_node.level);
447 fout << "</" << node_name << ">" << std::endl;
448 } break;
449 case HDF5: {
450 if (m_write_xml_hdf) {
451 _tab(parent_node.level);
452 fout << "<" << node_name << " format=\"hdf\" type=\"" << m_types.type(char())
453 << "\">" << std::endl;
454 _tab(parent_node.level);
455 fout << hfile_name << ":" << parent_node.path_name << std::endl;
456 _tab(parent_node.level);
457 fout << "</" << node_name << ">" << std::endl;
458 }
459#ifdef ALIEN_USE_HDF5
460 hsize_t dim = buffer.size();
461 hid_t dataspace_id = H5Screate_simple(1, &dim, NULL);
462 hid_t dataset_id =
463 H5Dcreate2(parent_node.h_id, node_name.c_str(), m_types.nativeType(char()),
464 dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
465 herr_t status = H5Dwrite(dataset_id, m_types.nativeType(char()), H5S_ALL, H5S_ALL,
466 H5P_DEFAULT, buffer.c_str());
467 if (status)
468 std::cerr << "Error while writing HDF5 data set" << std::endl;
469 H5Dclose(dataset_id);
470 H5Sclose(dataspace_id);
471#endif
472 } break;
473 case SMART: {
474 _tab(parent_node.level);
475 fout << "<" << node_name << " format=\"xml\" type=\"" << m_types.type(char())
476 << "\">" << std::endl;
477 fout << buffer << std::endl;
478 _tab(parent_node.level);
479 fout << "</" << node_name << ">" << std::endl;
480#ifdef ALIEN_USE_HDF5
481 hsize_t dim = buffer.size();
482 hid_t dataspace_id = H5Screate_simple(1, &dim, NULL);
483 hid_t dataset_id =
484 H5Dcreate2(parent_node.h_id, node_name.c_str(), m_types.nativeType(char()),
485 dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
486 herr_t status = H5Dwrite(dataset_id, m_types.nativeType(char()), H5S_ALL, H5S_ALL,
487 H5P_DEFAULT, buffer.data());
488 if (status)
489 std::cerr << "Error while writing HDF5 data set" << std::endl;
490 H5Dclose(dataset_id);
491 H5Sclose(dataspace_id);
492#endif
493 } break;
494 default:
495 std::cerr << "Unknown output format " << std::endl;
496 break;
497 }
498 }
499
500 std::ofstream fout;
501 int m_smart_size_limit;
502 bool m_write_xml_hdf;
503
504 void _tab(const int level)
505 {
506 for (int i = 0; i < level; ++i)
507 fout << "\t";
508 }
509};
510
511struct Importer : public HDF5Base
512{
513
514 Importer(std::string const& name, std::string const& in_format, int prec)
515 : HDF5Base(name)
516 {
517 if (in_format.compare("ascii") == 0) {
518 format = "xml";
519 type = ASCII;
520#ifdef ALIEN_USE_LIBXML2
521 doc = xmlParseFile(xfile_name.c_str());
522 if (doc == NULL) {
523 std::cerr << "Error while parsing XML file : " << xfile_name << std::endl;
524 }
525#else
526 throw FatalErrorException(
527 A_FUNCINFO, "xml format requested while there is no support for xml in Alien");
528#endif
529 }
530 else if (in_format.compare("hdf5") == 0) {
531 format = "hdf";
532 type = HDF5;
533#ifdef ALIEN_USE_HDF5
534 hfile = H5Fopen(hfile_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
535#else
536 throw FatalErrorException(A_FUNCINFO,
537 "hdf5 format requested while there is no support for hdf5 in Alien");
538#endif
539 }
540 else {
541 throw FatalErrorException(
542 A_FUNCINFO, "format requested not supported for read operations");
543 }
544 }
545
546 ~Importer()
547 {
548 switch (type) {
549 case ASCII:
550#ifdef ALIEN_USE_LIBXML2
551 xmlFreeDoc(doc);
552#endif
553 break;
554 case HDF5: {
555#ifdef ALIEN_USE_HDF5
556 H5Fclose(hfile);
557#endif
558 } break;
559 default:
560 break;
561 }
562 }
563
564 // open a file node with no parent
565 FileNode openFileNode(const std::string& node_name)
566 {
567 FileNode node;
568
569 switch (type) {
570 case ASCII:
571#ifdef ALIEN_USE_LIBXML2
572 node.x_id = xmlDocGetRootElement(doc);
573 if (xmlStrcmp(node.x_id->name, (const xmlChar*)node_name.c_str())) {
574 throw FatalErrorException(A_FUNCINFO, "node not found");
575 }
576#endif
577 break;
578 case HDF5:
579#ifdef ALIEN_USE_HDF5
580 node.h_id = H5Gopen2(hfile, node.name.c_str(), H5P_DEFAULT);
581#endif
582 break;
583 default:
584 throw FatalErrorException(
585 A_FUNCINFO, "format requested not supported for read operations");
586 break;
587 }
588 return node;
589 }
590
591 FileNode openFileNode(FileNode const& parent, const std::string& name)
592 {
593 FileNode node;
594 node.name = name;
595 node.path_name = parent.path_name + "/" + name;
596 node.level = parent.level + 1;
597 switch (type) {
598 case ASCII: {
599#ifdef ALIEN_USE_LIBXML2
600 xmlNodePtr cur = parent.x_id->xmlChildrenNode;
601 while (cur != NULL) {
602 if ((!xmlStrcmp(cur->name, (const xmlChar*)name.c_str()))) {
603 node.x_id = cur;
604 break;
605 }
606 cur = cur->next;
607 }
608// TODO: manage error when name not found
609#endif
610 } break;
611 case HDF5: {
612#ifdef ALIEN_USE_HDF5
613 /* Open an existing dataset. */
614 node.h_id = H5Gopen2(parent.h_id, node.name.c_str(), H5P_DEFAULT);
615// TODO: manage error when name not found
616#endif
617 } break;
618 default:
619 throw FatalErrorException(
620 A_FUNCINFO, "format requested not supported for read operations");
621 break;
622 }
623 return node;
624 }
625
626 void closeFileNode(FileNode const& group)
627 {
628 switch (type) {
629 case ASCII: {
630 // xmlFree(group.x_id) ;
631 } break;
632 case HDF5: {
633#ifdef ALIEN_USE_HDF5
634 H5Gclose(group.h_id);
635#endif
636 } break;
637 default:
638 throw FatalErrorException(
639 A_FUNCINFO, "format requested not supported for read operations");
640 break;
641 }
642 }
643
644 template <typename ValueT>
645 void read(FileNode const& parent_node, const std::string& node_name,
646 std::vector<ValueT>& buffer)
647 {
648 switch (type) {
649 case ASCII: {
650#ifdef ALIEN_USE_LIBXML2
651 FileNode node;
652
653 xmlNodePtr cur = parent_node.x_id->xmlChildrenNode;
654 while (cur != nullptr) {
655 if ((!xmlStrcmp(cur->name, (const xmlChar*)node_name.c_str()))) {
656 node.x_id = cur;
657 break;
658 }
659 cur = cur->next;
660 }
661 // TODO: handle when not found
662
663 xmlChar* contenu = xmlNodeGetContent(node.x_id);
664 // printf("%s\n",contenu);
665 std::stringstream flux;
666 flux << (const xmlChar*)contenu;
667 for (std::size_t i = 0; i < buffer.size(); ++i)
668 flux >> buffer[i];
669 xmlFree(contenu);
670#endif
671 } break;
672 case HDF5: {
673#ifdef ALIEN_USE_HDF5
674 /* Open an existing dataset. */
675 hid_t dataset_id = H5Dopen2(parent_node.h_id, node_name.c_str(), H5P_DEFAULT);
676 hid_t dataspace_id = H5Dget_space(dataset_id);
677
678 int ndim = H5Sget_simple_extent_ndims(dataspace_id);
679
680 if (ndim != 1) {
681 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
682 }
683 hsize_t size, maxsize;
684 herr_t status = H5Sget_simple_extent_dims(dataspace_id, &size, &maxsize);
685 if (status) {
686 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
687 }
688 if (size != buffer.size()) {
689 // buffer size and data must match
690 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
691 }
692
693 status = H5Dread(dataset_id, m_types.nativeType(ValueT()), H5S_ALL, H5S_ALL,
694 H5P_DEFAULT, buffer.data());
695 if (status)
696 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 node");
697
698 H5Sclose(dataspace_id);
699 H5Dclose(dataset_id);
700#endif
701 } break;
702 default:
703 throw FatalErrorException(A_FUNCINFO, "Unknown input format ");
704 break;
705 }
706 }
707
708 template <typename ValueT>
709 void read(FileNode const& parent_node, const std::string& node_name, ValueT& val)
710 {
711 switch (type) {
712 case ASCII: {
713#ifdef ALIEN_USE_LIBXML2
714 FileNode node;
715
716 xmlNodePtr cur = parent_node.x_id->xmlChildrenNode;
717 while (cur != nullptr) {
718 if ((!xmlStrcmp(cur->name, (const xmlChar*)node_name.c_str()))) {
719 node.x_id = cur;
720 break;
721 }
722 cur = cur->next;
723 }
724 // TODO: handle when not found
725
726 xmlChar* contenu = xmlNodeGetContent(node.x_id);
727 // printf("%s\n",contenu);
728 std::stringstream flux;
729 flux << (const xmlChar*)contenu;
730 flux >> val;
731 xmlFree(contenu);
732#endif
733 } break;
734 case HDF5: {
735#ifdef ALIEN_USE_HDF5
736 /* Open an existing dataset. */
737 hid_t dataset_id = H5Dopen2(parent_node.h_id, node_name.c_str(), H5P_DEFAULT);
738 hid_t dataspace_id = H5Dget_space(dataset_id);
739
740 int ndim = H5Sget_simple_extent_ndims(dataspace_id);
741
742 if (ndim != 1) {
743 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
744 }
745 hsize_t size, maxsize;
746 herr_t status = H5Sget_simple_extent_dims(dataspace_id, &size, &maxsize);
747 if (status) {
748 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
749 }
750 if (size != 1) {
751 // buffer size and data must match
752 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
753 }
754
755 status = H5Dread(
756 dataset_id, m_types.nativeType(ValueT()), H5S_ALL, H5S_ALL, H5P_DEFAULT, &val);
757 if (status)
758 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 node");
759
760 H5Sclose(dataspace_id);
761 H5Dclose(dataset_id);
762#endif
763 } break;
764 default:
765 throw FatalErrorException(A_FUNCINFO, "Unknown input format ");
766 break;
767 }
768 }
769
770 void read(FileNode const& node, std::string& buffer)
771 {
772 switch (type) {
773 case ASCII: {
774#ifdef ALIEN_USE_LIBXML2
775 xmlChar* contenu = xmlNodeGetContent(node.x_id);
776 buffer = std::string((char*)contenu);
777 xmlFree(contenu);
778#endif
779 } break;
780 case HDF5: {
781#ifdef ALIEN_USE_HDF5
782 /* Open an existing dataset. */
783 hid_t dataset_id = H5Dopen2(node.h_id, "data", H5P_DEFAULT);
784 hid_t dataspace_id = H5Dget_space(dataset_id);
785 int ndim = H5Sget_simple_extent_ndims(dataspace_id);
786
787 if (ndim != 1) {
788 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
789 }
790
791 hsize_t size, maxsize;
792 herr_t status = H5Sget_simple_extent_dims(dataspace_id, &size, &maxsize);
793 if (status) {
794 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
795 }
796 // resize String to size
797 buffer.reserve(size + 1);
798 buffer.resize(size + 1);
799 buffer[size] = '\0';
800 status = H5Dread(dataset_id, m_types.nativeType(char()), H5S_ALL, H5S_ALL,
801 H5P_DEFAULT, &buffer[0]);
802 if (status) {
803 throw FatalErrorException(A_FUNCINFO, "Error while reading HDF5 data set");
804 }
805
806 status = H5Sclose(dataspace_id);
807 status = H5Dclose(dataset_id);
808#endif
809 } break;
810 default:
811 std::cerr << "Unknown output format " << std::endl;
812 break;
813 }
814 }
815};
816
817} // namespace Alien
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17