Skip to content
Snippets Groups Projects
Commit daa9d3d8 authored by pnorbert's avatar pnorbert Committed by GitHub
Browse files

Merge pull request #207 from williamfgc/profiling_json

Moved profiling.log to profiling.json format
parents b007da73 1d610267
No related branches found
No related tags found
No related merge requests found
...@@ -71,37 +71,12 @@ void BPFileWriter::Close(const int transportIndex) ...@@ -71,37 +71,12 @@ void BPFileWriter::Close(const int transportIndex)
m_BP1Writer.m_HeapBuffer.m_DataPosition, m_BP1Writer.m_HeapBuffer.m_DataPosition,
transportIndex); transportIndex);
// close them
m_TransportsManager.CloseFiles(transportIndex); m_TransportsManager.CloseFiles(transportIndex);
if (m_BP1Writer.m_Profiler.IsActive) if (m_BP1Writer.m_Profiler.IsActive &&
m_TransportsManager.AllTransportsClosed())
{ {
// aggregate and write profiling.log WriteProfilingJSONFile();
if (m_TransportsManager.AllTransportsClosed())
{
auto transportTypes = m_TransportsManager.GetTransportsTypes();
auto transportProfilers =
m_TransportsManager.GetTransportsProfilers();
const std::string log(m_BP1Writer.GetRankProfilingLog(
transportTypes, transportProfilers));
// TODO profiling.log from rank0
const std::string profilingLog(
m_BP1Writer.AggregateProfilingLog(log));
if (m_BP1Writer.m_BP1Aggregator.m_RankMPI == 0)
{
transport::FileStream profilingLogStream(m_MPIComm,
m_DebugMode);
auto bpBaseNames = m_BP1Writer.GetBPBaseNames({m_Name});
profilingLogStream.Open(bpBaseNames[0] + "/profiling.log",
OpenMode::Write);
profilingLogStream.Write(profilingLog.c_str(),
profilingLog.size());
profilingLogStream.Close();
}
}
} }
} }
...@@ -147,4 +122,26 @@ void BPFileWriter::InitBPBuffer() ...@@ -147,4 +122,26 @@ void BPFileWriter::InitBPBuffer()
} }
} }
void BPFileWriter::WriteProfilingJSONFile()
{
auto transportTypes = m_TransportsManager.GetTransportsTypes();
auto transportProfilers = m_TransportsManager.GetTransportsProfilers();
const std::string lineJSON(
m_BP1Writer.GetRankProfilingJSON(transportTypes, transportProfilers));
const std::string profilingJSON(
m_BP1Writer.AggregateProfilingJSON(lineJSON));
if (m_BP1Writer.m_BP1Aggregator.m_RankMPI == 0)
{
transport::FileStream profilingJSONStream(m_MPIComm, m_DebugMode);
auto bpBaseNames = m_BP1Writer.GetBPBaseNames({m_Name});
profilingJSONStream.Open(bpBaseNames[0] + "/profiling.json",
OpenMode::Write);
profilingJSONStream.Write(profilingJSON.c_str(), profilingJSON.size());
profilingJSONStream.Close();
}
}
} // end namespace adios } // end namespace adios
...@@ -77,6 +77,10 @@ private: ...@@ -77,6 +77,10 @@ private:
*/ */
template <class T> template <class T>
void DoWriteCommon(Variable<T> &variable, const T *values); void DoWriteCommon(Variable<T> &variable, const T *values);
/** Write a profiling.json file from m_BP1Writer and m_TransportsManager
* profilers*/
void WriteProfilingJSONFile();
}; };
} // end namespace adios } // end namespace adios
......
...@@ -33,9 +33,9 @@ BP1Aggregator::BP1Aggregator(MPI_Comm mpiComm, const bool debugMode) ...@@ -33,9 +33,9 @@ BP1Aggregator::BP1Aggregator(MPI_Comm mpiComm, const bool debugMode)
MPI_Comm_size(m_MPIComm, &m_SizeMPI); MPI_Comm_size(m_MPIComm, &m_SizeMPI);
} }
std::string BP1Aggregator::GetGlobalProfilingLog(const std::string &rankLog) std::string BP1Aggregator::GetGlobalProfilingJSON(const std::string &rankLog)
{ {
std::string profilingLog; std::string profilingJSON;
if (m_RankMPI == 0) if (m_RankMPI == 0)
{ {
...@@ -80,38 +80,17 @@ std::string BP1Aggregator::GetGlobalProfilingLog(const std::string &rankLog) ...@@ -80,38 +80,17 @@ std::string BP1Aggregator::GetGlobalProfilingLog(const std::string &rankLog)
// write global string // write global string
// key is to reserve memory first // key is to reserve memory first
profilingLog.reserve(rankLog.size() * m_SizeMPI); profilingJSON.reserve(rankLog.size() * m_SizeMPI);
profilingLog += "{\n"; profilingJSON += "[\n";
profilingLog += rankLog + ",\n"; profilingJSON += rankLog;
for (unsigned int i = 1; i < sizeMPI; ++i) for (unsigned int i = 1; i < sizeMPI; ++i)
{ {
const std::string rankLogStr(rankLogs[i - 1].data(), profilingJSON += ",\n";
rankLogs[i - 1].size()); profilingJSON.append(rankLogs[i - 1].data(),
profilingLog += rankLogStr + ","; rankLogs[i - 1].size());
if (i < sizeMPI - 1)
{
profilingLog += "\n";
}
} }
profilingLog.pop_back(); // eliminate trailing comma profilingJSON += "\n]\n"; // close json
profilingLog += "\n";
profilingLog += "}\n";
// // write to file
// std::ofstream logStream(fileName);
// if (m_DebugMode)
// {
// if (!logStream)
// {
// throw std::ios_base::failure(
// "ERROR: couldn't open profiling file " + fileName
// + "\n");
// }
// }
//
// logStream.write(logFile.c_str(), logFile.size());
// logStream.close();
} }
else else
{ {
...@@ -127,7 +106,7 @@ std::string BP1Aggregator::GetGlobalProfilingLog(const std::string &rankLog) ...@@ -127,7 +106,7 @@ std::string BP1Aggregator::GetGlobalProfilingLog(const std::string &rankLog)
MPI_Barrier(m_MPIComm); // Barrier here? MPI_Barrier(m_MPIComm); // Barrier here?
return profilingLog; return profilingJSON;
} }
} // end namespace format } // end namespace format
......
...@@ -46,7 +46,7 @@ public: ...@@ -46,7 +46,7 @@ public:
* python dictionary format * python dictionary format
* @param rankLog contain rank profiling info to be aggregated * @param rankLog contain rank profiling info to be aggregated
*/ */
std::string GetGlobalProfilingLog(const std::string &rankLog); std::string GetGlobalProfilingJSON(const std::string &rankLog);
private: private:
const bool m_DebugMode = false; const bool m_DebugMode = false;
......
...@@ -182,36 +182,39 @@ void BP1Writer::Close() noexcept ...@@ -182,36 +182,39 @@ void BP1Writer::Close() noexcept
} }
} }
std::string BP1Writer::GetRankProfilingLog( std::string BP1Writer::GetRankProfilingJSON(
const std::vector<std::string> &transportsTypes, const std::vector<std::string> &transportsTypes,
const std::vector<profiling::IOChrono *> &transportsProfilers) noexcept const std::vector<profiling::IOChrono *> &transportsProfilers) noexcept
{ {
auto lf_WriterTimer = [](std::string &rankLog, auto lf_WriterTimer = [](std::string &rankLog,
const profiling::Timer &timer) { const profiling::Timer &timer) {
rankLog += "'" + timer.m_Process + "_" + timer.GetShortUnits() + "': " + rankLog += "\"" + timer.m_Process + "_" + timer.GetShortUnits() +
std::to_string(timer.m_ProcessTime) + ", "; "\": " + std::to_string(timer.m_ProcessTime) + ", ";
}; };
// prepare string dictionary per rank // prepare string dictionary per rank
std::string rankLog("'rank_" + std::to_string(m_BP1Aggregator.m_RankMPI) + std::string rankLog("{ \"rank\": " +
"': { "); std::to_string(m_BP1Aggregator.m_RankMPI) + ", ");
auto &profiler = m_Profiler; auto &profiler = m_Profiler;
std::string timeDate(profiler.Timers.at("buffering").m_LocalTimeDate); std::string timeDate(profiler.Timers.at("buffering").m_LocalTimeDate);
timeDate.pop_back(); timeDate.pop_back();
// avoid whitespace
std::replace(timeDate.begin(), timeDate.end(), ' ', '_');
rankLog += "'date_and_time': '" + timeDate + "', 'threads': " + rankLog += "\"start\": \"" + timeDate + "\", ";
std::to_string(m_Threads) + ", 'bytes': " + rankLog += "\"threads\": " + std::to_string(m_Threads) + ", ";
std::to_string(profiler.Bytes.at("buffering")) + ", "; rankLog +=
"\"bytes\": " + std::to_string(profiler.Bytes.at("buffering")) + ", ";
lf_WriterTimer(rankLog, profiler.Timers.at("buffering")); lf_WriterTimer(rankLog, profiler.Timers.at("buffering"));
const size_t transportsSize = transportsTypes.size(); const size_t transportsSize = transportsTypes.size();
for (unsigned int t = 0; t < transportsSize; ++t) for (unsigned int t = 0; t < transportsSize; ++t)
{ {
rankLog += "'transport_" + std::to_string(t) + "': { "; rankLog += "\"transport_" + std::to_string(t) + "\": { ";
rankLog += "'type': '" + transportsTypes[t] + "', "; rankLog += "\"type\": \"" + transportsTypes[t] + "\", ";
for (const auto &transportTimerPair : transportsProfilers[t]->Timers) for (const auto &transportTimerPair : transportsProfilers[t]->Timers)
{ {
...@@ -231,15 +234,15 @@ std::string BP1Writer::GetRankProfilingLog( ...@@ -231,15 +234,15 @@ std::string BP1Writer::GetRankProfilingLog(
rankLog += "},"; rankLog += "},";
} }
} }
rankLog += " }"; rankLog += " }"; // end rank entry
return rankLog; return rankLog;
} }
std::string std::string
BP1Writer::AggregateProfilingLog(const std::string &rankProfilingLog) noexcept BP1Writer::AggregateProfilingJSON(const std::string &rankProfilingLog) noexcept
{ {
return m_BP1Aggregator.GetGlobalProfilingLog(rankProfilingLog); return m_BP1Aggregator.GetGlobalProfilingJSON(rankProfilingLog);
} }
// PRIVATE FUNCTIONS // PRIVATE FUNCTIONS
......
...@@ -86,12 +86,17 @@ public: ...@@ -86,12 +86,17 @@ public:
* @param transportsTypes list of transport types * @param transportsTypes list of transport types
* @param transportsProfilers list of references to transport profilers * @param transportsProfilers list of references to transport profilers
*/ */
std::string GetRankProfilingLog( std::string GetRankProfilingJSON(
const std::vector<std::string> &transportsTypes, const std::vector<std::string> &transportsTypes,
const std::vector<profiling::IOChrono *> &transportsProfilers) noexcept; const std::vector<profiling::IOChrono *> &transportsProfilers) noexcept;
/**
* Forms the final profiling.json string aggregating from all ranks
* @param rankProfilingJSON
* @return profiling.json
*/
std::string std::string
AggregateProfilingLog(const std::string &rankProfilingLog) noexcept; AggregateProfilingJSON(const std::string &rankProfilingJSON) noexcept;
private: private:
/** BP format version */ /** BP format version */
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
# We currently require ADIOS1 to test ADIOS v2 bp functionality since the read # We currently require ADIOS1 to test ADIOS v2 bp functionality since the read
# API is not available yet # API is not available yet
if(ADIOS2_HAVE_ADIOS1) add_subdirectory(bp)
add_subdirectory(bp)
endif()
if(ADIOS2_HAVE_ADIOS1) if(ADIOS2_HAVE_ADIOS1)
add_subdirectory(adios1) add_subdirectory(adios1)
......
...@@ -5,19 +5,27 @@ ...@@ -5,19 +5,27 @@
# MPI versions of the test are not properly implemented at the moment # MPI versions of the test are not properly implemented at the moment
if(NOT ADIOS2_HAVE_MPI) if(NOT ADIOS2_HAVE_MPI)
find_package(ADIOS1 COMPONENTS sequential REQUIRED)
add_executable(TestBPWriteRead TestBPWriteRead.cpp)
target_link_libraries(TestBPWriteRead adios2 gtest adios1::adios)
add_executable(TestBPWriteReadstdio TestBPWriteReadstdio.cpp) if(ADIOS2_HAVE_ADIOS1)
target_link_libraries(TestBPWriteReadstdio adios2 gtest adios1::adios) find_package(ADIOS1 COMPONENTS sequential REQUIRED)
add_executable(TestBPWriteReadfstream TestBPWriteReadfstream.cpp) add_executable(TestBPWriteRead TestBPWriteRead.cpp)
target_link_libraries(TestBPWriteReadfstream adios2 gtest adios1::adios) target_link_libraries(TestBPWriteRead adios2 gtest adios1::adios)
add_executable(TestBPWriteReadstdio TestBPWriteReadstdio.cpp)
target_link_libraries(TestBPWriteReadstdio adios2 gtest adios1::adios)
gtest_add_tests(TARGET TestBPWriteRead) add_executable(TestBPWriteReadfstream TestBPWriteReadfstream.cpp)
gtest_add_tests(TARGET TestBPWriteReadstdio) target_link_libraries(TestBPWriteReadfstream adios2 gtest adios1::adios)
gtest_add_tests(TARGET TestBPWriteReadfstream)
gtest_add_tests(TARGET TestBPWriteRead)
gtest_add_tests(TARGET TestBPWriteReadstdio)
gtest_add_tests(TARGET TestBPWriteReadfstream)
endif()
add_executable(TestBPWriteProfilingJSON TestBPWriteProfilingJSON.cpp)
target_link_libraries(TestBPWriteProfilingJSON adios2 gtest gtest_main NLohmannJson)
gtest_add_tests(TARGET TestBPWriteProfilingJSON)
endif() endif()
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* TestBPWriteProfilingJSON.cpp
*
* Created on: Jul 18, 2017
* Author: William F Godoy godoywf@ornl.gov
*/
#include <cstdint>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <adios2.h>
#include <gtest/gtest.h>
#include <json.hpp> //This fails to be included
#include "../SmallTestData.h"
using json = nlohmann::json;
class BPWriteProfilingJSONTest : public ::testing::Test
{
public:
BPWriteProfilingJSONTest() = default;
SmallTestData m_TestData;
};
//******************************************************************************
// 1D 1x8 test data
//******************************************************************************
// ADIOS2 write, native ADIOS1 read
TEST_F(BPWriteProfilingJSONTest, ADIOS2BPWriteProfilingJSON)
{
std::string fname = "ADIOS2BPWriteProfilingJSON.bp";
// Write test data and profiling.json using ADIOS2
{
adios2::ADIOS adios(true);
adios2::IO &io = adios.DeclareIO("TestIO");
// Declare 1D variables
{
auto &var_i8 =
io.DefineVariable<char>("i8", {}, {}, adios2::Dims{8});
auto &var_i16 =
io.DefineVariable<short>("i16", {}, {}, adios2::Dims{8});
auto &var_i32 =
io.DefineVariable<int>("i32", {}, {}, adios2::Dims{8});
auto &var_i64 =
io.DefineVariable<long>("i64", {}, {}, adios2::Dims{8});
auto &var_u8 =
io.DefineVariable<unsigned char>("u8", {}, {}, adios2::Dims{8});
auto &var_u16 = io.DefineVariable<unsigned short>("u16", {}, {},
adios2::Dims{8});
auto &var_u32 =
io.DefineVariable<unsigned int>("u32", {}, {}, adios2::Dims{8});
auto &var_u64 = io.DefineVariable<unsigned long>("u64", {}, {},
adios2::Dims{8});
auto &var_r32 =
io.DefineVariable<float>("r32", {}, {}, adios2::Dims{8});
auto &var_r64 =
io.DefineVariable<double>("r64", {}, {}, adios2::Dims{8});
}
// Create the BP Engine
io.SetEngine("BPFileWriter");
io.SetParameters({{"Threads", "2"}});
io.AddTransport("File", {{"Library", "POSIX"}});
auto engine = io.Open(fname, adios2::OpenMode::Write);
ASSERT_NE(engine.get(), nullptr);
for (size_t step = 0; step < 3; ++step)
{
// Retrieve the variables that previously went out of scope
auto &var_i8 = io.GetVariable<char>("i8");
auto &var_i16 = io.GetVariable<short>("i16");
auto &var_i32 = io.GetVariable<int>("i32");
auto &var_i64 = io.GetVariable<long>("i64");
auto &var_u8 = io.GetVariable<unsigned char>("u8");
auto &var_u16 = io.GetVariable<unsigned short>("u16");
auto &var_u32 = io.GetVariable<unsigned int>("u32");
auto &var_u64 = io.GetVariable<unsigned long>("u64");
auto &var_r32 = io.GetVariable<float>("r32");
auto &var_r64 = io.GetVariable<double>("r64");
// Write each one
engine->Write(var_i8, m_TestData.I8.data() + step);
engine->Write(var_i16, m_TestData.I16.data() + step);
engine->Write(var_i32, m_TestData.I32.data() + step);
engine->Write(var_i64, m_TestData.I64.data() + step);
engine->Write(var_u8, m_TestData.U8.data() + step);
engine->Write(var_u16, m_TestData.U16.data() + step);
engine->Write(var_u32, m_TestData.U32.data() + step);
engine->Write(var_u64, m_TestData.U64.data() + step);
engine->Write(var_r32, m_TestData.R32.data() + step);
engine->Write(var_r64, m_TestData.R64.data() + step);
// Advance to the next time step
engine->Advance();
}
// Close the file
engine->Close();
}
// open json file, parse it to a json structure, and verify a few things
{
std::ifstream profilingJSONFile(fname + ".dir/profiling.json");
std::stringstream buffer;
buffer << profilingJSONFile.rdbuf();
const json profilingJSON = json::parse(buffer);
// check rank is zero
const int rank = profilingJSON[0].value("rank", -1);
ASSERT_EQ(rank, 0);
// check threads
const int threads = profilingJSON[0].value("threads", 0);
ASSERT_EQ(threads, 2);
// check bytes
const unsigned long int bytes = profilingJSON[0].value("bytes", 0UL);
ASSERT_EQ(bytes, 6536);
const auto transportType =
profilingJSON[0]["transport_0"].value("type", "0");
ASSERT_EQ(transportType, "File_POSIX");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment