@@ -69,21 +69,27 @@ ADIOS2IOHandlerImpl::ADIOS2IOHandlerImpl(
6969 AbstractIOHandler *handler,
7070 MPI_Comm communicator,
7171 json::TracingJSON cfg,
72- std::string engineType)
72+ std::string engineType,
73+ std::string specifiedExtension)
7374 : AbstractIOHandlerImplCommon(handler)
7475 , m_ADIOS{communicator, ADIOS2_DEBUG_MODE}
7576 , m_engineType(std::move(engineType))
77+ , m_userSpecifiedExtension{std::move (specifiedExtension)}
7678{
7779 init (std::move (cfg));
7880}
7981
8082#endif // openPMD_HAVE_MPI
8183
8284ADIOS2IOHandlerImpl::ADIOS2IOHandlerImpl (
83- AbstractIOHandler *handler, json::TracingJSON cfg, std::string engineType)
85+ AbstractIOHandler *handler,
86+ json::TracingJSON cfg,
87+ std::string engineType,
88+ std::string specifiedExtension)
8489 : AbstractIOHandlerImplCommon(handler)
8590 , m_ADIOS{ADIOS2_DEBUG_MODE}
8691 , m_engineType(std::move(engineType))
92+ , m_userSpecifiedExtension(std::move(specifiedExtension))
8793{
8894 init (std::move (cfg));
8995}
@@ -228,28 +234,85 @@ ADIOS2IOHandlerImpl::getOperators()
228234 return getOperators (m_config);
229235}
230236
237+ using AcceptedEndingsForEngine = std::map<std::string, std::string>;
238+
231239std::string ADIOS2IOHandlerImpl::fileSuffix () const
232240{
233241 // SST engine adds its suffix unconditionally
234242 // so we don't add it
235- static std::map<std::string, std::string> endings{
236- {" sst" , " " },
237- {" staging" , " " },
238- {" bp4" , " .bp" },
239- {" bp5" , " .bp" },
240- {" bp3" , " .bp" },
241- {" file" , " .bp" },
242- {" hdf5" , " .h5" },
243- {" nullcore" , " .nullcore" },
244- {" ssc" , " .ssc" }};
245- auto it = endings.find (m_engineType);
246- if (it != endings.end ())
247- {
248- return it->second ;
243+ static std::map<std::string, AcceptedEndingsForEngine> const endings{
244+ {" sst" , {{" " , " " }, {" .sst" , " " }}},
245+ {" staging" , {{" " , " " }, {" .sst" , " " }}},
246+ {" filestream" , {{" .bp" , " .bp" }, {" .bp4" , " .bp4" }, {" .bp5" , " .bp5" }}},
247+ {" bp4" , {{" .bp4" , " .bp4" }, {" .bp" , " .bp" }}},
248+ {" bp5" , {{" .bp5" , " .bp5" }, {" .bp" , " .bp" }}},
249+ {" bp3" , {{" .bp" , " .bp" }}},
250+ {" file" , {{" .bp" , " .bp" }, {" .bp4" , " .bp4" }, {" .bp5" , " .bp5" }}},
251+ {" hdf5" , {{" .h5" , " .h5" }}},
252+ {" nullcore" , {{" .nullcore" , " .nullcore" }, {" .bp" , " .bp" }}},
253+ {" ssc" , {{" .ssc" , " .ssc" }}}};
254+
255+ if (auto engine = endings.find (m_engineType); engine != endings.end ())
256+ {
257+ auto const &acceptedEndings = engine->second ;
258+ if (auto ending = acceptedEndings.find (m_userSpecifiedExtension);
259+ ending != acceptedEndings.end ())
260+ {
261+ if ((m_engineType == " file" || m_engineType == " filestream" ) &&
262+ (m_userSpecifiedExtension == " .bp3" ||
263+ m_userSpecifiedExtension == " .bp4" ||
264+ m_userSpecifiedExtension == " .bp5" ))
265+ {
266+ std::cerr
267+ << " [ADIOS2] Explicit ending '" << m_userSpecifiedExtension
268+ << " ' was specified in combination with generic file "
269+ " engine '"
270+ << m_engineType
271+ << " '. ADIOS2 will pick a default file ending "
272+ " independent of specified suffix. (E.g. 'simData.bp5' "
273+ " might actually be written as a BP4 dataset.)"
274+ << std::endl;
275+ }
276+ return ending->second ;
277+ }
278+ else if (m_userSpecifiedExtension.empty ())
279+ {
280+ std::cerr << " [ADIOS2] No file ending specified. Will not add one."
281+ << std::endl;
282+ if (m_engineType == " bp3" )
283+ {
284+ std::cerr
285+ << " Note that the ADIOS2 BP3 engine will add its "
286+ " ending '.bp' if not specified (e.g. 'simData.bp3' "
287+ " will appear on disk as 'simData.bp3.bp')."
288+ << std::endl;
289+ }
290+ return " " ;
291+ }
292+ else
293+ {
294+ std::cerr << " [ADIOS2] Specified ending '"
295+ << m_userSpecifiedExtension
296+ << " ' does not match the selected engine '"
297+ << m_engineType
298+ << " '. Will use the specified ending anyway."
299+ << std::endl;
300+ if (m_engineType == " bp3" )
301+ {
302+ std::cerr
303+ << " Note that the ADIOS2 BP3 engine will add its "
304+ " ending '.bp' if not specified (e.g. 'simData.bp3' "
305+ " will appear on disk as 'simData.bp3.bp')."
306+ << std::endl;
307+ }
308+ return m_userSpecifiedExtension;
309+ }
249310 }
250311 else
251312 {
252- return " .adios2" ;
313+ throw error::WrongAPIUsage (
314+ " [ADIOS2] Specified engine '" + m_engineType +
315+ " ' is not supported by ADIOS2 backend." );
253316 }
254317}
255318
@@ -281,12 +344,7 @@ void ADIOS2IOHandlerImpl::createFile(
281344
282345 if (!writable->written )
283346 {
284- std::string name = parameters.name ;
285- std::string suffix (fileSuffix ());
286- if (!auxiliary::ends_with (name, suffix))
287- {
288- name += suffix;
289- }
347+ std::string name = parameters.name + fileSuffix ();
290348
291349 auto res_pair = getPossiblyExisting (name);
292350 InvalidatableFile shared_name = InvalidatableFile (name);
@@ -459,12 +517,7 @@ void ADIOS2IOHandlerImpl::openFile(
459517 m_handler->directory );
460518 }
461519
462- std::string name = parameters.name ;
463- std::string suffix (fileSuffix ());
464- if (!auxiliary::ends_with (name, suffix))
465- {
466- name += suffix;
467- }
520+ std::string name = parameters.name + fileSuffix ();
468521
469522 auto file = std::get<PE_InvalidatableFile>(getPossiblyExisting (name));
470523
@@ -704,7 +757,8 @@ void ADIOS2IOHandlerImpl::getBufferView(
704757 Writable *writable, Parameter<Operation::GET_BUFFER_VIEW> ¶meters)
705758{
706759 // @todo check access mode
707- if (m_engineType != " bp4" )
760+ if (m_engineType != " bp4" && m_engineType != " file" &&
761+ m_engineType != " filestream" && m_engineType != " bp5" )
708762 {
709763 parameters.out ->backendManagedBuffer = false ;
710764 return ;
@@ -2245,8 +2299,8 @@ namespace detail
22452299 {
22462300 throw std::runtime_error (
22472301 " [ADIOS2IOHandler] Unknown engine type. Please choose "
2248- " one out of "
2249- " [sst, staging, bp4, bp3, hdf5, file , null]" );
2302+ " one out of [sst, staging, bp4, bp3, hdf5, file, "
2303+ " filestream , null]" );
22502304 // not listing unsupported engines
22512305 }
22522306 }
@@ -2886,9 +2940,15 @@ ADIOS2IOHandler::ADIOS2IOHandler(
28862940 openPMD::Access at,
28872941 MPI_Comm comm,
28882942 json::TracingJSON options,
2889- std::string engineType)
2943+ std::string engineType,
2944+ std::string specifiedExtension)
28902945 : AbstractIOHandler(std::move(path), at, comm)
2891- , m_impl{this , comm, std::move (options), std::move (engineType)}
2946+ , m_impl{
2947+ this ,
2948+ comm,
2949+ std::move (options),
2950+ std::move (engineType),
2951+ std::move (specifiedExtension)}
28922952{}
28932953
28942954#endif
@@ -2897,9 +2957,14 @@ ADIOS2IOHandler::ADIOS2IOHandler(
28972957 std::string path,
28982958 Access at,
28992959 json::TracingJSON options,
2900- std::string engineType)
2960+ std::string engineType,
2961+ std::string specifiedExtension)
29012962 : AbstractIOHandler(std::move(path), at)
2902- , m_impl{this , std::move (options), std::move (engineType)}
2963+ , m_impl{
2964+ this ,
2965+ std::move (options),
2966+ std::move (engineType),
2967+ std::move (specifiedExtension)}
29032968{}
29042969
29052970std::future<void >
@@ -2912,14 +2977,19 @@ ADIOS2IOHandler::flush(internal::FlushParams const &flushParams)
29122977
29132978#if openPMD_HAVE_MPI
29142979ADIOS2IOHandler::ADIOS2IOHandler (
2915- std::string path, Access at, MPI_Comm comm, json::TracingJSON, std::string)
2980+ std::string path,
2981+ Access at,
2982+ MPI_Comm comm,
2983+ json::TracingJSON,
2984+ std::string,
2985+ std::string)
29162986 : AbstractIOHandler(std::move(path), at, comm)
29172987{}
29182988
29192989#endif // openPMD_HAVE_MPI
29202990
29212991ADIOS2IOHandler::ADIOS2IOHandler (
2922- std::string path, Access at, json::TracingJSON, std::string)
2992+ std::string path, Access at, json::TracingJSON, std::string, std::string )
29232993 : AbstractIOHandler(std::move(path), at)
29242994{}
29252995
0 commit comments