GADGET-4
io_readtrees_mbound.cc
Go to the documentation of this file.
1/*******************************************************************************
2 * \copyright This file is part of the GADGET4 N-body/SPH code developed
3 * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4 * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5 *******************************************************************************/
6
12#include "gadgetconfig.h"
13
14#ifdef MERGERTREE
15
16#include <gsl/gsl_rng.h>
17#include <hdf5.h>
18#include <math.h>
19#include <mpi.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <unistd.h>
26
27#include "../data/allvars.h"
28#include "../data/dtypes.h"
29#include "../data/mymalloc.h"
30#include "../fof/fof.h"
31#include "../io/hdf5_util.h"
32#include "../io/io.h"
33#include "../logs/timer.h"
34#include "../main/simulation.h"
35#include "../mergertree/io_readtrees_mbound.h"
36#include "../mergertree/mergertree.h"
37#include "../mpi_utils/mpi_utils.h"
38#include "../sort/parallel_sort.h"
39#include "../subfind/subfind.h"
40#include "../system/system.h"
41
42/*
43 struct treehalo_ids_type
44 {
45 MyIDType SubMostBoundID;
46 long long TreeID;
47 };
48 treehalo_ids_type *HaloIDdata;
49*/
50
51readtrees_mbound_io::readtrees_mbound_io(mergertree *MergerTree_ptr, MPI_Comm comm, int format) : IO_Def(comm, format)
52{
53 MergerTree = MergerTree_ptr;
54
55 this->N_IO_Fields = 0;
56 this->N_DataGroups = 2;
57 this->header_size = sizeof(header);
58 this->header_buf = &header;
59 this->type_of_file = FILE_IS_TREECAT;
60 sprintf(this->info, "MERGERTREE: reading/writing mergertrees");
61
62 init_field("MTRL", "Length", MEM_INT, FILE_INT, READ_IF_PRESENT, 1, A_TT, &MergerTree->TreeTable[0].HaloCount, NULL, TREELENGTH, 0,
63 0, 0, 0, 0, 0, 0);
64 init_field("MTRS", "StartOffset", MEM_INT64, FILE_INT64, READ_IF_PRESENT, 1, A_TT, &MergerTree->TreeTable[0].FirstHalo, NULL,
65 TREELENGTH, 0, 0, 0, 0, 0, 0, 0);
66 init_field("MTRI", "TreeID", MEM_INT64, FILE_INT64, READ_IF_PRESENT, 1, A_TT, &MergerTree->TreeTable[0].TreeID, NULL, TREELENGTH, 0,
67 0, 0, 0, 0, 0, 0);
68
69 /* just read most-bound ID */
70
71 init_field("TRID", "TreeID", MEM_INT64, FILE_INT64, READ_IF_PRESENT, 1, A_TID, &MergerTree->HaloIDdata[0].TreeID, NULL, TREEHALOS, 0,
72 0, 0, 0, 0, 0, 0);
73
74 init_field("SIDM", "SubhaloIDMostbound", MEM_MY_ID_TYPE, FILE_MY_ID_TYPE, READ_IF_PRESENT, 1, A_TID,
75 &MergerTree->HaloIDdata[0].SubMostBoundID, NULL, TREEHALOS, 0, 0, 0, 0, 0, 0, 0);
76}
77
78void readtrees_mbound_io::read_trees_mostbound(void)
79{
80 double t0 = Logs.second();
81
82 MergerTree->TotNtrees = 0;
83 MergerTree->TotNhalos = 0;
84
85 char fname[MAXLEN_PATH_EXTRA];
86
88 sprintf(fname, "%s/treedata/%s", All.OutputDir, "trees");
89 else
90 sprintf(fname, "%s%s", All.OutputDir, "trees");
91
92 int num_files = find_files(fname, fname);
93
94 reset_io_byte_count();
95
96 for(int rep = 0; rep < 2; rep++)
97 {
98 MergerTree->Ntrees = 0;
99 MergerTree->Nhalos = 0;
100
101 read_files_driver(fname, rep, num_files);
102
103 /* now do the memory allocation */
104 if(rep == 0)
105 {
106 MergerTree->TreeTable = (halotrees_table *)Mem.mymalloc_movable(&MergerTree->TreeTable, "TreeTable",
107 (MergerTree->Ntrees + 1) * sizeof(halotrees_table));
108 MergerTree->HaloIDdata = (treehalo_ids_type *)Mem.mymalloc_movable(&MergerTree->HaloIDdata, "HaloIDdata",
109 (MergerTree->Nhalos + 1) * sizeof(treehalo_ids_type));
110 }
111 }
112
113 MPI_Barrier(Communicator);
114
115 long long byte_count = get_io_byte_count(), byte_count_all;
116 sumup_longs(1, &byte_count, &byte_count_all, Communicator);
117
118 double t1 = Logs.second();
119
120 mpi_printf("MERGERTREE-READ: reading done. Took %g sec, total size %g MB, corresponds to effective I/O rate of %g MB/sec\n",
121 Logs.timediff(t0, t1), byte_count_all / (1024.0 * 1024.0), byte_count_all / (1024.0 * 1024.0) / Logs.timediff(t0, t1));
122
123 mpi_printf("\nMERGERTREE-READ: Total number of trees=%ldd, total number of halos=%lld\n\n", MergerTree->TotNtrees,
124 MergerTree->TotNhalos);
125
126 MPI_Barrier(Communicator);
127
128 for(int i = 0; i < MergerTree->Ntrees; i++)
129 {
130 if(MergerTree->HaloIDdata[i].TreeID > MergerTree->TotNtrees)
131 Terminate("i=%d MergerTree->Ntrees=%d MergerTree->HaloIDdata[i].TreeID=%lld MergerTree->TotNtrees=%lld ", i,
132 MergerTree->Ntrees, MergerTree->HaloIDdata[i].TreeID, MergerTree->TotNtrees);
133 }
134}
135
136void readtrees_mbound_io::fill_file_header(int writeTask, int lastTask, long long *n_type, long long *ntot_type) {}
137
138void readtrees_mbound_io::write_header_fields(hid_t handle) {}
139
140int readtrees_mbound_io::get_filenr_from_header(void) { return header.num_files; }
141
142void readtrees_mbound_io::set_filenr_in_header(int numfiles) { header.num_files = numfiles; }
143
144void readtrees_mbound_io::read_increase_numbers(int type, int n_for_this_task)
145{
146 switch(type)
147 {
148 case 0:
149 MergerTree->Ntrees += n_for_this_task;
150 break;
151 case 1:
152 MergerTree->Nhalos += n_for_this_task;
153 break;
154
155 default:
156 Terminate("wrong group");
157 break;
158 }
159}
160
161void readtrees_mbound_io::read_file_header(const char *fname, int filenr, int readTask, int lastTask, long long *n_type,
162 long long *ntot_type, int *nstart)
163{
164 if(ThisTask == readTask)
165 {
166 if(filenr == 0 && nstart == NULL)
167 {
168 mpi_printf(
169 "\nREAD-TREES: filenr=%d, '%s' contains %lld trees out of a total of %lld, and %lld halos out of a total of %lld\n",
170 filenr, fname, header.Ntrees, header.TotNtrees, header.Nhalos, header.TotNhalos);
171 }
172 }
173
174 if(MergerTree->TotNtrees == 0)
175 {
176 MergerTree->TotNtrees = header.TotNtrees;
177 MergerTree->TotNhalos = header.TotNhalos;
178 }
179
180 for(int k = 0; k < 2; k++)
181 n_type[k] = ntot_type[k] = 0;
182
183 {
184 ntot_type[0] = header.Ntrees;
185 long long n_in_file = header.Ntrees;
186 int ntask = lastTask - readTask + 1;
187 int n_for_this_task = n_in_file / ntask;
188 if((ThisTask - readTask) < (n_in_file % ntask))
189 n_for_this_task++;
190 n_type[0] = n_for_this_task;
191
192 if(nstart)
193 memmove(&MergerTree->TreeTable[n_for_this_task], &MergerTree->TreeTable[0], MergerTree->Ntrees * sizeof(halotrees_table));
194 }
195
196 {
197 ntot_type[1] = header.Nhalos;
198 long long n_in_file = header.Nhalos;
199 int ntask = lastTask - readTask + 1;
200 int n_for_this_task = n_in_file / ntask;
201 if((ThisTask - readTask) < (n_in_file % ntask))
202 n_for_this_task++;
203 n_type[1] = n_for_this_task;
204
205 if(nstart)
206 memmove(&MergerTree->HaloIDdata[n_for_this_task], &MergerTree->HaloIDdata[0], MergerTree->Nhalos * sizeof(treehalo_ids_type));
207 }
208
209 if(nstart)
210 *nstart = 0;
211}
212
213void readtrees_mbound_io::read_header_fields(const char *fname)
214{
215 memset(&header, 0, sizeof(header));
216
217 hid_t hdf5_file = my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
218 hid_t handle = my_H5Gopen(hdf5_file, "/Header");
219
220 read_scalar_attribute(handle, "Ntrees_ThisFile", &header.Ntrees, H5T_NATIVE_UINT64);
221 read_scalar_attribute(handle, "Ntrees_Total", &header.TotNtrees, H5T_NATIVE_UINT64);
222
223 read_scalar_attribute(handle, "Nhalos_ThisFile", &header.Nhalos, H5T_NATIVE_UINT64);
224 read_scalar_attribute(handle, "Nhalos_Total", &header.TotNhalos, H5T_NATIVE_UINT64);
225
226 read_scalar_attribute(handle, "NumFiles", &header.num_files, H5T_NATIVE_INT);
227
228 read_scalar_attribute(handle, "LastSnapShotNr", &header.lastsnapshotnr, H5T_NATIVE_INT);
229
230 my_H5Gclose(handle, "/Header");
231 my_H5Fclose(hdf5_file, fname);
232}
233
234void readtrees_mbound_io::get_datagroup_name(int type, char *buf)
235{
236 switch(type)
237 {
238 case 0:
239 sprintf(buf, "/TreeTable");
240 break;
241 case 1:
242 sprintf(buf, "/TreeHalos");
243 break;
244 default:
245 Terminate("wrong group");
246 break;
247 }
248}
249
250int readtrees_mbound_io::get_type_of_element(int index)
251{
252 /* empty */
253 return 0;
254}
255
256void readtrees_mbound_io::set_type_of_element(int index, int type)
257{ /* empty */
258}
259
260void *readtrees_mbound_io::get_base_address_of_structure(enum arrays array, int index)
261{
262 switch(array)
263 {
264 case A_TT:
265 return (void *)(MergerTree->TreeTable + index);
266 case A_TID:
267 return (void *)(MergerTree->HaloIDdata + index);
268 default:
269 Terminate("strange, we don't expect to get here");
270 }
271}
272
273#endif
global_data_all_processes All
Definition: main.cc:40
Definition: io.h:129
double timediff(double t0, double t1)
Definition: logs.cc:488
double second(void)
Definition: logs.cc:471
#define MAXLEN_PATH_EXTRA
Definition: constants.h:301
hid_t my_H5Gopen(hid_t loc_id, const char *groupname)
Definition: hdf5_util.cc:311
hid_t my_H5Fopen(const char *fname, unsigned int flags, hid_t fapl_id)
Definition: hdf5_util.cc:297
herr_t my_H5Gclose(hid_t group_id, const char *groupname)
Definition: hdf5_util.cc:457
herr_t my_H5Fclose(hid_t file_id, const char *fname)
Definition: hdf5_util.cc:482
void read_scalar_attribute(hid_t handle, const char *attr_name, void *buf, hid_t mem_type_id)
Definition: hdf5_util.cc:589
@ READ_IF_PRESENT
Definition: io.h:124
@ TREELENGTH
Definition: io.h:112
@ TREEHALOS
Definition: io.h:113
arrays
Definition: io.h:30
@ A_TT
Definition: io.h:42
@ A_TID
Definition: io.h:48
@ FILE_INT64
Definition: io.h:68
@ FILE_MY_ID_TYPE
Definition: io.h:71
@ FILE_INT
Definition: io.h:67
@ MEM_INT
Definition: io.h:79
@ MEM_MY_ID_TYPE
Definition: io.h:81
@ MEM_INT64
Definition: io.h:80
@ FILE_IS_TREECAT
Definition: io.h:57
logs Logs
Definition: main.cc:43
#define Terminate(...)
Definition: macros.h:15
void sumup_longs(int n, long long *src, long long *res, MPI_Comm comm)
memory Mem
Definition: main.cc:44
char OutputDir[MAXLEN_PATH]
Definition: allvars.h:272