@@ -605,14 +605,31 @@ Engine &IO::Open(const std::string &name, const Mode mode, helper::Comm comm, co
605605 if (engineTypeLC == " filestream" )
606606 {
607607 // FileStream streams BP4/BP5 file output only (not DAOS, timeseries,
608- // etc.). A not-yet-created stream is normal, so BPVersionLocal returns
609- // '4' for a missing path and the engine waits rather than erroring.
610- char version = ' 4' ;
611- if (comm.Rank () == 0 )
608+ // etc.). The choice is mode-dependent: when writing a new file we
609+ // produce the latest streamable format (BP5) and do not query the
610+ // filesystem for a version (there is nothing to conform to). When
611+ // reading, or appending to, an existing stream we conform to the
612+ // file's version. A not-yet-created stream is normal (a reader may
613+ // open before the writer creates the file): BPVersionLocal reports
614+ // '0' (unknown), and we default to BP5, the format FileStream
615+ // writers produce, so the reader matches rather than guessing BP4.
616+ if (mode_to_use == Mode::Write)
612617 {
613- version = helper::BPVersionLocal (name);
618+ engineTypeLC = " bp5" ;
619+ }
620+ else
621+ {
622+ char version = ' 5' ;
623+ if (comm.Rank () == 0 )
624+ {
625+ char detected = helper::BPVersionLocal (name);
626+ if (detected != ' 0' )
627+ {
628+ version = detected;
629+ }
630+ }
631+ engineTypeLC = std::string (" bp" ) + comm.BroadcastValue (version);
614632 }
615- engineTypeLC = std::string (" bp" ) + comm.BroadcastValue (version);
616633 }
617634 else if (helper::EndsWith (name, " .h5" , false ))
618635 {
@@ -626,8 +643,11 @@ Engine &IO::Open(const std::string &name, const Mode mode, helper::Comm comm, co
626643 {
627644 engineTypeLC = " timeseries" ;
628645 }
629- else if ((mode_to_use == Mode::Read) || (mode_to_use == Mode::ReadRandomAccess))
646+ else if ((mode_to_use == Mode::Read) || (mode_to_use == Mode::ReadRandomAccess) ||
647+ (mode_to_use == Mode::Append))
630648 {
649+ // Read and Append both conform to the on-disk file's version; only a
650+ // fresh Write (the final else) chooses the latest format outright.
631651 auto it = m_Parameters.find (" TarInfo" );
632652 if (it != m_Parameters.end ())
633653 {
@@ -676,18 +696,30 @@ Engine &IO::Open(const std::string &name, const Mode mode, helper::Comm comm, co
676696 comm.BroadcastVector (selected);
677697 if (selected.empty ())
678698 {
679- // Built identically on every rank from 'name', so all ranks
680- // throw together without broadcasting the message.
681- std::string err = " Cannot determine the engine for reading \" " + name +
682- " \" : nothing exists at that location." ;
683- if (mode_to_use == Mode::Read)
699+ // Nothing on disk. Appending to a not-yet-created file creates
700+ // it in the latest format; reading is an error.
701+ if (mode_to_use == Mode::Append)
684702 {
685- err += " If it is a stream that has not been created yet, select "
686- " the engine explicitly with IO::SetEngine()." ;
703+ engineTypeLC = " bp5" ;
687704 }
688- helper::Throw<std::runtime_error>(" Core" , " IO" , " Open" , err);
705+ else
706+ {
707+ // Built identically on every rank from 'name', so all ranks
708+ // throw together without broadcasting the message.
709+ std::string err = " Cannot determine the engine for reading \" " + name +
710+ " \" : nothing exists at that location." ;
711+ if (mode_to_use == Mode::Read)
712+ {
713+ err += " If it is a stream that has not been created yet, select "
714+ " the engine explicitly with IO::SetEngine()." ;
715+ }
716+ helper::Throw<std::runtime_error>(" Core" , " IO" , " Open" , err);
717+ }
718+ }
719+ else
720+ {
721+ engineTypeLC.assign (selected.begin (), selected.end ());
689722 }
690- engineTypeLC.assign (selected.begin (), selected.end ());
691723 }
692724 }
693725 else
0 commit comments