diff --git a/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp b/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp
index 44f428bfefb52f04d500fad05dfb9cf7ecc84b5d..5603b89b5dd5560887b6acf9f234ffba5976960c 100644
--- a/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp
+++ b/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
             hdf5IO.Open("myVector.h5", adios2::Mode::Write);
 
         /** Write variable for buffering */
-        hdf5Writer.Write<float>(bpFloats, myFloats.data());
+        hdf5Writer.GetSync<float>(bpFloats, myFloats.data());
 
         /** Create bp file, engine becomes unreachable after this*/
         hdf5Writer.Close();
diff --git a/source/adios2/engine/bp/BPFileReader.cpp b/source/adios2/engine/bp/BPFileReader.cpp
index d329b29949bfd2251cee96bb08ce1c25dc0d3fc1..39791720603914c87e01b43d9425a58de6ff1f1c 100644
--- a/source/adios2/engine/bp/BPFileReader.cpp
+++ b/source/adios2/engine/bp/BPFileReader.cpp
@@ -19,7 +19,8 @@ namespace adios2
 BPFileReader::BPFileReader(IO &io, const std::string &name, const Mode openMode,
                            MPI_Comm mpiComm)
 : Engine("BPFileReader", io, name, openMode, mpiComm),
-  m_BP3Deserializer(mpiComm, m_DebugMode), m_FileManager(mpiComm, m_DebugMode)
+  m_BP3Deserializer(mpiComm, m_DebugMode), m_FileManager(mpiComm, m_DebugMode),
+  m_SubFileManager(mpiComm, m_DebugMode)
 {
     Init();
 }
@@ -57,13 +58,16 @@ void BPFileReader::InitTransports()
         defaultTransportParameters["transport"] = "File";
         m_IO.m_TransportsParameters.push_back(defaultTransportParameters);
     }
+    // TODO Set Parameters
 
     if (m_BP3Deserializer.m_RankMPI == 0)
     {
         const std::string metadataFile(
             m_BP3Deserializer.GetBPMetadataFileName(m_Name));
+
+        const bool profile = m_BP3Deserializer.m_Profiler.IsActive;
         m_FileManager.OpenFiles({}, {metadataFile}, adios2::Mode::Read,
-                                m_IO.m_TransportsParameters, true);
+                                m_IO.m_TransportsParameters, profile);
     }
 }
 
@@ -104,4 +108,52 @@ void BPFileReader::InitBuffer()
 ADIOS2_FOREACH_TYPE_1ARG(declare_type)
 #undef declare_type
 
+void BPFileReader::ReadVariables(
+    IO &io, const std::map<std::string, SubFileInfoMap> &variablesSubFileInfo)
+{
+    const bool &profile = m_BP3Deserializer.m_Profiler.IsActive;
+
+    // sequentially request bytes from transport manager
+    // threaded here?
+    for (const auto &variableNamePair : variablesSubFileInfo) // variable name
+    {
+        const std::string variableName(variableNamePair.first);
+        unsigned int subFileTransportIndex = 0;
+
+        // or threaded here?
+        for (const auto &subFileIndexPair : variableNamePair.second)
+        {
+            const unsigned int subFileIndex = subFileIndexPair.first;
+            const std::string subFile(
+                m_BP3Deserializer.GetBPSubFileName(m_Name, subFileIndex));
+
+            m_SubFileManager.OpenFiles({}, {subFile}, adios2::Mode::Read,
+                                       std::vector<Params>(), profile);
+
+            for (const auto &stepPair : subFileIndexPair.second) // step
+            {
+                const size_t step = stepPair.first;
+
+                for (const auto &blockInfo : stepPair.second)
+                {
+                    const auto &seek = blockInfo.Seeks;
+                    const size_t blockStart = seek.first;
+                    const size_t blockSize = seek.second - seek.first;
+                    std::vector<char> contiguousData(blockSize);
+                    m_SubFileManager.ReadFile(contiguousData.data(), blockStart,
+                                              blockSize, subFileTransportIndex);
+
+                    // will go to BP3Deserializer along with contiguous data
+
+                    // Variable Data
+                    // blockInfo.IntersectionBox;
+                } // end block
+            }     // end step
+            ++subFileTransportIndex;
+        } // end subfile
+    }     // end variable
+
+    m_SubFileManager.CloseFiles();
+}
+
 } // end namespace adios2
