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 
51 readtrees_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 
78 void 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 
87  if(All.NumFilesPerSnapshot > 1)
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 
136 void readtrees_mbound_io::fill_file_header(int writeTask, int lastTask, long long *n_type, long long *ntot_type) {}
137 
138 void readtrees_mbound_io::write_header_fields(hid_t handle) {}
139 
140 int readtrees_mbound_io::get_filenr_from_header(void) { return header.num_files; }
141 
142 void readtrees_mbound_io::set_filenr_in_header(int numfiles) { header.num_files = numfiles; }
143 
144 void 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 
161 void 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 
213 void 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 
234 void 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 
250 int readtrees_mbound_io::get_type_of_element(int index)
251 {
252  /* empty */
253  return 0;
254 }
255 
256 void readtrees_mbound_io::set_type_of_element(int index, int type)
257 { /* empty */
258 }
259 
260 void *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:19
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