Cholla 3.0.1-dev
Cholla - Massively parallel hydro on GPUs
Loading...
Searching...
No Matches
AttrRecorderInterface.h
Go to the documentation of this file.
1
13#pragma once
14
15#include <cstdio> // std::FILE
16#include <string>
17#include <string_view>
18
19#include "../utils/error_handling.h"
20
36{
37 public:
38 // I don't anticipate that we'll need the virtual destructor, but we're
39 // including it just in case. I'm concerned that if we don't declare it to
40 // be virtual a future change could make it necessary and people may be
41 // confused about failure since inheritance is EXTREMELY rare in this
42 // codebase
43 virtual ~AttrRecorderInterface() {}
44
45 // declare the recording methods for arrays of values
47
48 virtual void record_arr(const char* name, const double* arr, int length) = 0;
49 virtual void record_arr(const char* name, const int* arr, int length) = 0;
50 virtual void record_arr(const char* name, const long* arr, int length) = 0;
52
53 // the following member group consists of member functions for recording scalar
54 // attributes. The overload for writing a string is the only pure virtual member.
55 // Every other member function has a default implementation that treats the scalar
56 // as a 1 element array
57
59
60 virtual void record(const char* name, const char* val) = 0;
61 virtual void record(const char* name, double val) = 0;
62 virtual void record(const char* name, int val) = 0;
63 virtual void record(const char* name, long val) = 0;
65
67 void record_triple(const char* name, double a, double b, double c)
68 {
69 double tmp[3] = {a, b, c};
70 this->record_arr(name, tmp, 3);
71 }
72
73 /* A convenience method for recording 3 ints */
74 void record_triple(const char* name, int a, int b, int c)
75 {
76 int tmp[3] = {a, b, c};
77 this->record_arr(name, tmp, 3);
78 }
79};
80
81namespace io_detail
82{
83
88std::string encode_toml_key(std::string_view key);
89
94std::string encode_toml_str(std::string_view s);
95} // namespace io_detail
96
116{
117 std::FILE* fp_;
119 bool is_closed_;
120
121 template <typename T>
122 void write_val_(T val)
123 {
124 if constexpr (std::is_same_v<T, long>) {
125 std::fprintf(this->fp_, "%ld", val);
126 } else if constexpr (std::is_same_v<T, int>) {
127 std::fprintf(this->fp_, "%d", val);
128 } else if constexpr (std::is_same_v<T, double>) {
129 std::fprintf(this->fp_, "%.17g", val);
130 } else if constexpr (std::is_same_v<T, const char*>) {
131 std::string tmp = io_detail::encode_toml_str(val);
132 std::fputs(tmp.c_str(), this->fp_);
133 } else {
134 static_assert(always_false<T>, "unexpected type");
135 }
136 }
137
138 template <typename T>
139 void record_(const char* name, const T* val, int length)
140 {
141 if (is_closed_) {
142 CHOLLA_ERROR("can't record any more header attributes after closing the recorder");
143 }
144 std::string key = io_detail::encode_toml_key(name);
145 std::fprintf(this->fp_, "%s = ", key.c_str());
146 if (length < 0) { // denotes a scalar
147 this->write_val_<T>(*val);
148 } else { // recording an array
149 std::fputc('[', this->fp_);
150 for (int i = 0; i < length; i++) {
151 if (i > 0) {
152 std::fputc(',', this->fp_);
153 std::fputc(' ', this->fp_);
154 }
155 write_val_(val[i]);
156 }
157 std::fputc(']', this->fp_);
158 }
159 std::fputc('\n', this->fp_);
160 }
161
162 public:
163 TextAttrRecorder() = delete;
164
165 explicit TextAttrRecorder(std::FILE* fp) : fp_{fp}, is_closed_(false)
166 {
167 CHOLLA_ASSERT(fp != nullptr, "received nullptr");
168 std::fputs("BEGIN-HEADER\n", this->fp_);
169 }
170
180 {
181 if (not this->is_closed_) {
182 std::fputs("END-HEADER\n", this->fp_);
183 this->is_closed_ = true;
184 }
185 }
186
187 // the destructor does NOT call `std::fclose(this->fp_)` since instances of this type
188 // are intended to be temporary wrappers
189 ~TextAttrRecorder() override { this->ensure_closed(); }
190
191 void record_arr(const char* name, const double* arr, int length) override { this->record_(name, arr, length); }
192
193 void record_arr(const char* name, const int* arr, int length) override { this->record_(name, arr, length); }
194
195 void record_arr(const char* name, const long* arr, int length) override { this->record_(name, arr, length); }
196
197 void record(const char* name, const char* val) override { this->record_(name, &val, -1); }
198 void record(const char* name, double val) override { this->record_(name, &val, -1); }
199 void record(const char* name, int val) override { this->record_(name, &val, -1); }
200 void record(const char* name, long val) override { this->record_(name, &val, -1); }
201};
Definition AttrRecorderInterface.h:36
void record_triple(const char *name, double a, double b, double c)
Definition AttrRecorderInterface.h:67
virtual void record(const char *name, const char *val)=0
virtual void record_arr(const char *name, const double *arr, int length)=0
Definition AttrRecorderInterface.h:116
void ensure_closed()
Definition AttrRecorderInterface.h:179
void record_arr(const char *name, const double *arr, int length) override
Definition AttrRecorderInterface.h:191
void record(const char *name, const char *val) override
Definition AttrRecorderInterface.h:197