diff --git a/source/adios2/engine/bp/BPFileReader.h b/source/adios2/engine/bp/BPFileReader.h
index a1d1731b4b0ec7ecd2c16a3cb8ef1aff8bdcfb90..4c123500ec1c589382a6a4065897d5e76a6630c1 100644
--- a/source/adios2/engine/bp/BPFileReader.h
+++ b/source/adios2/engine/bp/BPFileReader.h
@@ -42,6 +42,7 @@ public:
 private:
     format::BP3Deserializer m_BP3Deserializer;
     transportman::TransportMan m_FileManager;
+    transportman::TransportMan m_SubFileManager;
 
     void Init();
     void InitTransports();
@@ -59,6 +60,10 @@ private:
 
     template <class T>
     void GetDeferredCommon(Variable<T> &variable, T *data);
+
+    void
+    ReadVariables(IO &io,
+                  const std::map<std::string, SubFileInfoMap> &variablesInfo);
 };
 
 } // end namespace adios2
diff --git a/source/adios2/engine/bp/BPFileReader.tcc b/source/adios2/engine/bp/BPFileReader.tcc
index 860567c315d92968542920bda13d09a8f85845df..57c81eff376dd20814598bba81897ee99f178323 100644
--- a/source/adios2/engine/bp/BPFileReader.tcc
+++ b/source/adios2/engine/bp/BPFileReader.tcc
@@ -19,6 +19,7 @@ namespace adios2
 template <class T>
 void BPFileReader::GetSyncCommon(Variable<T> &variable, T *data)
 {
+    // subfile info
     const std::map<std::string, SubFileInfoMap> variableSubfileInfo =
         m_BP3Deserializer.GetSyncVariableSubFileInfo(variable);
 }
@@ -26,6 +27,8 @@ void BPFileReader::GetSyncCommon(Variable<T> &variable, T *data)
 template <class T>
 void BPFileReader::GetDeferredCommon(Variable<T> &variable, T *data)
 {
+    // returns immediately
+    m_BP3Deserializer.GetDeferredVariable(variable, data);
 }
 
 } // end namespace adios2
