Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Hdf5MpiReaderWriter.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* Hdf5MpiReaderWriter.cc (C) 2000-2025 */
9/* */
10/* Lecture/Ecriture au format HDF5. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/String.h"
15#include "arcane/utils/StringBuilder.h"
16#include "arcane/utils/OStringStream.h"
17#include "arcane/utils/ScopedPtr.h"
18#include "arcane/utils/List.h"
19#include "arcane/utils/ITraceMng.h"
20
21#include "arcane/core/Item.h"
22#include "arcane/core/IDataReader.h"
23#include "arcane/core/IDataWriter.h"
24#include "arcane/core/ISubDomain.h"
25#include "arcane/core/StdNum.h"
26#include "arcane/core/IVariable.h"
27#include "arcane/core/CheckpointService.h"
28#include "arcane/core/Directory.h"
29#include "arcane/core/IParallelMng.h"
30#include "arcane/core/ArcaneException.h"
31#include "arcane/core/VerifierService.h"
32#include "arcane/core/IVariableMng.h"
33#include "arcane/core/FactoryService.h"
34#include "arcane/core/IData.h"
35#include "arcane/core/Timer.h"
36#include "arcane/core/ISerializedData.h"
37#include "arcane/core/IIOMng.h"
38#include "arcane/core/IXmlDocumentHolder.h"
39#include "arcane/core/VariableCollection.h"
40#include "arcane/core/internal/SerializeMessage.h"
41#include "arcane/core/SerializeBuffer.h"
42#include "arcane/core/ISerializeMessageList.h"
43
44#include "arcane/hdf5/Hdf5MpiReaderWriter.h"
45
46#include "arcane/hdf5/Hdf5MpiReaderWriter_axl.h"
47
48#include "arcane_packages.h"
49
50#ifdef ARCANE_HAS_PACKAGE_MPI
51#ifndef OMPI_SKIP_MPICXX
52#define OMPI_SKIP_MPICXX
53#endif
54#ifndef MPICH_SKIP_MPICXX
55#define MPICH_SKIP_MPICXX
56#endif
57#include <mpi.h>
58
59//#define ARCANE_TEST_HDF5MPI
60
61// Pour l'instant (1.8.0 beta 2), cela ne fonctionne pas sur tera 10
62// #define ARCANE_TEST_HDF5DIRECT
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
67namespace Arcane
68{
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73using namespace Hdf5Utils;
74
75static herr_t _Hdf5MpiReaderWriterIterateMe(hid_t,const char*,void*);
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
80Hdf5MpiReaderWriter::
81Hdf5MpiReaderWriter(ISubDomain* sd,const String& filename,
82 const String& sub_group_name,Integer fileset_size,
83 eOpenMode open_mode,bool do_verif)
84: TraceAccessor(sd->traceMng())
85, m_sub_domain(sd)
86, m_parallel_mng(sd->parallelMng())
87, m_open_mode(open_mode)
88, m_filename(filename)
89, m_sub_group_name(sub_group_name)
90, m_is_initialized(false)
91, m_io_timer(sd,"Hdf5TimerHd",Timer::TimerReal)
92, m_write_timer(sd,"Hdf5TimerWrite",Timer::TimerReal)
93, m_is_parallel(false)
94, m_my_rank(m_parallel_mng->commRank())
95, m_send_rank(m_my_rank)
96, m_last_recv_rank(m_my_rank)
97, m_fileset_size(fileset_size)
98{
99 ARCANE_UNUSED(do_verif);
100 if (m_fileset_size!=1 && m_parallel_mng->isParallel()){
101 m_is_parallel = true;
102 Integer nb_rank = m_parallel_mng->commSize();
103 if (m_fileset_size==0){
104 m_send_rank = 0;
105 m_last_recv_rank = nb_rank;
106 --m_last_recv_rank;
107 }
108 else{
109 m_send_rank = (m_my_rank / m_fileset_size) * m_fileset_size;
110 m_last_recv_rank = m_send_rank + m_fileset_size;
111 if (m_last_recv_rank>nb_rank)
112 m_last_recv_rank = nb_rank;
113 --m_last_recv_rank;
114 }
115 }
116 sd->traceMng()->info() << " INFOS PARALLEL: my_rank=" << m_my_rank
117 << " send_rank=" << m_send_rank
118 << " last_recv_rank=" << m_last_recv_rank
119 << " filename=" << filename
120 << " fileset_size=" << m_fileset_size;
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126void Hdf5MpiReaderWriter::
127initialize()
128{
129 if (m_is_initialized)
130 return;
131
132 m_is_initialized = true;
133
134 const char* func_name = "Hdf5MpiReaderWriter::initialize()";
135
136 HInit();
137
138 if (m_open_mode==OpenModeRead){
139 m_file_id.openRead(m_filename);
140 m_sub_group_id.recursiveOpen(m_file_id,m_sub_group_name);
141 //m_variable_group_id.open(m_sub_group_id,"Variables");
142 }
143 else{
144 void* arcane_comm = m_sub_domain->parallelMng()->getMPICommunicator();
145 if (!arcane_comm)
146 throw FatalErrorException("No MPI environment available");
147 MPI_Comm mpi_comm = *((MPI_Comm*)arcane_comm);
148 Integer nb_rank = m_parallel_mng->commSize();
149 if (m_fileset_size>1){
150 UniqueArray<int> senders;
151 for( Integer i=0; i<nb_rank; ++i ){
152 Integer modulo = i % m_fileset_size;
153 if (modulo==0){
154 info() << " ADD SENDER n=" << i;
155 senders.add(i);
156 }
157 }
158 MPI_Group all_group;
159 if (MPI_Comm_group(mpi_comm,&all_group)!=MPI_SUCCESS)
160 fatal() << "Error in MPI_Comm_group";
161 MPI_Group writer_group;
162 if (MPI_Group_incl(all_group,senders.size(),senders.data(),&writer_group)!=MPI_SUCCESS)
163 fatal() << "Error in MPI_Group_incl";
164 if (MPI_Comm_create(mpi_comm,writer_group,&mpi_comm)!=MPI_SUCCESS)
165 fatal() << "Error in MPI_Comm_create";
166 }
167
168 // Si ce n'est pas moi qui écrit, n'ouvre pas le fichier
169 if (m_send_rank!=m_my_rank)
170 return;
171 if (m_open_mode==OpenModeTruncate || m_open_mode==OpenModeAppend){
172 hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS);
173 //bool use_gpfs = false;
174 info() << " USE MPI-POSIX";
175 //H5Pset_fapl_mpiposix(plist_id, mpi_comm, true);
176#ifdef H5_HAVE_PARALLEL
177 H5Pset_fapl_mpio(plist_id, mpi_comm, MPI_INFO_NULL); //mpi_info);
178#endif
179
180#ifdef ARCANE_TEST_HDF5DIRECT
181# ifdef H5_HAVE_DIRECT
182 info() << " HAVE DIRECT DRIVER";
183 H5Pset_fapl_direct(plist_id,4096,512,16*1024*1024);
184# endif
185#endif
186 int mdc_nelmts;
187 size_t rdcc_nelmts;
188 size_t rdcc_nbytes;
189 double rdcc_w0;
190 herr_t r = H5Pget_cache(plist_id,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0);
191 info() << " CACHE SIZE r=" << r << " mdc=" << mdc_nelmts
192 << " rdcc=" << rdcc_nelmts << " rdcc_bytes=" << rdcc_nbytes << " w0=" << rdcc_w0;
193 mdc_nelmts *= 10;
194 rdcc_nelmts *= 10;
195 rdcc_nbytes = 10000000;
196 r = H5Pset_cache(plist_id,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0);
197 info() << " SET CACHE SIZE R1=" << r;
198 //r = H5Pset_fapl_stdio(plist_id);
199 //info() << " R2=" << r;
200 hsize_t sieve_buf = (1024 << 12);
201 r = H5Pset_sieve_buf_size(plist_id,sieve_buf);
202 info() << " SIEVE_BUF=" << sieve_buf << " r=" << r;
203 hsize_t small_block_size = 0;
204 r = H5Pget_small_data_block_size(plist_id,&small_block_size);
205 info() << " SMALL BLOCK SIZE=" << small_block_size;
206 small_block_size <<= 10;
207 r = H5Pset_small_data_block_size(plist_id,small_block_size);
208 info() << " SET SMALL BLOCK SIZE s=" << small_block_size << " r=" << r;
209 //hsize_t block_size = 0;
210 //block_size = H5Pget_buffer(plist_id,0,0);
211 //info() << " BLOCK SIZE s=" << block_size;
212 //block_size = 10000000;
213 //herr_t r = H5Pset_buffer(plist_id,block_size,0,0);
214 //info() << " BLOCK SIZE r=" << r << " s=" << block_size;
215 //if (m_parallel_mng->commRank()==0){
216 //herr_t r = H5Pset_fapl_core(plist_id,1000000,1);
217 //else
218 //herr_t r = H5Pset_fapl_core(plist_id,1000000,0);
219 //m_file_id.openTruncate("toto",plist_id);
220 //}
221 //else
222 if (m_open_mode==OpenModeTruncate){
223 info() << " BEGIN OPEN TRUNCATE";
224 m_file_id.openTruncate(m_filename,plist_id);
225 info() << " END OPEN TRUNCATE";
226 }
227 else if (m_open_mode==OpenModeAppend){
228 info() << " BEGIN OPEN ADD";
229 m_file_id.openAppend(m_filename,plist_id);
230 info() << " END OPEN ADD";
231 }
232 }
233 if (m_sub_group_name!="/"){
234 info() << " CHECK CREATE GROUP name=" << m_sub_group_name;
235 //m_sub_group_id.checkDelete(m_file_id,m_sub_group_name);
236 m_sub_group_id.recursiveCreate(m_file_id,m_sub_group_name);
237 info() << " END CHECK CREATE GROUP name=" << m_sub_group_name;
238 }
239 else
240 m_sub_group_id.open(m_file_id,m_sub_group_name);
241 m_variable_group_id.create(m_sub_group_id,"Variables");
242 }
243
244 if (m_file_id.isBad()){
245 OStringStream ostr;
246 ostr() << "Unable to open file <" << m_filename << ">";
247 throw ReaderWriterException(func_name,ostr.str());
248 }
249 if (m_sub_group_id.isBad()){
250 OStringStream ostr;
251 ostr() << "HDF5 group '" << m_sub_group_name << "' not found";
252 throw ReaderWriterException(func_name,ostr.str());
253 }
254#if 0
255 if (m_variable_group_id.isBad()){
256 OStringStream ostr;
257 ostr() << "Group HDF5 'Variables' not found";
258 throw ReaderWriterException(func_name,ostr.str());
259 }
260#endif
261
262 info() << " INFO END INITIALIZE";
263
264
265 if (m_open_mode==OpenModeRead){
266 int index = 0;
267 //H5Giterate(m_sub_group_id.id(),"Variables",&index,_Hdf5MpiReaderWriterIterateMe,this);
268 H5Giterate(m_file_id.id(),m_sub_group_name.localstr(),&index,_Hdf5MpiReaderWriterIterateMe,this);
269 }
270}
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
274
275Hdf5MpiReaderWriter::
276~Hdf5MpiReaderWriter()
277{
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
283void Hdf5MpiReaderWriter::
284_checkValid()
285{
286 if (m_is_initialized)
287 return;
288 fatal() << "Use of a Hdf5MpiReaderWriter instance not initialized";
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294String Hdf5MpiReaderWriter::
295_variableGroupName(IVariable* var)
296{
297 return var->fullName();
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
303void Hdf5MpiReaderWriter::
304beginWrite(const VariableCollection& vars)
305{
306 IParallelMng* pm = m_parallel_mng;
307 Integer nb_rank = pm->commSize();
308
309 pwarning() << "Implementation of this checkpoint format is not operational yet";
310
311 for( VariableCollection::Enumerator i(vars); ++i; ){
312 IVariable* v = *i;
313 if (v->itemKind()==IK_Unknown)
314 continue;
315
316 Ref<ISerializedData> sdata(v->data()->createSerializedDataRef(false));
317 Int64 nb_base_element = sdata->nbBaseElement();
318
319 Int64 my_size = nb_base_element;
320 Int64ConstArrayView a_my_size(1,&my_size);
321 SharedArray<Int64> all_sizes(nb_rank);
322 pm->allGather(a_my_size,all_sizes);
323
324 Int64 total_size = 0;
325 for( Integer i=0; i<nb_rank; ++i )
326 total_size += all_sizes[i];
327 Int64 my_index = 0;
328 for( Integer i=0; i<m_my_rank; ++i )
329 my_index += all_sizes[i];
330 m_variables_offset.insert(std::make_pair(v->fullName(),VarOffset(my_index,total_size,all_sizes)));
331 info() << " ADD OFFSET v=" << v->fullName() << " offset=" << my_index
332 << " total_size=" << total_size;
333 }
334
335}
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
339/*!
340 * \brief Ecriture en parallèle.
341 *
342 * \warning En cours de test, pas utilisable.
343 */
344void Hdf5MpiReaderWriter::
345_writeValParallel(IVariable* v,const ISerializedData* sdata)
346{
347 SerializeBuffer sb;
348 sb.setMode(ISerializer::ModeReserve);
349 sb.reserve(DT_Int32,1); // Pour indiquer la fin des envois
350 sb.reserve(v->fullName());
351 sb.reserve(m_sub_group_name); //!< Nom du groupe.
352 //sb.reserveInteger(1); // Pour le type de données
353 //sb.reserveInteger(1); // Pour la dimension
354 //v->serialize(&sb,0);
355 sdata->serialize(&sb);
356 sb.allocateBuffer();
357 sb.setMode(ISerializer::ModePut);
358 sb.putInt32(1); // Indique qu'il s'agit d'un message non vide
359 sb.put(v->fullName());
360 sb.put(m_sub_group_name); //!< Nom du groupe.
361 //sb.putInteger(v->dataType()); // Pour le type de données
362 //sb.putInteger(v->dimension()); // Pour la dimension
363 //v->serialize(&sb,0);
364 sdata->serialize(&sb);
365
366 m_parallel_mng->sendSerializer(&sb,m_send_rank);
367}
368
369/*---------------------------------------------------------------------------*/
370/*---------------------------------------------------------------------------*/
371
372void Hdf5MpiReaderWriter::
373_directReadVal(IVariable* v,IData* data)
374{
375 _checkValid();
376
377 info() << "DIRECT READ VAL v=" << v->name();
378 _readVal(v,data);
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
384void Hdf5MpiReaderWriter::
385_directWriteVal(IVariable* v,IData* data)
386{
387 _checkValid();
388
389 Ref<ISerializedData> sdata(data->createSerializedDataRef(false));
390
391 _writeVal(v->fullName(),m_sub_group_name,sdata.get());
392}
393
394/*---------------------------------------------------------------------------*/
395/*---------------------------------------------------------------------------*/
396
397static herr_t
398_Hdf5MpiReaderWriterIterateMe(hid_t g,const char* mn,void* ptr)
399{
400 Hdf5MpiReaderWriter* rw = reinterpret_cast<Hdf5MpiReaderWriter*>(ptr);
401 return rw->iterateMe(g,mn);
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
407herr_t Hdf5MpiReaderWriter::
408iterateMe(hid_t group_id,const char* member_name)
409{
410 ARCANE_UNUSED(group_id);
411
412 m_variables_name.add(std::string_view(member_name));
413 return 0;
414}
415
416/*---------------------------------------------------------------------------*/
417/*---------------------------------------------------------------------------*/
418/*!
419 */
420void Hdf5MpiReaderWriter::
421_writeVal(const String& var_group_name,const String& sub_group_name,
422 const ISerializedData* sdata)
423{
424 ARCANE_UNUSED(sub_group_name);
425 const char* func_name = "Hdf5MpiReaderWriter::_writeVal() ";
426 Timer::Sentry ts(&m_io_timer);
427 double v0 = ::MPI_Wtime();
428 info() << " SDATA name=" << var_group_name << " nb_element=" << sdata->nbElement()
429 << " dim=" << sdata->nbDimension() << " datatype=" << sdata->baseDataType()
430 << " nb_basic_element=" << sdata->nbBaseElement()
431 << " is_multi=" << sdata->isMultiSize()
432 << " dimensions_size=" << sdata->extents().size()
433 << " memory_size=" << sdata->memorySize()
434 << " bytes_size=" << sdata->constBytes().size();
435
436 hid_t save_typeid = m_types.saveType(sdata->baseDataType());
437 hid_t trueid = m_types.nativeType(sdata->baseDataType());
438 const void* ptr = sdata->constBytes().data();
439 Int64 nb_base_element = sdata->nbBaseElement();
440
441 OffsetMap::const_iterator offset_info = m_variables_offset.find(var_group_name);
442 if (offset_info==m_variables_offset.end()){
443 fatal() << "Can not find offset informations for ->" << var_group_name;
444 }
445 Int64 nb_element_to_write = nb_base_element;
446
447 //String var_group_name = _variableGroupName(v);
448 RealUniqueArray real_array;
449 Real3UniqueArray real3_array;
450 Real3x3UniqueArray real3x3_array;
451 Int32UniqueArray int32_array;
452 if (m_is_parallel && m_fileset_size!=1){
453 if (m_send_rank==m_my_rank){
454 // Je recois les valeurs des autres
455 nb_element_to_write = 0;
456 for( Integer i=m_send_rank; i<=m_last_recv_rank; ++i ){
457 nb_element_to_write += offset_info->second.m_all_sizes[i];
458 //info() << "ADD TO WRITE n=" << nb_element_to_write << " add=" << offset_info->second.m_all_sizes[i];
459 }
460 switch(sdata->baseDataType()){
461 case DT_Real:
462 real_array.resize(nb_element_to_write);
463 ptr = real_array.data();
464 break;
465 case DT_Real3:
466 real3_array.resize(nb_element_to_write);
467 ptr = real3_array.data();
468 break;
469 case DT_Real3x3:
470 real3x3_array.resize(nb_element_to_write);
471 ptr = real3x3_array.data();
472 break;
473 case DT_Int32:
474 int32_array.resize(nb_element_to_write);
475 ptr = int32_array.data();
476 break;
477 default:
478 fatal() << "Type not handled "<< dataTypeName(sdata->baseDataType());
479 }
480 }
481 else{
482 return;
483 // J'envoie à mon référent
484 //switch(sdata->baseDataType()){
485 //case DT_Real:
486 //_send(sdata,Real());
487 // break;
488 //}
489 }
490 }
491
492#if 0
493 HGroup var_base_group;
494 var_base_group.recursiveCreate(m_file_id,sub_group_name);
495
496 // Création du groupe contenant les informations de la variable
497 HGroup group_id;
498 //group_id.create(m_variable_group_id,var_group_name);
499 group_id.create(var_base_group,var_group_name);
500 if (group_id.isBad()){
501 OStringStream ostr;
502 ostr() << "Group HDF5 '" << var_group_name << "' not found";
503 throw ReaderWriterException(func_name,ostr.str());
504 }
505#endif
506
507 //Integer dim2 = dim2_array.size();
508 //Integer nb_element = sdata->nbElement();
509#if 0
510 bool is_multi_size = sdata->isMultiSize();
511 Integer dim2_size = 0;
512 Integer dim1_size = 0;
513 if (nb_dimension==2 && !is_multi_size){
514 dim1_size = dimensions[0];
515 dim2_size = dimensions[1];
516 }
517#endif
518 //Integer dimension_array_size = dimensions.size();
519
520#if 0
521 // Sauve les informations concernant les tailles et dimensions de la variable
522 {
523 hsize_t att_dims[1];
524 att_dims[0] = 9;
525 HSpace space_id;
526 space_id.createSimple(1,att_dims);
527 Integer dim_val[9];
528
529 dim_val[0] = nb_dimension;
530 dim_val[1] = dim1_size;
531 dim_val[2] = dim2_size;
532 dim_val[3] = nb_element;
533 dim_val[4] = nb_base_element;
534 dim_val[5] = dimension_array_size;
535 dim_val[6] = is_multi_size ? 1 : 0;
536 dim_val[7] = (Integer)sdata->baseDataType();
537 dim_val[8] = sdata->memorySize();
538
539 HAttribute att_id;
540
541 att_id.create(group_id,"Dims",m_types.saveType(dim1_size),space_id);
542 herr_t herr = att_id.write(m_types.nativeType(dim2_size),dim_val);
543 if (herr<0){
544 OStringStream ostr;
545 ostr() << "Bad writing of the dimensions for the variable '" << var_group_name << "'";
546 throw ReaderWriterException(func_name,ostr.str());
547 }
548 }
549#endif
550
551#if 0
552 // Si la variable est de type tableau à deux dimensions, sauve les
553 // tailles de la deuxième dimension par élément.
554 if (dimension_array_size!=0){
555 hsize_t att_dims[1];
556 att_dims[0] = dimension_array_size;
557 HSpace space_id;
558 HDataset array_id;
559
560 space_id.createSimple(1,att_dims);
561
562 array_id.create(group_id,"Dim2",m_types.saveType(dim1_size),space_id,H5P_DEFAULT);
563 herr_t herr = array_id.write(m_types.nativeType(dim1_size),dimensions.begin());
564 if (herr<0){
565 OStringStream ostr;
566 ostr() << "Bad writing of the dimensions for the variable '" << var_group_name << "'";
567 throw ReaderWriterException(func_name,ostr.str());
568 }
569 }
570#endif
571
572 //IParallelMng* pm = m_parallel_mng;
573 //Integer nb_rank = pm->commSize();
574
575 // Maintenant, sauve les valeurs si necessaire
576 if (nb_base_element!=0 && ptr!=0){
577 debug(Trace::High) << "Variable " << var_group_name << " begin dumped (nb_base_element=" << nb_base_element << ").";
578
579 hsize_t offset[1];
580 hsize_t count[1];
581 offset[0] = 0;
582 count[0] = nb_element_to_write;
583
584 //Int64UniqueArray all_sizes(nb_rank);
585 //Int64 my_size = nb_base_element;
586 //Int64ConstArrayView a_my_size(1,&my_size);
587 //double v1 = MPI_Wtime();
588 //pm->allGather(a_my_size,all_sizes);
589 //info() << " CLOCK GATHER = " << (MPI_Wtime() - v1);
590
591 //Int64 total_size = 0;
592 //for( Integer i=0; i<nb_rank; ++i )
593 //total_size += all_sizes[i];
594 //Int64 my_index = 0;
595 // for( Integer i=0; i<m_my_rank; ++i )
596 //my_index += all_sizes[i];
597 //my_index -= nb_base_element;
598 Int64 my_index = offset_info->second.m_offset;
599 Int64 total_size = offset_info->second.m_total_size;
600 offset[0] = my_index;
601
602 double v1 = MPI_Wtime();
603 hsize_t dims[1];
604 dims[0] = total_size;
605 HSpace filespace_id;
606 filespace_id.createSimple(1,dims);
607 HSpace memspace_id;
608 memspace_id.createSimple(1,count);
609 if (memspace_id.isBad()){
610 OStringStream ostr;
611 ostr() << "Wrong dataspace for variable '" << var_group_name << "'";
612 throw ReaderWriterException(func_name,ostr.str());
613 }
614
615
616 HDataset dataset_id;
617
618 //hid_t plist_id = H5P_DEFAULT;
619 hid_t write_plist_id = H5Pcreate(H5P_DATASET_XFER);
620#ifdef H5_HAVE_PARALLEL
621 H5Pset_dxpl_mpio(write_plist_id, H5FD_MPIO_COLLECTIVE);
622#endif
623 //H5Pset_dxpl_mpio(write_plist_id, H5FD_MPIO_INDEPENDENT);
624
625 hid_t create_dataset_plist_id = H5P_DEFAULT;
626#if 0
627 Integer chunk_size = (4096 << 9);
628 if (total_size>chunk_size){
629 create_dataset_plist_id = H5Pcreate(H5P_DATASET_CREATE);
630 H5Pcreate(H5P_DATASET_CREATE);
631 hsize_t chunk_dim[1];
632 chunk_dim[0] = chunk_size;
633 herr_t r = H5Pset_chunk(create_dataset_plist_id,1,chunk_dim);
634 info() << " SET CHUNK FOR " << var_group_name << " total=" << total_size << " chunk=" << chunk_dim[0];
635 }
636#endif
637
638 //dataset_id.create(group_id,"Values",save_typeid,filespace_id,plist_id);
639 v1 = MPI_Wtime();
640 dataset_id.create(m_variable_group_id,var_group_name,save_typeid,filespace_id,create_dataset_plist_id);
641 if (dataset_id.isBad()){
642 OStringStream ostr;
643 ostr() << "Wrong dataset for variable '" << var_group_name << "'";
644 throw ReaderWriterException(func_name,ostr.str());
645 }
646 H5Sselect_hyperslab(filespace_id.id(), H5S_SELECT_SET, offset, NULL, count, NULL);
647
648
649 v1 = MPI_Wtime();
650 {
651 Timer::Sentry ts(&m_write_timer);
652 herr_t herr = dataset_id.write(trueid,ptr,memspace_id,filespace_id,write_plist_id);
653 if (herr<0){
654 OStringStream ostr;
655 ostr() << "Wrong dataset written for variable '" << var_group_name << "'";
656 throw ReaderWriterException(func_name,ostr.str());
657 }
658 }
659 if (create_dataset_plist_id!=H5P_DEFAULT)
660 H5Pclose(create_dataset_plist_id);
661 H5Pclose(write_plist_id);
662
663 info() << " WRITE DATASET name=" << var_group_name
664 << " offset=" << offset[0]
665 << " mysize=" << nb_base_element
666 << " write_size=" << count[0]
667 << " total=" << total_size
668 << " rank=" << m_my_rank
669 << " clock=" << (MPI_Wtime() - v1);
670
671 //pinfo() << " CLOCK WRITE = " << << " CPU=" << m_my_rank;
672 //pm->barrier();
673 //info() << " CLOCK BARRIER = " << (MPI_Wtime() - v1);
674
675 dataset_id.close();
676 }
677 info() << "TOTAL = " << (MPI_Wtime()-v0);
678}
679
680/*---------------------------------------------------------------------------*/
681/*---------------------------------------------------------------------------*/
682
683Ref<ISerializedData> Hdf5MpiReaderWriter::
684_readDim2(IVariable* var)
685{
686 const char* func_name = "Hdf5MpiReaderWriter::_readDim2()";
687
688 const int max_dim = 256; // Nombre maxi de dimensions des tableaux HDF
689
690 String vname = _variableGroupName(var);
691
692 info() << " READ DIM name=" << vname;
693
694 Integer dimension_array_size = 0;
695 Integer nb_element = 0;
696 Integer nb_dimension = -1;
697 // Regarde si le nom correspondant est dans la liste des variables.
698 // S'il n'y est pas, cela signifie que le tableau n'a pas été sauvé et
699 // donc que ses dimensions sont nulles.
700 {
701 bool is_found = false;
702 for( StringList::Enumerator i(m_variables_name); ++i; )
703 if (*i==vname){
704 is_found = true;
705 break;
706 }
707 if (!is_found){
708 OStringStream ostr;
709 ostr() << "No HDF5 group with name '" << vname << "' exists";
710 throw ReaderWriterException(func_name,ostr.str());
711 }
712 }
713
714 // Récupère le groupe contenant les informations de la variable
715 HGroup group_id;
716 //group_id.open(m_variable_group_id,vname);
717 group_id.open(m_sub_group_id,vname);
718 if (group_id.isBad()){
719 OStringStream ostr;
720 ostr() << "No HDF5 with name '" << vname << "' exists";
721 throw ReaderWriterException(func_name,ostr.str());
722 }
723 bool is_multi_size = false;
724 eDataType data_type = DT_Unknown;
725 Integer memory_size = 0;
726 Integer nb_base_element = 0;
727 Integer dim1_size = 0;
728 Integer dim2_size = 0;
729 Int64UniqueArray dims;
730 // Récupère les informations concernant les tailles et dimensions de la variable
731 {
732 HAttribute att_id;
733 att_id.open(group_id,"Dims");
734 HSpace space_id = att_id.getSpace();
735
736 // On attend une seule dimension, et le nombre d'eléments de
737 // l'attribut (hdf_dims[0]) doit être égal à 1 ou 2.
738 hsize_t hdf_dims[max_dim];
739 hsize_t max_dims[max_dim];
740 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
741
742 Integer dim_val[9];
743 //herr_t herr = H5Aread(att_id,nativeType(Integer()),dim_val);
744 att_id.read(m_types.nativeType(Integer()),dim_val);
745 if (hdf_dims[0]!=9){
746 OStringStream ostr;
747 ostr() << "Wrong dimensions for variable '" << vname
748 << "' (found: " << (int)hdf_dims[0] << " expected 9)";
749 throw ReaderWriterException(func_name,ostr.str());
750 }
751 nb_dimension = dim_val[0];
752 dim1_size = dim_val[1];
753 dim2_size = dim_val[2];
754 nb_element = dim_val[3];
755 nb_base_element = dim_val[4];
756 dimension_array_size = dim_val[5];
757 is_multi_size = dim_val[6]!=0;
758 data_type = (eDataType)dim_val[7];
759 memory_size = dim_val[8];
760 }
761
762 info() << " READ DIM name=" << vname
763 << " nb_dim=" << nb_dimension << " dim1_size=" << dim1_size
764 << " dim2_size=" << dim2_size << " nb_element=" << nb_element
765 << " dimension_size=" << dimension_array_size
766 << " is_multi_size=" << is_multi_size
767 << " data_type" << data_type;
768
769 if (dimension_array_size>0){
770 HDataset array_id;
771 array_id.open(group_id,"Dim2");
772 //hid_t array_id = H5Dopen(group_id.id(),"Dim2");
773 if (array_id.isBad()){
774 OStringStream ostr;
775 ostr() << "Wrong dataset for variable '" << vname << "'";
776 throw ReaderWriterException(func_name,ostr.str());
777 }
778 HSpace space_id = array_id.getSpace();
779 if (space_id.isBad()){
780 OStringStream ostr;
781 ostr() << "Wrong dataspace for variable '" << vname << "'";
782 throw ReaderWriterException(func_name,ostr.str());
783 }
784 hsize_t hdf_dims[max_dim];
785 hsize_t max_dims[max_dim];
786 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
787 // Vérifie que le nombre d'éléments du dataset est bien égal à celui
788 // attendu.
789 if ((Integer)hdf_dims[0]!=dimension_array_size){
790 OStringStream ostr;
791 ostr() << "Wrong number of elements in 'Dim2' for variable '"
792 << vname << "' (found: " << hdf_dims[0]
793 << " expected " << dimension_array_size << ")";
794 throw ReaderWriterException(func_name,ostr.str());
795 }
796 dim2_size = 0;
797 dims.resize(dimension_array_size);
798 herr_t herr = array_id.read(m_types.nativeType(Integer()),dims.data());
799 if (herr<0){
800 OStringStream ostr;
801 ostr() << "Wrong dataset read for variable '" << vname << "'";
802 throw ReaderWriterException(func_name,ostr.str());
803 }
804 }
805
806 Ref<ISerializedData> sdata = arcaneCreateSerializedDataRef(data_type,memory_size,nb_dimension,nb_element,
807 nb_base_element,is_multi_size,dims);
808 return sdata;
809}
810
811/*---------------------------------------------------------------------------*/
812/*---------------------------------------------------------------------------*/
813
814/*---------------------------------------------------------------------------*/
815/*---------------------------------------------------------------------------*/
816
817void Hdf5MpiReaderWriter::
818write(IVariable* v,IData* data)
819{
820 if (v->itemKind()==IK_Unknown)
821 return;
822 //if (v->dataType()==DT_Real3)
823 //return;
824 _directWriteVal(v,data);
825}
826
827/*---------------------------------------------------------------------------*/
828/*---------------------------------------------------------------------------*/
829
830void Hdf5MpiReaderWriter::
831_readVal(IVariable* v,IData* data)
832{
833 const char* func_name = "Hdf5MpiReaderWriter::_readVal() ";
834
835 String var_group_name = _variableGroupName(v);
836
837 info() << " TRY TO READ var_group=" << var_group_name;
838
839 Ref<ISerializedData> sd(_readDim2(v));
840 Int64 storage_size = sd->memorySize();
841 //ByteUniqueArray byte_values(storage_size);
842 info() << " READ DATA n=" << storage_size;
843
844 data->allocateBufferForSerializedData(sd.get());
845
846 //bool no_dump = v.property() & IVariable::PNoDump;
847 // Lit toujours, car le fait de sauver ou non se fait en amont
848 //bool no_dump = false;
849 if (storage_size!=0){
850 // Récupère le groupe contenant les informations de la variable
851 HGroup group_id;
852 //group_id.open(m_variable_group_id,var_group_name);
853 group_id.open(m_sub_group_id,var_group_name);
854 if (group_id.isBad()){
855 OStringStream ostr;
856 ostr() << "No HDF5 group with name '" << var_group_name << "' exists";
857 throw ReaderWriterException(func_name,ostr.str());
858 }
859
860 HDataset dataset_id;
861 dataset_id.open(group_id,"Values");
862 if (dataset_id.isBad()){
863 OStringStream ostr;
864 ostr() << "Wrong dataset for variable '" << var_group_name << "'";
865 throw ReaderWriterException(func_name,ostr.str());
866 }
867
868 //dataset_id.read(trueid,ptr);
869 //debug(Trace::High) << "Variable " << var_group_name << " readed (nb_element=" << nb_element << ").";
870 void* ptr = sd->writableBytes().data();
871 info() << "READ Variable " << var_group_name << " ptr=" << ptr;;
872 hid_t trueid = m_types.nativeType(sd->baseDataType());
873 dataset_id.read(trueid,ptr);
874 }
875
876 data->assignSerializedData(sd.get());
877}
878
879/*---------------------------------------------------------------------------*/
880/*---------------------------------------------------------------------------*/
881
882void Hdf5MpiReaderWriter::
883read(IVariable* var,IData* data)
884{
885 _directReadVal(var,data);
886}
887
888/*---------------------------------------------------------------------------*/
889/*---------------------------------------------------------------------------*/
890
891void Hdf5MpiReaderWriter::
892setMetaData(const String& meta_data)
893{
894 ARCANE_UNUSED(meta_data);
895#if 0
896 if (m_is_parallel){
897 IParallelMng* pm = m_parallel_mng;
898 Integer nb_rank = pm->commSize();
899 if (m_send_rank!=m_my_rank){
900 // Envoie le groupe et les meta donnees
901 SerializeBuffer sb;
902 sb.setMode(ISerializer::ModeReserve);
903 sb.reserve(m_sub_group_name);
904 sb.reserve(meta_data);
905 sb.allocateBuffer();
906 sb.setMode(ISerializer::ModePut);
907 sb.put(m_sub_group_name);
908 sb.put(meta_data);
909 m_parallel_mng->sendSerializer(&sb,m_send_rank);
910 }
911 else{
912 _setMetaData(meta_data,m_sub_group_name);
913 for( Integer i=m_send_rank+1; i<=m_last_recv_rank; ++i ){
914 SerializeBuffer sb;
915 pm->recvSerializer(&sb,i);
916 sb.setMode(ISerializer::ModeGet);
917 String remote_group_name;
918 String remote_meta_data;
919 sb.get(remote_group_name);
920 sb.get(remote_meta_data);
921 _setMetaData(remote_meta_data,remote_group_name);
922 }
923 }
924 }
925 else
926 _setMetaData(meta_data,m_sub_group_name);
927#endif
928}
929
930/*---------------------------------------------------------------------------*/
931/*---------------------------------------------------------------------------*/
932
933void Hdf5MpiReaderWriter::
934_setMetaData(const String& meta_data,const String& sub_group_name)
935{
936 ARCANE_UNUSED(meta_data);
937 ARCANE_UNUSED(sub_group_name);
938#if 0
939 const char* func_name ="Hdf5MpiReaderWriter::setMetaData()";
940
941 HGroup base_group;
942 base_group.recursiveCreate(m_file_id,sub_group_name);
943
944 ByteConstArrayView meta_data_utf8 = meta_data.utf8();
945 const Byte* _meta_data = meta_data_utf8.begin();
946
947 hsize_t dims[1];
948 dims[0] = meta_data_utf8.size() + 1;
949 HSpace space_id;
950 space_id.createSimple(1,dims);
951 if (space_id.isBad())
952 throw ReaderWriterException(func_name,"Bad 'space' for the meta-data ('MetaData')");
953
954 HDataset dataset_id;
955 dataset_id.create(base_group,"MetaData",m_types.nativeType(Byte()),space_id,H5P_DEFAULT);
956 if (dataset_id.isBad())
957 throw ReaderWriterException(func_name,"Bad 'dataset' for the meta-data ('MetaData')");
958
959 herr_t herr = dataset_id.write(m_types.nativeType(Byte()),_meta_data);
960 if (herr<0)
961 throw ReaderWriterException(func_name,"Can't write the meta-data ('MetaData')");
962#endif
963}
964
965/*---------------------------------------------------------------------------*/
966/*---------------------------------------------------------------------------*/
967
968String Hdf5MpiReaderWriter::
969metaData()
970{
971 const char* func_name ="Hdf5MpiReaderWriter::readMetaData()";
972 HDataset dataset_id;
973 dataset_id.open(m_sub_group_id,"MetaData");
974 if (dataset_id.isBad()){
975 throw ReaderWriterException(func_name,"Wrong dataset for meta-data ('MetaData')");
976 }
977 HSpace space_id = dataset_id.getSpace();
978 if (space_id.isBad()){
979 throw ReaderWriterException(func_name,"Wrong space for meta-data ('MetaData')");
980 }
981 const int max_dim = 256;
982 hsize_t hdf_dims[max_dim];
983 hsize_t max_dims[max_dim];
984 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
985 if (hdf_dims[0]<=0)
986 throw ReaderWriterException(func_name,"Wrong number of elements for meta-data ('MetaData')");
987 Integer nb_byte = static_cast<Integer>(hdf_dims[0]);
988 ByteUniqueArray uchars(nb_byte);
989 dataset_id.read(m_types.nativeType(Byte()),uchars.data());
990 String s(uchars);
991 return s;
992}
993
994/*---------------------------------------------------------------------------*/
995/*---------------------------------------------------------------------------*/
996
997void Hdf5MpiReaderWriter::
998endWrite()
999{
1000#if 0
1001 if (m_is_parallel){
1002 if (m_my_rank==m_send_rank){
1003 _receiveRemoteVariables();
1004 }
1005 else{
1006 // Envoie un message de fin
1007 SerializeBuffer sb;
1008 sb.setMode(ISerializer::ModeReserve);
1009 sb.reserve(DT_Int32,1); // Pour indiquer la fin des envoies
1010 sb.allocateBuffer();
1011 sb.setMode(ISerializer::ModePut);
1012 sb.putInt32(0); // Indique qu'il s'agit d'un message de fin
1013 m_parallel_mng->sendSerializer(&sb,m_send_rank);
1014 }
1015 }
1016#endif
1017 {
1018 info() << " Hdf5Timer: nb_activated=" << m_io_timer.nbActivated()
1019 << " time=" << m_io_timer.totalTime()
1020 << " write=" << m_write_timer.nbActivated()
1021 << " timewrite=" << m_write_timer.totalTime();
1022 }
1023}
1024
1025/*---------------------------------------------------------------------------*/
1026/*---------------------------------------------------------------------------*/
1027
1028void Hdf5MpiReaderWriter::
1029_receiveRemoteVariables()
1030{
1031 IParallelMng* pm = m_parallel_mng;
1032 Integer nb_remaining = m_last_recv_rank - m_send_rank;
1033 info() << "NB REMAINING = " << nb_remaining;
1034 Ref<ISerializeMessageList> m_messages(pm->createSerializeMessageListRef());
1035
1036 while(nb_remaining>0){
1037 ISerializeMessage* sm = new SerializeMessage(m_my_rank,NULL_SUB_DOMAIN_ID,ISerializeMessage::MT_Recv);
1038 m_messages->addMessage(sm);
1039 m_messages->processPendingMessages();
1040 m_messages->waitMessages(Parallel::WaitAll);
1041
1042 ISerializer* sb = sm->serializer();
1043 sb->setMode(ISerializer::ModeGet);
1044 //info() << " RECEIVING BUFFER!";
1045 Int32 id = sb->getInt32();
1046 if (id==0){
1047 //info() << " LAST MESSAGE!";
1048 --nb_remaining;
1049 }
1050 else
1051 _writeRemoteVariable(sb);
1052 delete sm;
1053 }
1054}
1055
1056/*---------------------------------------------------------------------------*/
1057/*---------------------------------------------------------------------------*/
1058
1059void Hdf5MpiReaderWriter::
1060_writeRemoteVariable(ISerializer* sb)
1061{
1062 String var_name;
1063 sb->get(var_name);
1064 String group_name;
1065 sb->get(group_name);
1066 //eDataType data_type = (eDataType)sb->getInteger();
1067 //Integer dim = sb->getInteger();
1068 //info() << " REMOTE VAR = name=" << var_name << " data_type=" << data_type
1069 // << " dim=" << dim << " group=" << group_name;
1070 Ref<ISerializedData> sdata = arcaneCreateEmptySerializedDataRef();
1071 sb->setReadMode(ISerializer::ReadReplace);
1072 sdata->serialize(sb);
1073 _writeVal(var_name,group_name,sdata.get());
1074}
1075
1076/*---------------------------------------------------------------------------*/
1077/*---------------------------------------------------------------------------*/
1078
1079/*---------------------------------------------------------------------------*/
1080/*---------------------------------------------------------------------------*/
1081/*!
1082 * \brief Protection/reprise au format ArcaneHdf5.
1083 */
1084class ArcaneHdf5MpiCheckpointService2
1085: public ArcaneHdf5MpiReaderWriterObject
1086{
1087 public:
1088
1089 ArcaneHdf5MpiCheckpointService2(const ServiceBuildInfo& sbi)
1090 : ArcaneHdf5MpiReaderWriterObject(sbi), m_write_index(0), m_writer(0), m_reader(0)
1091 , m_fileset_size(0)
1092 {
1093 }
1094 virtual IDataWriter* dataWriter() { return m_writer; }
1095 virtual IDataReader* dataReader() { return m_reader; }
1096
1097 virtual void notifyBeginWrite();
1098 virtual void notifyEndWrite();
1099 virtual void notifyBeginRead();
1100 virtual void notifyEndRead();
1101 virtual void close() {}
1102 virtual String readerServiceName() const { return "ArcaneHdf5MpiCheckpointReader2"; }
1103
1104 private:
1105
1106 Integer m_write_index;
1107 Hdf5MpiReaderWriter* m_writer;
1108 Hdf5MpiReaderWriter* m_reader;
1109 Integer m_fileset_size;
1110
1111 private:
1112
1113 String _defaultFileName()
1114 {
1115 return "arcanedump.mpi.h5";
1116 }
1117 Directory _defaultDirectory()
1118 {
1119 return Directory(baseDirectoryName());
1120 }
1121 void _parseMetaData(String meta_data);
1122};
1123
1124/*---------------------------------------------------------------------------*/
1125/*---------------------------------------------------------------------------*/
1126
1127void ArcaneHdf5MpiCheckpointService2::
1128_parseMetaData(String meta_data)
1129{
1130 IIOMng* io_mng = subDomain()->ioMng();
1131 ScopedPtrT<IXmlDocumentHolder> xml_doc(io_mng->parseXmlBuffer(meta_data.utf8(),"MetaData"));
1132 XmlNode root = xml_doc->documentNode().documentElement();
1133 Integer version = root.attr("version").valueAsInteger();
1134 if (version!=1){
1135 throw ReaderWriterException("ArcaneHdf5MpiCheckpointService2::_parseMetaData","Bad version (expected 1)");
1136 }
1137 m_fileset_size = 0;
1138
1139 info() << " FileSet size=" << m_fileset_size;
1140}
1141
1142/*---------------------------------------------------------------------------*/
1143/*---------------------------------------------------------------------------*/
1144
1145void ArcaneHdf5MpiCheckpointService2::
1146notifyBeginRead()
1147{
1148 String meta_data = readerMetaData();
1149 _parseMetaData(meta_data);
1150
1151 info() << " GET META DATA READER " << readerMetaData()
1152 << " filename=" << fileName();
1153
1154 if (fileName().null()){
1155 Directory dump_dir(_defaultDirectory());
1156 //Directory dump_dir(subDomain()->exportDirectory(),"protection");
1157 //Directory dump_dir("/tmp/grospelx/");
1158 setFileName(dump_dir.file(_defaultFileName()));
1159 //setFileName(dump_dir.file("arcanedump.0.h5"));
1160 //setFileName(_defaultFileName());
1161 }
1162 info() << " READ CHECKPOINT FILENAME = " << fileName();
1163 StringBuilder sub_group;
1164 //sub_group = "SubDomain";
1165 //sub_group += subDomain()->subDomainId();
1166 //sub_group += "/Index";
1167 //sub_group += currentIndex();
1168 sub_group = "Index";
1169 sub_group += currentIndex();
1170 m_reader = new Hdf5MpiReaderWriter(subDomain(),fileName(),sub_group.toString(),0,Hdf5MpiReaderWriter::OpenModeRead);
1171 m_reader->initialize();
1172}
1173
1174/*---------------------------------------------------------------------------*/
1175/*---------------------------------------------------------------------------*/
1176
1177void ArcaneHdf5MpiCheckpointService2::
1178notifyEndRead()
1179{
1180 delete m_reader;
1181 m_reader = 0;
1182}
1183
1184/*---------------------------------------------------------------------------*/
1185/*---------------------------------------------------------------------------*/
1186
1187void ArcaneHdf5MpiCheckpointService2::
1188notifyBeginWrite()
1189{
1190 if (options())
1191 m_fileset_size = options()->filesetSize();
1192
1193 if (fileName().null()){
1194 Directory dump_dir(_defaultDirectory());
1195 //info() << "USE TMP DIRECTORY\n";
1196 //Directory dump_dir("/tmp/grospelx/");
1197 //dump_dir.createDirectory();
1198 setFileName(dump_dir.file(_defaultFileName()));
1199 //setFileName(_defaultFileName());
1200 }
1201 Hdf5MpiReaderWriter::eOpenMode open_mode = Hdf5MpiReaderWriter::OpenModeAppend;
1202 Integer write_index = checkpointTimes().size();
1203 --write_index;
1204 if (write_index==0)
1205 open_mode = Hdf5MpiReaderWriter::OpenModeTruncate;
1206
1207 //IParallelMng* pm = subDomain()->parallelMng();
1208 //Integer sid = pm->commRank();
1209
1210 StringBuilder sub_group;
1211 //sub_group = "SubDomain";
1212 //sub_group += sid;
1213 //sub_group += "/Index";
1214 //sub_group += write_index;
1215
1216 sub_group = "Index";
1217 sub_group += write_index;
1218
1219 m_writer = new Hdf5MpiReaderWriter(subDomain(),fileName(),sub_group.toString(),m_fileset_size,open_mode);
1220 m_writer->initialize();
1221}
1222
1223/*---------------------------------------------------------------------------*/
1224/*---------------------------------------------------------------------------*/
1225
1226void ArcaneHdf5MpiCheckpointService2::
1227notifyEndWrite()
1228{
1229 OStringStream ostr;
1230 ostr() << "<infos version='1'>\n";
1231 ostr() << " <fileset-size>" << m_fileset_size << "</fileset-size>\n";
1232 ostr() << "</infos>\n";
1233 setReaderMetaData(ostr.str());
1234 ++m_write_index;
1235 delete m_writer;
1236 m_writer = 0;
1237}
1238
1239/*---------------------------------------------------------------------------*/
1240/*---------------------------------------------------------------------------*/
1241
1242ARCANE_REGISTER_SUB_DOMAIN_FACTORY(ArcaneHdf5MpiCheckpointService2,
1243 ICheckpointReader,
1244 ArcaneHdf5MpiCheckpointReader2);
1245
1246ARCANE_REGISTER_SUB_DOMAIN_FACTORY(ArcaneHdf5MpiCheckpointService2,
1247 ICheckpointWriter,
1248 ArcaneHdf5MpiCheckpointWriter2);
1249
1250ARCANE_REGISTER_SERVICE_HDF5MPIREADERWRITER(ArcaneHdf5MpiCheckpoint2,
1251 ArcaneHdf5MpiCheckpointService2);
1252
1253/*---------------------------------------------------------------------------*/
1254/*---------------------------------------------------------------------------*/
1255
1256} // End namespace Arcane
1257
1258/*---------------------------------------------------------------------------*/
1259/*---------------------------------------------------------------------------*/
1260
1261#endif
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Chaîne de caractères unicode.
Gestion d'un timer.
Definition Timer.h:62
Fonctions utilitaires pour Hdf5.
Definition Hdf5Utils.cc:36
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Ref< ISerializedData > arcaneCreateSerializedDataRef(eDataType data_type, Int64 memory_size, Integer nb_dim, Int64 nb_element, Int64 nb_base_element, bool is_multi_size, Int64ConstArrayView dimensions)
Créé des données sérialisées.
UniqueArray< Real3x3 > Real3x3UniqueArray
Tableau dynamique à une dimension de tenseurs de rang 3.
Definition UtilsTypes.h:454
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:426
Int32 Integer
Type représentant un entier.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
Definition UtilsTypes.h:450
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:567
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:422
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:428
UniqueArray< Real > RealUniqueArray
Tableau dynamique à une dimension de réels.
Definition UtilsTypes.h:436
Ref< ISerializedData > arcaneCreateEmptySerializedDataRef()
Créé des données sérialisées.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:563
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:43
eDataType
Type d'une donnée.
Definition DataTypes.h:39
@ DT_Real3x3
Donnée de type tenseur 3x3.
Definition DataTypes.h:49
@ DT_Int32
Donnée de type entier 32 bits.
Definition DataTypes.h:43
@ DT_Real3
Donnée de type vecteur 3.
Definition DataTypes.h:47
@ DT_Unknown
Donnée de type inconnue ou non initialisée.
Definition DataTypes.h:56
@ DT_Real
Donnée de type réel.
Definition DataTypes.h:41
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Definition DataTypes.cc:70