Unverified Commit bada93f0 authored by Wang, Ruonan's avatar Wang, Ruonan Committed by GitHub
Browse files

Merge pull request #2032 from JasonRuonanWang/ssc-fortran

Fix bugs for Fortran column major conversion in SSC
parents a0ca48e8 b43d5b05
......@@ -10,6 +10,7 @@
#include "SscHelper.h"
#include "adios2/common/ADIOSMacros.h"
#include "adios2/helper/adiosJSONcomplex.h"
#include "adios2/helper/adiosType.h"
#include <iostream>
#include <numeric>
......@@ -132,6 +133,84 @@ RankPosMap AllOverlapRanks(const BlockVecVec &bvv)
return ret;
}
void BlockVecToJson(const BlockVec &input, nlohmann::json &output)
{
for (const auto &b : input)
{
output["Variables"].emplace_back();
auto &jref = output["Variables"].back();
jref["Name"] = b.name;
jref["Type"] = b.type;
jref["Shape"] = b.shape;
jref["Start"] = b.start;
jref["Count"] = b.count;
jref["BufferStart"] = b.bufferStart;
jref["BufferCount"] = b.bufferCount;
}
}
void AttributeMapToJson(IO &input, nlohmann::json &output)
{
const auto &attributeMap = input.GetAttributesDataMap();
auto &attributesJson = output["Attributes"];
for (const auto &attributePair : attributeMap)
{
const std::string name(attributePair.first);
const std::string type(attributePair.second.first);
if (type.empty())
{
}
#define declare_type(T) \
else if (type == helper::GetType<T>()) \
{ \
const auto &attribute = input.InquireAttribute<T>(name); \
nlohmann::json attributeJson; \
attributeJson["Name"] = attribute->m_Name; \
attributeJson["Type"] = attribute->m_Type; \
attributeJson["IsSingleValue"] = attribute->m_IsSingleValue; \
if (attribute->m_IsSingleValue) \
{ \
attributeJson["Value"] = attribute->m_DataSingleValue; \
} \
else \
{ \
attributeJson["Array"] = attribute->m_DataArray; \
} \
output["Attributes"].emplace_back(std::move(attributeJson)); \
}
ADIOS2_FOREACH_ATTRIBUTE_STDTYPE_1ARG(declare_type)
#undef declare_type
}
}
void LocalJsonToGlobalJson(const std::vector<char> &input,
const size_t maxLocalSize, const int streamSize,
nlohmann::json &output)
{
try
{
for (size_t i = 0; i < streamSize; ++i)
{
if (input[i * maxLocalSize] == '\0')
{
output[i] = nullptr;
}
else
{
output[i] = nlohmann::json::parse(
input.begin() + i * maxLocalSize,
input.begin() + (i + 1) * maxLocalSize);
}
}
}
catch (std::exception &e)
{
throw(std::runtime_error(
std::string("corrupted global write pattern metadata, ") +
std::string(e.what())));
}
}
void JsonToBlockVecVec(const nlohmann::json &input, BlockVecVec &output)
{
for (int i = 0; i < output.size(); ++i)
......
......@@ -12,6 +12,7 @@
#define ADIOS2_ENGINE_SSCHELPER_H_
#include "adios2/common/ADIOSTypes.h"
#include "adios2/core/IO.h"
#include "nlohmann/json.hpp"
#include <map>
#include <vector>
......@@ -60,6 +61,12 @@ void CalculateOverlap(BlockVecVec &globalPattern, const BlockVec &localPattern);
RankPosMap AllOverlapRanks(const BlockVecVec &mapVec);
void BlockVecToJson(const BlockVec &input, nlohmann::json &output);
void AttributeMapToJson(IO &input, nlohmann::json &output);
void LocalJsonToGlobalJson(const std::vector<char> &input,
const size_t maxLocalSize, const int streamSize,
nlohmann::json &output);
void JsonToBlockVecVec(const nlohmann::json &input, BlockVecVec &output);
void JsonToBlockVecVec(const std::vector<char> &input, BlockVecVec &output);
void JsonToBlockVecVec(const std::string &input, BlockVecVec &output);
......
......@@ -250,28 +250,8 @@ void SscReader::SyncWritePattern()
maxLocalSize, MPI_CHAR, m_StreamComm);
// deserialize global metadata Json
try
{
for (size_t i = 0; i < m_StreamSize; ++i)
{
if (globalVec[i * maxLocalSize] == '\0')
{
m_GlobalWritePatternJson[i] = nullptr;
}
else
{
m_GlobalWritePatternJson[i] = nlohmann::json::parse(
globalVec.begin() + i * maxLocalSize,
globalVec.begin() + (i + 1) * maxLocalSize);
}
}
}
catch (std::exception &e)
{
throw(std::runtime_error(
std::string("corrupted global write pattern metadata, ") +
std::string(e.what())));
}
ssc::LocalJsonToGlobalJson(globalVec, maxLocalSize, m_StreamSize,
m_GlobalWritePatternJson);
// deserialize variables metadata
ssc::JsonToBlockVecVec(m_GlobalWritePatternJson, m_GlobalWritePattern);
......@@ -290,7 +270,14 @@ void SscReader::SyncWritePattern()
auto v = m_IO.InquireVariable<T>(b.name); \
if (not v) \
{ \
m_IO.DefineVariable<T>(b.name, b.shape, b.start, b.shape); \
Dims vStart = b.start; \
Dims vShape = b.shape; \
if (!helper::IsRowMajor(m_IO.m_HostLanguage)) \
{ \
std::reverse(vStart.begin(), vStart.end()); \
std::reverse(vShape.begin(), vShape.end()); \
} \
m_IO.DefineVariable<T>(b.name, vShape, vStart, vShape); \
} \
}
ADIOS2_FOREACH_STDTYPE_1ARG(declare_type)
......
......@@ -13,6 +13,7 @@
#include "SscReader.h"
#include "adios2/helper/adiosMemory.h"
#include "adios2/helper/adiosSystem.h"
#include <iostream>
namespace adios2
......@@ -34,14 +35,27 @@ template <class T>
void SscReader::GetDeferredCommon(Variable<T> &variable, T *data)
{
TAU_SCOPED_TIMER_FUNC();
variable.SetData(data);
Dims vStart = variable.m_Start;
Dims vCount = variable.m_Count;
Dims vShape = variable.m_Shape;
if (!helper::IsRowMajor(m_IO.m_HostLanguage))
{
std::reverse(vStart.begin(), vStart.end());
std::reverse(vCount.begin(), vCount.end());
std::reverse(vShape.begin(), vShape.end());
}
if (m_CurrentStep == 0)
{
m_LocalReadPattern.emplace_back();
auto &b = m_LocalReadPattern.back();
b.name = variable.m_Name;
b.count = variable.m_Count;
b.start = variable.m_Start;
b.shape = variable.m_Shape;
b.count = vCount;
b.start = vStart;
b.shape = vShape;
b.type = helper::GetType<T>();
for (const auto &d : b.count)
......@@ -57,9 +71,9 @@ void SscReader::GetDeferredCommon(Variable<T> &variable, T *data)
auto &jref = m_LocalReadPatternJson["Variables"].back();
jref["Name"] = variable.m_Name;
jref["Type"] = helper::GetType<T>();
jref["Start"] = variable.m_Start;
jref["Count"] = variable.m_Count;
jref["Shape"] = variable.m_Shape;
jref["Start"] = vStart;
jref["Count"] = vCount;
jref["Shape"] = vShape;
jref["BufferStart"] = 0;
jref["BufferCount"] = 0;
......@@ -92,20 +106,10 @@ void SscReader::GetDeferredCommon(Variable<T> &variable, T *data)
{
if (b.name == variable.m_Name)
{
if (b.start.size() == 1 and b.count.size() == 1 and
b.shape.size() == 1 and b.start[0] == 0 and
b.count[0] == 1 and b.shape[0] == 1)
{
std::memcpy(data, m_Buffer.data() + b.bufferStart,
sizeof(T));
}
else
{
helper::NdCopy<T>(
m_Buffer.data() + b.bufferStart, b.start, b.count, true,
true, reinterpret_cast<char *>(data), variable.m_Start,
variable.m_Count, true, true);
}
helper::NdCopy<T>(m_Buffer.data() + b.bufferStart, b.start,
b.count, true, true,
reinterpret_cast<char *>(data), vStart,
vCount, true, true);
}
}
}
......@@ -140,10 +144,16 @@ SscReader::BlocksInfoCommon(const Variable<T> &variable,
b.Start = v.start;
b.Count = v.count;
b.Shape = v.shape;
if (!helper::IsRowMajor(m_IO.m_HostLanguage))
{
std::reverse(b.Start.begin(), b.Start.end());
std::reverse(b.Count.begin(), b.Count.end());
std::reverse(b.Shape.begin(), b.Shape.end());
}
b.IsValue = false;
if (v.shape.size() == 1)
if (b.Shape.size() == 1)
{
if (v.shape[0] == 1)
if (b.Shape[0] == 1)
{
b.IsValue = true;
}
......
......@@ -11,8 +11,6 @@
#include "SscWriter.tcc"
#include "adios2/helper/adiosComm.h"
#include "adios2/helper/adiosCommMPI.h"
#include "adios2/helper/adiosJSONcomplex.h"
#include "nlohmann/json.hpp"
namespace adios2
{
......@@ -238,51 +236,13 @@ void SscWriter::SyncWritePattern()
<< ", Writer Rank " << m_WriterRank << std::endl;
}
// serialize local writer rank variables metadata
nlohmann::json localRankMetaJ;
for (const auto &b : m_GlobalWritePattern[m_StreamRank])
{
localRankMetaJ["Variables"].emplace_back();
auto &jref = localRankMetaJ["Variables"].back();
jref["Name"] = b.name;
jref["Type"] = b.type;
jref["Shape"] = b.shape;
jref["Start"] = b.start;
jref["Count"] = b.count;
jref["BufferStart"] = b.bufferStart;
jref["BufferCount"] = b.bufferCount;
}
// serialize local writer rank attributes metadata
auto &attributesJson = localRankMetaJ["Attributes"];
const auto &attributeMap = m_IO.GetAttributesDataMap();
for (const auto &attributePair : attributeMap)
ssc::BlockVecToJson(m_GlobalWritePattern[m_StreamRank], localRankMetaJ);
if (m_WriterRank == 0)
{
const std::string name(attributePair.first);
const std::string type(attributePair.second.first);
if (type.empty())
{
}
#define declare_type(T) \
else if (type == helper::GetType<T>()) \
{ \
const auto &attribute = m_IO.InquireAttribute<T>(name); \
nlohmann::json attributeJson; \
attributeJson["Name"] = attribute->m_Name; \
attributeJson["Type"] = attribute->m_Type; \
attributeJson["IsSingleValue"] = attribute->m_IsSingleValue; \
if (attribute->m_IsSingleValue) \
{ \
attributeJson["Value"] = attribute->m_DataSingleValue; \
} \
else \
{ \
attributeJson["Array"] = attribute->m_DataArray; \
} \
attributesJson.emplace_back(std::move(attributeJson)); \
}
ADIOS2_FOREACH_ATTRIBUTE_STDTYPE_1ARG(declare_type)
#undef declare_type
ssc::AttributeMapToJson(m_IO, localRankMetaJ);
}
std::string localStr = localRankMetaJ.dump();
......@@ -300,28 +260,8 @@ void SscWriter::SyncWritePattern()
// deserialize global metadata Json
nlohmann::json globalJson;
try
{
for (size_t i = 0; i < m_StreamSize; ++i)
{
if (globalVec[i * maxLocalSize] == '\0')
{
globalJson[i] = nullptr;
}
else
{
globalJson[i] = nlohmann::json::parse(
globalVec.begin() + i * maxLocalSize,
globalVec.begin() + (i + 1) * maxLocalSize);
}
}
}
catch (std::exception &e)
{
throw(std::runtime_error(
std::string("corrupted global write pattern metadata, ") +
std::string(e.what())));
}
ssc::LocalJsonToGlobalJson(globalVec, maxLocalSize, m_StreamSize,
globalJson);
// deserialize variables metadata
ssc::JsonToBlockVecVec(globalJson, m_GlobalWritePattern);
......
......@@ -82,9 +82,6 @@ private:
template <class T>
void PutDeferredCommon(Variable<T> &variable, const T *values);
template <class T>
bool HasBlock(const Variable<T> &variable);
void CalculatePosition(ssc::BlockVecVec &writerMapVec,
ssc::BlockVecVec &readerMapVec, const int writerRank,
ssc::RankPosMap &allOverlapRanks);
......
......@@ -12,6 +12,7 @@
#define ADIOS2_ENGINE_SSCWRITER_TCC_
#include "SscWriter.h"
#include "adios2/helper/adiosSystem.h"
#include <iostream>
namespace adios2
......@@ -21,74 +22,68 @@ namespace core
namespace engine
{
template <class T>
bool SscWriter::HasBlock(const Variable<T> &variable)
{
for (const auto &b : m_GlobalWritePattern[m_StreamRank])
{
if (b.name == variable.m_Name and
ssc::AreSameDims(variable.m_Start, b.start) and
ssc::AreSameDims(variable.m_Count, b.count) and
ssc::AreSameDims(variable.m_Shape, b.shape))
{
return true;
}
}
return false;
}
template <class T>
void SscWriter::PutDeferredCommon(Variable<T> &variable, const T *data)
{
TAU_SCOPED_TIMER_FUNC();
if (variable.m_Start.empty())
variable.SetData(data);
Dims vStart = variable.m_Start;
Dims vCount = variable.m_Count;
Dims vShape = variable.m_Shape;
if (!helper::IsRowMajor(m_IO.m_HostLanguage))
{
variable.m_Start.push_back(0);
std::reverse(vStart.begin(), vStart.end());
std::reverse(vCount.begin(), vCount.end());
std::reverse(vShape.begin(), vShape.end());
}
if (variable.m_Count.empty())
if (vStart.empty())
{
variable.m_Count.push_back(1);
vStart.push_back(0);
}
if (variable.m_Shape.empty())
if (vCount.empty())
{
variable.m_Shape.push_back(1);
vCount.push_back(1);
}
if (m_CurrentStep == 0)
if (vShape.empty())
{
if (not HasBlock(variable))
{
m_GlobalWritePattern[m_StreamRank].emplace_back();
auto &b = m_GlobalWritePattern[m_StreamRank].back();
b.name = variable.m_Name;
b.type = helper::GetType<T>();
b.shape = variable.m_Shape;
b.start = variable.m_Start;
b.count = variable.m_Count;
b.bufferStart = m_Buffer.size();
b.bufferCount = ssc::TotalDataSize(b.count, b.type);
m_Buffer.resize(b.bufferStart + b.bufferCount);
}
vShape.push_back(1);
}
variable.SetData(data);
bool found = false;
for (const auto &b : m_GlobalWritePattern[m_StreamRank])
{
if (b.name == variable.m_Name and
ssc::AreSameDims(variable.m_Start, b.start) and
ssc::AreSameDims(variable.m_Count, b.count) and
ssc::AreSameDims(variable.m_Shape, b.shape))
if (b.name == variable.m_Name and ssc::AreSameDims(vStart, b.start) and
ssc::AreSameDims(vCount, b.count) and
ssc::AreSameDims(vShape, b.shape))
{
std::memcpy(m_Buffer.data() + b.bufferStart, data, b.bufferCount);
found = true;
}
}
if (not found)
{
throw std::runtime_error("ssc only accepts fixed IO pattern");
if (m_CurrentStep == 0)
{
m_GlobalWritePattern[m_StreamRank].emplace_back();
auto &b = m_GlobalWritePattern[m_StreamRank].back();
b.name = variable.m_Name;
b.type = helper::GetType<T>();
b.shape = vShape;
b.start = vStart;
b.count = vCount;
b.bufferStart = m_Buffer.size();
b.bufferCount = ssc::TotalDataSize(b.count, b.type);
m_Buffer.resize(b.bufferStart + b.bufferCount);
std::memcpy(m_Buffer.data() + b.bufferStart, data, b.bufferCount);
}
else
{
throw std::runtime_error("ssc only accepts fixed IO pattern");
}
}
}
......
......@@ -22,6 +22,7 @@ int mpiRank = 0;
int mpiSize = 1;
size_t print_lines = 0;
size_t to_print_lines = 0;
template <class T>
void GenData(std::vector<std::complex<T>> &data, const size_t step)
......@@ -67,7 +68,7 @@ void VerifyData(const std::complex<T> *data, const size_t size, size_t step)
{
ASSERT_EQ(data[i], tmpdata[i]);
}
if (print_lines < 100)
if (print_lines < to_print_lines)
{
PrintData(data, size, step);
++print_lines;
......@@ -83,7 +84,7 @@ void VerifyData(const T *data, const size_t size, size_t step)
{
ASSERT_EQ(data[i], tmpdata[i]);
}
if (print_lines < 100)
if (print_lines < to_print_lines)
{
PrintData(data, size, step);
++print_lines;
......
......@@ -166,7 +166,7 @@ set (SIMPLE_MPI_FORTRAN_TESTS "")
if (ADIOS2_HAVE_MPI)
set (SIMPLE_MPI_TESTS "2x1;1x2;3x5;5x3;DelayedReader_3x5;3x5LockGeometry;2x1.Local;1x2.Local;3x5.Local;5x3.Local;2x1ZeroDataVar;2x1ZeroDataR64")
list (APPEND SPECIAL_TESTS "2x1.NoPreload;2x3.ForcePreload")
if (ADIOS_HAVE_Fortran)
if (ADIOS2_HAVE_Fortran)
set (SIMPLE_MPI_FORTRAN_TESTS "FtoC.3x5;CtoF.3x5;FtoF.3x5")
endif()
endif()
......@@ -236,7 +236,8 @@ if(ADIOS2_HAVE_MPI)
endif()
if(ADIOS2_HAVE_SSC)
set (SSC_TESTS "1x1;1x1.Attrs;TimeoutOnOpen;2x1;1x2;3x5;5x3;3x5LockGeometry;2x1ZeroDataVar;2x1ZeroDataR64")
set (SSC_BASE_TESTS "1x1;1x1.Attrs;2x1;1x2;2x1ZeroDataVar;2x1ZeroDataR64;3x5;5x3;3x5LockGeometry;TimeoutOnOpen")
set (SSC_TESTS ${SIMPLE_FORTRAN_TESTS} ${SIMPLE_MPI_FORTRAN_TESTS} ${SSC_BASE_TESTS})
foreach(test ${SSC_TESTS})
add_common_test(${test} SSC)
endforeach()
......
......@@ -116,6 +116,11 @@ set (FtoC.1x1_CMD "run_test.py.$<CONFIG> -nw 1 -nr 1 -w $<TARGET_FILE:TestCommo
set (CtoF.1x1_CMD "run_test.py.$<CONFIG> -nw 1 -nr 1 -r $<TARGET_FILE:TestCommonRead_f>")
set (FtoF.1x1_CMD "run_test.py.$<CONFIG> -nw 1 -nr 1 -w $<TARGET_FILE:TestCommonWrite_f> -r $<TARGET_FILE:TestCommonRead_f>")
# MPI Fortran tests, Fortran to C, C to Fortran and Fortran to Fortran
set (FtoC.3x5_CMD "run_test.py.$<CONFIG> -nw 3 -nr 5 -w $<TARGET_FILE:TestCommonWrite_f>")
set (CtoF.3x5_CMD "run_test.py.$<CONFIG> -nw 3 -nr 5 -r $<TARGET_FILE:TestCommonRead_f>")
set (FtoF.3x5_CMD "run_test.py.$<CONFIG> -nw 3 -nr 5 -w $<TARGET_FILE:TestCommonWrite_f> -r $<TARGET_FILE:TestCommonRead_f>")
# Tests for ZFP compression (where supported by an engine param)
set (ZFPCompression.1x1_CMD "run_test.py.$<CONFIG> -nw 1 -nr 1 --warg=CompressionMethod=zfp,WENGINE_PARAMS" )
set (ZFPCompression.3x5_CMD "run_test.py.$<CONFIG> -nw 3 -nr 5 --warg=CompressionMethod=zfp,WENGINE_PARAMS" )
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment