1 /*
2  * Distributed under the OSI-approved Apache License, Version 2.0.  See
3  * accompanying file Copyright.txt for details.
4  *
5  * BP3Base.cpp
6  *
7  *  Created on: Feb 7, 2017
8  *      Author: William F Godoy godoywf@ornl.gov
9  */
10 #include "BP3Base.h"
11 
12 #include <algorithm> // std::transform
13 #include <iostream>  // std::cout Warnings
14 
15 #include "adios2/common/ADIOSTypes.h"     //PathSeparator
16 #include "adios2/helper/adiosFunctions.h" //CreateDirectory, StringToTimeUnit,
17 
18 namespace adios2
19 {
20 namespace format
21 {
22 
BP3Base(helper::Comm const & comm)23 BP3Base::BP3Base(helper::Comm const &comm) : BPBase(comm) {}
24 
25 std::vector<std::string>
GetBPBaseNames(const std::vector<std::string> & names) const26 BP3Base::GetBPBaseNames(const std::vector<std::string> &names) const noexcept
27 {
28     std::vector<std::string> bpBaseNames;
29     bpBaseNames.reserve(names.size());
30 
31     for (const std::string &name : names)
32     {
33         const std::string bpBaseName =
34             helper::AddExtension(name, ".bp") + ".dir";
35         bpBaseNames.push_back(bpBaseName);
36     }
37     return bpBaseNames;
38 }
39 
40 std::vector<std::string>
GetBPMetadataFileNames(const std::vector<std::string> & names) const41 BP3Base::GetBPMetadataFileNames(const std::vector<std::string> &names) const
42     noexcept
43 {
44     std::vector<std::string> metadataFileNames;
45     metadataFileNames.reserve(names.size());
46     for (const auto &name : names)
47     {
48         metadataFileNames.push_back(GetBPMetadataFileName(name));
49     }
50     return metadataFileNames;
51 }
52 
GetBPMetadataFileName(const std::string & name) const53 std::string BP3Base::GetBPMetadataFileName(const std::string &name) const
54     noexcept
55 {
56     return helper::AddExtension(name, ".bp");
57 }
58 
59 std::vector<std::string>
GetBPSubStreamNames(const std::vector<std::string> & names) const60 BP3Base::GetBPSubStreamNames(const std::vector<std::string> &names) const
61     noexcept
62 {
63     std::vector<std::string> bpNames;
64     bpNames.reserve(names.size());
65 
66     for (const auto &name : names)
67     {
68         bpNames.push_back(
69             GetBPSubStreamName(name, static_cast<unsigned int>(m_RankMPI)));
70     }
71     return bpNames;
72 }
73 
GetBPSubFileName(const std::string & name,const size_t subFileIndex,const bool hasSubFiles,const bool isReader) const74 std::string BP3Base::GetBPSubFileName(const std::string &name,
75                                       const size_t subFileIndex,
76                                       const bool hasSubFiles,
77                                       const bool isReader) const noexcept
78 {
79     return GetBPSubStreamName(name, subFileIndex, hasSubFiles, isReader);
80 }
81 
GetBPIndexSizeInData(const std::string & variableName,const Dims & count) const82 size_t BP3Base::GetBPIndexSizeInData(const std::string &variableName,
83                                      const Dims &count) const noexcept
84 {
85     size_t indexSize = 23; // header
86     indexSize += variableName.size();
87 
88     // characteristics 3 and 4, check variable number of dimensions
89     const size_t dimensions = count.size();
90     indexSize += 28 * dimensions; // 28 bytes per dimension
91     indexSize += 1;               // id
92 
93     // characteristics, offset + payload offset in data
94     indexSize += 2 * (1 + 8);
95     // characteristic 0, if scalar add value, for now only allowing string
96     if (dimensions == 1)
97     {
98         indexSize += 2 * sizeof(uint64_t); // complex largest size
99         indexSize += 1;                    // id
100         indexSize += 1;                    // id
101     }
102 
103     // characteristic statistics
104     indexSize += 5; // count + length
105     // default, only min and max and dimensions
106     if (m_Parameters.StatsLevel > 0)
107     {
108         indexSize += 2 * (2 * sizeof(uint64_t) + 1);
109         indexSize += 1 + 1; // id
110 
111         indexSize += 28 * dimensions + 1;
112     }
113 
114     indexSize += 32 + 5; // extra bytes for padding
115     indexSize += 12;     // extra 12 bytes in case of attributes
116     return indexSize;
117 }
118 
119 // PROTECTED
120 BP3Base::ElementIndexHeader
ReadElementIndexHeader(const std::vector<char> & buffer,size_t & position,const bool isLittleEndian) const121 BP3Base::ReadElementIndexHeader(const std::vector<char> &buffer,
122                                 size_t &position,
123                                 const bool isLittleEndian) const noexcept
124 {
125     ElementIndexHeader header;
126     header.Length =
127         helper::ReadValue<uint32_t>(buffer, position, isLittleEndian);
128     header.MemberID =
129         helper::ReadValue<uint32_t>(buffer, position, isLittleEndian);
130     header.GroupName = ReadBPString(buffer, position, isLittleEndian);
131     header.Name = ReadBPString(buffer, position, isLittleEndian);
132     header.Path = ReadBPString(buffer, position, isLittleEndian);
133     header.DataType =
134         helper::ReadValue<int8_t>(buffer, position, isLittleEndian);
135     header.CharacteristicsSetsCount =
136         helper::ReadValue<uint64_t>(buffer, position, isLittleEndian);
137 
138     return header;
139 }
140 
141 // PRIVATE
GetBPSubStreamName(const std::string & name,const size_t id,const bool hasSubFiles,const bool isReader) const142 std::string BP3Base::GetBPSubStreamName(const std::string &name,
143                                         const size_t id, const bool hasSubFiles,
144                                         const bool isReader) const noexcept
145 {
146     if (!hasSubFiles)
147     {
148         return name;
149     }
150 
151     const std::string bpName = helper::AddExtension(name, ".bp");
152 
153     // path/root.bp.dir/root.bp.Index
154     std::string bpRoot = bpName;
155     const auto lastPathSeparator(bpName.find_last_of(PathSeparator));
156 
157     if (lastPathSeparator != std::string::npos)
158     {
159         bpRoot = bpName.substr(lastPathSeparator);
160     }
161 
162     const size_t index =
163         isReader ? id
164                  : m_Aggregator.m_IsActive ? m_Aggregator.m_SubStreamIndex : id;
165 
166     const std::string bpRankName(bpName + ".dir" + PathSeparator + bpRoot +
167                                  "." + std::to_string(index));
168     return bpRankName;
169 }
170 
171 } // end namespace format
172 } // end namespace adios2
173