From ffdcb96224fabc9a788f16d7b3847e31081ba914 Mon Sep 17 00:00:00 2001
From: Norbert Podhorszki <pnorbert@ornl.gov>
Date: Wed, 26 Apr 2017 20:14:57 -0400
Subject: [PATCH] - Changed DefineVariable to support Joined and Irregular
 arrays. - Added examples/groupless/multistep writer example to the build -
 Added ADIOS1 reader but it does not work yet - Added heat transfer example
 reader

---
 examples/CMakeLists.txt                       |   1 +
 examples/groupless/CMakeLists.txt             |   6 +
 examples/groupless/basic/reader.cpp           |   4 +-
 examples/groupless/compound/reader.cpp        |   4 +-
 examples/groupless/multistep/CMakeLists.txt   |  14 ++
 .../groupless/multistep/reader_allsteps.cpp   |   4 +-
 .../groupless/multistep/reader_stepping.cpp   |   4 +-
 .../groupless/multistep/writer_multistep.cpp  | 216 ++++++++++------
 .../heatTransfer/read/heatRead_adios2.cpp     |  13 +-
 examples/heatTransfer/write/IO_adios2.cpp     |  25 +-
 examples/hello/bpWriter/helloBPWriter.cpp     |   6 +-
 .../datamanWriter/helloDataManWriter.cpp      |   7 +-
 examples/hello/hdf5Writer/helloHDF5Writer.cpp |  15 +-
 examples/hello/timeBP/timeBPWriter.cpp        |   6 +-
 source/adios2/ADIOS.cpp                       |  14 +-
 source/adios2/ADIOS.h                         |  32 ++-
 source/adios2/ADIOS.tcc                       |  13 +-
 source/adios2/ADIOSTypes.h                    |  42 ++--
 source/adios2/core/Engine.cpp                 | 163 +++++++++++-
 source/adios2/core/Engine.h                   |  62 ++++-
 source/adios2/core/Variable.h                 |  15 +-
 source/adios2/core/VariableBase.h             |  69 ++---
 source/adios2/core/VariableCompound.h         |   5 +-
 source/adios2/core/adiosFunctions.cpp         |  11 +
 source/adios2/core/adiosFunctions.h           |   9 +
 source/adios2/engine/adios1/ADIOS1Reader.cpp  | 235 +++++++++++++++++-
 source/adios2/engine/adios1/ADIOS1Reader.h    |  72 +++++-
 source/adios2/engine/adios1/ADIOS1Writer.cpp  | 115 +++++----
 .../adios2/engine/dataman/DataManWriter.tcc   |  22 +-
 source/adios2/engine/hdf5/HDF5WriterP.cpp     |   8 +-
 .../adios2/utilities/format/bp1/BP1Writer.tcc |  14 +-
 31 files changed, 944 insertions(+), 282 deletions(-)
 create mode 100644 examples/groupless/CMakeLists.txt
 create mode 100644 examples/groupless/multistep/CMakeLists.txt

diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 59d0aaef3..4f2778761 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -5,3 +5,4 @@
 
 add_subdirectory(hello)
 add_subdirectory(heatTransfer)
+add_subdirectory(groupless)
diff --git a/examples/groupless/CMakeLists.txt b/examples/groupless/CMakeLists.txt
new file mode 100644
index 000000000..5f37a0bb4
--- /dev/null
+++ b/examples/groupless/CMakeLists.txt
@@ -0,0 +1,6 @@
+#------------------------------------------------------------------------------#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#------------------------------------------------------------------------------#
+
+add_subdirectory(multistep)
diff --git a/examples/groupless/basic/reader.cpp b/examples/groupless/basic/reader.cpp
index 7f021604f..2f46aa7ad 100644
--- a/examples/groupless/basic/reader.cpp
+++ b/examples/groupless/basic/reader.cpp
@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
 
         // ? how do we know about the type? std::string varNice->m_Type
         uint64_t gdim =
-            varNice->m_GlobalDimensions[0]; // ?member var or member func?
+            varNice->m_Shape[0]; // ?member var or member func?
         uint64_t ldim = gdim / nproc;
         uint64_t offs = rank * ldim;
         if (rank == nproc - 1)
@@ -128,7 +128,7 @@ int main(int argc, char *argv[])
         // inquiry about a variable, whose name we know
         std::shared_ptr<adios::Variable<void>> varRagged =
             bpReader.InquiryVariable("Ragged");