diff --git a/source/adios2/helper/adiosType.h b/source/adios2/helper/adiosType.h
index d1cffddea3d8e85c00c7e3fac3f165192ae95d23..9d4154ec616031578fc3dd54fe7f788909516d19 100644
--- a/source/adios2/helper/adiosType.h
+++ b/source/adios2/helper/adiosType.h
@@ -27,6 +27,7 @@ struct SubFileInfo
 {
     Box<Dims> IntersectionBox; ///< first = Start point, second = End point
     Box<size_t> Seeks;         ///< first = Start seek, second = End seek
+    std::vector<char> Data;
 };
 
 /**
diff --git a/source/adios2/toolkit/format/bp3/BP3Base.cpp b/source/adios2/toolkit/format/bp3/BP3Base.cpp
index 8d22296562aa65c67d7bbc623b041a575f73377a..ea585c4d4416b921cbd14579240744a2f1a04759 100644
--- a/source/adios2/toolkit/format/bp3/BP3Base.cpp
+++ b/source/adios2/toolkit/format/bp3/BP3Base.cpp
@@ -118,34 +118,24 @@ std::string BP3Base::GetBPMetadataFileName(const std::string &name) const
 std::vector<std::string>
 BP3Base::GetBPNames(const std::vector<std::string> &baseNames) const noexcept
 {
-    auto lf_GetBPName = [](const std::string &baseName,
-                           const int rank) -> std::string {
-
-        const std::string bpBaseName = AddExtension(baseName, ".bp");
-
-        // path/root.bp.dir/root.bp.rank
-        std::string bpRootName = bpBaseName;
-        const auto lastPathSeparator(bpBaseName.find_last_of(PathSeparator));
-
-        if (lastPathSeparator != std::string::npos)
-        {
-            bpRootName = bpBaseName.substr(lastPathSeparator);
-        }
-        const std::string bpName(bpBaseName + ".dir/" + bpRootName + "." +
-                                 std::to_string(rank));
-        return bpName;
-    };
-
     std::vector<std::string> bpNames;
     bpNames.reserve(baseNames.size());
 
     for (const auto &baseName : baseNames)
     {
-        bpNames.push_back(lf_GetBPName(baseName, m_RankMPI));
+        bpNames.push_back(
+            GetBPRankName(baseName, static_cast<unsigned int>(m_RankMPI)));
     }
     return bpNames;
 }
 
+std::string BP3Base::GetBPSubFileName(const std::string &name,
+                                      const unsigned int subFileIndex) const
+    noexcept
+{
+    return GetBPRankName(name, subFileIndex);
+}
+
 // PROTECTED
 void BP3Base::InitOnOffParameter(const std::string value, bool &parameter,
                                  const std::string hint)
@@ -459,16 +449,16 @@ BP3Base::ReadElementIndexHeader(const std::vector<char> &buffer,
     ElementIndexHeader header;
     header.Length = ReadValue<uint32_t>(buffer, position);
     header.MemberID = ReadValue<uint32_t>(buffer, position);
-    header.GroupName = ReadBP1String(buffer, position);
-    header.Name = ReadBP1String(buffer, position);
-    header.Path = ReadBP1String(buffer, position);
+    header.GroupName = ReadBP3String(buffer, position);
+    header.Name = ReadBP3String(buffer, position);
+    header.Path = ReadBP3String(buffer, position);
     header.DataType = ReadValue<int8_t>(buffer, position);
     header.CharacteristicsSetsCount = ReadValue<uint64_t>(buffer, position);
 
     return header;
 }
 
-std::string BP3Base::ReadBP1String(const std::vector<char> &buffer,
+std::string BP3Base::ReadBP3String(const std::vector<char> &buffer,
                                    size_t &position) const noexcept
 {
     const size_t size =
@@ -500,6 +490,24 @@ void BP3Base::ProfilerStop(const std::string process)
     }
 }
 
+std::string BP3Base::GetBPRankName(const std::string &name,
+                                   const unsigned int rank) const noexcept
+{
+    const std::string bpName = AddExtension(name, ".bp");
+
+    // path/root.bp.dir/root.bp.rank
+    std::string bpRoot = bpName;
+    const auto lastPathSeparator(bpName.find_last_of(PathSeparator));
+
+    if (lastPathSeparator != std::string::npos)
+    {
+        bpRoot = bpName.substr(lastPathSeparator);
+    }
+    const std::string bpRankName(bpName + ".dir/" + bpRoot + "." +
+                                 std::to_string(rank));
+    return bpRankName;
+}
+
 #define declare_template_instantiation(T)                                      \
     template BP3Base::ResizeResult BP3Base::ResizeBuffer(                      \
         const Variable<T> &variable);                                          \
diff --git a/source/adios2/toolkit/format/bp3/BP3Base.h b/source/adios2/toolkit/format/bp3/BP3Base.h
index 5758f3e0abb63553d5fdfc0482f0533d75ad4fb4..3fe4a06c9bd8f3d806b3a1be82fd60133ac17e2f 100644
--- a/source/adios2/toolkit/format/bp3/BP3Base.h
+++ b/source/adios2/toolkit/format/bp3/BP3Base.h
@@ -165,6 +165,10 @@ public:
 
     std::string GetBPMetadataFileName(const std::string &name) const noexcept;
 
+    std::string GetBPSubFileName(const std::string &name,
+                                 const unsigned int subFileIndex) const
+        noexcept;
+
     /** Return type of the CheckAllocation function. */
     enum class ResizeResult
     {
@@ -418,7 +422,7 @@ protected:
      * @param position
      * @return
      */
-    std::string ReadBP1String(const std::vector<char> &buffer,
+    std::string ReadBP3String(const std::vector<char> &buffer,
                               size_t &position) const noexcept;
 
     void ProfilerStart(const std::string process);
@@ -433,6 +437,9 @@ private:
      */
     template <class T>
     size_t GetVariableIndexSize(const Variable<T> &variable) const noexcept;
+
+    std::string GetBPRankName(const std::string &name,
+                              const unsigned int rank) const noexcept;
 };
 
 #define declare_template_instantiation(T)                                      \
diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.h b/source/adios2/toolkit/format/bp3/BP3Deserializer.h
index aaa265f775a8858b9ee60e82dfbd48b2be24d522..3eb88183c899492e702ca6562af65e62c3856956 100644
--- a/source/adios2/toolkit/format/bp3/BP3Deserializer.h
+++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.h
@@ -54,6 +54,10 @@ public:
     std::map<std::string, SubFileInfoMap>
     PerformGetsVariablesSubFileInfo(IO &io);
 
+    template <class T>
+    void ClipContiguousMemory(const std::vector<char> &contiguousMemory,
+                              Variable<T> &variable);
+
 private:
     std::map<std::string, SubFileInfoMap> m_DeferredVariables;
 
diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc b/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc
index fe99e5e5428e935af1fb05e940d668a91f6ec9a8..9bf793f956f8adb1cf00145faebefe68e7ba75b9 100644
--- a/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc
+++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc
@@ -33,8 +33,7 @@ template <class T>
 void BP3Deserializer::GetDeferredVariable(Variable<T> &variable, T *data)
 {
     variable.SetData(data);
-    SubFileInfoMap emptyMap;
-    m_DeferredVariables[variable.m_Name] = emptyMap;
+    m_DeferredVariables[variable.m_Name] = SubFileInfoMap();
 }
 
 // PRIVATE
diff --git a/source/adios2/toolkit/transportman/TransportMan.cpp b/source/adios2/toolkit/transportman/TransportMan.cpp
index 1b396c1b7f7948413cc204c1a5c6d3b380277066..ce81f04a1c8c6b1908d55916583c62e90edb5335 100644
--- a/source/adios2/toolkit/transportman/TransportMan.cpp
+++ b/source/adios2/toolkit/transportman/TransportMan.cpp
@@ -40,7 +40,8 @@ void TransportMan::OpenFiles(const std::vector<std::string> &baseNames,
                              const std::vector<Params> &parametersVector,
                              const bool profile)
 {
-    for (auto i = 0; i < names.size(); ++i)
+
+    for (size_t i = 0; i < names.size(); ++i)
     {
         const Params &parameters = parametersVector[i];
         const std::string type(parameters.at("transport"));
@@ -51,11 +52,23 @@ void TransportMan::OpenFiles(const std::vector<std::string> &baseNames,
             {
                 CreateDirectory(baseNames[i]);
             }
-            OpenFileTransport(names[i], openMode, parameters, profile);
+
+            std::shared_ptr<Transport> file =
+                OpenFileTransport(names[i], openMode, parameters, profile);
+            m_Transports.insert({i, file});
         }
     }
 }
 
+void TransportMan::OpenFileID(const std::string &name, const unsigned int id,
+                              const Mode openMode, const Params &parameters,
+                              const bool profile)
+{
+
+    std::shared_ptr<Transport> file =
+        OpenFileTransport(name, openMode, parameters, profile);
+}
+
 std::vector<std::string> TransportMan::GetFilesBaseNames(
     const std::string &baseName,
     const std::vector<Params> &parametersVector) const
@@ -108,8 +121,9 @@ std::vector<std::string> TransportMan::GetTransportsTypes() noexcept
     std::vector<std::string> types;
     types.reserve(m_Transports.size());
 
-    for (const auto &transport : m_Transports)
+    for (const auto &transportPair : m_Transports)
     {
+        const std::shared_ptr<Transport> &transport = transportPair.second;
         types.push_back(transport->m_Type + "_" + transport->m_Library);
     }
     return types;
@@ -121,8 +135,9 @@ TransportMan::GetTransportsProfilers() noexcept
     std::vector<profiling::IOChrono *> profilers;
     profilers.reserve(m_Transports.size());
 
-    for (const auto &transport : m_Transports)
+    for (const auto &transportPair : m_Transports)
     {
+        const auto &transport = transportPair.second;
         profilers.push_back(&transport->m_Profiler);
     }
     return profilers;
@@ -133,8 +148,9 @@ void TransportMan::WriteFiles(const char *buffer, const size_t size,
 {
     if (transportIndex == -1)
     {
-        for (auto &transport : m_Transports)
+        for (auto &transportPair : m_Transports)
         {
+            auto &transport = transportPair.second;
             if (transport->m_Type == "File")
             {
                 // make this truly asynch?
@@ -173,8 +189,10 @@ void TransportMan::CloseFiles(const int transportIndex)
 {
     if (transportIndex == -1)
     {
-        for (auto &transport : m_Transports)
+        for (auto &transportPair : m_Transports)
         {
+            auto &transport = transportPair.second;
+
             if (transport->m_Type == "File")
             {
                 transport->Close();
@@ -191,8 +209,10 @@ void TransportMan::CloseFiles(const int transportIndex)
 bool TransportMan::AllTransportsClosed() const noexcept
 {
     bool allClose = true;
-    for (const auto &transport : m_Transports)
+    for (const auto &transportPair : m_Transports)
     {
+        const auto &transport = transportPair.second;
+
         if (transport->m_IsOpen)
         {
             allClose = false;
@@ -203,10 +223,10 @@ bool TransportMan::AllTransportsClosed() const noexcept
 }
 
 // PRIVATE
-void TransportMan::OpenFileTransport(const std::string &fileName,
-                                     const Mode openMode,
-                                     const Params &parameters,
-                                     const bool profile)
+std::shared_ptr<Transport>
+TransportMan::OpenFileTransport(const std::string &fileName,
+                                const Mode openMode, const Params &parameters,
+                                const bool profile)
 {
     auto lf_SetFileTransport = [&](const std::string library,
                                    std::shared_ptr<Transport> &transport) {
@@ -266,9 +286,9 @@ void TransportMan::OpenFileTransport(const std::string &fileName,
                                 lf_GetTimeUnits(DefaultTimeUnit, parameters));
     }
 
-    // open and move transport to container
+    // open
     transport->Open(fileName, openMode);
-    m_Transports.push_back(std::move(transport)); // is move needed?
+    return transport;
 }
 
 void TransportMan::CheckFileType(const int transportIndex)
diff --git a/source/adios2/toolkit/transportman/TransportMan.h b/source/adios2/toolkit/transportman/TransportMan.h
index 8e571a470680134baf237dd276697e0abe7f3b6c..8171f562f3067a713327356d9ec8cb37f6c6471a 100644
--- a/source/adios2/toolkit/transportman/TransportMan.h
+++ b/source/adios2/toolkit/transportman/TransportMan.h
@@ -30,13 +30,14 @@ class TransportMan
 {
 
 public:
-    /** contains all transports from IO AddTransport
+    /**
+     * Contains all transports
      * <pre>
-     * key : unique id from IO AddTransport
-     * value : obejct derived from Transport.h class
+     * key : unique id
+     * value : object derived from Transport base class
      * </pre>
      */
-    std::vector<std::shared_ptr<Transport>> m_Transports;
+    std::unordered_map<size_t, std::shared_ptr<Transport>> m_Transports;
 
     /**
      * Unique base constructor
@@ -60,8 +61,13 @@ public:
                    const std::vector<Params> &parametersVector,
                    const bool profile);
 
+    void OpenFileID(const std::string &name, const unsigned int id,
+                    const Mode openMode, const Params &parameters,
+                    const bool profile);
+
     /**
-     * Gets each transport base name from either baseName at Open or name key in
+     * Gets each transport base name from either baseName at Open or name
+     * key in
      * parameters
      * Checks if transport name rules IO AddTransport have unique names for
      * every type (for now)
@@ -128,8 +134,10 @@ protected:
     MPI_Comm m_MPIComm;
     const bool m_DebugMode = false;
 
-    void OpenFileTransport(const std::string &fileName, const Mode openMode,
-                           const Params &parameters, const bool profile);
+    std::shared_ptr<Transport> OpenFileTransport(const std::string &fileName,
+                                                 const Mode openMode,
+                                                 const Params &parameters,
+                                                 const bool profile);
 
     void CheckFileType(const int transportIndex);
 };