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/ArcanePrecomp.h"
20#include "arcane/utils/ITraceMng.h"
21#include "arcane/utils/PlatformUtils.h"
22#include "arcane/utils/StringBuilder.h"
24#include "arcane/Item.h"
25#include "arcane/IDataReader.h"
26#include "arcane/IDataWriter.h"
27#include "arcane/ISubDomain.h"
28#include "arcane/StdNum.h"
29#include "arcane/IVariable.h"
30#include "arcane/CheckpointService.h"
31#include "arcane/Directory.h"
32#include "arcane/IParallelMng.h"
33#include "arcane/Service.h"
34#include "arcane/ArcaneException.h"
35#include "arcane/ItemGroup.h"
36#include "arcane/ItemEnumerator.h"
37#include "arcane/VerifierService.h"
38#include "arcane/IVariableMng.h"
39#include "arcane/FactoryService.h"
40#include "arcane/IData.h"
41#include "arcane/Timer.h"
42#include "arcane/ISerializedData.h"
43#include "arcane/IIOMng.h"
44#include "arcane/IXmlDocumentHolder.h"
45#include "arcane/VariableCollection.h"
47#include "arcane/datatype/DataTypeTraits.h"
49#include "arcane/SerializeBuffer.h"
50#include "arcane/ISerializeMessageList.h"
51#include "arcane/SerializeMessage.h"
53#include "arcane/hdf5/Hdf5MpiReaderWriter.h"
55#include "arcane/hdf5/Hdf5MpiReaderWriter_axl.h"
57#include "arcane_packages.h"
59#ifdef ARCANE_HAS_PACKAGE_MPI
60#ifndef OMPI_SKIP_MPICXX
61#define OMPI_SKIP_MPICXX
63#ifndef MPICH_SKIP_MPICXX
64#define MPICH_SKIP_MPICXX
82using namespace Hdf5Utils;
84static herr_t _Hdf5MpiReaderWriterIterateMe(hid_t,
const char*,
void*);
90Hdf5MpiReaderWriter(ISubDomain* sd,
const String& filename,
91 const String& sub_group_name,Integer fileset_size,
92 eOpenMode open_mode,
bool do_verif)
93: TraceAccessor(sd->traceMng())
95, m_parallel_mng(sd->parallelMng())
96, m_open_mode(open_mode)
98, m_sub_group_name(sub_group_name)
99, m_is_initialized(false)
100, m_io_timer(sd,
"Hdf5TimerHd",Timer::TimerReal)
101, m_write_timer(sd,
"Hdf5TimerWrite",Timer::TimerReal)
102, m_is_parallel(false)
103, m_my_rank(m_parallel_mng->commRank())
104, m_send_rank(m_my_rank)
105, m_last_recv_rank(m_my_rank)
106, m_fileset_size(fileset_size)
108 ARCANE_UNUSED(do_verif);
109 if (m_fileset_size!=1 && m_parallel_mng->isParallel()){
110 m_is_parallel =
true;
111 Integer nb_rank = m_parallel_mng->commSize();
112 if (m_fileset_size==0){
114 m_last_recv_rank = nb_rank;
118 m_send_rank = (m_my_rank / m_fileset_size) * m_fileset_size;
119 m_last_recv_rank = m_send_rank + m_fileset_size;
120 if (m_last_recv_rank>nb_rank)
121 m_last_recv_rank = nb_rank;
125 sd->traceMng()->info() <<
" INFOS PARALLEL: my_rank=" << m_my_rank
126 <<
" send_rank=" << m_send_rank
127 <<
" last_recv_rank=" << m_last_recv_rank
128 <<
" filename=" << filename
129 <<
" fileset_size=" << m_fileset_size;
135void Hdf5MpiReaderWriter::
138 if (m_is_initialized)
141 m_is_initialized =
true;
143 const char* func_name =
"Hdf5MpiReaderWriter::initialize()";
147 if (m_open_mode==OpenModeRead){
148 m_file_id.openRead(m_filename);
149 m_sub_group_id.recursiveOpen(m_file_id,m_sub_group_name);
153 void* arcane_comm = m_sub_domain->parallelMng()->getMPICommunicator();
155 throw FatalErrorException(
"No MPI environment available");
156 MPI_Comm mpi_comm = *((MPI_Comm*)arcane_comm);
157 Integer nb_rank = m_parallel_mng->commSize();
158 if (m_fileset_size>1){
159 UniqueArray<int> senders;
160 for( Integer i=0; i<nb_rank; ++i ){
161 Integer modulo = i % m_fileset_size;
163 info() <<
" ADD SENDER n=" << i;
168 if (MPI_Comm_group(mpi_comm,&all_group)!=MPI_SUCCESS)
169 fatal() <<
"Error in MPI_Comm_group";
170 MPI_Group writer_group;
171 if (MPI_Group_incl(all_group,senders.size(),senders.data(),&writer_group)!=MPI_SUCCESS)
172 fatal() <<
"Error in MPI_Group_incl";
173 if (MPI_Comm_create(mpi_comm,writer_group,&mpi_comm)!=MPI_SUCCESS)
174 fatal() <<
"Error in MPI_Comm_create";
178 if (m_send_rank!=m_my_rank)
180 if (m_open_mode==OpenModeTruncate || m_open_mode==OpenModeAppend){
181 hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS);
183 info() <<
" USE MPI-POSIX";
185#ifdef H5_HAVE_PARALLEL
186 H5Pset_fapl_mpio(plist_id, mpi_comm, MPI_INFO_NULL);
189#ifdef ARCANE_TEST_HDF5DIRECT
190# ifdef H5_HAVE_DIRECT
191 info() <<
" HAVE DIRECT DRIVER";
192 H5Pset_fapl_direct(plist_id,4096,512,16*1024*1024);
199 herr_t r = H5Pget_cache(plist_id,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0);
200 info() <<
" CACHE SIZE r=" << r <<
" mdc=" << mdc_nelmts
201 <<
" rdcc=" << rdcc_nelmts <<
" rdcc_bytes=" << rdcc_nbytes <<
" w0=" << rdcc_w0;
204 rdcc_nbytes = 10000000;
205 r = H5Pset_cache(plist_id,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0);
206 info() <<
" SET CACHE SIZE R1=" << r;
209 hsize_t sieve_buf = (1024 << 12);
210 r = H5Pset_sieve_buf_size(plist_id,sieve_buf);
211 info() <<
" SIEVE_BUF=" << sieve_buf <<
" r=" << r;
212 hsize_t small_block_size = 0;
213 r = H5Pget_small_data_block_size(plist_id,&small_block_size);
214 info() <<
" SMALL BLOCK SIZE=" << small_block_size;
215 small_block_size <<= 10;
216 r = H5Pset_small_data_block_size(plist_id,small_block_size);
217 info() <<
" SET SMALL BLOCK SIZE s=" << small_block_size <<
" r=" << r;
231 if (m_open_mode==OpenModeTruncate){
232 info() <<
" BEGIN OPEN TRUNCATE";
233 m_file_id.openTruncate(m_filename,plist_id);
234 info() <<
" END OPEN TRUNCATE";
236 else if (m_open_mode==OpenModeAppend){
237 info() <<
" BEGIN OPEN ADD";
238 m_file_id.openAppend(m_filename,plist_id);
239 info() <<
" END OPEN ADD";
242 if (m_sub_group_name!=
"/"){
243 info() <<
" CHECK CREATE GROUP name=" << m_sub_group_name;
245 m_sub_group_id.recursiveCreate(m_file_id,m_sub_group_name);
246 info() <<
" END CHECK CREATE GROUP name=" << m_sub_group_name;
249 m_sub_group_id.open(m_file_id,m_sub_group_name);
250 m_variable_group_id.create(m_sub_group_id,
"Variables");
253 if (m_file_id.isBad()){
255 ostr() <<
"Unable to open file <" << m_filename <<
">";
256 throw ReaderWriterException(func_name,ostr.str());
258 if (m_sub_group_id.isBad()){
260 ostr() <<
"HDF5 group '" << m_sub_group_name <<
"' not found";
261 throw ReaderWriterException(func_name,ostr.str());
264 if (m_variable_group_id.isBad()){
266 ostr() <<
"Group HDF5 'Variables' not found";
267 throw ReaderWriterException(func_name,ostr.str());
271 info() <<
" INFO END INITIALIZE";
274 if (m_open_mode==OpenModeRead){
277 H5Giterate(m_file_id.id(),m_sub_group_name.localstr(),&index,_Hdf5MpiReaderWriterIterateMe,
this);
285~Hdf5MpiReaderWriter()
292void Hdf5MpiReaderWriter::
295 if (m_is_initialized)
297 fatal() <<
"Use of a Hdf5MpiReaderWriter instance not initialized";
303String Hdf5MpiReaderWriter::
304_variableGroupName(IVariable* var)
306 return var->fullName();
312void Hdf5MpiReaderWriter::
313beginWrite(
const VariableCollection& vars)
315 IParallelMng* pm = m_parallel_mng;
316 Integer nb_rank = pm->commSize();
318 pwarning() <<
"Implementation of this checkpoint format is not operational yet";
320 for( VariableCollection::Enumerator i(vars); ++i; ){
322 if (v->itemKind()==IK_Unknown)
325 Ref<ISerializedData> sdata(v->data()->createSerializedDataRef(
false));
326 Int64 nb_base_element = sdata->nbBaseElement();
328 Int64 my_size = nb_base_element;
330 SharedArray<Int64> all_sizes(nb_rank);
331 pm->allGather(a_my_size,all_sizes);
333 Int64 total_size = 0;
334 for( Integer i=0; i<nb_rank; ++i )
335 total_size += all_sizes[i];
337 for( Integer i=0; i<m_my_rank; ++i )
338 my_index += all_sizes[i];
339 m_variables_offset.insert(std::make_pair(v->fullName(),VarOffset(my_index,total_size,all_sizes)));
340 info() <<
" ADD OFFSET v=" << v->fullName() <<
" offset=" << my_index
341 <<
" total_size=" << total_size;
353void Hdf5MpiReaderWriter::
354_writeValParallel(IVariable* v,
const ISerializedData* sdata)
357 sb.setMode(ISerializer::ModeReserve);
358 sb.reserve(DT_Int32,1);
359 sb.reserve(v->fullName());
360 sb.reserve(m_sub_group_name);
364 sdata->serialize(&sb);
366 sb.setMode(ISerializer::ModePut);
368 sb.put(v->fullName());
369 sb.put(m_sub_group_name);
373 sdata->serialize(&sb);
375 m_parallel_mng->sendSerializer(&sb,m_send_rank);
381void Hdf5MpiReaderWriter::
382_directReadVal(IVariable* v,IData* data)
386 info() <<
"DIRECT READ VAL v=" << v->name();
393void Hdf5MpiReaderWriter::
394_directWriteVal(IVariable* v,IData* data)
398 Ref<ISerializedData> sdata(data->createSerializedDataRef(
false));
400 _writeVal(v->fullName(),m_sub_group_name,sdata.get());
407_Hdf5MpiReaderWriterIterateMe(hid_t g,
const char* mn,
void* ptr)
409 Hdf5MpiReaderWriter* rw =
reinterpret_cast<Hdf5MpiReaderWriter*
>(ptr);
410 return rw->iterateMe(g,mn);
416herr_t Hdf5MpiReaderWriter::
417iterateMe(hid_t group_id,
const char* member_name)
419 ARCANE_UNUSED(group_id);
421 m_variables_name.add(std::string_view(member_name));
429void Hdf5MpiReaderWriter::
430_writeVal(
const String& var_group_name,
const String& sub_group_name,
431 const ISerializedData* sdata)
433 ARCANE_UNUSED(sub_group_name);
434 const char* func_name =
"Hdf5MpiReaderWriter::_writeVal() ";
435 Timer::Sentry ts(&m_io_timer);
436 double v0 = ::MPI_Wtime();
437 info() <<
" SDATA name=" << var_group_name <<
" nb_element=" << sdata->nbElement()
438 <<
" dim=" << sdata->nbDimension() <<
" datatype=" << sdata->baseDataType()
439 <<
" nb_basic_element=" << sdata->nbBaseElement()
440 <<
" is_multi=" << sdata->isMultiSize()
441 <<
" dimensions_size=" << sdata->extents().size()
442 <<
" memory_size=" << sdata->memorySize()
443 <<
" bytes_size=" << sdata->constBytes().size();
445 hid_t save_typeid = m_types.saveType(sdata->baseDataType());
446 hid_t trueid = m_types.nativeType(sdata->baseDataType());
447 const void* ptr = sdata->constBytes().data();
448 Int64 nb_base_element = sdata->nbBaseElement();
450 OffsetMap::const_iterator offset_info = m_variables_offset.find(var_group_name);
451 if (offset_info==m_variables_offset.end()){
452 fatal() <<
"Can not find offset informations for ->" << var_group_name;
454 Int64 nb_element_to_write = nb_base_element;
461 if (m_is_parallel && m_fileset_size!=1){
462 if (m_send_rank==m_my_rank){
464 nb_element_to_write = 0;
465 for( Integer i=m_send_rank; i<=m_last_recv_rank; ++i ){
466 nb_element_to_write += offset_info->second.m_all_sizes[i];
469 switch(sdata->baseDataType()){
471 real_array.resize(nb_element_to_write);
472 ptr = real_array.data();
475 real3_array.resize(nb_element_to_write);
476 ptr = real3_array.data();
479 real3x3_array.resize(nb_element_to_write);
480 ptr = real3x3_array.data();
483 int32_array.resize(nb_element_to_write);
484 ptr = int32_array.data();
487 fatal() <<
"Type not handled "<<
dataTypeName(sdata->baseDataType());
502 HGroup var_base_group;
503 var_base_group.recursiveCreate(m_file_id,sub_group_name);
508 group_id.create(var_base_group,var_group_name);
509 if (group_id.isBad()){
511 ostr() <<
"Group HDF5 '" << var_group_name <<
"' not found";
512 throw ReaderWriterException(func_name,ostr.str());
519 bool is_multi_size = sdata->isMultiSize();
522 if (nb_dimension==2 && !is_multi_size){
523 dim1_size = dimensions[0];
524 dim2_size = dimensions[1];
535 space_id.createSimple(1,att_dims);
538 dim_val[0] = nb_dimension;
539 dim_val[1] = dim1_size;
540 dim_val[2] = dim2_size;
541 dim_val[3] = nb_element;
542 dim_val[4] = nb_base_element;
543 dim_val[5] = dimension_array_size;
544 dim_val[6] = is_multi_size ? 1 : 0;
545 dim_val[7] = (
Integer)sdata->baseDataType();
546 dim_val[8] = sdata->memorySize();
550 att_id.create(group_id,
"Dims",m_types.saveType(dim1_size),space_id);
551 herr_t herr = att_id.write(m_types.nativeType(dim2_size),dim_val);
554 ostr() <<
"Bad writing of the dimensions for the variable '" << var_group_name <<
"'";
555 throw ReaderWriterException(func_name,ostr.str());
563 if (dimension_array_size!=0){
565 att_dims[0] = dimension_array_size;
569 space_id.createSimple(1,att_dims);
571 array_id.create(group_id,
"Dim2",m_types.saveType(dim1_size),space_id,H5P_DEFAULT);
572 herr_t herr = array_id.write(m_types.nativeType(dim1_size),dimensions.begin());
575 ostr() <<
"Bad writing of the dimensions for the variable '" << var_group_name <<
"'";
576 throw ReaderWriterException(func_name,ostr.str());
585 if (nb_base_element!=0 && ptr!=0){
586 debug(
Trace::High) <<
"Variable " << var_group_name <<
" begin dumped (nb_base_element=" << nb_base_element <<
").";
591 count[0] = nb_element_to_write;
607 Int64 my_index = offset_info->second.m_offset;
608 Int64 total_size = offset_info->second.m_total_size;
609 offset[0] = my_index;
611 double v1 = MPI_Wtime();
613 dims[0] = total_size;
615 filespace_id.createSimple(1,dims);
617 memspace_id.createSimple(1,count);
618 if (memspace_id.isBad()){
620 ostr() <<
"Wrong dataspace for variable '" << var_group_name <<
"'";
621 throw ReaderWriterException(func_name,ostr.str());
628 hid_t write_plist_id = H5Pcreate(H5P_DATASET_XFER);
629#ifdef H5_HAVE_PARALLEL
630 H5Pset_dxpl_mpio(write_plist_id, H5FD_MPIO_COLLECTIVE);
634 hid_t create_dataset_plist_id = H5P_DEFAULT;
636 Integer chunk_size = (4096 << 9);
637 if (total_size>chunk_size){
638 create_dataset_plist_id = H5Pcreate(H5P_DATASET_CREATE);
639 H5Pcreate(H5P_DATASET_CREATE);
640 hsize_t chunk_dim[1];
641 chunk_dim[0] = chunk_size;
642 herr_t r = H5Pset_chunk(create_dataset_plist_id,1,chunk_dim);
643 info() <<
" SET CHUNK FOR " << var_group_name <<
" total=" << total_size <<
" chunk=" << chunk_dim[0];
649 dataset_id.create(m_variable_group_id,var_group_name,save_typeid,filespace_id,create_dataset_plist_id);
650 if (dataset_id.isBad()){
652 ostr() <<
"Wrong dataset for variable '" << var_group_name <<
"'";
653 throw ReaderWriterException(func_name,ostr.str());
655 H5Sselect_hyperslab(filespace_id.id(), H5S_SELECT_SET, offset, NULL, count, NULL);
660 Timer::Sentry ts(&m_write_timer);
661 herr_t herr = dataset_id.write(trueid,ptr,memspace_id,filespace_id,write_plist_id);
664 ostr() <<
"Wrong dataset written for variable '" << var_group_name <<
"'";
665 throw ReaderWriterException(func_name,ostr.str());
668 if (create_dataset_plist_id!=H5P_DEFAULT)
669 H5Pclose(create_dataset_plist_id);
670 H5Pclose(write_plist_id);
672 info() <<
" WRITE DATASET name=" << var_group_name
673 <<
" offset=" << offset[0]
674 <<
" mysize=" << nb_base_element
675 <<
" write_size=" << count[0]
676 <<
" total=" << total_size
677 <<
" rank=" << m_my_rank
678 <<
" clock=" << (MPI_Wtime() - v1);
686 info() <<
"TOTAL = " << (MPI_Wtime()-v0);
692Ref<ISerializedData> Hdf5MpiReaderWriter::
693_readDim2(IVariable* var)
695 const char* func_name =
"Hdf5MpiReaderWriter::_readDim2()";
697 const int max_dim = 256;
699 String vname = _variableGroupName(var);
701 info() <<
" READ DIM name=" << vname;
703 Integer dimension_array_size = 0;
710 bool is_found =
false;
711 for( StringList::Enumerator i(m_variables_name); ++i; )
718 ostr() <<
"No HDF5 group with name '" << vname <<
"' exists";
719 throw ReaderWriterException(func_name,ostr.str());
726 group_id.open(m_sub_group_id,vname);
727 if (group_id.isBad()){
729 ostr() <<
"No HDF5 with name '" << vname <<
"' exists";
730 throw ReaderWriterException(func_name,ostr.str());
732 bool is_multi_size =
false;
742 att_id.open(group_id,
"Dims");
743 HSpace space_id = att_id.getSpace();
747 hsize_t hdf_dims[max_dim];
748 hsize_t max_dims[max_dim];
749 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
753 att_id.read(m_types.nativeType(
Integer()),dim_val);
756 ostr() <<
"Wrong dimensions for variable '" << vname
757 <<
"' (found: " << (int)hdf_dims[0] <<
" expected 9)";
758 throw ReaderWriterException(func_name,ostr.str());
760 nb_dimension = dim_val[0];
761 dim1_size = dim_val[1];
762 dim2_size = dim_val[2];
763 nb_element = dim_val[3];
764 nb_base_element = dim_val[4];
765 dimension_array_size = dim_val[5];
766 is_multi_size = dim_val[6]!=0;
768 memory_size = dim_val[8];
771 info() <<
" READ DIM name=" << vname
772 <<
" nb_dim=" << nb_dimension <<
" dim1_size=" << dim1_size
773 <<
" dim2_size=" << dim2_size <<
" nb_element=" << nb_element
774 <<
" dimension_size=" << dimension_array_size
775 <<
" is_multi_size=" << is_multi_size
776 <<
" data_type" << data_type;
778 if (dimension_array_size>0){
780 array_id.open(group_id,
"Dim2");
782 if (array_id.isBad()){
784 ostr() <<
"Wrong dataset for variable '" << vname <<
"'";
785 throw ReaderWriterException(func_name,ostr.str());
787 HSpace space_id = array_id.getSpace();
788 if (space_id.isBad()){
790 ostr() <<
"Wrong dataspace for variable '" << vname <<
"'";
791 throw ReaderWriterException(func_name,ostr.str());
793 hsize_t hdf_dims[max_dim];
794 hsize_t max_dims[max_dim];
795 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
798 if ((Integer)hdf_dims[0]!=dimension_array_size){
800 ostr() <<
"Wrong number of elements in 'Dim2' for variable '"
801 << vname <<
"' (found: " << hdf_dims[0]
802 <<
" expected " << dimension_array_size <<
")";
803 throw ReaderWriterException(func_name,ostr.str());
806 dims.resize(dimension_array_size);
807 herr_t herr = array_id.read(m_types.nativeType(
Integer()),dims.data());
810 ostr() <<
"Wrong dataset read for variable '" << vname <<
"'";
811 throw ReaderWriterException(func_name,ostr.str());
816 nb_base_element,is_multi_size,dims);
826void Hdf5MpiReaderWriter::
827write(IVariable* v,IData* data)
829 if (v->itemKind()==IK_Unknown)
833 _directWriteVal(v,data);
839void Hdf5MpiReaderWriter::
840_readVal(IVariable* v,IData* data)
842 const char* func_name =
"Hdf5MpiReaderWriter::_readVal() ";
844 String var_group_name = _variableGroupName(v);
846 info() <<
" TRY TO READ var_group=" << var_group_name;
848 Ref<ISerializedData> sd(_readDim2(v));
849 Int64 storage_size = sd->memorySize();
851 info() <<
" READ DATA n=" << storage_size;
853 data->allocateBufferForSerializedData(sd.get());
858 if (storage_size!=0){
862 group_id.open(m_sub_group_id,var_group_name);
863 if (group_id.isBad()){
865 ostr() <<
"No HDF5 group with name '" << var_group_name <<
"' exists";
866 throw ReaderWriterException(func_name,ostr.str());
870 dataset_id.open(group_id,
"Values");
871 if (dataset_id.isBad()){
873 ostr() <<
"Wrong dataset for variable '" << var_group_name <<
"'";
874 throw ReaderWriterException(func_name,ostr.str());
879 void* ptr = sd->writableBytes().data();
880 info() <<
"READ Variable " << var_group_name <<
" ptr=" << ptr;;
881 hid_t trueid = m_types.nativeType(sd->baseDataType());
882 dataset_id.read(trueid,ptr);
885 data->assignSerializedData(sd.get());
891void Hdf5MpiReaderWriter::
892read(IVariable* var,IData* data)
894 _directReadVal(var,data);
900void Hdf5MpiReaderWriter::
901setMetaData(
const String& meta_data)
903 ARCANE_UNUSED(meta_data);
906 IParallelMng* pm = m_parallel_mng;
907 Integer nb_rank = pm->commSize();
908 if (m_send_rank!=m_my_rank){
911 sb.setMode(ISerializer::ModeReserve);
912 sb.reserve(m_sub_group_name);
913 sb.reserve(meta_data);
915 sb.setMode(ISerializer::ModePut);
916 sb.put(m_sub_group_name);
918 m_parallel_mng->sendSerializer(&sb,m_send_rank);
921 _setMetaData(meta_data,m_sub_group_name);
922 for( Integer i=m_send_rank+1; i<=m_last_recv_rank; ++i ){
924 pm->recvSerializer(&sb,i);
925 sb.setMode(ISerializer::ModeGet);
926 String remote_group_name;
927 String remote_meta_data;
928 sb.get(remote_group_name);
929 sb.get(remote_meta_data);
930 _setMetaData(remote_meta_data,remote_group_name);
935 _setMetaData(meta_data,m_sub_group_name);
942void Hdf5MpiReaderWriter::
943_setMetaData(
const String& meta_data,
const String& sub_group_name)
945 ARCANE_UNUSED(meta_data);
946 ARCANE_UNUSED(sub_group_name);
948 const char* func_name =
"Hdf5MpiReaderWriter::setMetaData()";
951 base_group.recursiveCreate(m_file_id,sub_group_name);
954 const Byte* _meta_data = meta_data_utf8.begin();
957 dims[0] = meta_data_utf8.size() + 1;
959 space_id.createSimple(1,dims);
960 if (space_id.isBad())
961 throw ReaderWriterException(func_name,
"Bad 'space' for the meta-data ('MetaData')");
964 dataset_id.create(base_group,
"MetaData",m_types.nativeType(
Byte()),space_id,H5P_DEFAULT);
965 if (dataset_id.isBad())
966 throw ReaderWriterException(func_name,
"Bad 'dataset' for the meta-data ('MetaData')");
968 herr_t herr = dataset_id.write(m_types.nativeType(
Byte()),_meta_data);
970 throw ReaderWriterException(func_name,
"Can't write the meta-data ('MetaData')");
977String Hdf5MpiReaderWriter::
980 const char* func_name =
"Hdf5MpiReaderWriter::readMetaData()";
982 dataset_id.open(m_sub_group_id,
"MetaData");
983 if (dataset_id.isBad()){
984 throw ReaderWriterException(func_name,
"Wrong dataset for meta-data ('MetaData')");
986 HSpace space_id = dataset_id.getSpace();
987 if (space_id.isBad()){
988 throw ReaderWriterException(func_name,
"Wrong space for meta-data ('MetaData')");
990 const int max_dim = 256;
991 hsize_t hdf_dims[max_dim];
992 hsize_t max_dims[max_dim];
993 H5Sget_simple_extent_dims(space_id.id(),hdf_dims,max_dims);
995 throw ReaderWriterException(func_name,
"Wrong number of elements for meta-data ('MetaData')");
998 dataset_id.read(m_types.nativeType(
Byte()),uchars.data());
1006void Hdf5MpiReaderWriter::
1011 if (m_my_rank==m_send_rank){
1012 _receiveRemoteVariables();
1017 sb.setMode(ISerializer::ModeReserve);
1018 sb.reserve(DT_Int32,1);
1019 sb.allocateBuffer();
1020 sb.setMode(ISerializer::ModePut);
1022 m_parallel_mng->sendSerializer(&sb,m_send_rank);
1027 info() <<
" Hdf5Timer: nb_activated=" << m_io_timer.nbActivated()
1028 <<
" time=" << m_io_timer.totalTime()
1029 <<
" write=" << m_write_timer.nbActivated()
1030 <<
" timewrite=" << m_write_timer.totalTime();
1037void Hdf5MpiReaderWriter::
1038_receiveRemoteVariables()
1040 IParallelMng* pm = m_parallel_mng;
1041 Integer nb_remaining = m_last_recv_rank - m_send_rank;
1042 info() <<
"NB REMAINING = " << nb_remaining;
1043 Ref<ISerializeMessageList> m_messages(pm->createSerializeMessageListRef());
1045 while(nb_remaining>0){
1046 ISerializeMessage* sm =
new SerializeMessage(m_my_rank,NULL_SUB_DOMAIN_ID,ISerializeMessage::MT_Recv);
1047 m_messages->addMessage(sm);
1048 m_messages->processPendingMessages();
1049 m_messages->waitMessages(Parallel::WaitAll);
1051 ISerializer* sb = sm->serializer();
1052 sb->setMode(ISerializer::ModeGet);
1054 Int32
id = sb->getInt32();
1060 _writeRemoteVariable(sb);
1068void Hdf5MpiReaderWriter::
1069_writeRemoteVariable(ISerializer* sb)
1074 sb->get(group_name);
1080 sb->setReadMode(ISerializer::ReadReplace);
1081 sdata->serialize(sb);
1082 _writeVal(var_name,group_name,sdata.get());
1093class ArcaneHdf5MpiCheckpointService2
1094:
public ArcaneHdf5MpiReaderWriterObject
1098 ArcaneHdf5MpiCheckpointService2(
const ServiceBuildInfo& sbi)
1099 : ArcaneHdf5MpiReaderWriterObject(sbi), m_write_index(0), m_writer(0), m_reader(0)
1103 virtual IDataWriter* dataWriter() {
return m_writer; }
1104 virtual IDataReader* dataReader() {
return m_reader; }
1106 virtual void notifyBeginWrite();
1107 virtual void notifyEndWrite();
1108 virtual void notifyBeginRead();
1109 virtual void notifyEndRead();
1110 virtual void close() {}
1111 virtual String readerServiceName()
const {
return "ArcaneHdf5MpiCheckpointReader2"; }
1116 Hdf5MpiReaderWriter* m_writer;
1117 Hdf5MpiReaderWriter* m_reader;
1122 String _defaultFileName()
1124 return "arcanedump.mpi.h5";
1126 Directory _defaultDirectory()
1128 return Directory(baseDirectoryName());
1130 void _parseMetaData(String meta_data);
1136void ArcaneHdf5MpiCheckpointService2::
1137_parseMetaData(String meta_data)
1139 IIOMng* io_mng = subDomain()->ioMng();
1140 ScopedPtrT<IXmlDocumentHolder> xml_doc(io_mng->parseXmlBuffer(meta_data.utf8(),
"MetaData"));
1141 XmlNode root = xml_doc->documentNode().documentElement();
1142 Integer version = root.attr(
"version").valueAsInteger();
1144 throw ReaderWriterException(
"ArcaneHdf5MpiCheckpointService2::_parseMetaData",
"Bad version (expected 1)");
1148 info() <<
" FileSet size=" << m_fileset_size;
1154void ArcaneHdf5MpiCheckpointService2::
1157 String meta_data = readerMetaData();
1158 _parseMetaData(meta_data);
1160 info() <<
" GET META DATA READER " << readerMetaData()
1161 <<
" filename=" << fileName();
1163 if (fileName().null()){
1164 Directory dump_dir(_defaultDirectory());
1167 setFileName(dump_dir.file(_defaultFileName()));
1171 info() <<
" READ CHECKPOINT FILENAME = " << fileName();
1172 StringBuilder sub_group;
1177 sub_group =
"Index";
1178 sub_group += currentIndex();
1179 m_reader =
new Hdf5MpiReaderWriter(subDomain(),fileName(),sub_group.toString(),0,Hdf5MpiReaderWriter::OpenModeRead);
1180 m_reader->initialize();
1186void ArcaneHdf5MpiCheckpointService2::
1196void ArcaneHdf5MpiCheckpointService2::
1200 m_fileset_size = options()->filesetSize();
1202 if (fileName().null()){
1203 Directory dump_dir(_defaultDirectory());
1207 setFileName(dump_dir.file(_defaultFileName()));
1210 Hdf5MpiReaderWriter::eOpenMode open_mode = Hdf5MpiReaderWriter::OpenModeAppend;
1211 Integer write_index = checkpointTimes().size();
1214 open_mode = Hdf5MpiReaderWriter::OpenModeTruncate;
1219 StringBuilder sub_group;
1225 sub_group =
"Index";
1226 sub_group += write_index;
1228 m_writer =
new Hdf5MpiReaderWriter(subDomain(),fileName(),sub_group.toString(),m_fileset_size,open_mode);
1229 m_writer->initialize();
1235void ArcaneHdf5MpiCheckpointService2::
1239 ostr() <<
"<infos version='1'>\n";
1240 ostr() <<
" <fileset-size>" << m_fileset_size <<
"</fileset-size>\n";
1241 ostr() <<
"</infos>\n";
1242 setReaderMetaData(ostr.str());
1253 ArcaneHdf5MpiCheckpointReader2);
1257 ArcaneHdf5MpiCheckpointWriter2);
1259ARCANE_REGISTER_SERVICE_HDF5MPIREADERWRITER(ArcaneHdf5MpiCheckpoint2,
1260 ArcaneHdf5MpiCheckpointService2);
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
-*- 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.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à 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.
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.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Int32 Integer
Type représentant un entier.