-        if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION)
+        if (varRagged->m_Shape[1] != adios::VARYING_DIMENSION)
         {
             throw std::ios_base::failure(
                 "Unexpected condition: Ragged array's fast dimension "
diff --git a/examples/groupless/compound/reader.cpp b/examples/groupless/compound/reader.cpp
index ddd462085..9181d50f8 100644
--- a/examples/groupless/compound/reader.cpp
+++ b/examples/groupless/compound/reader.cpp
@@ -128,7 +128,7 @@ int main(int argc, char *argv[])
 
         // ? how do we know about the type? std::string varNice->m_Type
         uint64_t gdim =
-            varNice->m_GlobalDimensions[0]; // ?member var or member func?
+            varNice->m_Shape[0]; // ?member var or member func?
         uint64_t ldim = gdim / nproc;
         uint64_t offs = rank * ldim;
         if (rank == nproc - 1)
@@ -152,7 +152,7 @@ int main(int argc, char *argv[])
         // inquiry about a variable, whose name we know
         std::shared_ptr<adios::Variable<void>> varRagged =
             bpReader.InquiryVariable("Ragged");
-        if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION)
+        if (varRagged->m_Shape[1] != adios::VARYING_DIMENSION)
         {
             throw std::ios_base::failure(
                 "Unexpected condition: Ragged array's fast dimension "
diff --git a/examples/groupless/multistep/CMakeLists.txt b/examples/groupless/multistep/CMakeLists.txt
new file mode 100644
index 000000000..97c434eab
--- /dev/null
+++ b/examples/groupless/multistep/CMakeLists.txt
@@ -0,0 +1,14 @@
+#------------------------------------------------------------------------------#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#------------------------------------------------------------------------------#
+
+if(ADIOS_USE_MPI)
+  find_package(MPI COMPONENTS C REQUIRED)
+
+  add_executable(writer_multistep writer_multistep.cpp)
+  target_include_directories(writer_multistep PRIVATE ${MPI_C_INCLUDE_PATH})
+  target_link_libraries(writer_multistep ${MPI_C_LIBRARIES})
+endif()
+target_link_libraries(writer_multistep adios2)
+
diff --git a/examples/groupless/multistep/reader_allsteps.cpp b/examples/groupless/multistep/reader_allsteps.cpp
index 563d55369..0b3afb4f8 100644
--- a/examples/groupless/multistep/reader_allsteps.cpp
+++ b/examples/groupless/multistep/reader_allsteps.cpp
@@ -123,7 +123,7 @@ int main(int argc, char *argv[])
 
         // ? how do we know about the type? std::string varNice->m_Type
         unsigned long long int gdim =
-            varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func?
+            varMyDoubles->m_Shape[0]; // ?member var or member func?
         unsigned long long int ldim = gdim / nproc;
         unsigned long long int offs = rank * ldim;
         if (rank == nproc - 1)
@@ -148,7 +148,7 @@ int main(int argc, char *argv[])
         // inquiry about a variable, whose name we know
         std::shared_ptr<adios::Variable<void>> varRagged =
             bpReader.InquiryVariable("Ragged");
-        if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION)
+        if (varRagged->m_Shape[1] != adios::VARYING_DIMENSION)
         {
             throw std::ios_base::failure(
                 "Unexpected condition: Ragged array's fast dimension "
diff --git a/examples/groupless/multistep/reader_stepping.cpp b/examples/groupless/multistep/reader_stepping.cpp
index dcac90747..7835c54db 100644
--- a/examples/groupless/multistep/reader_stepping.cpp
+++ b/examples/groupless/multistep/reader_stepping.cpp
@@ -85,7 +85,7 @@ int main(int argc, char *argv[])
 
                 // ? how do we know about the type? std::string varNice->m_Type
                 unsigned long long int gdim =
-                    varMyDoubles->m_GlobalDimensions[0]; // ?member var or
+                    varMyDoubles->m_Shape[0]; // ?member var or
                                                          // member func?
                 unsigned long long int ldim = gdim / nproc;
                 unsigned long long int offs = rank * ldim;
@@ -110,7 +110,7 @@ int main(int argc, char *argv[])
                 // inquiry about a variable, whose name we know
                 std::shared_ptr<adios::Variable<void>> varRagged =
                     bpReader.InquiryVariable("Ragged");
-                if (varRagged->m_GlobalDimensions[1] !=
+                if (varRagged->m_Shape[1] !=
                     adios::VARYING_DIMENSION)
                 {
                     throw std::ios_base::failure(
diff --git a/examples/groupless/multistep/writer_multistep.cpp b/examples/groupless/multistep/writer_multistep.cpp
index 0b6b365b5..0879ddb4d 100644
--- a/examples/groupless/multistep/writer_multistep.cpp
+++ b/examples/groupless/multistep/writer_multistep.cpp
@@ -14,11 +14,6 @@
 #include <adios2.h>
 #include <mpi.h>
 
-namespace adios
-{
-typedef enum { VARYING_DIMENSION = -1, LOCAL_VALUE = 0, GLOBAL_VALUE = 1 };
-}
-
 int main(int argc, char *argv[])
 {
     int rank, nproc;
@@ -28,60 +23,105 @@ int main(int argc, char *argv[])
     const bool adiosDebug = true;
     const int NSTEPS = 5;
 
-    adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug);
+    adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN);
 
-    // Application variable
+    // Application variables for output
+    // 1. Global value, constant across processes, constant over time
     const unsigned int Nx = 10;
-    int Nparts; // random size per process, 5..10 each
-
-    std::vector<double> NiceArray(Nx);
+    // 2. Local value, varying across processes, constant over time
+    const int ProcessID = rank; // = rank
+    // 3. Global array, global dimensions, local dimensions and offsets are
+    // constant over time
+    std::vector<double> GlobalArrayFixedDims(Nx);
     for (int i = 0; i < Nx; i++)
     {
-        NiceArray[i] = rank * Nx + (double)i;
+        GlobalArrayFixedDims[i] = rank * Nx + (double)i;
     }
-
-    std::vector<float> RaggedArray;
+    // 4. Local array, local dimensions are
+    // constant over time (but different across processors here)
+    std::vector<float> LocalArrayFixedDims(nproc - rank + 1, rank);
+
+    // 5. Global value, constant across processes, VARYING value over time
+    unsigned int Ny = 0;
+    // 6. Local value, varying across processes, VARYING over time
+    unsigned int Nparts; // random size per process, 5..10 each
+    // 7. Global array, dimensions and offsets are VARYING over time
+    std::vector<double> GlobalArray;
+    // 8. Local array, dimensions and offsets are VARYING over time
+    std::vector<float> IrregularArray;
 
     try
     {
-        // Define group and variables with transforms, variables don't have
-        // functions, only group can access variables
+        /*
+         * Define variables
+         */
+        // 1. Global value, constant across processes, constant over time
         adios::Variable<unsigned int> &varNX =
-            adios.DefineVariable<unsigned int>(
-                "NX"); // global single-value across processes
-        adios::Variable<int> &varNproc = adios.DefineVariable<int>(
-            "nproc", adios::GLOBAL_VALUE); // same def for global value
-        adios::Variable<int> &varNparts =
-            adios.DefineVariable<int>("Nparts",
-                                      adios::LOCAL_VALUE); // a single-value
-                                                           // different on
-                                                           // every process
-        adios::Variable<double> &varNice = adios.DefineVariable<double>(
-            "Nice", {nproc * Nx}); // 1D global array
-        adios::Variable<float> &varRagged = adios.DefineVariable<float>(
-            "Ragged", {nproc, adios::VARYING_DIMENSION}); // ragged array
+            adios.DefineVariable<unsigned int>("NX");
+
+        // 2. Local value, varying across processes, constant over time
+        adios::Variable<int> &varProcessID = adios.DefineVariable<int>(
+            "processid", {nproc}, {rank}, {1}, adios::ConstantShape);
+
+        // 3. Global array, global dimensions (shape), offsets (start) and local
+        // dimensions (count)  are  constant over time
+        adios::Variable<double> &varGlobalArrayFixedDims =
+            adios.DefineVariable<double>("GlobalArrayFixedDims", {nproc * Nx});
+
+        // 4. Local array, local dimensions and offsets are
+        // constant over time.
+        // 4.a. Want to see this at reading as an irregular 2D array
+        // with appropriate global dimensions and offsets-per-writer
+        // generated by the reader and with rank serving as
+        // offset in the slow dimension
+        adios::Variable<float> &varLocalArrayFixedDims2D =
+            adios.DefineVariable<float>("LocalArrayFixedDims2D",
+                                        {nproc, adios::VarDim}, {rank, 0},
+                                        {1, LocalArrayFixedDims.size()});
+        // 4.b. Joined array, a 1D array, with global dimension and offsets
+        // calculated at read time
+        adios::Variable<float> &varLocalArrayFixedDims1D =
+            adios.DefineVariable<float>("LocalArrayFixedDims1D",
+                                        {adios::JoinedDim}, {rank},
+                                        {LocalArrayFixedDims.size()});
+
+        // 5. Global value, constant across processes, VARYING value over time
+        adios::Variable<unsigned int> &varNY =
+            adios.DefineVariable<unsigned int>("NY");
+
+        // 6. Local value, varying across processes, VARYING over time
+        adios::Variable<unsigned int> &varNparts =
+            adios.DefineVariable<unsigned int>("Nparts", {nproc}, {rank}, {1},
+                                               adios::ConstantShape);
+
+        // 7. Global array, dimensions and offsets are VARYING over time
+        adios::Variable<double> &varGlobalArray =
+            adios.DefineVariable<double>("GlobalArray", {adios::UnknownDim});
+
+        // 8. Ragged array, dimensions and offsets are VARYING over time
+        // Want to see this at reading as a ragged 2D array with rank serving as
+        // offset in the slow dimension
+        adios::Variable<float> &varIrregularArray =
+            adios.DefineVariable<float>("Irregular", {nproc, adios::VarDim});
 
         // add transform to variable in group...not executed (just testing API)
-        adios::Transform bzip2 = adios::transform::BZIP2();
-        varNice->AddTransform(bzip2, 1);
+        // adios::Transform bzip2 = adios::transform::BZIP2();
+        // varNice->AddTransform(bzip2, 1);
 
         // Define method for engine creation
         // 1. Get method def from config file or define new one
-        adios::Method &bpWriterSettings = adios.GetMethod("output");
-        if (bpWriterSettings.undeclared())
+        adios::Method &bpWriterSettings = adios.DeclareMethod("output");
+        if (!bpWriterSettings.IsUserDefined())
         {
             // if not defined by user, we can change the default settings
-            bpWriterSettings.SetEngine("BP"); // BP is the default engine
-            bpWriterSettings.AddTransport(
-                "File",
-                "lucky=yes"); // ISO-POSIX file is the default transport
-                              // Passing parameters to the transport
-            bpWriterSettings.SetParameters(
-                "have_metadata_file",
-                "yes"); // Passing parameters to the engine
-            bpWriterSettings.SetParameters("Aggregation",
-                                           (nproc + 1) /
-                                               2); // number of aggregators
+            bpWriterSettings.SetEngine("ADIOS1Writer");
+            // ISO-POSIX file is the default transport
+            // Passing parameters to the transport
+            bpWriterSettings.AddTransport("File", "library=MPI-IO");
+            // Passing parameters to the engine
+            bpWriterSettings.SetParameters("have_metadata_file", "yes");
+            // number of aggregators
+            // bpWriterSettings.SetParameters("Aggregation", (nproc + 1) / 2);
         }
 
         // Open returns a smart pointer to Engine containing the Derived class
@@ -95,54 +135,70 @@ int main(int argc, char *argv[])
             throw std::ios_base::failure(
                 "ERROR: failed to open ADIOS bpWriter\n");
 
-        for (int step; step < NSTEPS; step++)
+        for (int step = 0; step < NSTEPS; step++)
         {
-            int Nparts = rand() % 6 + 5; // random size per process, 5..10 each
-            RaggedArray.reserve(Nparts);
+            // Create and fill the arrays whose dimensions change over time
+            Ny = Nx + step;
+            GlobalArray.reserve(Ny);
+            for (int i = 0; i < Ny; i++)
+            {
+                GlobalArray[i] = rank * Ny + (double)i;
+            }
+
+            Nparts = rand() % 6 + 5; // random size per process, 5..10 each
+            IrregularArray.reserve(Nparts);
             for (int i = 0; i < Nparts; i++)
             {
-                RaggedArray[i] = rank * Nx + (float)i;
+                IrregularArray[i] = rank * Nx + (float)i;
             }
 
+            // 1. and 5. Writing a global scalar from only one process
             if (rank == 0)
             {
-                // Writing a global scalar from only one process
-                bpWriter->Write<unsigned int>(varNX, &Nx);
+                // 5. Writing a global constant scalar only once
+                if (step == 0)
+                {
+                    bpWriter->Write<unsigned int>(varNX, Nx);
+                }
+                bpWriter->Write<unsigned int>(varNY, Ny);
             }
-            // Writing a local scalar on every process. Will be shown at reading
-            // as a
-            // 1D array
-            bpWriter->Write<int>(varNparts, &Nparts);
 
-            // Writing a global scalar on every process is useless. Information
-            // will
-            // be thrown away
-            // and only rank 0's data will be in the output
-            bpWriter->Write<int>(varNproc, &nproc);
+            // 2. and 6. Writing a local scalar on every process. Will be shown
+            // at reading as a 1D array
+            bpWriter->Write<int>(varProcessID, ProcessID);
+            bpWriter->Write<unsigned int>(varNparts, Nparts);
 
+            // 3.
+            // Make a 1D selection to describe the local dimensions of the
+            // variable we write and its offsets in the global spaces
+            adios::SelectionBoundingBox sel({rank * Nx}, {Nx});
+            varGlobalArrayFixedDims.SetSelection(sel);
+            bpWriter->Write<double>(varGlobalArrayFixedDims,
+                                    GlobalArrayFixedDims.data());
+
+            // 4.a Local array that will be shown at read as an irregular 2D
+            // global array
+            bpWriter->Write<float>(varLocalArrayFixedDims2D,
+                                   LocalArrayFixedDims.data());
+            // 4.b Local array that will be shown at read as a joined 1D
+            // global array
+            bpWriter->Write<float>(varLocalArrayFixedDims1D,
+                                   LocalArrayFixedDims.data());
+
+            // 7.
             // Make a 1D selection to describe the local dimensions of the
-            // variable we
-            // write and
-            // its offsets in the global spaces
-            adios::Selection &sel = adios.SelectionBoundingBox(
-                {Nx}, {rank * Nx}); // local dims and offsets; both as list
-            NiceArray.SetSelection(sel);
-            bpWriter->Write<double>(varNice,
-                                    NiceArray.data()); // Base class Engine
-                                                       // own the Write<T>
-                                                       // that will call
-                                                       // overloaded Write
-                                                       // from Derived
-
-            adios::Selection &lsel =
-                adios.SelectionBoundingBox({1, Nparts}, {rank, 0});
-            RaggedArray.SetSelection(sel);
-            bpWriter->Write<float>(varRagged, RaggedArray.data()); // Base class
-            // Engine own the
-            // Write<T> that
-            // will call
-            // overloaded Write
-            // from Derived
+            // variable we write and its offsets in the global spaces
+            // Also set the global dimension of the array now
+
+            // TODO: varGlobalArray.SetGlobalDimension({nproc * Ny});
+            varGlobalArray.m_Shape = adios::Dims({nproc * Ny});
+            varGlobalArray.SetSelection({rank * Ny}, {Ny});
+            bpWriter->Write<double>(varGlobalArray, GlobalArray.data());
+
+            // 8. Local array that will be shown at read as a ragged 2D global
+            // array with ranks in slow dimension
+            varIrregularArray.SetSelection({rank, 0}, {1, Nparts});
+            bpWriter->Write<float>(varIrregularArray, IrregularArray.data());
 
             // Indicate we are done for this step
             // N-to-M Aggregation, disk I/O will be performed during this call,
diff --git a/examples/heatTransfer/read/heatRead_adios2.cpp b/examples/heatTransfer/read/heatRead_adios2.cpp
index 9d19ad852..01d103925 100644
--- a/examples/heatTransfer/read/heatRead_adios2.cpp
+++ b/examples/heatTransfer/read/heatRead_adios2.cpp
@@ -69,8 +69,15 @@ int main(int argc, char *argv[])
 
     unsigned int gndx;
     unsigned int gndy;
-    bpReader->Read<unsigned int>("gndx", &gndx);
-    bpReader->Read<unsigned int>("gndy", &gndy);
+    // bpReader->Read<unsigned int>("gndx", &gndx);
+    // bpReader->Read<unsigned int>("gndy", &gndy);
+
+    adios::Variable<unsigned int> *vgndx =
+        bpReader->InquireVariableUInt("gndx");
+    gndx = vgndx->m_Data[0];
+    adios::Variable<unsigned int> *vgndy =
+        bpReader->InquireVariableUInt("gndy");
+    gndy = vgndy->m_Data[0];
 
     if (rank == 0)
     {
@@ -100,7 +107,7 @@ int main(int argc, char *argv[])
 
     // Arrays are read by scheduling one or more of them
     // and performing the reads at once
-    bpReader->ScheduleRead(*vT, T);
+    bpReader->ScheduleRead<double>(*vT, T);
     bpReader->PerformReads(adios::PerformReadMode::BLOCKINGREAD);
 
     printData(T, readsize.data(), offset.data(), rank, vT->GetNSteps());
diff --git a/examples/heatTransfer/write/IO_adios2.cpp b/examples/heatTransfer/write/IO_adios2.cpp
index c16c4000d..13fd9a45c 100644
--- a/examples/heatTransfer/write/IO_adios2.cpp
+++ b/examples/heatTransfer/write/IO_adios2.cpp
@@ -18,6 +18,7 @@ static int rank_saved;
 adios::ADIOS *ad = nullptr;
 std::shared_ptr<adios::Engine> bpWriter;
 adios::Variable<double> *varT = nullptr;
+adios::Variable<unsigned int> *varGndx = nullptr;
 
 IO::IO(const Settings &s, MPI_Comm comm)
 {
@@ -33,12 +34,12 @@ IO::IO(const Settings &s, MPI_Comm comm)
     {
         // if not defined by user, we can change the default settings
         // BPFileWriter is the default engine
-        bpWriterSettings.SetEngine("BPFileWriter");
+        bpWriterSettings.SetEngine("ADIOS1Writer");
         // Allow an extra thread for data processing
         bpWriterSettings.AllowThreads(1);
         // ISO-POSIX file is the default transport
         // Passing parameters to the transport
-        bpWriterSettings.AddTransport("File", "lucky=yes");
+        bpWriterSettings.AddTransport("File", "library=MPI-IO");
 
         const std::string aggregatorsParam("Aggregators=" +
                                            std::to_string((s.nproc + 1) / 2));
@@ -46,15 +47,19 @@ IO::IO(const Settings &s, MPI_Comm comm)
                                        aggregatorsParam);
     }
 
+    //    ad->DefineScalar<unsigned int>("gndx", true);
+    varGndx = &ad->DefineVariable<unsigned int>("gndx");
+    ad->DefineVariable<unsigned int>("gndy");
+
     // define T as 2D global array
-    varT = &ad->DefineVariable<double>(
+    varT = &ad->DefineArray<double>(
         "T",
-        // local size, could be defined later using SetSelection()
-        {s.ndx, s.ndy},
         // Global dimensions
         {s.gndx, s.gndy},
-        // offset of the local array in the global space
-        {s.offsx, s.offsy});
+        // starting offset of the local array in the global space
+        {s.offsx, s.offsy},
+        // local size, could be defined later using SetSelection()
+        {s.ndx, s.ndy});
 
     // add transform to variable
     // adios::Transform tr = adios::transform::BZIP2( );
@@ -99,10 +104,12 @@ void IO::write(int step, const HeatTransfer &ht, const Settings &s,
        Default memspace is always the full selection.
     */
     adios::SelectionBoundingBox memspace =
-        adios::SelectionBoundingBox({s.ndx, s.ndy}, {1, 1});
+        adios::SelectionBoundingBox({1, 1}, {s.ndx, s.ndy});
     varT->SetMemorySelection(memspace);
 
-    bpWriter->Write<double>(*varT, ht.data());
+    bpWriter->Write<unsigned int>(*varGndx, s.gndx);
+    bpWriter->Write<unsigned int>("gndy", s.gndy);
+    bpWriter->Write<double>(*varT, ht.data_noghost().data());
     bpWriter->Advance();
 
 #else
diff --git a/examples/hello/bpWriter/helloBPWriter.cpp b/examples/hello/bpWriter/helloBPWriter.cpp
index e10ecea77..bd0b62e1d 100644
--- a/examples/hello/bpWriter/helloBPWriter.cpp
+++ b/examples/hello/bpWriter/helloBPWriter.cpp
@@ -50,13 +50,13 @@ int main(int argc, char *argv[])
     {
         // Define variable and local size
         adios::Variable<double> &ioMyDoubles =
-            adios.DefineVariable<double>("myDoubles", {Nx});
+            adios.DefineLocalArray<double>("myDoubles", true, {Nx});
 
         adios::Variable<float> &ioMyMatrix =
-            adios.DefineVariable<float>("myMatrix", {rows, columns});
+            adios.DefineLocalArray<float>("myMatrix", true, {rows, columns});
 
         adios::Variable<float> &ioMyMatrix2 =
-            adios.DefineVariable<float>("myMatrix2", {rows, columns});
+            adios.DefineLocalArray<float>("myMatrix2", false, {rows, columns});
 
         // Define method for engine creation, it is basically straight-forward
         // parameters
diff --git a/examples/hello/datamanWriter/helloDataManWriter.cpp b/examples/hello/datamanWriter/helloDataManWriter.cpp
index 1fc22a80c..f74e7e5d8 100644
--- a/examples/hello/datamanWriter/helloDataManWriter.cpp
+++ b/examples/hello/datamanWriter/helloDataManWriter.cpp
@@ -36,9 +36,10 @@ int main(int argc, char *argv[])
     try
     {
         // Define variable and local size
-        auto ioMyDoubles = adios.DefineVariable<double>("myDoubles", {Nx});
-        auto ioMyCFloats =
-            adios.DefineVariable<std::complex<float>>("myCFloats", {3});
+        auto ioMyDoubles =
+            adios.DefineLocalArray<double>("myDoubles", false, {Nx});
+        auto ioMyCFloats = adios.DefineLocalArray<std::complex<float>>(
+            "myCFloats", false, {3});
 
         // Define method for engine creation, it is basically straight-forward
         // parameters
diff --git a/examples/hello/hdf5Writer/helloHDF5Writer.cpp b/examples/hello/hdf5Writer/helloHDF5Writer.cpp
index ecfe1b940..1b521d11f 100644
--- a/examples/hello/hdf5Writer/helloHDF5Writer.cpp
+++ b/examples/hello/hdf5Writer/helloHDF5Writer.cpp
@@ -69,17 +69,16 @@ int main(int argc, char *argv[])
     {
         // Define variable and local size
         auto &ioMyInts =
-            adios.DefineVariable<int>("myInts", {intCountDim1, intDim2}, {4, 3},
-                                      {intOffsetDim1, intOffsetDim2});
-        auto &ioMyDoubles = adios.DefineVariable<double>(
+            adios.DefineArray<int>("myInts", {intCountDim1, intDim2}, {4, 3},
+                                   {intOffsetDim1, intOffsetDim2});
+        auto &ioMyDoubles = adios.DefineArray<double>(
             "myDoubles", {doubleVCount}, {Nx}, {doubleVOffset});
-        auto &ioMyCFloats = adios.DefineVariable<std::complex<float>>(
+        auto &ioMyCFloats = adios.DefineArray<std::complex<float>>(
             "myCFloats", {complexCount}, {3}, {complexOffset});
-        auto &ioMyCDoubles = adios.DefineVariable<std::complex<double>>(
+        auto &ioMyCDoubles = adios.DefineArray<std::complex<double>>(
             "myCDoubles", {complexCount}, {3}, {complexOffset});
-        auto &ioMyCLongDoubles =
-            adios.DefineVariable<std::complex<long double>>(
-                "myCLongDoubles", {complexCount}, {3}, {complexOffset});
+        auto &ioMyCLongDoubles = adios.DefineArray<std::complex<long double>>(
+            "myCLongDoubles", {complexCount}, {3}, {complexOffset});
 
         // Define method for engine creation, it is basically straight-forward
         // parameters
diff --git a/examples/hello/timeBP/timeBPWriter.cpp b/examples/hello/timeBP/timeBPWriter.cpp
index eea25dcb2..d2411293f 100644
--- a/examples/hello/timeBP/timeBPWriter.cpp
+++ b/examples/hello/timeBP/timeBPWriter.cpp
@@ -48,13 +48,13 @@ int main(int argc, char *argv[])
     {
         // Define variable and local size
         adios::Variable<double> &ioMyDoubles =
-            adios.DefineVariable<double>("myDoubles", {Nx});
+            adios.DefineLocalArray<double>("myDoubles", false, {Nx});
 
         adios::Variable<float> &ioMyMatrix =
-            adios.DefineVariable<float>("myMatrix", {rows, columns});
+            adios.DefineLocalArray<float>("myMatrix", true, {rows, columns});
 
         adios::Variable<float> &ioMyMatrix2 =
-            adios.DefineVariable<float>("myMatrix2", {rows, columns});
+            adios.DefineLocalArray<float>("myMatrix2", false, {rows, columns});
 
         // Define method for engine creation, it is basically straight-forward
         // parameters
diff --git a/source/adios2/ADIOS.cpp b/source/adios2/ADIOS.cpp
index ac4725a53..9df44c64a 100644
--- a/source/adios2/ADIOS.cpp
+++ b/source/adios2/ADIOS.cpp
@@ -176,6 +176,17 @@ std::shared_ptr<Engine> ADIOS::Open(const std::string &name,
         throw std::invalid_argument(
             "ERROR: this version didn't compile with ADIOS "
             "1.x library, can't Open ADIOS1Writer\n");
+#endif
+    }
+    else if (type == "ADIOS1Reader")
+    {
+#ifdef ADIOS2_HAVE_ADIOS1
+        return std::make_shared<ADIOS1Reader>(*this, name, accessMode, mpiComm,
+                                              method);
+#else
+        throw std::invalid_argument(
+            "ERROR: this version didn't compile with ADIOS "
+            "1.x library, can't Open ADIOS1Reader\n");
 #endif
     }
     else if (type == "Vis")
@@ -394,7 +405,8 @@ void ADIOS::CheckMethod(std::map<std::string, Method>::const_iterator itMethod,
 // Explicitly instantiate the necessary template implementations
 #define define_template_instantiation(T)                                       \
     template Variable<T> &ADIOS::DefineVariable<T>(                            \
-        const std::string &, const Dims, const Dims, const Dims);              \
+        const std::string &, const Dims, const Dims, const Dims,               \
+        bool constantShape);                                                   \
                                                                                \
     template Variable<T> &ADIOS::GetVariable<T>(const std::string &);
 
diff --git a/source/adios2/ADIOS.h b/source/adios2/ADIOS.h
index 0a5a23439..dbb84d76d 100644
--- a/source/adios2/ADIOS.h
+++ b/source/adios2/ADIOS.h
@@ -97,13 +97,34 @@ public:
      * @param dimensions
      * @param selections
      * @param offsets
+     * @constantShape true if dimensions, offsets and local sizes don't change
+     * over time
      * @return reference to Variable object
      */
     template <class T>
-    Variable<T> &DefineVariable(const std::string &name,
-                                const Dims localDimensions = Dims{1},
-                                const Dims globalDimensions = Dims{},
-                                const Dims offsets = Dims{});
+    Variable<T> &DefineVariable(const std::string &name, const Dims shape = {},
+                                const Dims start = {}, const Dims count = {},
+                                bool constantShape = false);
+
+    template <class T>
+    Variable<T> &DefineScalar(const std::string &name)
+    {
+        return DefineVariable<T>(name, {}, {}, {}, false);
+    }
+
+    template <class T>
+    Variable<T> &DefineLocalArray(const std::string &name, bool isJoined,
+                                  Dims shape = {})
+    {
+        return DefineVariable<T>(name, shape, {}, {}, false);
+    }
+
+    template <class T>
+    Variable<T> &DefineArray(const std::string &name, Dims shape = {},
+                             Dims start = {}, Dims count = {})
+    {
+        return DefineVariable<T>(name, shape, start, count, false);
+    }
 
     template <class T>
     Variable<T> &GetVariable(const std::string &name);
@@ -348,7 +369,8 @@ protected: // no const to allow default empty and copy constructors
 // Explicit declaration of the template methods
 #define declare_template_instantiation(T)                                      \
     extern template Variable<T> &ADIOS::DefineVariable<T>(                     \
-        const std::string &name, const Dims, const Dims, const Dims);          \
+        const std::string &name, const Dims, const Dims, const Dims,           \
+        bool constantShape);                                                   \
                                                                                \
     extern template Variable<T> &ADIOS::GetVariable<T>(const std::string &);
 
diff --git a/source/adios2/ADIOS.tcc b/source/adios2/ADIOS.tcc
index 81af327ac..1f44b7ee6 100644
--- a/source/adios2/ADIOS.tcc
+++ b/source/adios2/ADIOS.tcc
@@ -120,16 +120,15 @@ ADIOS::GetVariableMap()
 // -----------------------------------------------------------------------------
 
 template <typename T>
-Variable<T> &
-ADIOS::DefineVariable(const std::string &name, const Dims globalDimensions,
-                      const Dims localDimensions, const Dims offsets)
+Variable<T> &ADIOS::DefineVariable(const std::string &name, const Dims shape,
+                                   const Dims start, const Dims count,
+                                   bool constantShape)
 {
     auto &variableMap = GetVariableMap<T>();
-    CheckVariableInput(name, globalDimensions);
+    CheckVariableInput(name, shape);
     const unsigned int size = variableMap.size();
-    variableMap.emplace(size,
-                        Variable<T>(name, globalDimensions, localDimensions,
-                                    offsets, m_DebugMode));
+    variableMap.emplace(size, Variable<T>(name, shape, start, count,
+                                          constantShape, m_DebugMode));
     m_Variables.emplace(name, std::make_pair(GetType<T>(), size));
     return variableMap.at(size);
 }
diff --git a/source/adios2/ADIOSTypes.h b/source/adios2/ADIOSTypes.h
index a5ea21b9e..89144a834 100644
--- a/source/adios2/ADIOSTypes.h
+++ b/source/adios2/ADIOSTypes.h
@@ -21,29 +21,6 @@
 namespace adios
 {
 
-/** Use these values in Dims() when defining variables
- */
-enum
-{
-    VARYING_DIMENSION = -1, //!< VARYING_DIMENSION
-    LOCAL_VALUE = 0,        //!< LOCAL_VALUE
-    GLOBAL_VALUE = 1        //!< GLOBAL_VALUE
-};
-
-enum class Verbose
-{
-    ERROR = 0,
-    WARN = 1,
-    INFO = 2,
-    DEBUG = 3
-};
-
-enum class IOMode
-{
-    INDEPENDENT = 0,
-    COLLECTIVE = 1
-};
-
 // Alias the fixed sized typed into the adios namespace to make sure we're
 // always using the right ones.
 using std::size_t;
@@ -137,6 +114,25 @@ struct TypeInfo<T, typename std::enable_if<std::is_same<
     using ValueType = typename T::value_type;
 };
 
+const size_t UnknownDim = 0;
+const size_t JoinedDim = SIZE_MAX;
+const size_t VarDim = JoinedDim - 1;
+const bool ConstantShape = true;
+
+enum class Verbose
+{
+    ERROR = 0,
+    WARN = 1,
+    INFO = 2,
+    DEBUG = 3
+};
+
+enum class IOMode
+{
+    INDEPENDENT = 0,
+    COLLECTIVE = 1
+};
+
 } // end namespace adios
 
 #endif /* ADIOS2_ADIOSTYPES_H_ */
diff --git a/source/adios2/core/Engine.cpp b/source/adios2/core/Engine.cpp
index 5911be7bd..4a55fa433 100644
--- a/source/adios2/core/Engine.cpp
+++ b/source/adios2/core/Engine.cpp
@@ -47,6 +47,14 @@ void Engine::SetCallBack(std::function<void(const void *, std::string,
 {
 }
 
+static void engineThrowUp(const std::string &engineType,
+                          const std::string &func)
+{
+    throw std::invalid_argument(
+        "ERROR: Engine bass class " + func + "() called. " + engineType +
+        " child class is not implementing this function\n");
+}
+
 // should these functions throw an exception?
 void Engine::Write(Variable<char> & /*variable*/, const char * /*values*/) {}
 void Engine::Write(Variable<unsigned char> & /*variable*/,
@@ -215,7 +223,7 @@ Variable<int> *Engine::InquireVariableInt(const std::string & /*name*/,
 Variable<unsigned int> *
 Engine::InquireVariableUInt(const std::string & /*name*/, const bool /*readIn*/)
 {
-    return nullptr;
+    engineThrowUp(m_EngineType, "InquireVariableUInt");
 }
 Variable<long int> *Engine::InquireVariableLInt(const std::string & /*name*/,
                                                 const bool /*readIn*/)
@@ -280,23 +288,158 @@ VariableCompound *Engine::InquireVariableCompound(const std::string & /*name*/,
     return nullptr;
 }
 
-void Engine::ScheduleRead(Variable<unsigned int> & /*variable*/,
-                          unsigned int * /*values*/)
+void Engine::ScheduleRead(Variable<char> &variable, char *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<unsigned char> &variable,
+                          unsigned char *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<short> &variable, short *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<unsigned short> &variable,
+                          unsigned short *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<int> &variable, int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<unsigned int> &variable,
+                          unsigned int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<long int> &variable, long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<unsigned long int> &variable,
+                          unsigned long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<long long int> &variable,
+                          long long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<unsigned long long int> &variable,
+                          unsigned long long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<float> &variable, float *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<double> &variable, double *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<long double> &variable, long double *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<std::complex<float>> &variable,
+                          std::complex<float> *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<std::complex<double>> &variable,
+                          std::complex<double> *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(Variable<std::complex<long double>> &variable,
+                          std::complex<long double> *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+
+void Engine::ScheduleRead(const std::string &variableName, char *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName,
+                          unsigned char *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName, short *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName,
+                          unsigned short *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName, int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName, unsigned int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName, long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName,
+                          unsigned long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName,
+                          long long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName,
+                          unsigned long long int *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName, float *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName, double *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName, long double *values)
+{
+    engineThrowUp(m_EngineType, "ScheduleRead");
+}
+void Engine::ScheduleRead(const std::string &variableName,
+                          std::complex<float> *values)
 {
+    engineThrowUp(m_EngineType, "ScheduleRead");
 }
-void Engine::ScheduleRead(Variable<double> & /*variable*/, double * /*values*/)
+void Engine::ScheduleRead(const std::string &variableName,
+                          std::complex<double> *values)
 {
+    engineThrowUp(m_EngineType, "ScheduleRead");
 }
-void Engine::ScheduleRead(const std::string & /*variableName*/,
-                          unsigned int * /*values*/)
+void Engine::ScheduleRead(const std::string &variableName,
+                          std::complex<long double> *values)
 {
+    engineThrowUp(m_EngineType, "ScheduleRead");
 }
-void Engine::ScheduleRead(const std::string & /*variableName*/,
-                          double * /*values*/)
+
+void Engine::ScheduleRead(const std::string & /*variableName*/)
 {
+    engineThrowUp(m_EngineType, "ScheduleRead");
 }
-void Engine::ScheduleRead(const std::string & /*variableName*/) {}
-void Engine::ScheduleRead() {}
+void Engine::ScheduleRead() { engineThrowUp(m_EngineType, "ScheduleRead"); }
 void Engine::Release() {}
 void Engine::PerformReads(PerformReadMode /*mode*/){};
 
diff --git a/source/adios2/core/Engine.h b/source/adios2/core/Engine.h
index 34478a891..5e70fc64d 100644
--- a/source/adios2/core/Engine.h
+++ b/source/adios2/core/Engine.h
@@ -365,6 +365,61 @@ public:
      */
     virtual void ScheduleRead();
 
+    virtual void ScheduleRead(Variable<char> &variable, char *values);
+    virtual void ScheduleRead(Variable<unsigned char> &variable,
+                              unsigned char *values);
+    virtual void ScheduleRead(Variable<short> &variable, short *values);
+    virtual void ScheduleRead(Variable<unsigned short> &variable,
+                              unsigned short *values);
+    virtual void ScheduleRead(Variable<int> &variable, int *values);
+    virtual void ScheduleRead(Variable<unsigned int> &variable,
+                              unsigned int *values);
+    virtual void ScheduleRead(Variable<long int> &variable, long int *values);
+    virtual void ScheduleRead(Variable<unsigned long int> &variable,
+                              unsigned long int *values);
+    virtual void ScheduleRead(Variable<long long int> &variable,
+                              long long int *values);
+    virtual void ScheduleRead(Variable<unsigned long long int> &variable,
+                              unsigned long long int *values);
+    virtual void ScheduleRead(Variable<float> &variable, float *values);
+    virtual void ScheduleRead(Variable<double> &variable, double *values);
+    virtual void ScheduleRead(Variable<long double> &variable,
+                              long double *values);
+    virtual void ScheduleRead(Variable<std::complex<float>> &variable,
+                              std::complex<float> *values);
+    virtual void ScheduleRead(Variable<std::complex<double>> &variable,
+                              std::complex<double> *values);
+    virtual void ScheduleRead(Variable<std::complex<long double>> &variable,
+                              std::complex<long double> *values);
+
+    virtual void ScheduleRead(const std::string &variableName, char *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              unsigned char *values);
+    virtual void ScheduleRead(const std::string &variableName, short *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              unsigned short *values);
+    virtual void ScheduleRead(const std::string &variableName, int *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              unsigned int *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              long int *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              unsigned long int *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              long long int *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              unsigned long long int *values);
+    virtual void ScheduleRead(const std::string &variableName, float *values);
+    virtual void ScheduleRead(const std::string &variableName, double *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              long double *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              std::complex<float> *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              std::complex<double> *values);
+    virtual void ScheduleRead(const std::string &variableName,
+                              std::complex<long double> *values);
+
     /**
      * Perform all scheduled reads, either blocking until all reads completed,
      * or
@@ -534,13 +589,6 @@ protected:
      * @param transportIndex must be in the range [ -1 , m_Transports.size()-1 ]
      */
     void CheckTransportIndex(const int transportIndex);
-
-    virtual void ScheduleRead(Variable<unsigned int> &variable,
-                              unsigned int *values);
-    virtual void ScheduleRead(Variable<double> &variable, double *values);
-    virtual void ScheduleRead(const std::string &variableName,
-                              unsigned int *values);
-    virtual void ScheduleRead(const std::string &variableName, double *values);
 };
 
 } // end namespace
diff --git a/source/adios2/core/Variable.h b/source/adios2/core/Variable.h
index 949387837..0773aff30 100644
--- a/source/adios2/core/Variable.h
+++ b/source/adios2/core/Variable.h
@@ -43,7 +43,10 @@ class Variable : public VariableBase
 
 public:
     const T *m_AppValues = nullptr; ///< pointer to values passed from user in
-    /// ADIOS Write, it might change in ADIOS Read
+    /// ADIOS Write
+
+    ///< vector of values as a possible result of ADIOS Read or InquireVariable
+    std::vector<T> m_Data;
 
     std::vector<TransformData>
         m_Transforms; ///< associated transforms, sequence
@@ -52,14 +55,12 @@ public:
     /// Transforms[1]. Pointer used as
     /// reference (no memory management).
 
-    Variable<T>(const std::string &name, const Dims localDimensions,
-                const Dims globalDimensions, const Dims offsets,
+    Variable<T>(const std::string &name, const Dims shape, const Dims start,
+                const Dims count, const bool constantShape,
                 const bool debugMode)
-    : VariableBase(name, GetType<T>(), sizeof(T), localDimensions,
-                   globalDimensions, offsets, debugMode)
+    : VariableBase(name, GetType<T>(), sizeof(T), shape, start, count,
+                   constantShape, debugMode)
     {
-        if (m_LocalDimensions == Dims{1})
-            m_IsScalar = true;
     }
 
     template <class... Args>
diff --git a/source/adios2/core/VariableBase.h b/source/adios2/core/VariableBase.h
index 0061c8ec5..98ac37ecf 100644
--- a/source/adios2/core/VariableBase.h
+++ b/source/adios2/core/VariableBase.h
@@ -20,6 +20,7 @@
 /// \endcond
 
 #include "adios2/ADIOSConfig.h"
+#include "adios2/ADIOSTypes.h"
 #include "adios2/core/SelectionBoundingBox.h"
 #include "adios2/core/adiosFunctions.h"
 #include "adios2/core/adiosTemplates.h"
@@ -33,8 +34,10 @@ class VariableBase
 {
 
 public:
-    const std::string m_Name; ///< variable name
-    const std::string m_Type; ///< variable type
+    const std::string m_Name;   ///< variable name
+    const std::string m_Type;   ///< variable type
+    const bool m_ConstantShape; ///< dimensions and offsets cannot change after
+                                /// declaration
 
     /**
      * Variable -> sizeof(T),
@@ -42,9 +45,9 @@ public:
      */
     const std::size_t m_ElementSize;
 
-    Dims m_LocalDimensions;  ///< dimensions per rank (MPI)
-    Dims m_GlobalDimensions; ///< total dimensions across MPI
-    Dims m_Offsets;          ///< selections offset
+    Dims m_Shape;            ///< total dimensions across MPI
+    Dims m_Start;            ///< offsets of local writer in global shape
+    Dims m_Count;            ///< dimensions of the local writer in global shape
     Dims m_MemoryDimensions; ///< array of memory dimensions
     Dims m_MemoryOffsets;    ///< array of memory offsets
     bool m_IsScalar = false;
@@ -52,21 +55,20 @@ public:
     const bool m_DebugMode = false;
 
     VariableBase(const std::string &name, const std::string type,
-                 const std::size_t elementSize, const Dims localDimensions,
-                 const Dims globalDimensions, const Dims offsets,
+                 const std::size_t elementSize, const Dims shape,
+                 const Dims start, const Dims count, const bool constantShape,
                  const bool debugMode)
-    : m_Name{name}, m_Type{type}, m_ElementSize{elementSize},
-      m_LocalDimensions{localDimensions}, m_GlobalDimensions{globalDimensions},
-      m_Offsets{offsets}, m_DebugMode{debugMode}
+    : m_Name{name}, m_Type{type}, m_ConstantShape{constantShape},
+      m_ElementSize{elementSize}, m_Count{count}, m_Shape{shape},
+      m_Start{start}, m_DebugMode{debugMode}
     {
+        if (shape.empty())
+            m_IsScalar = true;
     }
 
     virtual ~VariableBase() {}
 
-    std::size_t DimensionsSize() const noexcept
-    {
-        return m_LocalDimensions.size();
-    }
+    std::size_t DimensionsSize() const noexcept { return m_Count.size(); }
 
     /**
      * Returns the payload size in bytes
@@ -74,39 +76,48 @@ public:
      */
     std::size_t PayLoadSize() const noexcept
     {
-        return GetTotalSize(m_LocalDimensions) * m_ElementSize;
+        return GetTotalSize(m_Count) * m_ElementSize;
     }
 
     /**
      * Returns the total size
      * @return number of elements
      */
-    std::size_t TotalSize() const noexcept
-    {
-        return GetTotalSize(m_LocalDimensions);
-    }
+    std::size_t TotalSize() const noexcept { return GetTotalSize(m_Count); }
 
     /**
-     * Set the local dimension and global offset of the variable using a
-     * selection
-     * Only bounding boxes are allowed
+     * Set the local dimension and global offset of the variable
      */
-    void SetSelection(const SelectionBoundingBox &sel)
+    void SetSelection(const Dims start, const Dims count)
     {
-        if (m_GlobalDimensions.size() == 0)
+        if (m_IsScalar)
         {
             throw std::invalid_argument("Variable.SetSelection() is an invalid "
                                         "call for single value variables\n");
         }
-        if (m_GlobalDimensions.size() != sel.m_Count.size())
+        if (m_ConstantShape)
+        {
+            throw std::invalid_argument(
+                "Variable.SetSelection() is not allowed "
+                "for arrays with a constant shape\n");
+        }
+        if (m_Shape.size() != count.size())
         {
             throw std::invalid_argument("Variable.SetSelection() bounding box "
                                         "dimension must equal the global "
                                         "dimension of the variable\n");
         }
+        ConvertUint64VectorToSizetVector(count, m_Count);
+        ConvertUint64VectorToSizetVector(start, m_Start);
+    }
 
-        ConvertUint64VectorToSizetVector(sel.m_Count, m_LocalDimensions);
-        ConvertUint64VectorToSizetVector(sel.m_Start, m_Offsets);
+    /**
+     * Set the local dimension and global offset of the variable using a
+     * selection
+     */
+    void SetSelection(const SelectionBoundingBox &sel)
+    {
+        SetSelection(sel.m_Start, sel.m_Count);
     }
 
     /**
@@ -116,13 +127,13 @@ public:
      */
     void SetMemorySelection(const SelectionBoundingBox &sel)
     {
-        if (m_GlobalDimensions.size() == 0)
+        if (m_Shape.size() == 0)
         {
             throw std::invalid_argument(
                 "Variable.SetMemorySelection() is an invalid "
                 "call for single value variables\n");
         }
-        if (m_GlobalDimensions.size() != sel.m_Count.size())
+        if (m_Shape.size() != sel.m_Count.size())
         {
             throw std::invalid_argument(
                 "Variable.SetMemorySelection() bounding box "
diff --git a/source/adios2/core/VariableCompound.h b/source/adios2/core/VariableCompound.h
index 4a64cbd45..5153a7c44 100644
--- a/source/adios2/core/VariableCompound.h
+++ b/source/adios2/core/VariableCompound.h
@@ -36,9 +36,10 @@ public:
 
     VariableCompound(const std::string name, const std::size_t sizeOfStruct,
                      const Dims dimensions, const Dims globalDimensions,
-                     const Dims globalOffsets, const bool debugMode)
+                     const Dims globalOffsets, const bool constantShape,
+                     const bool debugMode)
     : VariableBase(name, "compound", sizeOfStruct, dimensions, globalDimensions,
-                   globalOffsets, debugMode)
+                   globalOffsets, constantShape, debugMode)
     {
     }
 
diff --git a/source/adios2/core/adiosFunctions.cpp b/source/adios2/core/adiosFunctions.cpp
index 3c18cd3c2..6c6901880 100644
--- a/source/adios2/core/adiosFunctions.cpp
+++ b/source/adios2/core/adiosFunctions.cpp
@@ -662,6 +662,17 @@ void ConvertUint64VectorToSizetVector(const std::vector<std::uint64_t> &in,
     }
 }
 
+std::vector<std::size_t> Uint64ArrayToSizetVector(const std::size_t nElements,
+                                                  const uint64_t *in)
+{
+    std::vector<std::size_t> out(nElements);
+    for (std::size_t i = 0; i < nElements; i++)
+    {
+        out[i] = static_cast<std::size_t>(in[i]);
+    }
+    return out;
+}
+
 bool CheckBufferAllocation(const std::size_t newSize, const float growthFactor,
                            const std::size_t maxBufferSize,
                            std::vector<char> &buffer)
diff --git a/source/adios2/core/adiosFunctions.h b/source/adios2/core/adiosFunctions.h
index 791661b2d..545c5c3e9 100644
--- a/source/adios2/core/adiosFunctions.h
+++ b/source/adios2/core/adiosFunctions.h
@@ -188,6 +188,15 @@ std::vector<int> CSVToVectorInt(const std::string csv);
  */
 void ConvertUint64VectorToSizetVector(const std::vector<std::uint64_t> &in,
                                       std::vector<std::size_t> &out);
+
+/** Convert a C array of uint64_t elements to a vector of std::size_t elements
+ *  @param number of elements
+ *  @param input array of uint64_t elements
+ *  @return vector of std::size_t elements
+ */
+std::vector<std::size_t> Uint64ArrayToSizetVector(const std::size_t nElements,
+                                                  const uint64_t *in);
+
 /**
  * Converts a vector of dimensions to a CSV string
  * @param dims vector of dimensions
diff --git a/source/adios2/engine/adios1/ADIOS1Reader.cpp b/source/adios2/engine/adios1/ADIOS1Reader.cpp
index b1ad2750d..3cfc07693 100644
--- a/source/adios2/engine/adios1/ADIOS1Reader.cpp
+++ b/source/adios2/engine/adios1/ADIOS1Reader.cpp
@@ -181,16 +181,176 @@ void ADIOS1Reader::ScheduleReadCommon(const std::string &name,
     adios_selection_delete(sel);
 }
 
+void ADIOS1Reader::ScheduleRead(Variable<char> &variable, char *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<unsigned char> &variable,
+                                unsigned char *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<short> &variable, short *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<unsigned short> &variable,
+                                unsigned short *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<int> &variable, int *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<unsigned int> &variable,
+                                unsigned int *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<long int> &variable, long int *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<unsigned long int> &variable,
+                                unsigned long int *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<long long int> &variable,
+                                long long int *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<unsigned long long int> &variable,
+                                unsigned long long int *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<float> &variable, float *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
 void ADIOS1Reader::ScheduleRead(Variable<double> &variable, double *values)
 {
-    ScheduleReadCommon(variable.m_Name, variable.m_LocalDimensions,
-                       variable.m_Offsets, (void *)values);
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<long double> &variable,
+                                long double *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<std::complex<float>> &variable,
+                                std::complex<float> *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<std::complex<double>> &variable,
+                                std::complex<double> *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
+}
+void ADIOS1Reader::ScheduleRead(Variable<std::complex<long double>> &variable,
+                                std::complex<long double> *values)
+{
+    ScheduleReadCommon(variable.m_Name, variable.m_Count, variable.m_Start,
+                       (void *)values);
 }
 
-void ADIOS1Reader::ScheduleRead(const std::string variableName, double *values)
+void ADIOS1Reader::ScheduleRead(const std::string &variableName, char *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<char>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                unsigned char *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<unsigned char>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName, short *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<short>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                unsigned short *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<unsigned short>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName, int *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<int>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                unsigned int *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<unsigned int>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                long int *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<long int>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                unsigned long int *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<unsigned long int>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                long long int *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<long long int>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                unsigned long long int *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<unsigned long long int>(variableName),
+                 values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName, float *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<float>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName, double *values)
 {
     ScheduleRead(m_ADIOS.GetVariable<double>(variableName), values);
 }
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                long double *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<long double>(variableName), values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                std::complex<float> *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<std::complex<float>>(variableName),
+                 values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                std::complex<double> *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<std::complex<double>>(variableName),
+                 values);
+}
+void ADIOS1Reader::ScheduleRead(const std::string &variableName,
+                                std::complex<long double> *values)
+{
+    ScheduleRead(m_ADIOS.GetVariable<std::complex<long double>>(variableName),
+                 values);
+}
 
 void ADIOS1Reader::PerformReads(PerformReadMode mode)
 {
@@ -249,4 +409,73 @@ void ADIOS1Reader::InitTransports()
     }
 }
 
+bool ADIOS1Reader::CheckADIOS1TypeCompatibility(std::string adios2Type,
+                                                enum ADIOS_DATATYPES adios1Type)
+{
+    bool compatible = false;
+    switch (adios1Type)
+    {
+    case adios_unsigned_byte:
+        compatible = (adios2Type == "unsigned char");
+        break;
+    case adios_unsigned_short:
+        compatible = (adios2Type == "unsigned short");
+        break;
+    case adios_unsigned_integer:
+        compatible = (adios2Type == "unsigned int");
+        break;
+    case adios_unsigned_long:
+        compatible = (adios2Type == "unsigned long long int");
+        break;
+
+    case adios_byte:
+        compatible = (adios2Type == "char");
+        break;
+    case adios_short:
+        compatible = (adios2Type == "short");
+        break;
+    case adios_integer:
+        compatible = (adios2Type == "int");
+        break;
+    case adios_long:
+        compatible = (adios2Type == "long long int");
+        break;
+
+    case adios_real:
+        compatible = (adios2Type == "float");
+        break;
+    case adios_double:
+        compatible = (adios2Type == "double");
+        break;
+    case adios_long_double:
+        compatible = (adios2Type == "long double");
+        break;
+
+    case adios_string:
+        compatible = (adios2Type == "string");
+        break;
+    case adios_complex:
+        compatible = (adios2Type == "float complex");
+        break;
+    case adios_double_complex:
+        compatible = (adios2Type == "double complex");
+        break;
+
+    case adios_string_array:
+        compatible = false;
+        break;
+    default:
+        compatible = false;
+    }
+    if (!compatible)
+    {
+        std::string typeStr(adios_type_to_string(adios1Type));
+        throw std::invalid_argument("Type mismatch. The expected ADIOS2 type " +
+                                    adios2Type +
+                                    " is not compatible with ADIOS1 type " +
+                                    typeStr + " of the requested variable\n");
+    }
+    return true;
+}
+
 } // end namespace
diff --git a/source/adios2/engine/adios1/ADIOS1Reader.h b/source/adios2/engine/adios1/ADIOS1Reader.h
index e600754ea..b7c7c843a 100644
--- a/source/adios2/engine/adios1/ADIOS1Reader.h
+++ b/source/adios2/engine/adios1/ADIOS1Reader.h
@@ -15,9 +15,11 @@
 
 #include <iostream> //this must go away
 
+#include "adios2/ADIOS.h"
 #include "adios2/ADIOSConfig.h"
 #include "adios2/capsule/heap/STLVector.h"
 #include "adios2/core/Engine.h"
+#include "adios2/core/adiosFunctions.h"
 
 // Fake out the include guard from ADIOS1's mpidummy.h to prevent it from
 // getting included
@@ -98,8 +100,50 @@ public:
     VariableCompound *InquireVariableCompound(const std::string &name,
                                               const bool readIn = true);
 
+    void ScheduleRead(Variable<char> &variable, char *values);
+    void ScheduleRead(Variable<unsigned char> &variable, unsigned char *values);
+    void ScheduleRead(Variable<short> &variable, short *values);
+    void ScheduleRead(Variable<unsigned short> &variable,
+                      unsigned short *values);
+    void ScheduleRead(Variable<int> &variable, int *values);
+    void ScheduleRead(Variable<unsigned int> &variable, unsigned int *values);
+    void ScheduleRead(Variable<long int> &variable, long int *values);
+    void ScheduleRead(Variable<unsigned long int> &variable,
+                      unsigned long int *values);
+    void ScheduleRead(Variable<long long int> &variable, long long int *values);
+    void ScheduleRead(Variable<unsigned long long int> &variable,
+                      unsigned long long int *values);
+    void ScheduleRead(Variable<float> &variable, float *values);
     void ScheduleRead(Variable<double> &variable, double *values);
-    void ScheduleRead(const std::string variableName, double *values);
+    void ScheduleRead(Variable<long double> &variable, long double *values);
+    void ScheduleRead(Variable<std::complex<float>> &variable,
+                      std::complex<float> *values);
+    void ScheduleRead(Variable<std::complex<double>> &variable,
+                      std::complex<double> *values);
+    void ScheduleRead(Variable<std::complex<long double>> &variable,
+                      std::complex<long double> *values);
+
+    void ScheduleRead(const std::string &variableName, char *values);
+    void ScheduleRead(const std::string &variableName, unsigned char *values);
+    void ScheduleRead(const std::string &variableName, short *values);
+    void ScheduleRead(const std::string &variableName, unsigned short *values);
+    void ScheduleRead(const std::string &variableName, int *values);
+    void ScheduleRead(const std::string &variableName, unsigned int *values);
+    void ScheduleRead(const std::string &variableName, long int *values);
+    void ScheduleRead(const std::string &variableName,
+                      unsigned long int *values);
+    void ScheduleRead(const std::string &variableName, long long int *values);
+    void ScheduleRead(const std::string &variableName,
+                      unsigned long long int *values);
+    void ScheduleRead(const std::string &variableName, float *values);
+    void ScheduleRead(const std::string &variableName, double *values);
+    void ScheduleRead(const std::string &variableName, long double *values);
+    void ScheduleRead(const std::string &variableName,
+                      std::complex<float> *values);
+    void ScheduleRead(const std::string &variableName,
+                      std::complex<double> *values);
+    void ScheduleRead(const std::string &variableName,
+                      std::complex<long double> *values);
 
     void PerformReads(PerformReadMode mode);
     void Close(const int transportIndex = -1);
@@ -122,12 +166,36 @@ private:
         // Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" +
         // name, )
         // return &variable; //return address if success
-        return nullptr; // on failure
+        ADIOS_VARINFO *vi = adios_inq_var(m_fh, name.c_str());
+        adios::Variable<T> *var = nullptr;
+        if (vi != nullptr)
+        {
+            CheckADIOS1TypeCompatibility(GetType<T>(), vi->type); // throws
+            if (vi->ndim > 0)
+            {
+                Dims gdims = Uint64ArrayToSizetVector(vi->ndim, vi->dims);
+                var = &m_ADIOS.DefineArray<T>(name, gdims);
+            }
+            else /* scalar variable */
+            {
+                var = &m_ADIOS.DefineVariable<T>(name);
+                if (var && readIn)
+                {
+                    var->m_Data = std::vector<T>(1);
+                    var->m_Data[0] = *static_cast<T *>(vi->value);
+                }
+            }
+            adios_free_varinfo(vi);
+        }
+        return var;
     }
 
     void ScheduleReadCommon(const std::string &name, const Dims &ldims,
                             const Dims &offs, void *data);
 
+    bool CheckADIOS1TypeCompatibility(std::string adios2Type,
+                                      enum ADIOS_DATATYPES adios1Type);
+
     enum ADIOS_READ_METHOD m_ReadMethod = ADIOS_READ_METHOD_BP;
 };
 
diff --git a/source/adios2/engine/adios1/ADIOS1Writer.cpp b/source/adios2/engine/adios1/ADIOS1Writer.cpp
index 9dff8ee98..5d5f547e5 100644
--- a/source/adios2/engine/adios1/ADIOS1Writer.cpp
+++ b/source/adios2/engine/adios1/ADIOS1Writer.cpp
@@ -100,55 +100,80 @@ void ADIOS1Writer::WriteVariable(std::string name, bool isScalar,
     }
 }
 
+static std::string DimsToCSV_LocalAware(const std::vector<std::size_t> &dims)
+{
+    std::string dimsCSV;
+    bool localVar = false;
+
+    for (const auto dim : dims)
+    {
+        dimsCSV += std::to_string(dim) + ",";
+        if (dim == JoinedDim || dim == VarDim)
+            localVar = true;
+    }
+
+    if (dimsCSV.empty() == false)
+    {
+        dimsCSV.pop_back();
+    }
+
+    if (localVar)
+    {
+        dimsCSV.clear();
+    }
+
+    return dimsCSV;
+}
+
 void ADIOS1Writer::Write(Variable<char> &variable, const char *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_byte,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<unsigned char> &variable,
                          const unsigned char *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_byte,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<short> &variable, const short *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_short,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<unsigned short> &variable,
                          const unsigned short *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_short,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<int> &variable, const int *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_integer,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<unsigned int> &variable,
                          const unsigned int *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_integer,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<long int> &variable, const long int *values)
@@ -160,9 +185,9 @@ void ADIOS1Writer::Write(Variable<long int> &variable, const long int *values)
         type = adios_long;
     }
     WriteVariable(variable.m_Name, variable.m_IsScalar, type,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<unsigned long int> &variable,
@@ -175,43 +200,43 @@ void ADIOS1Writer::Write(Variable<unsigned long int> &variable,
         type = adios_unsigned_long;
     }
     WriteVariable(variable.m_Name, variable.m_IsScalar, type,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<long long int> &variable,
                          const long long int *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_long,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<unsigned long long int> &variable,
                          const unsigned long long int *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_long,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<float> &variable, const float *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_real,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<double> &variable, const double *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_double,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<long double> &variable,
@@ -221,27 +246,27 @@ void ADIOS1Writer::Write(Variable<long double> &variable,
      * but
      * long double is compiler dependent */
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_long_double,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<std::complex<float>> &variable,
                          const std::complex<float> *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_complex,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<std::complex<double>> &variable,
                          const std::complex<double> *values)
 {
     WriteVariable(variable.m_Name, variable.m_IsScalar, adios_double_complex,
-                  DimsToCSV(variable.m_LocalDimensions),
-                  DimsToCSV(variable.m_GlobalDimensions),
-                  DimsToCSV(variable.m_Offsets), values);
+                  DimsToCSV_LocalAware(variable.m_Count),
+                  DimsToCSV_LocalAware(variable.m_Shape),
+                  DimsToCSV_LocalAware(variable.m_Start), values);
 }
 
 void ADIOS1Writer::Write(Variable<std::complex<long double>> &variable,
diff --git a/source/adios2/engine/dataman/DataManWriter.tcc b/source/adios2/engine/dataman/DataManWriter.tcc
index e22d2e4b5..c4518167e 100644
--- a/source/adios2/engine/dataman/DataManWriter.tcc
+++ b/source/adios2/engine/dataman/DataManWriter.tcc
@@ -34,13 +34,13 @@ void DataManWriter::WriteVariableCommon(Variable<T> &variable, const T *values)
     jmsg["doid"] = m_Name;
     jmsg["var"] = variable.m_Name;
     jmsg["dtype"] = GetType<T>();
-    jmsg["putshape"] = variable.m_LocalDimensions;
-    if (variable.m_GlobalDimensions.size() == 0)
-        variable.m_GlobalDimensions = variable.m_LocalDimensions;
-    jmsg["varshape"] = variable.m_GlobalDimensions;
-    if (variable.m_Offsets.size() == 0)
-        variable.m_Offsets.assign(variable.m_LocalDimensions.size(), 0);
-    jmsg["offset"] = variable.m_Offsets;
+    jmsg["putshape"] = variable.m_Count;
+    if (variable.m_Shape.size() == 0)
+        variable.m_Shape = variable.m_Count;
+    jmsg["varshape"] = variable.m_Shape;
+    if (variable.m_Start.size() == 0)
+        variable.m_Start.assign(variable.m_Count.size(), 0);
+    jmsg["offset"] = variable.m_Start;
     jmsg["timestep"] = 0;
     m_Man.put(values, jmsg);
 
@@ -48,11 +48,9 @@ void DataManWriter::WriteVariableCommon(Variable<T> &variable, const T *values)
     {
         MPI_Barrier(m_MPIComm);
         std::cout << "I am hooked to the DataMan library\n";
-        std::cout << "putshape " << variable.m_LocalDimensions.size()
-                  << std::endl;
-        std::cout << "varshape " << variable.m_GlobalDimensions.size()
-                  << std::endl;
-        std::cout << "offset " << variable.m_Offsets.size() << std::endl;
+        std::cout << "putshape " << variable.m_Count.size() << std::endl;
+        std::cout << "varshape " << variable.m_Shape.size() << std::endl;
+        std::cout << "offset " << variable.m_Start.size() << std::endl;
         for (int i = 0; i < m_SizeMPI; ++i)
         {
             if (i == m_RankMPI)
diff --git a/source/adios2/engine/hdf5/HDF5WriterP.cpp b/source/adios2/engine/hdf5/HDF5WriterP.cpp
index bb01c6301..bd31ab64f 100644
--- a/source/adios2/engine/hdf5/HDF5WriterP.cpp
+++ b/source/adios2/engine/hdf5/HDF5WriterP.cpp
@@ -306,7 +306,7 @@ void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values,
     variable.m_AppValues = values;
     m_WrittenVariables.insert(variable.m_Name);
 
-    int dimSize = variable.m_GlobalDimensions.size();
+    int dimSize = variable.m_Shape.size();
     /*
     std::cout << "writting : " << variable.m_Name
               << " dim size:" << variable.m_GlobalDimensions.size() <<
@@ -322,9 +322,9 @@ void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values,
 
     for (int i = 0; i < dimSize; i++)
     {
-        dimsf.push_back(variable.m_GlobalDimensions[i]);
-        count.push_back(variable.m_LocalDimensions[i]);
-        offset.push_back(variable.m_Offsets[i]);
+        dimsf.push_back(variable.m_Shape[i]);
+        count.push_back(variable.m_Count[i]);
+        offset.push_back(variable.m_Start[i]);
     }
 
     _filespace = H5Screate_simple(dimSize, dimsf.data(), NULL);
diff --git a/source/adios2/utilities/format/bp1/BP1Writer.tcc b/source/adios2/utilities/format/bp1/BP1Writer.tcc
index 1e5f0fb4f..2c820f396 100644
--- a/source/adios2/utilities/format/bp1/BP1Writer.tcc
+++ b/source/adios2/utilities/format/bp1/BP1Writer.tcc
@@ -177,16 +177,15 @@ void BP1Writer::WriteVariableMetadataInData(
     InsertToBuffer(buffer, &no);
 
     // write variable dimensions
-    const std::uint8_t dimensions = variable.m_LocalDimensions.size();
+    const std::uint8_t dimensions = variable.m_Count.size();
     InsertToBuffer(buffer, &dimensions); // count
 
     // 27 is from 9 bytes for each: var y/n + local, var y/n + global dimension,
     // var y/n + global offset, changed for characteristic
     std::uint16_t dimensionsLength = 27 * dimensions;
     InsertToBuffer(buffer, &dimensionsLength); // length
-    WriteDimensionsRecord(buffer, variable.m_LocalDimensions,
-                          variable.m_GlobalDimensions, variable.m_Offsets, 18,
-                          true);
+    WriteDimensionsRecord(buffer, variable.m_Count, variable.m_Shape,
+                          variable.m_Start, 18, true);
 
     // CHARACTERISTICS
     WriteVariableCharacteristics(variable, stats, buffer, true);
@@ -255,7 +254,7 @@ void BP1Writer::WriteVariableCharacteristics(
     // DIMENSIONS
     std::uint8_t characteristicID = characteristic_dimensions;
     InsertToBuffer(buffer, &characteristicID);
-    const std::uint8_t dimensions = variable.m_LocalDimensions.size();
+    const std::uint8_t dimensions = variable.m_Count.size();
 
     if (addLength == true)
     {
@@ -267,9 +266,8 @@ void BP1Writer::WriteVariableCharacteristics(
     InsertToBuffer(buffer, &dimensions); // count
     const std::uint16_t dimensionsLength = 24 * dimensions;
     InsertToBuffer(buffer, &dimensionsLength); // length
-    WriteDimensionsRecord(buffer, variable.m_LocalDimensions,
-                          variable.m_GlobalDimensions, variable.m_Offsets, 16,
-                          addLength);
+    WriteDimensionsRecord(buffer, variable.m_Count, variable.m_Shape,
+                          variable.m_Start, 16, addLength);
     ++characteristicsCounter;
 
     // VALUE for SCALAR or STAT min, max for ARRAY
-- 
GitLab