Adaptyst
A comprehensive and architecture-agnostic performance analysis tool
Loading...
Searching...
No Matches
output.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 CERN
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#ifndef ADAPTYST_OUTPUT_HPP_
5#define ADAPTYST_OUTPUT_HPP_
6
7#include <filesystem>
8#include <nlohmann/json.hpp>
9#include <mutex>
10#include <fstream>
11
12namespace adaptyst {
13 namespace fs = std::filesystem;
14
20 protected:
21 nlohmann::json metadata;
22
23 public:
25 this->metadata = nlohmann::json::object();
26 }
27
36 template<class T>
37 void set_metadata(std::string key, T value,
38 bool save = true) {
39 if (this->metadata[key] != value) {
40 this->metadata[key] = value;
41
42 if (save) {
43 this->save_metadata();
44 }
45 }
46 }
47
58 template<class T>
59 T get_metadata(std::string key, T default_value) {
60 return this->metadata.value(key, default_value);
61 }
62
71 template<class T>
72 T get_metadata(std::string key) {
73 return this->metadata[key].get<T>();
74 }
75
80 virtual void save_metadata() = 0;
81 };
82
87 class Path : public ObjectWithMetadata {
88 friend class File;
89
90 private:
91 fs::path path;
92
93 void setup(fs::path path) {
94 this->path = fs::absolute(path);
95 try {
96 fs::create_directories(this->path);
97 } catch (std::exception &e) {
98 throw std::runtime_error("Could not create directory " +
99 this->path.string() + ": " +
100 std::string(e.what()));
101 }
102
103 fs::path metadata_path = this->path / "dirmeta.json";
104
105 if (fs::exists(metadata_path)) {
106 std::ifstream metadata_stream(metadata_path);
107
108 if (!metadata_stream) {
109 throw std::runtime_error("Could not open " +
110 (this->path / "dirmeta.json").string() +
111 " for reading!");
112 }
113
114 std::string json_str((std::istreambuf_iterator<char>(metadata_stream)),
115 std::istreambuf_iterator<char>());
116 this->metadata = nlohmann::json::parse(json_str);
117 }
118 }
119
120 public:
126 Path(fs::path path) {
127 this->setup(path);
128 }
129
135 const char *get_path_name() {
136 return this->path.c_str();
137 }
138
144 Path operator/(std::string second) {
145 return Path(this->path / second);
146 }
147
154 Path operator/(const char *second) {
155 return Path(this->path / second);
156 }
157
162 std::ofstream metadata_stream(this->path / "dirmeta.json");
163
164 if (!metadata_stream) {
165 throw std::runtime_error("Could not open " +
166 (this->path / "dirmeta.json").string() +
167 " for writing!");
168 }
169
170 metadata_stream << this->metadata.dump() << std::endl;
171 }
172 };
173
179 class File : public ObjectWithMetadata {
180 protected:
182 std::string name;
183 std::ifstream istream;
184 std::ofstream ostream;
185
186 public:
196 File(Path &path, std::string name,
197 std::string extension = "",
198 bool truncate = true) : path(path) {
199 this->name = name;
200
201 fs::path new_path = path.path / (name + extension);
202
203 if (fs::exists(new_path)) {
204 if (fs::is_directory(new_path)) {
205 throw std::runtime_error(new_path.string() + " is "
206 "a directory");
207 } else {
208 this->istream = std::ifstream(new_path);
209 }
210 }
211
212 this->ostream = std::ofstream(new_path, std::ios_base::out |
213 (truncate ?
214 std::ios_base::trunc : std::ios_base::app));
215
216 if (!this->ostream) {
217 throw std::runtime_error("Could not open " +
218 new_path.string() +
219 " for writing!");
220 }
221
222 fs::path metadata_path = path.path / ("meta_" + this->name + ".json");
223
224 if (fs::exists(metadata_path)) {
225 std::ifstream metadata_stream(metadata_path);
226
227 if (!metadata_stream) {
228 throw std::runtime_error("Could not open " +
229 (path.path / ("meta_" + this->name + ".json")).string() +
230 " for reading!");
231 }
232
233 std::string json_str((std::istreambuf_iterator<char>(metadata_stream)),
234 std::istreambuf_iterator<char>());
235 this->metadata = nlohmann::json::parse(json_str);
236 }
237 }
238
239 File &operator=(File &&source) {
240 this->path = source.path;
241 this->name = source.name;
242 this->istream = std::move(source.istream);
243 this->ostream = std::move(source.ostream);
244 this->metadata.swap(source.metadata);
245 return *this;
246 }
247
253 std::ifstream &get_istream() {
254 return this->istream;
255 }
256
262 std::ofstream &get_ostream() {
263 return this->ostream;
264 }
265
270 fs::path metadata_path = path.path / ("meta_" + this->name + ".json");
271
272 std::ofstream metadata_stream(metadata_path);
273
274 if (!metadata_stream) {
275 throw std::runtime_error("Could not open " + metadata_path.string() +
276 " for writing!");
277 }
278
279 metadata_stream << this->metadata.dump() << std::endl;
280 }
281 };
282
283 template<typename T>
284 concept is_pair = requires {
285 typename T::first_type;
286 typename T::second_type;
287 } && std::is_same_v<T, std::pair<typename T::first_type,
288 typename T::second_type> >;
289
295 template<class T>
296 class Array : public File {
297 private:
298 std::vector<T> vec;
299
300 public:
307 Array(Path &path, std::string name) : File(path, name, ".dat", false) {
308 while (this->istream && !this->istream.eof()) {
309 T val;
310
311 if constexpr (is_pair<T>) {
312 this->istream >> val.first;
313 this->istream >> val.second;
314 } else {
315 this->istream >> val;
316 }
317
318 if (this->istream) {
319 vec.push_back(val);
320 }
321 }
322 }
323
331 T operator[](int index) {
332 return this->vec[index];
333 }
334
340 int size() {
341 return this->vec.size();
342 }
343
350 void push_back(T val) {
351 this->vec.push_back(val);
352
353 if constexpr (is_pair<T>) {
354 this->ostream << val.first << " " << val.second << std::endl;
355 } else {
356 this->ostream << val << std::endl;
357 }
358 }
359 };
360}
361
362#endif
T operator[](int index)
Definition output.hpp:331
void push_back(T val)
Definition output.hpp:350
int size()
Definition output.hpp:340
Array(Path &path, std::string name)
Definition output.hpp:307
File & operator=(File &&source)
Definition output.hpp:239
File(Path &path, std::string name, std::string extension="", bool truncate=true)
Definition output.hpp:196
std::ofstream ostream
Definition output.hpp:184
std::string name
Definition output.hpp:182
std::ifstream & get_istream()
Definition output.hpp:253
Path & path
Definition output.hpp:181
std::ofstream & get_ostream()
Definition output.hpp:262
void save_metadata()
Definition output.hpp:269
std::ifstream istream
Definition output.hpp:183
virtual void save_metadata()=0
ObjectWithMetadata()
Definition output.hpp:24
nlohmann::json metadata
Definition output.hpp:21
T get_metadata(std::string key)
Definition output.hpp:72
void set_metadata(std::string key, T value, bool save=true)
Definition output.hpp:37
T get_metadata(std::string key, T default_value)
Definition output.hpp:59
Definition output.hpp:87
void save_metadata()
Definition output.hpp:161
const char * get_path_name()
Definition output.hpp:135
Path operator/(const char *second)
Definition output.hpp:154
friend class File
Definition output.hpp:88
Path(fs::path path)
Definition output.hpp:126
Path operator/(std::string second)
Definition output.hpp:144
Definition output.hpp:284
Definition output.hpp:12