14#include "arcane/std/internal/BasicReader.h"
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/JSONReader.h"
18#include "arcane/utils/Ref.h"
20#include "arcane/core/IParallelMng.h"
21#include "arcane/core/IIOMng.h"
22#include "arcane/core/IData.h"
23#include "arcane/core/ItemGroup.h"
24#include "arcane/core/IVariable.h"
25#include "arcane/core/SerializeBuffer.h"
27#include "arcane/std/internal/ParallelDataReader.h"
41BasicReader(IApplication* app, IParallelMng* pm,
Int32 forced_rank_to_read,
42 const String& path,
bool want_parallel)
44, m_want_parallel(want_parallel)
47, m_first_rank_to_read(0)
49, m_forced_rank_to_read(forced_rank_to_read)
50, m_item_group_finder(nullptr)
60 info() <<
"BasicReader::initialize()";
62 IParallelMng* pm = m_parallel_mng;
67 String db_filename = String::concat(m_path,
"/arcane_acr_db.json");
68 Int32 has_db_file = 0;
71 has_db_file = platform::isFileReadable(db_filename) ? 1 : 0;
72 pm->broadcast(
Int32ArrayView(1, &has_db_file), pm->masterIORank());
74 String data_compressor_name;
75 String hash_algorithm_name;
76 String comparison_hash_algorithm_name;
78 UniqueArray<Byte> bytes;
79 pm->ioMng()->collectiveRead(db_filename, bytes,
false);
80 JSONDocument json_doc;
81 json_doc.parse(bytes, db_filename);
82 JSONValue root = json_doc.root();
83 JSONValue jv_arcane_db = root.expectedChild(_getArcaneDBTag());
84 m_version = jv_arcane_db.expectedChild(
"Version").valueAsInt32();
85 m_nb_written_part = jv_arcane_db.expectedChild(
"NbPart").valueAsInt32();
86 data_compressor_name = jv_arcane_db.child(
"DataCompressor").value();
87 hash_algorithm_name = jv_arcane_db.child(
"HashAlgorithm").value();
88 comparison_hash_algorithm_name = jv_arcane_db.child(
"ComparisonHashAlgorithm").value();
89 info() <<
"**--** Begin read using database version=" << m_version
90 <<
" nb_part=" << m_nb_written_part
91 <<
" compressor=" << data_compressor_name
92 <<
" hash_algorithm=" << hash_algorithm_name
93 <<
" comparison_hash_algorithm=" << comparison_hash_algorithm_name;
100 if (pm->isMasterIO()) {
102 String filename = String::concat(m_path,
"/infos.txt");
103 std::ifstream ifile(filename.localstr());
105 info(4) <<
"** NB PART=" << nb_part;
106 m_nb_written_part = nb_part;
108 pm->broadcast(
Int32ArrayView(1, &m_nb_written_part), pm->masterIORank());
110 if (m_version >= 3) {
111 Int32 rank_to_read = m_forced_rank_to_read;
112 if (rank_to_read < 0) {
113 if (m_nb_written_part > 1)
114 rank_to_read = pm->commRank();
118 String main_filename = _getBasicVariableFile(m_version, m_path, rank_to_read);
119 m_forced_rank_to_read_text_reader =
makeRef(
new KeyValueTextReader(traceMng(), main_filename, m_version));
120 if (!data_compressor_name.empty()) {
121 Ref<IDataCompressor> dc = _createDeflater(m_application, data_compressor_name);
122 m_forced_rank_to_read_text_reader->setDataCompressor(dc);
124 if (!hash_algorithm_name.empty()) {
125 Ref<IHashAlgorithm> v = _createHashAlgorithm(m_application, hash_algorithm_name);
126 m_forced_rank_to_read_text_reader->setHashAlgorithm(v);
128 if (!comparison_hash_algorithm_name.empty()) {
129 Ref<IHashAlgorithm> v = _createHashAlgorithm(m_application, comparison_hash_algorithm_name);
130 m_comparison_hash_algorithm = v;
139_directReadVal(VariableMetaData* varmd, IData* data)
141 info(4) <<
"DIRECT READ VAL v=" << varmd->fullName();
143 bool is_item_variable = !varmd->itemFamilyName().null();
144 Int32 nb_rank_to_read = m_nb_rank_to_read;
148 if (!is_item_variable)
149 if (nb_rank_to_read > 1)
152 UniqueArray<Ref<IData>> allocated_data;
153 UniqueArray<IData*> written_data(nb_rank_to_read);
155 for (Integer i = 0; i < nb_rank_to_read; ++i) {
156 written_data[i] = data;
157 if ((nb_rank_to_read > 1 || m_want_parallel) && is_item_variable) {
158 Ref<IData> new_data = data->cloneEmptyRef();
159 written_data[i] = new_data.get();
160 allocated_data.add(new_data);
162 String vname = varmd->fullName();
163 info(4) <<
" TRY TO READ var_full_name=" << vname;
164 m_global_readers[i]->readData(vname, written_data[i]);
165 if (i == 0 && m_comparison_hash_algorithm.get())
166 info(5) <<
"COMPARISON_HASH =" << m_global_readers[i]->comparisonHashValue(vname);
169 if (is_item_variable) {
170 Ref<ParallelDataReader> parallel_data_reader = _getReader(varmd);
173 IData* full_written_data =
nullptr;
175 if (nb_rank_to_read == 0) {
179 full_written_data =
nullptr;
181 else if (nb_rank_to_read == 1) {
183 full_written_data = written_data[0];
187 Ref<IData> allocated_written_data = data->cloneEmptyRef();
188 allocated_data.add(allocated_written_data);
189 full_written_data = allocated_written_data.get();
190 SerializeBuffer sbuf;
191 sbuf.setMode(ISerializer::ModeReserve);
192 for (Int32 i = 0; i < nb_rank_to_read; ++i)
193 written_data[i]->serialize(&sbuf,
nullptr);
194 sbuf.allocateBuffer();
195 sbuf.setMode(ISerializer::ModePut);
196 for (Int32 i = 0; i < nb_rank_to_read; ++i)
197 written_data[i]->serialize(&sbuf,
nullptr);
198 sbuf.setMode(ISerializer::ModeGet);
199 sbuf.setReadMode(ISerializer::ReadAdd);
200 for (Int32 i = 0; i < nb_rank_to_read; ++i)
201 full_written_data->serialize(&sbuf,
nullptr);
203 if (data != full_written_data) {
204 info(5) <<
"PARALLEL READ";
205 parallel_data_reader->getSortedValues(full_written_data, data);
213Ref<ParallelDataReader> BasicReader::
214_getReader(VariableMetaData* varmd)
216 Int32 nb_to_read = m_nb_rank_to_read;
221 const String& var_group_name = varmd->itemGroupName();
222 String group_full_name = varmd->meshName() +
"_" + varmd->itemFamilyName() +
"_" + var_group_name;
223 auto ix = m_parallel_data_readers.find(group_full_name);
224 if (ix != m_parallel_data_readers.end())
227 IParallelMng* pm = m_parallel_mng;
228 Ref<ParallelDataReader> reader =
makeRef(
new ParallelDataReader(pm));
230 UniqueArray<SharedArray<Int64>> written_unique_ids(nb_to_read);
231 Int64Array& wanted_unique_ids = reader->wantedUniqueIds();
232 for (Integer i = 0; i < nb_to_read; ++i) {
233 m_global_readers[i]->readItemGroup(group_full_name, written_unique_ids[i], wanted_unique_ids);
237 if (m_item_group_finder) {
238 ItemGroup ig = m_item_group_finder->getWantedGroup(varmd);
239 _fillUniqueIds(ig, wanted_unique_ids);
241 for (Integer i = 0; i < nb_to_read; ++i) {
242 Integer nb_uid = written_unique_ids[i].size();
244 info(5) <<
"PART I=" << i
245 <<
" nb_uid=" << nb_uid
246 <<
" min_uid=" << written_unique_ids[i][0]
247 <<
" max_uid=" << written_unique_ids[i][nb_uid - 1];
249 Int64Array& full_written_unique_ids = reader->writtenUniqueIds();
250 for (Integer i = 0; i < nb_to_read; ++i)
251 full_written_unique_ids.
addRange(written_unique_ids[i]);
252 info(5) <<
"FULL UID SIZE=" << full_written_unique_ids.size();
256 m_parallel_data_readers.insert(std::make_pair(group_full_name, reader));
269fillComparisonHash(std::map<String, String>& comparison_hash_map)
271 comparison_hash_map.clear();
272 if (m_nb_rank_to_read == 0)
274 if (m_parallel_mng->commRank() != m_parallel_mng->masterIORank())
277 for (
auto v : var_map) {
279 comparison_hash_map.try_emplace(vd->fullName(), vd->comparisonHashValue());
289 info(4) <<
"MASTER READ var=" << var->
fullName() <<
" data=" << data;
291 info() <<
"** WARNING: partial variable not implemented in BasicReaderWriter";
295 _directReadVal(vmd.
get(), data);
305 IData* data = infos.data();
306 info(4) <<
"MASTER2 READ var=" << vmd->
fullName() <<
" data=" << data;
307 if (vmd->isPartial()) {
308 info() <<
"** WARNING: partial variable not implemented in BasicReaderWriter";
311 _directReadVal(vmd, data);
323 info(5) <<
" S=" << s <<
'\n';
333 Int32 rank = m_parallel_mng->commRank();
334 if (m_forced_rank_to_read >= 0)
335 rank = m_forced_rank_to_read;
336 if (m_version >= 3) {
337 Int64 meta_data_size = 0;
338 String key_name =
"Global:CheckpointMetadata";
339 info(4) <<
"Reading checkpoint metadata from database";
341 bytes.resize(meta_data_size);
345 String filename = _getMetaDataFileName(rank);
346 info(4) <<
"Reading checkpoint metadata file=" << filename;
360 Int32 first_to_read = my_rank;
361 Int32 nb_to_read = 1;
363 if (m_forced_rank_to_read >= 0) {
364 m_first_rank_to_read = m_forced_rank_to_read;
365 m_nb_rank_to_read = 1;
369 nb_to_read = m_nb_written_part;
371 else if (nb_rank < m_nb_written_part) {
376 Int32 nb_part_per_rank = m_nb_written_part / nb_rank;
377 Int32 remaining_nb_part = m_nb_written_part - (nb_part_per_rank * nb_rank);
378 first_to_read = nb_part_per_rank * my_rank;
379 nb_to_read = nb_part_per_rank;
380 info(4) <<
"NB_PART_PER_RANK = " << nb_part_per_rank
381 <<
" REMAINING=" << remaining_nb_part;
382 if (my_rank >= remaining_nb_part) {
383 first_to_read += remaining_nb_part;
386 first_to_read += my_rank;
391 if (my_rank >= m_nb_written_part) {
397 m_first_rank_to_read = first_to_read;
398 m_nb_rank_to_read = nb_to_read;
404Ref<IGenericReader> BasicReader::
405_readOwnMetaDataAndCreateReader(Int32 rank)
407 String main_filename = _getBasicVariableFile(m_version, m_path, rank);
408 Ref<KeyValueTextReader> text_reader;
409 if (m_version >= 3) {
412 if (rank == m_forced_rank_to_read)
413 text_reader = m_forced_rank_to_read_text_reader;
415 text_reader =
makeRef(
new KeyValueTextReader(traceMng(), main_filename, m_version));
418 text_reader->setDataCompressor(m_forced_rank_to_read_text_reader->dataCompressor());
419 text_reader->setHashAlgorithm(m_forced_rank_to_read_text_reader->hashAlgorithm());
423 auto r = makeRef<IGenericReader>(
new BasicGenericReader(m_application, m_version, text_reader));
424 r->initialize(m_path, rank);
432beginRead(
const VariableCollection& vars)
435 beginRead(DataReaderInfo());
444 ARCANE_UNUSED(infos);
445 info(4) <<
"** ** BEGIN READ";
448 info(4) <<
"RanksToRead: FIRST TO READ =" << m_first_rank_to_read
449 <<
" nb=" << m_nb_rank_to_read <<
" version=" << m_version;
450 m_global_readers.resize(m_nb_rank_to_read);
451 for (
Integer i = 0; i < m_nb_rank_to_read; ++i)
452 m_global_readers[i] = _readOwnMetaDataAndCreateReader(i + m_first_rank_to_read);
void addRange(ConstReferenceType val, Int64 n)
Adds n elements of value val to the end of the array.
Data reading information.
Interface of a data item.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual String fullName() const =0
Full variable name (with family prefix).
virtual Ref< VariableMetaData > createMetaDataRef() const =0
Creates an instance containing the variable's metadata.
virtual bool isPartial() const =0
Indicates if the variable is partial.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Unicode character string.
TraceMessage info() const
Flow for an information message.
Data reading information for a variable.
Ref< KeyValueTextReader > m_forced_rank_to_read_text_reader
Reader for the first rank to read.
void fillMetaData(ByteArray &bytes) override
Fills bytes with the metadata content.
Associative map of variable data.
Variable data information.
Array< Int64 > Int64Array
Dynamic one-dimensional array of 64-bit integers.
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
Array< Byte > ByteArray
Dynamic one-dimensional array of characters.
UniqueArray< Byte > ByteUniqueArray
Dynamic 1D array of characters.
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
Impl::SpanTypeFromSize< std::byte, SizeType >::SpanType asWritableBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converts the view into an array of modifiable bytes.
std::int32_t Int32
Signed integer type of 32 bits.