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"
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"
44#include "arcane/hdf5/Hdf5MpiReaderWriter.h"
46#include "arcane/hdf5/Hdf5MpiReaderWriter_axl.h"
48#include "arcane_packages.h"
50#ifdef ARCANE_HAS_PACKAGE_MPI
51#ifndef OMPI_SKIP_MPICXX
52#define OMPI_SKIP_MPICXX
54#ifndef MPICH_SKIP_MPICXX
55#define MPICH_SKIP_MPICXX
75static herr_t _Hdf5MpiReaderWriterIterateMe(hid_t,
const char*,
void*);
83 eOpenMode open_mode,
bool do_verif)
86, m_parallel_mng(sd->parallelMng())
87, m_open_mode(open_mode)
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)
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)
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){
105 m_last_recv_rank = nb_rank;
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;
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;
126void Hdf5MpiReaderWriter::
129 if (m_is_initialized)
132 m_is_initialized =
true;
134 const char* func_name =
"Hdf5MpiReaderWriter::initialize()";
137 HInit::useMutex(m_parallel_mng->isThreadImplementation(), m_parallel_mng);
139 if (m_open_mode==OpenModeRead){
140 m_file_id.openRead(m_filename);
141 m_sub_group_id.recursiveOpen(m_file_id,m_sub_group_name);
145 void* arcane_comm = m_sub_domain->parallelMng()->getMPICommunicator();
147 throw FatalErrorException(
"No MPI environment available");
148 MPI_Comm mpi_comm = *((MPI_Comm*)arcane_comm);
149 Integer nb_rank = m_parallel_mng->commSize();
150 if (m_fileset_size>1){
151 UniqueArray<int> senders;
152 for( Integer i=0; i<nb_rank; ++i ){
153 Integer modulo = i % m_fileset_size;
155 info() <<
" ADD SENDER n=" << i;
160 if (MPI_Comm_group(mpi_comm,&all_group)!=MPI_SUCCESS)
161 fatal() <<
"Error in MPI_Comm_group";
162 MPI_Group writer_group;
163 if (MPI_Group_incl(all_group,senders.size(),senders.data(),&writer_group)!=MPI_SUCCESS)
164 fatal() <<
"Error in MPI_Group_incl";
165 if (MPI_Comm_create(mpi_comm,writer_group,&mpi_comm)!=MPI_SUCCESS)
166 fatal() <<
"Error in MPI_Comm_create";
170 if (m_send_rank!=m_my_rank)
172 if (m_open_mode==OpenModeTruncate || m_open_mode==OpenModeAppend){
173 hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS);
175 info() <<
" USE MPI-POSIX";
177#ifdef H5_HAVE_PARALLEL
178 H5Pset_fapl_mpio(plist_id, mpi_comm, MPI_INFO_NULL);
181#ifdef ARCANE_TEST_HDF5DIRECT
182# ifdef H5_HAVE_DIRECT
183 info() <<
" HAVE DIRECT DRIVER";
184 H5Pset_fapl_direct(plist_id,4096,512,16*1024*1024);
191 herr_t r = H5Pget_cache(plist_id,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0);
192 info() <<
" CACHE SIZE r=" << r <<
" mdc=" << mdc_nelmts
193 <<
" rdcc=" << rdcc_nelmts <<
" rdcc_bytes=" << rdcc_nbytes <<
" w0=" << rdcc_w0;
196 rdcc_nbytes = 10000000;
197 r = H5Pset_cache(plist_id,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0);
198 info() <<
" SET CACHE SIZE R1=" << r;
201 hsize_t sieve_buf = (1024 << 12);
202 r = H5Pset_sieve_buf_size(plist_id,sieve_buf);
203 info() <<
" SIEVE_BUF=" << sieve_buf <<
" r=" << r;
204 hsize_t small_block_size = 0;
205 r = H5Pget_small_data_block_size(plist_id,&small_block_size);
206 info() <<
" SMALL BLOCK SIZE=" << small_block_size;
207 small_block_size <<= 10;
208 r = H5Pset_small_data_block_size(plist_id,small_block_size);
209 info() <<
" SET SMALL BLOCK SIZE s=" << small_block_size <<
" r=" << r;
223 if (m_open_mode==OpenModeTruncate){
224 info() <<
" BEGIN OPEN TRUNCATE";
225 m_file_id.openTruncate(m_filename,plist_id);
226 info() <<
" END OPEN TRUNCATE";
228 else if (m_open_mode==OpenModeAppend){
229 info() <<
" BEGIN OPEN ADD";
230 m_file_id.openAppend(m_filename,plist_id);
231 info() <<
" END OPEN ADD";
234 if (m_sub_group_name!=
"/"){
235 info() <<
" CHECK CREATE GROUP name=" << m_sub_group_name;
237 m_sub_group_id.recursiveCreate(m_file_id,m_sub_group_name);
238 info() <<
" END CHECK CREATE GROUP name=" << m_sub_group_name;
241 m_sub_group_id.open(m_file_id,m_sub_group_name);
242 m_variable_group_id.create(m_sub_group_id,
"Variables");
245 if (m_file_id.isBad()){
247 ostr() <<
"Unable to open file <" << m_filename <<
">";
248 throw ReaderWriterException(func_name,ostr.str());
250 if (m_sub_group_id.isBad()){
252 ostr() <<
"HDF5 group '" << m_sub_group_name <<
"' not found";
253 throw ReaderWriterException(func_name,ostr.str());
256 if (m_variable_group_id.isBad()){
258 ostr() <<
"Group HDF5 'Variables' not found";
259 throw ReaderWriterException(func_name,ostr.str());
263 info() <<
" INFO END INITIALIZE";
266 if (m_open_mode==OpenModeRead){
269 H5Giterate(m_file_id.id(),m_sub_group_name.localstr(),&index,_Hdf5MpiReaderWriterIterateMe,
this);
277~Hdf5MpiReaderWriter()
284void Hdf5MpiReaderWriter::
287 if (m_is_initialized)
289 fatal() <<
"Use of a Hdf5MpiReaderWriter instance not initialized";
295String Hdf5MpiReaderWriter::
296_variableGroupName(IVariable* var)
298 return var->fullName();
304void Hdf5MpiReaderWriter::
305beginWrite(
const VariableCollection& vars)
307 IParallelMng* pm = m_parallel_mng;
308 Integer nb_rank = pm->commSize();
310 pwarning() <<
"Implementation of this checkpoint format is not operational yet";
312 for( VariableCollection::Enumerator i(vars); ++i; ){
314 if (v->itemKind()==IK_Unknown)
317 Ref<ISerializedData> sdata(v->data()->createSerializedDataRef(
false));
318 Int64 nb_base_element = sdata->nbBaseElement();
320 Int64 my_size = nb_base_element;
322 SharedArray<Int64> all_sizes(nb_rank);
323 pm->allGather(a_my_size,all_sizes);
325 Int64 total_size = 0;
326 for( Integer i=0; i<nb_rank; ++i )
327 total_size += all_sizes[i];
329 for( Integer i=0; i<m_my_rank; ++i )
330 my_index += all_sizes[i];
331 m_variables_offset.insert(std::make_pair(v->fullName(),VarOffset(my_index,total_size,all_sizes)));
332 info() <<
" ADD OFFSET v=" << v->fullName() <<
" offset=" << my_index
333 <<
" total_size=" << total_size;
345void Hdf5MpiReaderWriter::
346_writeValParallel(IVariable* v,
const ISerializedData* sdata)
349 sb.setMode(ISerializer::ModeReserve);
350 sb.reserve(DT_Int32,1);
351 sb.reserve(v->fullName());
352 sb.reserve(m_sub_group_name);
356 sdata->serialize(&sb);
358 sb.setMode(ISerializer::ModePut);
360 sb.put(v->fullName());
361 sb.put(m_sub_group_name);
365 sdata->serialize(&sb);
367 m_parallel_mng->sendSerializer(&sb,m_send_rank);
373void Hdf5MpiReaderWriter::
374_directReadVal(IVariable* v,IData* data)
378 info() <<
"DIRECT READ VAL v=" << v->name();
385void Hdf5MpiReaderWriter::
386_directWriteVal(IVariable* v,IData* data)
390 Ref<ISerializedData> sdata(data->createSerializedDataRef(
false));
392 _writeVal(v->fullName(),m_sub_group_name,sdata.get());
399_Hdf5MpiReaderWriterIterateMe(hid_t g,
const char* mn,
void* ptr)
401 Hdf5MpiReaderWriter* rw =
reinterpret_cast<Hdf5MpiReaderWriter*
>(ptr);
402 return rw->iterateMe(g,mn);
408herr_t Hdf5MpiReaderWriter::
409iterateMe(hid_t group_id,
const char* member_name)
411 ARCANE_UNUSED(group_id);
413 m_variables_name.add(std::string_view(member_name));
421void Hdf5MpiReaderWriter::
422_writeVal(
const String& var_group_name,
const String& sub_group_name,
423 const ISerializedData* sdata)
425 ARCANE_UNUSED(sub_group_name);
426 const char* func_name =
"Hdf5MpiReaderWriter::_writeVal() ";
427 Timer::Sentry ts(&m_io_timer);
428 double v0 = ::MPI_Wtime();
429 info() <<
" SDATA name=" << var_group_name <<
" nb_element=" << sdata->nbElement()
430 <<
" dim=" << sdata->nbDimension() <<
" datatype=" << sdata->baseDataType()
431 <<
" nb_basic_element=" << sdata->nbBaseElement()
432 <<
" is_multi=" << sdata->isMultiSize()
433 <<
" dimensions_size=" << sdata->extents().size()
434 <<
" memory_size=" << sdata->memorySize()
435 <<
" bytes_size=" << sdata->constBytes().size();
437 hid_t save_typeid = m_types.saveType(sdata->baseDataType());
438 hid_t trueid = m_types.nativeType(sdata->baseDataType());
439 const void* ptr = sdata->constBytes().data();
440 Int64 nb_base_element = sdata->nbBaseElement();
442 OffsetMap::const_iterator offset_info = m_variables_offset.find(var_group_name);
443 if (offset_info==m_variables_offset.end()){
444 fatal() <<
"Can not find offset informations for ->" << var_group_name;
446 Int64 nb_element_to_write = nb_base_element;
453 if (m_is_parallel && m_fileset_size!=1){
454 if (m_send_rank==m_my_rank){
456 nb_element_to_write = 0;
457 for( Integer i=m_send_rank; i<=m_last_recv_rank; ++i ){
458 nb_element_to_write += offset_info->second.m_all_sizes[i];
461 switch(sdata->baseDataType()){
463 real_array.resize(nb_element_to_write);
464 ptr = real_array.data();
467 real3_array.resize(nb_element_to_write);
468 ptr = real3_array.data();
471 real3x3_array.resize(nb_element_to_write);
472 ptr = real3x3_array.data();
475 int32_array.resize(nb_element_to_write);
476 ptr = int32_array.data();
479 fatal() <<
"Type not handled "<<
dataTypeName(sdata->baseDataType());
494 HGroup var_base_group;
495 var_base_group.recursiveCreate(m_file_id,sub_group_name);
500 group_id.create(var_base_group,var_group_name);
501 if (group_id.isBad()){
503 ostr() <<
"Group HDF5 '" << var_group_name <<
"' not found";
504 throw ReaderWriterException(func_name,ostr.str());
511 bool is_multi_size = sdata->isMultiSize();
514 if (nb_dimension==2 && !is_multi_size){
515 dim1_size = dimensions[0];
516 dim2_size = dimensions[1];
527 space_id.createSimple(1,att_dims);
530 dim_val[0] = nb_dimension;
531 dim_val[1] = dim1_size;
532 dim_val[2] = dim2_size;
533 dim_val[3] = nb_element;
534 dim_val[4] = nb_base_element;
535 dim_val[5] = dimension_array_size;
536 dim_val[6] = is_multi_size ? 1 : 0;
537 dim_val[7] = (
Integer)sdata->baseDataType();
538 dim_val[8] = sdata->memorySize();
542 att_id.create(group_id,
"Dims",m_types.saveType(dim1_size),space_id);
543 herr_t herr = att_id.write(m_types.nativeType(dim2_size),dim_val);
546 ostr() <<
"Bad writing of the dimensions for the variable '" << var_group_name <<
"'";
547 throw ReaderWriterException(func_name,ostr.str());
555 if (dimension_array_size!=0){
557 att_dims[0] = dimension_array_size;
561 space_id.createSimple(1,att_dims);
563 array_id.create(group_id,
"Dim2",m_types.saveType(dim1_size),space_id,H5P_DEFAULT);
564 herr_t herr = array_id.write(m_types.nativeType(dim1_size),dimensions.begin());
567 ostr() <<
"Bad writing of the dimensions for the variable '" << var_group_name <<
"'";
568 throw ReaderWriterException(func_name,ostr.str());
577 if (nb_base_element!=0 && ptr!=0){
578 debug(Trace::High) <<
"Variable " << var_group_name <<
" begin dumped (nb_base_element=" << nb_base_element <<
").";
583 count[0] = nb_element_to_write;
599 Int64 my_index = offset_info->second.m_offset;
600 Int64 total_size = offset_info->second.m_total_size;
601 offset[0] = my_index;
603 double v1 = MPI_Wtime();
605 dims[0] = total_size;
607 filespace_id.createSimple(1,dims);
609 memspace_id.createSimple(1,count);
610 if (memspace_id.isBad()){
612 ostr() <<
"Wrong dataspace for variable '" << var_group_name <<
"'";
613 throw ReaderWriterException(func_name,ostr.str());
620 hid_t write_plist_id = H5Pcreate(H5P_DATASET_XFER);
621#ifdef H5_HAVE_PARALLEL
622 H5Pset_dxpl_mpio(write_plist_id, H5FD_MPIO_COLLECTIVE);
626 hid_t create_dataset_plist_id = H5P_DEFAULT;
628 Integer chunk_size = (4096 << 9);
629 if (total_size>chunk_size){
630 create_dataset_plist_id = H5Pcreate(H5P_DATASET_CREATE);
631 H5Pcreate(H5P_DATASET_CREATE);
632 hsize_t chunk_dim[1];
633 chunk_dim[0] = chunk_size;
634 herr_t r = H5Pset_chunk(create_dataset_plist_id,1,chunk_dim);
635 info() <<
" SET CHUNK FOR " << var_group_name <<
" total=" << total_size <<
" chunk=" << chunk_dim[0];
641 dataset_id.create(m_variable_group_id,var_group_name,save_typeid,filespace_id,create_dataset_plist_id);
642 if (dataset_id.isBad()){
644 ostr() <<
"Wrong dataset for variable '" << var_group_name <<
"'";
645 throw ReaderWriterException(func_name,ostr.str());
647 H5Sselect_hyperslab(filespace_id.id(), H5S_SELECT_SET, offset, NULL, count, NULL);
652 Timer::Sentry ts(&m_write_timer);
653 herr_t herr = dataset_id.write(trueid,ptr,memspace_id,filespace_id,write_plist_id);
656 ostr() <<
"Wrong dataset written for variable '" << var_group_name <<
"'";
657 throw ReaderWriterException(func_name,ostr.str());
660 if (create_dataset_plist_id!=H5P_DEFAULT)
661 H5Pclose(create_dataset_plist_id);
662 H5Pclose(write_plist_id);
664 info() <<
" WRITE DATASET name=" << var_group_name
665 <<
" offset=" << offset[0]
666 <<
" mysize=" << nb_base_element
667 <<
" write_size=" << count[0]
668 <<
" total=" << total_size
669 <<
" rank=" << m_my_rank
670 <<
" clock=" << (MPI_Wtime() - v1);
678 info() <<
"TOTAL = " << (MPI_Wtime()-v0);
684Ref<ISerializedData> Hdf5MpiReaderWriter::
685_readDim2(IVariable* var)
687 const char* func_name =
"Hdf5MpiReaderWriter::_readDim2()";
689 const int max_dim = 256;
691 String vname = _variableGroupName(var);
693 info() <<
" READ DIM name=" << vname;
695 Integer dimension_array_size = 0;
702 bool is_found =
false;
703 for( StringList::Enumerator i(m_variables_name); ++i; )
710 ostr() <<
"No HDF5 group with name '" << vname <<
"' exists";
711 throw ReaderWriterException(func_name,ostr.str());
718 group_id.open(m_sub_group_id,vname);
719 if (group_id.isBad()){
721 ostr() <<
"No HDF5 with name '" << vname <<
"' exists";
722 throw ReaderWriterException(func_name,ostr.str());
724 bool is_multi_size =
false;
734 att_id.open(group_id,
"Dims");
735 HSpace space_id = att_id.getSpace();
739 hsize_t hdf_dims[max_dim];
740 hsize_t max_dims[max_dim];
741 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
745 att_id.read(m_types.nativeType(
Integer()),dim_val);
748 ostr() <<
"Wrong dimensions for variable '" << vname
749 <<
"' (found: " << (int)hdf_dims[0] <<
" expected 9)";
750 throw ReaderWriterException(func_name,ostr.str());
752 nb_dimension = dim_val[0];
753 dim1_size = dim_val[1];
754 dim2_size = dim_val[2];
755 nb_element = dim_val[3];
756 nb_base_element = dim_val[4];
757 dimension_array_size = dim_val[5];
758 is_multi_size = dim_val[6]!=0;
760 memory_size = dim_val[8];
763 info() <<
" READ DIM name=" << vname
764 <<
" nb_dim=" << nb_dimension <<
" dim1_size=" << dim1_size
765 <<
" dim2_size=" << dim2_size <<
" nb_element=" << nb_element
766 <<
" dimension_size=" << dimension_array_size
767 <<
" is_multi_size=" << is_multi_size
768 <<
" data_type" << data_type;
770 if (dimension_array_size>0){
772 array_id.open(group_id,
"Dim2");
774 if (array_id.isBad()){
776 ostr() <<
"Wrong dataset for variable '" << vname <<
"'";
777 throw ReaderWriterException(func_name,ostr.str());
779 HSpace space_id = array_id.getSpace();
780 if (space_id.isBad()){
782 ostr() <<
"Wrong dataspace for variable '" << vname <<
"'";
783 throw ReaderWriterException(func_name,ostr.str());
785 hsize_t hdf_dims[max_dim];
786 hsize_t max_dims[max_dim];
787 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
790 if ((Integer)hdf_dims[0]!=dimension_array_size){
792 ostr() <<
"Wrong number of elements in 'Dim2' for variable '"
793 << vname <<
"' (found: " << hdf_dims[0]
794 <<
" expected " << dimension_array_size <<
")";
795 throw ReaderWriterException(func_name,ostr.str());
798 dims.resize(dimension_array_size);
799 herr_t herr = array_id.read(m_types.nativeType(
Integer()),dims.data());
802 ostr() <<
"Wrong dataset read for variable '" << vname <<
"'";
803 throw ReaderWriterException(func_name,ostr.str());
808 nb_base_element,is_multi_size,dims);
818void Hdf5MpiReaderWriter::
819write(IVariable* v,IData* data)
821 if (v->itemKind()==IK_Unknown)
825 _directWriteVal(v,data);
831void Hdf5MpiReaderWriter::
832_readVal(IVariable* v,IData* data)
834 const char* func_name =
"Hdf5MpiReaderWriter::_readVal() ";
836 String var_group_name = _variableGroupName(v);
838 info() <<
" TRY TO READ var_group=" << var_group_name;
840 Ref<ISerializedData> sd(_readDim2(v));
841 Int64 storage_size = sd->memorySize();
843 info() <<
" READ DATA n=" << storage_size;
845 data->allocateBufferForSerializedData(sd.get());
850 if (storage_size!=0){
854 group_id.open(m_sub_group_id,var_group_name);
855 if (group_id.isBad()){
857 ostr() <<
"No HDF5 group with name '" << var_group_name <<
"' exists";
858 throw ReaderWriterException(func_name,ostr.str());
862 dataset_id.open(group_id,
"Values");
863 if (dataset_id.isBad()){
865 ostr() <<
"Wrong dataset for variable '" << var_group_name <<
"'";
866 throw ReaderWriterException(func_name,ostr.str());
871 void* ptr = sd->writableBytes().data();
872 info() <<
"READ Variable " << var_group_name <<
" ptr=" << ptr;;
873 hid_t trueid = m_types.nativeType(sd->baseDataType());
874 dataset_id.read(trueid,ptr);
877 data->assignSerializedData(sd.get());
883void Hdf5MpiReaderWriter::
884read(IVariable* var,IData* data)
886 _directReadVal(var,data);
892void Hdf5MpiReaderWriter::
893setMetaData(
const String& meta_data)
895 ARCANE_UNUSED(meta_data);
898 IParallelMng* pm = m_parallel_mng;
899 Integer nb_rank = pm->commSize();
900 if (m_send_rank!=m_my_rank){
903 sb.setMode(ISerializer::ModeReserve);
904 sb.reserve(m_sub_group_name);
905 sb.reserve(meta_data);
907 sb.setMode(ISerializer::ModePut);
908 sb.put(m_sub_group_name);
910 m_parallel_mng->sendSerializer(&sb,m_send_rank);
913 _setMetaData(meta_data,m_sub_group_name);
914 for( Integer i=m_send_rank+1; i<=m_last_recv_rank; ++i ){
916 pm->recvSerializer(&sb,i);
917 sb.setMode(ISerializer::ModeGet);
918 String remote_group_name;
919 String remote_meta_data;
920 sb.get(remote_group_name);
921 sb.get(remote_meta_data);
922 _setMetaData(remote_meta_data,remote_group_name);
927 _setMetaData(meta_data,m_sub_group_name);
934void Hdf5MpiReaderWriter::
935_setMetaData(
const String& meta_data,
const String& sub_group_name)
937 ARCANE_UNUSED(meta_data);
938 ARCANE_UNUSED(sub_group_name);
940 const char* func_name =
"Hdf5MpiReaderWriter::setMetaData()";
943 base_group.recursiveCreate(m_file_id,sub_group_name);
946 const Byte* _meta_data = meta_data_utf8.begin();
949 dims[0] = meta_data_utf8.size() + 1;
951 space_id.createSimple(1,dims);
952 if (space_id.isBad())
953 throw ReaderWriterException(func_name,
"Bad 'space' for the meta-data ('MetaData')");
956 dataset_id.create(base_group,
"MetaData",m_types.nativeType(
Byte()),space_id,H5P_DEFAULT);
957 if (dataset_id.isBad())
958 throw ReaderWriterException(func_name,
"Bad 'dataset' for the meta-data ('MetaData')");
960 herr_t herr = dataset_id.write(m_types.nativeType(
Byte()),_meta_data);
962 throw ReaderWriterException(func_name,
"Can't write the meta-data ('MetaData')");
969String Hdf5MpiReaderWriter::
972 const char* func_name =
"Hdf5MpiReaderWriter::readMetaData()";
974 dataset_id.open(m_sub_group_id,
"MetaData");
975 if (dataset_id.isBad()){
976 throw ReaderWriterException(func_name,
"Wrong dataset for meta-data ('MetaData')");
978 HSpace space_id = dataset_id.getSpace();
979 if (space_id.isBad()){
980 throw ReaderWriterException(func_name,
"Wrong space for meta-data ('MetaData')");
982 const int max_dim = 256;
983 hsize_t hdf_dims[max_dim];
984 hsize_t max_dims[max_dim];
985 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
987 throw ReaderWriterException(func_name,
"Wrong number of elements for meta-data ('MetaData')");
990 dataset_id.read(m_types.nativeType(
Byte()),uchars.data());
998void Hdf5MpiReaderWriter::
1003 if (m_my_rank==m_send_rank){
1004 _receiveRemoteVariables();
1009 sb.setMode(ISerializer::ModeReserve);
1010 sb.reserve(DT_Int32,1);
1011 sb.allocateBuffer();
1012 sb.setMode(ISerializer::ModePut);
1014 m_parallel_mng->sendSerializer(&sb,m_send_rank);
1019 info() <<
" Hdf5Timer: nb_activated=" << m_io_timer.nbActivated()
1020 <<
" time=" << m_io_timer.totalTime()
1021 <<
" write=" << m_write_timer.nbActivated()
1022 <<
" timewrite=" << m_write_timer.totalTime();
1029void Hdf5MpiReaderWriter::
1030_receiveRemoteVariables()
1032 IParallelMng* pm = m_parallel_mng;
1033 Integer nb_remaining = m_last_recv_rank - m_send_rank;
1034 info() <<
"NB REMAINING = " << nb_remaining;
1035 Ref<ISerializeMessageList> m_messages(pm->createSerializeMessageListRef());
1037 while(nb_remaining>0){
1038 ISerializeMessage* sm =
new SerializeMessage(m_my_rank,NULL_SUB_DOMAIN_ID,ISerializeMessage::MT_Recv);
1039 m_messages->addMessage(sm);
1040 m_messages->processPendingMessages();
1041 m_messages->waitMessages(Parallel::WaitAll);
1043 ISerializer* sb = sm->serializer();
1044 sb->setMode(ISerializer::ModeGet);
1046 Int32
id = sb->getInt32();
1052 _writeRemoteVariable(sb);
1060void Hdf5MpiReaderWriter::
1061_writeRemoteVariable(ISerializer* sb)
1066 sb->get(group_name);
1072 sb->setReadMode(ISerializer::ReadReplace);
1073 sdata->serialize(sb);
1074 _writeVal(var_name,group_name,sdata.get());
1085class ArcaneHdf5MpiCheckpointService2
1086:
public ArcaneHdf5MpiReaderWriterObject
1090 ArcaneHdf5MpiCheckpointService2(
const ServiceBuildInfo& sbi)
1091 : ArcaneHdf5MpiReaderWriterObject(sbi), m_write_index(0), m_writer(0), m_reader(0)
1095 virtual IDataWriter* dataWriter() {
return m_writer; }
1096 virtual IDataReader* dataReader() {
return m_reader; }
1098 virtual void notifyBeginWrite();
1099 virtual void notifyEndWrite();
1100 virtual void notifyBeginRead();
1101 virtual void notifyEndRead();
1102 virtual void close() {}
1103 virtual String readerServiceName()
const {
return "ArcaneHdf5MpiCheckpointReader2"; }
1108 Hdf5MpiReaderWriter* m_writer;
1109 Hdf5MpiReaderWriter* m_reader;
1114 String _defaultFileName()
1116 return "arcanedump.mpi.h5";
1118 Directory _defaultDirectory()
1120 return Directory(baseDirectoryName());
1122 void _parseMetaData(String meta_data);
1128void ArcaneHdf5MpiCheckpointService2::
1129_parseMetaData(String meta_data)
1131 IIOMng* io_mng = subDomain()->ioMng();
1132 ScopedPtrT<IXmlDocumentHolder> xml_doc(io_mng->parseXmlBuffer(meta_data.utf8(),
"MetaData"));
1133 XmlNode root = xml_doc->documentNode().documentElement();
1134 Integer version = root.attr(
"version").valueAsInteger();
1136 throw ReaderWriterException(
"ArcaneHdf5MpiCheckpointService2::_parseMetaData",
"Bad version (expected 1)");
1140 info() <<
" FileSet size=" << m_fileset_size;
1146void ArcaneHdf5MpiCheckpointService2::
1149 String meta_data = readerMetaData();
1150 _parseMetaData(meta_data);
1152 info() <<
" GET META DATA READER " << readerMetaData()
1153 <<
" filename=" << fileName();
1155 if (fileName().null()){
1156 Directory dump_dir(_defaultDirectory());
1159 setFileName(dump_dir.file(_defaultFileName()));
1163 info() <<
" READ CHECKPOINT FILENAME = " << fileName();
1164 StringBuilder sub_group;
1169 sub_group =
"Index";
1170 sub_group += currentIndex();
1171 m_reader =
new Hdf5MpiReaderWriter(subDomain(),fileName(),sub_group.toString(),0,Hdf5MpiReaderWriter::OpenModeRead);
1172 m_reader->initialize();
1178void ArcaneHdf5MpiCheckpointService2::
1188void ArcaneHdf5MpiCheckpointService2::
1192 m_fileset_size = options()->filesetSize();
1194 if (fileName().null()){
1195 Directory dump_dir(_defaultDirectory());
1199 setFileName(dump_dir.file(_defaultFileName()));
1202 Hdf5MpiReaderWriter::eOpenMode open_mode = Hdf5MpiReaderWriter::OpenModeAppend;
1203 Integer write_index = checkpointTimes().size();
1206 open_mode = Hdf5MpiReaderWriter::OpenModeTruncate;
1211 StringBuilder sub_group;
1217 sub_group =
"Index";
1218 sub_group += write_index;
1220 m_writer =
new Hdf5MpiReaderWriter(subDomain(),fileName(),sub_group.toString(),m_fileset_size,open_mode);
1221 m_writer->initialize();
1227void ArcaneHdf5MpiCheckpointService2::
1231 ostr() <<
"<infos version='1'>\n";
1232 ostr() <<
" <fileset-size>" << m_fileset_size <<
"</fileset-size>\n";
1233 ostr() <<
"</infos>\n";
1234 setReaderMetaData(ostr.str());
1245 ArcaneHdf5MpiCheckpointReader2);
1249 ArcaneHdf5MpiCheckpointWriter2);
1251ARCANE_REGISTER_SERVICE_HDF5MPIREADERWRITER(ArcaneHdf5MpiCheckpoint2,
1252 ArcaneHdf5MpiCheckpointService2);
#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.
Chaîne de caractères unicode.
Classe d'accès aux traces.
Fonctions utilitaires pour Hdf5.
-*- 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.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
UniqueArray< Real > RealUniqueArray
Tableau dynamique à une dimension de réels.
Ref< ISerializedData > arcaneCreateEmptySerializedDataRef()
Créé des données sérialisées.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
unsigned char Byte
Type d'un octet.
eDataType
Type d'une donnée.
@ DT_Real3x3
Donnée de type tenseur 3x3.
@ DT_Int32
Donnée de type entier 32 bits.
@ DT_Real3
Donnée de type vecteur 3.
@ DT_Unknown
Donnée de type inconnue ou non initialisée.
@ DT_Real
Donnée de type réel.
const char * dataTypeName(eDataType type)
Nom du type de donnée.