HILA
Loading...
Searching...
No Matches
field_io.h
1#ifndef FIELD_IO_H_
2#define FIELD_IO_H_
3
4//////////////////////////////////////////////////////////////////////
5// This file collects Field<> I/O routines
6
7#include "plumbing/field.h"
8
9namespace hila {
10// Define this as template, in order to avoid code generation if the function is not needed -
11// a bit crazy
12template <typename IS, std::enable_if_t<std::is_same<IS, std::ifstream>::value, int> = 0>
13bool open_input_file(const std::string &filename, IS &inputfile) {
14 bool ok = true;
15 if (hila::myrank() == 0) {
16 inputfile.open(filename, std::ios::in | std::ios::binary);
17 if (inputfile.fail()) {
18 hila::out0 << "ERROR in opening file " << filename << '\n';
19 ok = false;
20 }
21 }
23 if (!ok)
25
26 return ok;
27}
28
29template <typename OS, std::enable_if_t<std::is_same<OS, std::ofstream>::value, int> = 0>
30bool open_output_file(const std::string &filename, OS &outputfile, bool binary = true,
31 int precision = 8) {
32 bool ok = true;
33 if (hila::myrank() == 0) {
34 std::ios::openmode mode = std::ios::out | std::ios::trunc;
35 if (binary)
36 mode |= std::ios::binary;
37
38 outputfile.open(filename, mode);
39 outputfile.precision(precision);
40 if (outputfile.fail()) {
41 hila::out0 << "ERROR in opening file " << filename << '\n';
42 ok = false;
43 }
44 }
46 if (!ok)
48
49 return ok;
50}
51
52
53template <typename S, std::enable_if_t<std::is_same<S, std::ofstream>::value ||
54 std::is_same<S, std::ifstream>::value,
55 int> = 0>
56bool close_file(const std::string &filename, S &fstream) {
57 bool error = false;
58 if (hila::myrank() == 0) {
59 fstream.close();
60 if (fstream.fail()) {
61 hila::out0 << "ERROR in reading/writing file " << filename << '\n';
62 error = true;
63 }
64 }
65 hila::broadcast(error);
66
67 if (error)
69
70 return !error;
71}
72
73} // namespace hila
74
75//////////////////////////////////////////////////////////////////////////////////
76
77/// Write the field to a file stream
78template <typename T>
79void Field<T>::write(std::ofstream &outputfile, bool binary, int precision) const {
80 constexpr size_t sites_per_write = WRITE_BUFFER_SIZE / sizeof(T);
81 constexpr size_t write_size = sites_per_write * sizeof(T);
82
83 if (!binary)
84 outputfile.precision(precision);
85
86 std::vector<CoordinateVector> coord_list(sites_per_write);
87 T *buffer = (T *)memalloc(write_size);
88 CoordinateVector size = lattice.size();
89
90 for (size_t i = 0; i < lattice.volume(); i += sites_per_write) {
91 size_t sites = std::min(sites_per_write, lattice.volume() - i);
92 for (size_t j = 0; j < sites; j++)
93 coord_list[j] = lattice.global_coordinates(i + j);
94
95 if (sites < sites_per_write)
96 coord_list.resize(sites);
97
98 fs->gather_elements(buffer, coord_list);
99 if (hila::myrank() == 0) {
100 if (binary) {
101 outputfile.write((char *)buffer, sites * sizeof(T));
102 } else {
103 for (size_t j = 0; j < sites; j++) {
104 outputfile << buffer[j] << '\n';
105 }
106 }
107 }
108 }
109
110 std::free(buffer);
111}
112
113/// Write the Field to a named file replacing the file
114template <typename T>
115void Field<T>::write(const std::string &filename, bool binary, int precision) const {
116 std::ofstream outputfile;
117 hila::open_output_file(filename, outputfile, binary);
118 write(outputfile, binary, precision);
119 hila::close_file(filename, outputfile);
120}
121
122/// Write a list of fields into an output stream
123template <typename T>
124static void write_fields(std::ofstream &outputfile, Field<T> &last) {
125 last.write(outputfile);
126}
127
128template <typename T, typename... fieldtypes>
129static void write_fields(std::ofstream &outputfile, Field<T> &next, fieldtypes &...fields) {
130 next.write(outputfile);
131 write_fields(outputfile, fields...);
132}
133
134/// Write a list of fields to a file
135template <typename... fieldtypes>
136static void write_fields(const std::string &filename, fieldtypes &...fields) {
137 std::ofstream outputfile;
138 hila::open_output_file(filename, outputfile);
139 write_fields(outputfile, fields...);
140 hila::close_file(filename, outputfile);
141}
142
143/////////////////////////////////////////////////////////////////////////////////
144
145/// Read the Field from a stream
146template <typename T>
147void Field<T>::read(std::ifstream &inputfile) {
148 constexpr size_t sites_per_read = WRITE_BUFFER_SIZE / sizeof(T);
149 constexpr size_t read_size = sites_per_read * sizeof(T);
150
151 if (!this->is_allocated())
152 this->allocate();
153
154 mark_changed(ALL);
155
156 std::vector<CoordinateVector> coord_list(sites_per_read);
157 T *buffer = (T *)memalloc(read_size);
158 CoordinateVector size = lattice.size();
159
160 for (size_t i = 0; i < lattice.volume(); i += sites_per_read) {
161 size_t sites = std::min(sites_per_read, lattice.volume() - i);
162 for (size_t j = 0; j < sites; j++)
163 coord_list[j] = lattice.global_coordinates(i + j);
164
165 if (sites < sites_per_read)
166 coord_list.resize(sites);
167
168 if (hila::myrank() == 0)
169 inputfile.read((char *)buffer, sites * sizeof(T));
170
171 fs->scatter_elements(buffer, coord_list);
172 }
173
174 std::free(buffer);
175}
176
177// Read Field contents from the beginning of a file
178template <typename T>
179void Field<T>::read(const std::string &filename) {
180 std::ifstream inputfile;
181 hila::open_input_file(filename, inputfile);
182 read(inputfile);
183 hila::close_file(filename, inputfile);
184}
185
186// Read a list of fields from an input stream
187template <typename T>
188static void read_fields(std::ifstream &inputfile, Field<T> &last) {
189 last.read_from_stream(inputfile);
190}
191
192template <typename T, typename... fieldtypes>
193static void read_fields(std::ifstream &inputfile, Field<T> &next, fieldtypes &...fields) {
194 next.read_from_stream(inputfile);
195 read_fields(inputfile, fields...);
196}
197
198// Read a list of fields from a file
199template <typename... fieldtypes>
200static void read_fields(const std::string &filename, fieldtypes &...fields) {
201 std::ifstream inputfile;
202 hila::open_input_file(filename, inputfile);
203 read_fields(inputfile, fields...);
204 hila::close_file(filename, inputfile);
205}
206
207
208///////////////////////////////////////////////////////////////////////////////
209
210/// Write a "subspace" of the original lattice
211/// Each element is written on a single line
212/// TODO: more formatting?
213
214template <typename T>
215void Field<T>::write_subvolume(std::ofstream &outputfile, const CoordinateVector &cmin,
216 const CoordinateVector &cmax, int precision) const {
217
218 constexpr size_t sites_per_write = WRITE_BUFFER_SIZE / sizeof(T);
219
220 size_t sites = 1;
221 int line_len = 1; // number of elements on 1st non-trivial dimension
222 foralldir(d) {
223 assert(cmin[d] >= 0 && cmax[d] >= cmin[d] && cmax[d] < lattice.size(d) &&
224 "subvolume size mismatch");
225 sites *= cmax[d] - cmin[d] + 1;
226
227 if (line_len == 1)
228 line_len = sites;
229 }
230
231 size_t n_write = std::min(sites_per_write, sites);
232
233 std::vector<CoordinateVector> coord_list(n_write);
234 T *buffer = (T *)memalloc(n_write * sizeof(T));
235
237
238 size_t i = 0, j = 0;
239
240 if (hila::myrank() == 0) {
241 outputfile.precision(precision);
242 }
243
244 forcoordinaterange(c, cmin, cmax) {
245 coord_list[i] = c;
246 i++;
247 j++;
248 if (i == n_write || j == sites) {
249 if (i < n_write)
250 coord_list.resize(i);
251
252 fs->gather_elements(buffer, coord_list);
253
254 if (hila::myrank() == 0) {
255 for (size_t k = 0; k < i; k++) {
256 for (int l = 0; l < sizeof(T) / sizeof(hila::arithmetic_type<T>); l++) {
257 outputfile << hila::get_number_in_var(buffer[k], l) << ' ';
258 }
259 outputfile << '\n';
260 }
261 }
262 i = 0;
263 }
264 }
265}
266
267
268template <typename T>
269void Field<T>::write_subvolume(const std::string &filename, const CoordinateVector &cmin,
270 const CoordinateVector &cmax, int precision) const {
271
272 std::ofstream out;
273 hila::open_output_file(filename, out, false);
274 write_subvolume(out, cmin, cmax, precision);
275 hila::close_file(filename, out);
276}
277
278// Write a subspace (slice) of the original lattice. Here
279// slice[d] = fixed coordinate value, or < 0: run the dimension through.
280// For example, slice = {5,2,-1,0}; prints the line along z-axis at (x,y,t) = (5,2,0)
281// Outf is either filename or ofstream
282
283template <typename T>
284template <typename outf_type>
285void Field<T>::write_slice(outf_type &outf, const CoordinateVector &slice, int precision) const {
286
287 static_assert(std::is_same<outf_type, std::string>::value ||
288 std::is_same<outf_type, std::ofstream>::value,
289 "file name / output stream argument in write_slice()?");
290
291 CoordinateVector cmin, cmax;
292 foralldir(d) {
293 if (slice[d] < 0) {
294 cmin[d] = 0;
295 cmax[d] = lattice.size(d) - 1;
296 } else {
297 cmin[d] = cmax[d] = slice[d];
298 }
299 }
300 write_subvolume(outf, cmin, cmax, precision);
301}
302
303
304#endif
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:61
void write_subvolume(std::ofstream &outputfile, const CoordinateVector &cmin, const CoordinateVector &cmax, int precision=6) const
Definition field_io.h:215
void write(std::ofstream &outputfile, bool binary=true, int precision=8) const
Write the field to a file stream.
Definition field_io.h:79
void read(std::ifstream &inputfile)
Read the Field from a stream.
Definition field_io.h:147
CoordinateVector global_coordinates(size_t index) const
Definition lattice.h:381
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
constexpr Parity ALL
bit pattern: 011
This files containts definitions for the Field class and the classes required to define it such as fi...
Invert diagonal + const. matrix using Sherman-Morrison formula.
Definition array.h:920
int myrank()
rank of this node
Definition com_mpi.cpp:235
std::ostream out0
This writes output only from main process (node 0)
T broadcast(T &var, int rank=0)
Broadcast the value of var to all MPI ranks from rank (default=0).
Definition com_mpi.h:153
void terminate(int status)
hila::arithmetic_type< T > get_number_in_var(const T &var, int i)
Definition type_tools.h:118