12#include "gadgetconfig.h"
24#include "../cooling_sfr/cooling.h"
25#include "../data/allvars.h"
26#include "../data/dtypes.h"
27#include "../data/mymalloc.h"
28#include "../fof/fof.h"
29#include "../io/hdf5_util.h"
31#include "../io/parameters.h"
32#include "../lightcone/lightcone.h"
33#include "../logs/timer.h"
34#include "../main/main.h"
35#include "../main/simulation.h"
36#include "../mergertree/mergertree.h"
37#include "../mpi_utils/mpi_utils.h"
38#include "../subfind/subfind.h"
39#include "../system/system.h"
41#define HALF_ROUND_STYLE 1
42#include "../half/half.hpp"
50 Mem.myfree_movable(IO_Fields);
68 void *pointer_to_field,
void (*io_func)(
IO_Def *,
int,
int,
void *,
int),
int typelist_bitmask,
int flagunit,
69 double a,
double h,
double L,
double M,
double V,
double c,
bool compression_on)
71 const int alloc_step = 5;
73 if(values_per_block < 1)
78 IO_Fields = (IO_Field *)
Mem.mymalloc_movable(&IO_Fields,
"IO_Fields", alloc_step *
sizeof(IO_Field));
84 IO_Fields = (IO_Field *)
Mem.myrealloc_movable(IO_Fields,
Max_IO_Fields *
sizeof(IO_Field));
88 IO_Field *field = &IO_Fields[n];
96 field->type_in_memory = type_in_memory;
97 field->type_in_file_output = type_in_file_output;
98 field->read_flag = read_flag;
99 field->values_per_block = values_per_block;
100 field->typelist = typelist_bitmask;
101#ifdef ALLOW_HDF5_COMPRESSION
102 field->compression_on = compression_on;
104 field->compression_on =
false;
107 field->array = array;
108 field->io_func = io_func;
119 field->hasunit = flagunit;
135 char buf[200], buf1[200];
136 int dummy, files_found = 0;
140 sprintf(buf,
"%s.%d.hdf5", fname_multiple, 0);
141 sprintf(buf1,
"%s.hdf5", fname);
145 sprintf(buf,
"%s.%d", fname_multiple, 0);
146 sprintf(buf1,
"%s", fname);
153 if((fd = fopen(buf,
"r")))
159 my_fread(&dummy,
sizeof(dummy), 1, fd);
160 my_fread(&dummy,
sizeof(dummy), 1, fd);
161 my_fread(&dummy,
sizeof(dummy), 1, fd);
162 my_fread(&dummy,
sizeof(dummy), 1, fd);
165 my_fread(&dummy,
sizeof(dummy), 1, fd);
167 my_fread(&dummy,
sizeof(dummy), 1, fd);
186 if((fd = fopen(buf1,
"r")))
192 my_fread(&dummy,
sizeof(dummy), 1, fd);
193 my_fread(&dummy,
sizeof(dummy), 1, fd);
194 my_fread(&dummy,
sizeof(dummy), 1, fd);
195 my_fread(&dummy,
sizeof(dummy), 1, fd);
198 my_fread(&dummy,
sizeof(dummy), 1, fd);
200 my_fread(&dummy,
sizeof(dummy), 1, fd);
220 Terminate(
"Have found IC files, but number of files in header seems to be zero\n");
222 Terminate(
"\nCan't find files, neither as '%s'\nnor as '%s'\n", buf, buf1);
238 int rest_files = num_files;
240 while(rest_files >
NTask)
244 sprintf(buf,
"%s.%d", fname,
ThisTask + (rest_files -
NTask));
246 sprintf(buf,
"%s.%d.hdf5", fname,
ThisTask + (rest_files -
NTask));
251 int groupMaster = (
ThisTask / ngroups) * ngroups;
253 for(
int gr = 0; gr < ngroups; gr++)
270 int masterTask, filenr, lastTask;
272 distribute_file(rest_files, &filenr, &masterTask, &lastTask);
278 sprintf(buf,
"%s.%d", fname, filenr);
280 sprintf(buf,
"%s.%d.hdf5", fname, filenr);
284 sprintf(buf,
"%s", fname);
286 sprintf(buf,
"%s.hdf5", fname);
293 for(
int gr = 0; gr < ngroups; gr++)
298 share_particle_number_in_file(buf, filenr, masterTask, lastTask);
300 read_file(buf, filenr, masterTask, lastTask, CommBuffer);
306 Mem.myfree(CommBuffer);
330void IO_Def::share_particle_number_in_file(
const char *fname,
int filenr,
int readTask,
int lastTask)
333 unsigned int blksize1, blksize2;
345 if(!(fd = fopen(fname,
"r")))
346 Terminate(
"can't open file `%s' for reading initial conditions.\n", fname);
352 my_fread(&blksize1,
sizeof(
int), 1, fd);
354 my_fread(&nextblock,
sizeof(
int), 1, fd);
355 printf(
"%s Reading header => '%c%c%c%c' (%d byte)\n",
info, label[0], label[1], label[2], label[3], nextblock);
356 my_fread(&blksize2,
sizeof(
int), 1, fd);
359 my_fread(&blksize1,
sizeof(
int), 1, fd);
361 my_fread(&blksize2,
sizeof(
int), 1, fd);
364 if(blksize1 != 256 || blksize2 != 256)
365 Terminate(
"incorrect GADGET2 header format, blksize1=%d blksize2=%d header_size=%d\n", blksize1, blksize2,
368 if(blksize1 != blksize2)
369 Terminate(
"incorrect header format, blksize1=%d blksize2=%d header_size=%d \n%s \n", blksize1, blksize2, (
int)
header_size,
370 blksize1 == 256 ?
"You may need to set GADGET2_HEADER" :
"");
377 for(
int task = readTask + 1; task <= lastTask; task++)
387 mpi_printf(
"READIC: Reading file `%s' on task=%d and distribute it to %d to %d.\n", fname,
ThisTask, readTask, lastTask);
395 long long n_in_file = npart[type];
396 int ntask = lastTask - readTask + 1;
397 int n_for_this_task = n_in_file / ntask;
398 if((
ThisTask - readTask) < (n_in_file % ntask))
414void IO_Def::fill_write_buffer(
int blocknr,
int *startindex,
int pc,
int type,
void *CommBuffer)
419 IO_Field *field = &IO_Fields[blocknr];
421 int *intp = (
int *)CommBuffer;
422 long long *longp = (
long long *)CommBuffer;
423 float *floatp = (
float *)CommBuffer;
424 double *doublep = (
double *)CommBuffer;
431 int pindex = *startindex;
433 for(
int n = 0; n < pc; pindex++)
443 switch(field->type_in_memory)
446 field->io_func(
this, pindex, field->values_per_block, intp, 0);
447 intp += field->values_per_block;
450 field->io_func(
this, pindex, field->values_per_block, longp, 0);
451 longp += field->values_per_block;
454 field->io_func(
this, pindex, field->values_per_block, ip, 0);
455 ip += field->values_per_block;
458 field->io_func(
this, pindex, field->values_per_block, intposp, 0);
459 intposp += field->values_per_block;
462 field->io_func(
this, pindex, field->values_per_block, floatp, 0);
463 floatp += field->values_per_block;
466 field->io_func(
this, pindex, field->values_per_block, doublep, 0);
467 doublep += field->values_per_block;
470 field->io_func(
this, pindex, field->values_per_block, fp, 0);
471 fp += field->values_per_block;
474 field->io_func(
this, pindex, field->values_per_block, dp, 0);
475 dp += field->values_per_block;
478 Terminate(
"ERROR in fill_write_buffer: Type not found!\n");
498 for(
int k = 0; k < field->values_per_block; k++)
500 switch(field->type_in_memory)
503 *intp++ = *((
int *)((
size_t)array_pos + field->offset + k *
sizeof(int)));
507 *longp++ = *((
long long *)((
size_t)array_pos + field->offset + k *
sizeof(
long long)));
511 *ip++ = *((
MyIDType *)((
size_t)array_pos + field->offset + k *
sizeof(
MyIDType)));
519 *floatp++ = *((
float *)((
size_t)array_pos + field->offset + k *
sizeof(float)));
523 *doublep++ = *((
double *)((
size_t)array_pos + field->offset + k *
sizeof(double)));
527 *fp++ = *((
MyFloat *)((
size_t)array_pos + field->offset + k *
sizeof(
MyFloat)));
531 *dp++ = *((
MyDouble *)((
size_t)array_pos + field->offset + k *
sizeof(
MyDouble)));
535 Terminate(
"ERROR in fill_write_buffer: Type not found!\n");
544 *startindex = pindex;
556void IO_Def::empty_read_buffer(
int blocknr,
int offset,
int pc,
int type,
long long nprevious,
void *CommBuffer)
558 IO_Field *field = &IO_Fields[blocknr];
560 int *intp = (
int *)CommBuffer;
561 long long *longp = (
long long *)CommBuffer;
562 float *floatp = (
float *)CommBuffer;
563 double *doublep = (
double *)CommBuffer;
572 for(
int n = 0; n < pc; n++)
576 switch(field->type_in_memory)
579 field->io_func(
this, offset + n, field->values_per_block, intp, 1);
580 intp += field->values_per_block;
583 field->io_func(
this, offset + n, field->values_per_block, longp, 1);
584 longp += field->values_per_block;
587 field->io_func(
this, offset + n, field->values_per_block, ip, 1);
588 ip += field->values_per_block;
591 field->io_func(
this, offset + n, field->values_per_block, intposp, 1);
592 intposp += field->values_per_block;
595 field->io_func(
this, offset + n, field->values_per_block, floatp, 1);
596 floatp += field->values_per_block;
599 field->io_func(
this, offset + n, field->values_per_block, doublep, 1);
600 doublep += field->values_per_block;
603 field->io_func(
this, offset + n, field->values_per_block, fp, 1);
604 fp += field->values_per_block;
607 field->io_func(
this, offset + n, field->values_per_block, dp, 1);
608 dp += field->values_per_block;
629 for(
int k = 0; k < field->values_per_block; k++)
631 switch(field->type_in_memory)
634 *((
int *)((
size_t)array_pos + field->offset + k *
sizeof(int))) = *intp++;
637 *((
long long *)((
size_t)array_pos + field->offset + k *
sizeof(
long long))) = *longp++;
640 *((
MyIDType *)((
size_t)array_pos + field->offset + k *
sizeof(
MyIDType))) = *ip++;
646 *((
float *)((
size_t)array_pos + field->offset + k *
sizeof(float))) = *floatp++;
649 *((
double *)((
size_t)array_pos + field->offset + k *
sizeof(double))) = *doublep++;
652 *((
MyFloat *)((
size_t)array_pos + field->offset + k *
sizeof(
MyFloat))) = *fp++;
655 *((
MyDouble *)((
size_t)array_pos + field->offset + k *
sizeof(
MyDouble))) = *dp++;
658 *((
long long *)((
size_t)array_pos + field->offset + k *
sizeof(
long long))) = nprevious++;
670void IO_Def::polling(
int numfilesperdump)
673 if(files_completed < numfilesperdump)
683 int source = status.MPI_SOURCE;
689 if(files_started < numfilesperdump)
703 if(!(seq = (seq_data *)
Mem.mymalloc(
"seq",
NTask *
sizeof(seq_data))))
709 int filenr, masterTask, lastTask;
710 distribute_file(numfilesperdump, &filenr, &masterTask, &lastTask);
713 if(numfilesperdump > 1)
714 sprintf(buf,
"%s.%d", fname, filenr);
716 sprintf(buf,
"%s", fname);
724 seq_loc.thistask = -1;
726 MPI_Gather(&seq_loc,
sizeof(seq_data), MPI_BYTE, seq,
sizeof(seq_data), MPI_BYTE, 0,
Communicator);
731 for(
int i = 0; i < count; i++)
733 if(seq[i].thistask < 0)
740 if(count != numfilesperdump)
741 Terminate(
"count=%d != numfilesperdump=%d", count, numfilesperdump);
743 std::sort(seq, seq + numfilesperdump);
756 append_file(buf, masterTask, lastTask, CommBuffer, numfilesperdump, chunksize);
758 write_file(buf, masterTask, lastTask, CommBuffer, numfilesperdump, chunksize);
761 if(files_started < numfilesperdump)
767 while(files_completed < numfilesperdump)
768 polling(numfilesperdump);
777 append_file(buf, masterTask, lastTask, CommBuffer, numfilesperdump, chunksize);
779 write_file(buf, masterTask, lastTask, CommBuffer, numfilesperdump, chunksize);
787 append_file(buf, masterTask, lastTask, CommBuffer, numfilesperdump, chunksize);
789 write_file(buf, masterTask, lastTask, CommBuffer, numfilesperdump, chunksize);
792 Mem.myfree(CommBuffer);
817void IO_Def::write_file(
char *fname,
int writeTask,
int lastTask,
void *CommBuffer,
int numfilesperdump,
int chunksize)
822 unsigned int blksize, bytes_per_blockelement_in_file = 0;
824 hid_t hdf5_file = 0, hdf5_grp[
N_DataGroups], hdf5_headergrp = 0, hdf5_dataspace_memory;
825 hid_t hdf5_dataspace_in_file = 0, hdf5_dataset = 0, hdf5_prop = 0;
826 hsize_t dims[2], count[2], start[2];
828 hid_t hdf5_paramsgrp = 0;
829 hid_t hdf5_configgrp = 0;
833 my_fwrite(&blksize, sizeof(int), 1, fd); \
844 sprintf(buf,
"%s.hdf5", fname);
845 mpi_printf(
"%s file: '%s' (file 1 of %d)\n",
info, fname, numfilesperdump);
847 rename_file_to_bak_if_it_exists(buf);
849 hdf5_file =
my_H5Fcreate(buf, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
854 hdf5_paramsgrp =
my_H5Gcreate(hdf5_file,
"/Parameters", 0);
855 write_parameters_attributes_in_hdf5(hdf5_paramsgrp);
871 rename_file_to_bak_if_it_exists(fname);
873 if(!(fd = fopen(fname,
"w")))
874 Terminate(
"can't open file `%s' for writing.\n", fname);
876 mpi_printf(
"%s file: '%s' (file 1 of %d)\n",
info, fname, numfilesperdump);
880 blksize =
sizeof(int) + 4 *
sizeof(
char);
882 my_fwrite((
const void *)
"HEAD",
sizeof(
char), 4, fd);
884 my_fwrite(&nextblock,
sizeof(
int), 1, fd);
895 for(
int blocknr = 0; blocknr <
N_IO_Fields; blocknr++)
897 polling(numfilesperdump);
899 if(IO_Fields[blocknr].type_in_file_output !=
FILE_NONE)
901 unsigned int bytes_per_blockelement = get_bytes_per_memory_blockelement(blocknr, 0);
903 long long npart_in_block = get_particles_in_block(blocknr, npart, typelist);
904 hid_t hdf5_memory_datatype = get_hdf5_memorytype_of_block(blocknr);
906 get_dataset_name(blocknr, dname);
908 if(npart_in_block > 0)
916 bytes_per_blockelement_in_file =
917 IO_Fields[blocknr].values_per_block * H5Tget_size(get_hdf5_outputtype_of_block(blocknr));
921 blksize =
sizeof(int) +
LABEL_LEN *
sizeof(
char);
923 get_Tab_IO_Label(blocknr, label);
925 int nextblock = npart_in_block * bytes_per_blockelement_in_file + 2 *
sizeof(int);
926 my_fwrite(&nextblock,
sizeof(
int), 1, fd);
930 blksize = npart_in_block * bytes_per_blockelement_in_file;
941 hid_t hdf5_file_datatype = get_hdf5_outputtype_of_block(blocknr);
943 dims[0] = npart[type];
944 dims[1] = get_values_per_blockelement(blocknr);
952 hsize_t maxdims[2] = {H5S_UNLIMITED, dims[1]};
956 hdf5_prop = H5Pcreate(H5P_DATASET_CREATE);
957 hsize_t chunk_dims[2] = {0, dims[1]};
958 chunk_dims[0] = chunksize;
959 H5Pset_chunk(hdf5_prop, rank, chunk_dims);
962 my_H5Dcreate(hdf5_grp[type], dname, hdf5_file_datatype, hdf5_dataspace_in_file, hdf5_prop);
964 else if(IO_Fields[blocknr].compression_on)
969 hdf5_prop = H5Pcreate(H5P_DATASET_CREATE);
971 if(chunk_dims[0] > dims[0])
972 chunk_dims[0] = dims[0];
973 H5Pset_chunk(hdf5_prop, rank, chunk_dims);
974 H5Pset_shuffle(hdf5_prop);
975 H5Pset_deflate(hdf5_prop, 9);
976 if(H5Pall_filters_avail(hdf5_prop))
978 my_H5Dcreate(hdf5_grp[type], dname, hdf5_file_datatype, hdf5_dataspace_in_file, hdf5_prop);
980 Terminate(
"HDF5: Compression not available!\n");
986 my_H5Dcreate(hdf5_grp[type], dname, hdf5_file_datatype, hdf5_dataspace_in_file, H5P_DEFAULT);
989 write_dataset_attributes(hdf5_dataset, blocknr);
996 for(
int task = writeTask, offset = 0; task <= lastTask; task++)
998 long long n_for_this_task;
1002 n_for_this_task = n_type[type];
1004 for(
int p = writeTask; p <= lastTask; p++)
1012 while(n_for_this_task > 0)
1014 long long pc = n_for_this_task;
1016 if(pc > blockmaxlen)
1020 fill_write_buffer(blocknr, &offset, pc, type, CommBuffer);
1022 if(
ThisTask == writeTask && task != writeTask)
1037 count[1] = get_values_per_blockelement(blocknr);
1043 dims[1] = get_values_per_blockelement(blocknr);
1046 my_H5Dwrite(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_memory, hdf5_dataspace_in_file,
1047 H5P_DEFAULT, CommBuffer, dname);
1053 if(bytes_per_blockelement_in_file != bytes_per_blockelement)
1055 char *CommAuxBuffer =
1056 (
char *)
Mem.mymalloc(
"CommAuxBuffer", bytes_per_blockelement_in_file * pc);
1057 type_cast_data((
char *)CommBuffer, bytes_per_blockelement, (
char *)CommAuxBuffer,
1058 bytes_per_blockelement_in_file, pc, blocknr);
1059 my_fwrite(CommAuxBuffer, bytes_per_blockelement_in_file, pc, fd);
1060 Mem.myfree(CommAuxBuffer);
1063 my_fwrite(CommBuffer, bytes_per_blockelement, pc, fd);
1067 n_for_this_task -= pc;
1076 if(chunksize > 0 || IO_Fields[blocknr].compression_on)
1110 sprintf(buf,
"%s.hdf5", fname);
1118void IO_Def::append_file(
char *fname,
int writeTask,
int lastTask,
void *CommBuffer,
int numfilesperdump,
int chunksize)
1122 hid_t hdf5_file = 0, hdf5_grp[
N_DataGroups], hdf5_headergrp = 0, hdf5_dataspace_memory;
1123 hid_t hdf5_dataspace_in_file = 0, hdf5_dataset = 0;
1124 hsize_t dims[2], count[2], start[2];
1128 Terminate(
"appending to files only works with HDF5 format\n");
1133 n_previous[n] = n_type[n];
1141 sprintf(buf,
"%s.hdf5", fname);
1143 hdf5_file =
my_H5Fopen(buf, H5F_ACC_RDWR, H5P_DEFAULT);
1145 hdf5_headergrp =
my_H5Gopen(hdf5_file,
"/Header");
1153 if(n_previous[type] == 0)
1161 for(
int blocknr = 0; blocknr <
N_IO_Fields; blocknr++)
1163 polling(numfilesperdump);
1165 if(IO_Fields[blocknr].type_in_file_output !=
FILE_NONE)
1167 unsigned int bytes_per_blockelement = get_bytes_per_memory_blockelement(blocknr, 0);
1168 int blockmaxlen = (int)(
COMMBUFFERSIZE / bytes_per_blockelement);
1169 long long npart_in_block = get_particles_in_block(blocknr, npart, typelist);
1170 hid_t hdf5_memory_datatype = get_hdf5_memorytype_of_block(blocknr);
1172 get_dataset_name(blocknr, dname);
1174 if(npart_in_block > 0)
1184 hid_t hdf5_file_datatype = get_hdf5_outputtype_of_block(blocknr);
1186 dims[0] = npart[type] + n_previous[type];
1187 dims[1] = get_values_per_blockelement(blocknr);
1195 if(n_previous[type] == 0)
1199 hsize_t maxdims[2] = {H5S_UNLIMITED, dims[1]};
1203 hid_t prop = H5Pcreate(H5P_DATASET_CREATE);
1204 hsize_t chunk_dims[2] = {0, dims[1]};
1205 chunk_dims[0] = chunksize;
1206 H5Pset_chunk(prop, rank, chunk_dims);
1208 hdf5_dataset =
my_H5Dcreate(hdf5_grp[type], dname, hdf5_file_datatype, hdf5_dataspace_in_file, prop);
1213 my_H5Dcreate(hdf5_grp[type], dname, hdf5_file_datatype, hdf5_dataspace_in_file, H5P_DEFAULT);
1214 write_dataset_attributes(hdf5_dataset, blocknr);
1228 for(
int task = writeTask, offset = 0; task <= lastTask; task++)
1230 long long n_for_this_task;
1234 n_for_this_task = n_type[type];
1236 for(
int p = writeTask; p <= lastTask; p++)
1244 while(n_for_this_task > 0)
1246 long long pc = n_for_this_task;
1248 if(pc > blockmaxlen)
1252 fill_write_buffer(blocknr, &offset, pc, type, CommBuffer);
1254 if(
ThisTask == writeTask && task != writeTask)
1263 start[0] = pcsum + n_previous[type];
1267 count[1] = get_values_per_blockelement(blocknr);
1273 dims[1] = get_values_per_blockelement(blocknr);
1276 my_H5Dwrite(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_memory, hdf5_dataspace_in_file,
1277 H5P_DEFAULT, CommBuffer, dname);
1282 n_for_this_task -= pc;
1286 if(
ThisTask == writeTask && npart[type] > 0)
1310 sprintf(buf,
"%s.hdf5", fname);
1315void IO_Def::type_cast_data(
char *src,
int src_bytes_per_element,
char *target,
int target_bytes_per_element,
int len,
int blocknr)
1317 switch(IO_Fields[blocknr].type_in_memory)
1324 if(target_bytes_per_element > src_bytes_per_element)
1326 if(target_bytes_per_element != 2 * src_bytes_per_element)
1327 Terminate(
"something is odd here: target_bytes_per_element=%d != 2 * src_bytes_per_element=%d", target_bytes_per_element,
1328 src_bytes_per_element);
1330 int fac = src_bytes_per_element /
sizeof(int);
1331 int *sp = (
int *)src;
1332 long long *tp = (
long long *)target;
1333 for(
int i = 0; i < len * fac; i++)
1338 if(src_bytes_per_element != 2 * target_bytes_per_element)
1339 Terminate(
"something is odd here: src_bytes_per_element=%d != 2 * target_bytes_per_element=%d", src_bytes_per_element,
1340 target_bytes_per_element);
1341 int fac = src_bytes_per_element /
sizeof(
long long);
1342 long long *sp = (
long long *)src;
1343 int *tp = (
int *)target;
1344 for(
int i = 0; i < len * fac; i++)
1353 if((target_bytes_per_element % 8) == 0 &&
1354 (src_bytes_per_element % 4) == 0)
1356 int fac = src_bytes_per_element /
sizeof(float);
1357 float *sp = (
float *)src;
1358 double *tp = (
double *)target;
1359 for(
int i = 0; i < len * fac; i++)
1362 else if((target_bytes_per_element % 4) == 0 && (src_bytes_per_element % 8) == 0)
1364 int fac = src_bytes_per_element /
sizeof(double);
1365 double *sp = (
double *)src;
1366 float *tp = (
float *)target;
1367 for(
int i = 0; i < len * fac; i++)
1370 else if((target_bytes_per_element & 8) == 0 && (src_bytes_per_element % 2) == 0)
1372 int fac = src_bytes_per_element /
sizeof(
half);
1374 double *tp = (
double *)target;
1375 for(
int i = 0; i < len * fac; i++)
1378 else if((target_bytes_per_element % 2) == 0 && (src_bytes_per_element % 8) == 0)
1380 int fac = src_bytes_per_element /
sizeof(double);
1381 double *sp = (
double *)src;
1383 for(
int i = 0; i < len * fac; i++)
1388 Terminate(
"Strange conversion requested: target_bytes_per_element=%d src_bytes_per_element=%d\n",
1389 target_bytes_per_element, src_bytes_per_element);
1404void IO_Def::read_file(
const char *fname,
int filenr,
int readTask,
int lastTask,
void *CommBuffer)
1408 unsigned int blksize1, blksize2, bytes_per_blockelement_in_file = 0;
1409 hid_t hdf5_file = 0, hdf5_grp[
N_DataGroups], hdf5_dataspace_in_file;
1410 hid_t hdf5_dataspace_in_memory, hdf5_dataset;
1423 if(!(fd = fopen(fname,
"r")))
1424 Terminate(
"can't open file `%s' for reading initial conditions.\n", fname);
1430 my_fread(&blksize1,
sizeof(
int), 1, fd);
1432 my_fread(&nextblock,
sizeof(
int), 1, fd);
1433 my_fread(&blksize2,
sizeof(
int), 1, fd);
1436 my_fread(&blksize1,
sizeof(
int), 1, fd);
1438 my_fread(&blksize2,
sizeof(
int), 1, fd);
1443 for(
int task = readTask + 1; task <= lastTask; task++)
1450 read_file_header(fname, filenr, readTask, lastTask, n_type, npart, &nstart);
1456 hdf5_file =
my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
1470 for(
int blocknr = 0; blocknr <
N_IO_Fields; blocknr++)
1478 unsigned int bytes_per_blockelement = get_bytes_per_memory_blockelement(blocknr, 1);
1479 int blockmaxlen = (int)(
COMMBUFFERSIZE / bytes_per_blockelement);
1480 long long npart_in_block = get_particles_in_block(blocknr, npart, &typelist[0]);
1481 hid_t hdf5_memory_datatype = get_hdf5_memorytype_of_block(blocknr);
1483 get_dataset_name(blocknr, dname);
1485 if(npart_in_block > 0)
1488 mpi_printf(
"READIC: reading block %d (%s)...\n", blocknr, dname);
1495 get_Tab_IO_Label(blocknr, expected_label);
1496 find_block(expected_label, fd);
1501 my_fread(&blksize1,
sizeof(
int), 1, fd);
1502 bytes_per_blockelement_in_file = blksize1 / npart_in_block;
1513 int n_in_file = npart[type];
1516 long long nprevious = 0;
1517 for(
int t = 0; t < type; t++)
1521 for(
int nr = 0; nr < filenr; nr++)
1524 if(typelist[type] == 0)
1526 int ntask = lastTask - readTask + 1;
1527 int n_for_this_task = n_in_file / ntask;
1528 if((
ThisTask - readTask) < (n_in_file % ntask))
1531 offset += n_for_this_task;
1535 for(
int task = readTask; task <= lastTask; task++)
1537 int ntask = lastTask - readTask + 1;
1538 int n_for_this_task = n_in_file / ntask;
1539 if((task - readTask) < (n_in_file % ntask))
1544 int pc = n_for_this_task;
1546 if(pc > blockmaxlen)
1553 if(bytes_per_blockelement_in_file != bytes_per_blockelement)
1555 char *CommAuxBuffer =
1556 (
char *)
Mem.mymalloc(
"CommAuxBuffer", bytes_per_blockelement_in_file * pc);
1557 my_fread(CommAuxBuffer, bytes_per_blockelement_in_file, pc, fd);
1558 type_cast_data((
char *)CommAuxBuffer, bytes_per_blockelement_in_file, (
char *)CommBuffer,
1559 bytes_per_blockelement, pc, blocknr);
1560 Mem.myfree(CommAuxBuffer);
1563 my_fread(CommBuffer, bytes_per_blockelement, pc, fd);
1570 hsize_t dims[2], count[2], start[2];
1572 dims[0] = npart[type];
1573 dims[1] = get_values_per_blockelement(blocknr);
1588 count[1] = get_values_per_blockelement(blocknr);
1594 if(hdf5_dataset < 0)
1598 printf(
"\tDataset %s not present for particle type %d, using zero.\n", dname, type);
1599 memset(CommBuffer, 0, dims[0] * dims[1] *
my_H5Tget_size(hdf5_memory_datatype));
1603 hid_t hdf5_file_datatype = H5Dget_type(hdf5_dataset);
1606 H5Tclose(hdf5_file_datatype);
1608 my_H5Dread(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_in_memory,
1609 hdf5_dataspace_in_file, H5P_DEFAULT, CommBuffer, dname);
1612 my_H5Sclose(hdf5_dataspace_in_memory, H5S_SIMPLE);
1617 if(
ThisTask == readTask && task != readTask && pc > 0)
1626 if(blocknr == 0 && IO_Fields[blocknr].array ==
A_P)
1628 for(
int n = 0; n < pc; n++)
1632 if(blocknr == 0 && IO_Fields[blocknr].array ==
A_MTRP)
1634 for(
int n = 0; n < pc; n++)
1641 empty_read_buffer(blocknr, nstart + offset, pc, type, nprevious, CommBuffer);
1646 n_for_this_task -= pc;
1649 while(n_for_this_task > 0);
1657 my_fread(&blksize2,
sizeof(
int), 1, fd);
1659 if(blksize1 != blksize2)
1662 sprintf(buf,
"incorrect block-sizes detected!\n Task=%d blocknr=%d blksize1=%d blksize2=%d\n",
ThisTask,
1663 blocknr, blksize1, blksize2);
1665 strcat(buf,
"Possible mismatch of 32bit and 64bit ID's in IC file and GADGET compilation !\n");
1676 long long n_in_file = npart[type];
1677 int ntask = lastTask - readTask + 1;
1678 int n_for_this_task = n_in_file / ntask;
1679 if((
ThisTask - readTask) < (n_in_file % ntask))
1715void IO_Def::distribute_file(
int nfiles,
int *filenr,
int *master,
int *last)
1717 int tasks_per_file =
NTask / nfiles;
1718 int tasks_left =
NTask % nfiles;
1722 int group =
ThisTask / tasks_per_file;
1723 *master = group * tasks_per_file;
1724 *last = (group + 1) * tasks_per_file - 1;
1729 double tpf = ((double)
NTask) / nfiles;
1732 for(
int i = 0; i < nfiles; i++)
1734 *master = *last + 1;
1735 *last = (i + 1) * tpf;
1759int IO_Def::get_bytes_per_memory_blockelement(
int blocknr,
int mode)
1764 int bytes_per_blockelement = 0;
1766 IO_Field *field = &IO_Fields[blocknr];
1768 switch(field->type_in_memory)
1771 bytes_per_blockelement = field->values_per_block *
sizeof(int);
1774 bytes_per_blockelement = field->values_per_block *
sizeof(
long long);
1777 bytes_per_blockelement = field->values_per_block *
sizeof(
MyIDType);
1780 bytes_per_blockelement = field->values_per_block *
sizeof(
MyIntPosType);
1783 bytes_per_blockelement = field->values_per_block *
sizeof(float);
1786 bytes_per_blockelement = field->values_per_block *
sizeof(double);
1789 bytes_per_blockelement = field->values_per_block *
sizeof(
MyFloat);
1792 bytes_per_blockelement = field->values_per_block *
sizeof(
MyDouble);
1795 bytes_per_blockelement = field->values_per_block *
sizeof(
long long);
1799 return bytes_per_blockelement;
1802hid_t IO_Def::get_hdf5_outputtype_of_block(
int blocknr)
1804 hid_t hdf5_datatype = 0;
1806 switch(IO_Fields[blocknr].type_in_file_output)
1809 hdf5_datatype = H5T_NATIVE_INT;
1812 hdf5_datatype = H5T_NATIVE_INT64;
1815#ifdef OUTPUT_IN_DOUBLEPRECISION
1816 hdf5_datatype = H5T_NATIVE_DOUBLE;
1818 hdf5_datatype = H5T_NATIVE_FLOAT;
1822#if defined(IDS_32BIT)
1823 hdf5_datatype = H5T_NATIVE_UINT32;
1824#elif defined(IDS_48BIT)
1827 hdf5_datatype = H5T_NATIVE_UINT64;
1831#if defined(POSITIONS_IN_32BIT)
1832 hdf5_datatype = H5T_NATIVE_UINT32;
1833#elif defined(POSITIONS_IN_64BIT)
1834 hdf5_datatype = H5T_NATIVE_UINT64;
1840 hdf5_datatype = H5T_NATIVE_DOUBLE;
1843 hdf5_datatype = H5T_NATIVE_FLOAT;
1853 return hdf5_datatype;
1856hid_t IO_Def::get_hdf5_memorytype_of_block(
int blocknr)
1858 hid_t hdf5_datatype = 0;
1860 switch(IO_Fields[blocknr].type_in_memory)
1863 hdf5_datatype = H5T_NATIVE_INT;
1866 hdf5_datatype = H5T_NATIVE_INT64;
1870 hdf5_datatype = H5T_NATIVE_UINT32;
1872 hdf5_datatype = H5T_NATIVE_UINT64;
1876#ifdef POSITIONS_IN_32BIT
1877 hdf5_datatype = H5T_NATIVE_UINT32;
1878#elif defined(POSITIONS_IN_64BIT)
1879 hdf5_datatype = H5T_NATIVE_UINT64;
1885 hdf5_datatype = H5T_NATIVE_FLOAT;
1888 hdf5_datatype = H5T_NATIVE_DOUBLE;
1897 hdf5_datatype = H5T_NATIVE_INT64;
1901 return hdf5_datatype;
1912int IO_Def::get_values_per_blockelement(
int blocknr)
1917 return IO_Fields[blocknr].values_per_block;
1930long long IO_Def::get_particles_in_block(
int blocknr,
long long *npart_file,
int *typelist)
1932 long long npart = 0;
1937 switch(IO_Fields[blocknr].typelist)
1940 for(
int i = 0; i <
NTYPES; i++)
1942 typelist[i] = (
All.
MassTable[i] == 0 && npart_file[i] > 0);
1943 npart += npart_file[i] * typelist[i];
1949 for(
int i = 0; i <
NTYPES; i++)
1951 typelist[i] = (npart_file[i] > 0);
1956 npart += npart_file[i] * typelist[i];
1962 for(
int i = 0; i <
NTYPES; i++)
1964 typelist[i] = (npart_file[i] > 0);
1968 npart += npart_file[i] * typelist[i];
1974 npart = npart_file[0];
1980 npart = npart_file[1];
1986 npart = npart_file[2];
1997 npart = npart_file[0];
2003 npart = npart_file[1];
2009 npart = npart_file[2];
2015 npart = npart_file[
NTYPES];
2021 npart = npart_file[
NTYPES + 1];
2022 typelist[
NTYPES + 1] = 1;
2029 if((IO_Fields[blocknr].typelist & (1 << i)) && npart_file[i] > 0)
2032 npart += npart_file[i];
2051void IO_Def::get_Tab_IO_Label(
int blocknr,
char *label)
2056 strcpy(label, IO_Fields[blocknr].label);
2066void IO_Def::get_dataset_name(
int blocknr,
char *buf)
2071 strcpy(buf, IO_Fields[blocknr].datasetname);
2074void IO_Def::write_dataset_attributes(hid_t hdf5_dataset,
int blocknr)
2079 if(IO_Fields[blocknr].hasunit == 0)
2108void IO_Def::write_parameters_attributes_in_hdf5(hid_t handle)
2128void IO_Def::find_block(
char *label, FILE *fd)
2130 unsigned int blocksize = 0, blksize;
2131 char blocklabel[5] = {
" "};
2135 my_fread(&blksize, sizeof(int), 1, fd); \
2140 while(!feof(fd) && blocksize == 0)
2146 Terminate(
"Incorrect Format (blksize=%u)!\n", blksize);
2151 my_fread(&blocksize,
sizeof(
int), 1, fd);
2155 if(strncmp(label, blocklabel,
LABEL_LEN) != 0)
2157 fseek(fd, blocksize, 1);
2163 Terminate(
"Block '%c%c%c%c' not found !\n", label[0], label[1], label[2], label[3]);
2168 long long nleft = count;
2169 long long offleft = offset;
2170 long long nskip = 0;
2172 for(
int filenr = 0; filenr < num_files && nleft > 0; filenr++)
2180 if(nloc - offleft > nleft)
2183 nread = nloc - offleft;
2198 for(
int filenr = 0; filenr < num_files; filenr++)
2201 printf(
"filenr=%d: nloc=%lld\n", filenr, nloc);
2203 Terminate(
"Not all desired entries read: nleft=%lld type=%d\n", nleft, type);
2208 long long storage_offset,
int num_files)
2210 int bytes_per_blockelement_in_file = 0;
2211 hid_t hdf5_file = 0, hdf5_grp = 0, hdf5_dataspace_in_file;
2212 hid_t hdf5_dataspace_in_memory, hdf5_dataset;
2219 sprintf(fname,
"%s.%d.hdf5", basename, filenr);
2221 sprintf(fname,
"%s.%d", basename, filenr);
2226 sprintf(fname,
"%s.hdf5", basename);
2228 sprintf(fname,
"%s", basename);
2234 hdf5_file =
my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
2241 if(!(fd = fopen(fname,
"r")))
2242 Terminate(
"can't open file `%s' for reading initial conditions.\n", fname);
2244 unsigned int blksize1, blksize2;
2250 my_fread(&blksize1,
sizeof(
int), 1, fd);
2252 my_fread(&nextblock,
sizeof(
int), 1, fd);
2253 my_fread(&blksize2,
sizeof(
int), 1, fd);
2256 my_fread(&blksize1,
sizeof(
int), 1, fd);
2258 my_fread(&blksize2,
sizeof(
int), 1, fd);
2267 for(
int blocknr = 0; blocknr <
N_IO_Fields; blocknr++)
2271 unsigned int blksize1, blksize2;
2273 int bytes_per_blockelement = get_bytes_per_memory_blockelement(blocknr, 1);
2274 long long npart_in_block = get_particles_in_block(blocknr, npart, &typelist[0]);
2275 hid_t hdf5_memory_datatype = get_hdf5_memorytype_of_block(blocknr);
2277 get_dataset_name(blocknr, dname);
2279 if(npart_in_block > 0 && typelist[type] > 0 && IO_Fields[blocknr].read_flag !=
SKIP_ON_READ)
2284 get_Tab_IO_Label(blocknr, expected_label);
2285 find_block(expected_label, fd);
2290 my_fread(&blksize1,
sizeof(
int), 1, fd);
2291 bytes_per_blockelement_in_file = blksize1 / npart_in_block;
2294 void *CommBuffer = (
char *)
Mem.mymalloc(
"CommBuffer", bytes_per_blockelement * count);
2298 fseek(fd, bytes_per_blockelement_in_file * offset, SEEK_CUR);
2300 if(bytes_per_blockelement_in_file != bytes_per_blockelement)
2302 char *CommAuxBuffer = (
char *)
Mem.mymalloc(
"CommAuxBuffer", bytes_per_blockelement_in_file * count);
2303 my_fread(CommAuxBuffer, bytes_per_blockelement_in_file, count, fd);
2304 type_cast_data((
char *)CommAuxBuffer, bytes_per_blockelement_in_file, (
char *)CommBuffer, bytes_per_blockelement,
2306 Mem.myfree(CommAuxBuffer);
2309 my_fread(CommBuffer, bytes_per_blockelement, count, fd);
2311 fseek(fd, bytes_per_blockelement_in_file * (npart_in_block - offset - count), SEEK_CUR);
2313 my_fread(&blksize2,
sizeof(
int), 1, fd);
2314 if(blksize1 != blksize2)
2317 sprintf(buf,
"incorrect block-sizes detected!\n Task=%d blocknr=%d blksize1=%d blksize2=%d\n",
ThisTask,
2318 blocknr, blksize1, blksize2);
2320 strcat(buf,
"Possible mismatch of 32bit and 64bit ID's in IC file and GADGET compilation !\n");
2329 hsize_t dims[2], nelem[2], start[2];
2331 dims[0] = npart[type];
2332 dims[1] = get_values_per_blockelement(blocknr);
2347 nelem[1] = get_values_per_blockelement(blocknr);
2352 if(hdf5_dataset < 0)
2355 printf(
"\tDataset %s not present for particle type %d, using zero.\n", dname, type);
2356 memset(CommBuffer, 0, dims[0] * dims[1] *
my_H5Tget_size(hdf5_memory_datatype));
2360 hid_t hdf5_file_datatype = H5Dget_type(hdf5_dataset);
2362 H5Tclose(hdf5_file_datatype);
2364 my_H5Dread(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_in_memory, hdf5_dataspace_in_file, H5P_DEFAULT,
2368 my_H5Sclose(hdf5_dataspace_in_memory, H5S_SIMPLE);
2372 empty_read_buffer(blocknr, storage_offset, count, type, 0, CommBuffer);
2374 Mem.myfree(CommBuffer);
2380 my_fread(&blksize1,
sizeof(
int), 1, fd);
2381 bytes_per_blockelement_in_file = blksize1 / npart_in_block;
2382 fseek(fd, bytes_per_blockelement_in_file * npart_in_block, SEEK_CUR);
2383 my_fread(&blksize2,
sizeof(
int), 1, fd);
2384 if(blksize1 != blksize2)
2387 sprintf(buf,
"incorrect block-sizes detected!\n Task=%d blocknr=%d blksize1=%d blksize2=%d\n",
ThisTask,
2388 blocknr, blksize1, blksize2);
2390 strcat(buf,
"Possible mismatch of 32bit and 64bit ID's in IC file and GADGET compilation !\n");
2412void IO_Def::rename_file_to_bak_if_it_exists(
char *fname)
2418 char *p = strrchr(fin,
'/');
2422 sprintf(buf,
"%s/bak-%s", fin, p + 1);
2425 sprintf(buf,
"bak-%s", fname);
2427 if(FILE *fcheck = fopen(fname,
"r"))
2431 if(!fopen(buf,
"r"))
2443 for(
int filenr = 0; filenr < num_files; filenr++)
2449 sprintf(buf,
"%s.%d", fname, filenr);
2450 if(file_format == 3)
2451 sprintf(buf,
"%s.%d.hdf5", fname, filenr);
2455 sprintf(buf,
"%s", fname);
2456 if(file_format == 3)
2457 sprintf(buf,
"%s.hdf5", fname);
2460 if(file_format == 3)
2464 else if(file_format == 1 || file_format == 2)
2468 if(!(fd = fopen(buf,
"r")))
2469 Terminate(
"can't open file `%s' for reading initial conditions.\n", fname);
2471 int blksize1, blksize2;
2473 if(file_format == 2)
2477 my_fread(&blksize1,
sizeof(
int), 1, fd);
2478 my_fread(&label,
sizeof(
char), 4, fd);
2479 my_fread(&nextblock,
sizeof(
int), 1, fd);
2480 printf(
"READIC: Reading header => '%c%c%c%c' (%d byte)\n", label[0], label[1], label[2], label[3], nextblock);
2481 my_fread(&blksize2,
sizeof(
int), 1, fd);
2484 my_fread(&blksize1,
sizeof(
int), 1, fd);
2486 my_fread(&blksize2,
sizeof(
int), 1, fd);
2488 if(blksize1 != blksize2)
2489 Terminate(
"incorrect header format, blksize1=%d blksize2=%d header_size=%d\n", blksize1, blksize2, (
int)
header_size);
global_data_all_processes All
virtual int get_filenr_from_header(void)=0
void alloc_and_read_ntype_in_files(const char *fname, int num_files)
void write_multiple_files(char *fname, int numfilesperdump, int append_flag=0, int chunk_size=0)
long long * ntype_in_files
virtual void * get_base_address_of_structure(enum arrays array, int index)=0
void read_segment(const char *fname, int type, long long offset, long long count, int numfiles)
virtual void set_type_of_element(int index, int type)=0
virtual void read_increase_numbers(int type, int n_for_this_task)=0
virtual void fill_file_header(int writeTask, int lastTask, long long *nloc_part, long long *npart)=0
void init_field(const char *label, const char *datasetname, enum types_in_memory type_in_memory, enum types_in_file type_in_file_output, enum read_flags read_flag, int values_per_block, enum arrays array, void *pointer_to_field, void(*io_func)(IO_Def *, int, int, void *, int), int typelist_bitmask, int hasunits, double a, double h, double L, double M, double V, double c, bool compression_on=false)
virtual void read_header_fields(const char *fname)=0
virtual void read_file_header(const char *fname, int filenr, int readTask, int lastTask, long long *nloc_part, long long *npart, int *nstart)=0
virtual void set_filenr_in_header(int)=0
enum file_contents type_of_file
virtual void write_header_fields(hid_t)=0
void read_files_driver(const char *fname, int rep, int numfiles)
virtual void get_datagroup_name(int grnr, char *gname)=0
void read_single_file_segment(const char *fname, int filenr, int type, long long offset, unsigned long long count, long long storage_offset, int numfiles)
virtual int get_type_of_element(int index)=0
int find_files(const char *fname, const char *fname_multiple)
This function determines on how many files a given snapshot or group/desc catalogue is distributed.
void write_compile_time_options_in_hdf5(hid_t handle)
size_t my_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
A wrapper for the fread() function.
size_t my_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
A wrapper for the fwrite() function.
char ParametersType[MAX_PARAMETERS]
char ParametersTag[MAX_PARAMETERS][MAXLEN_PARAM_TAG]
void * ParametersValue[MAX_PARAMETERS]
void mpi_printf(const char *fmt,...)
#define FILEFORMAT_LEGACY2
#define FILEFORMAT_LEGACY1
#define H5T_NATIVE_MYDOUBLE
#define H5T_NATIVE_MYFLOAT
hid_t my_H5Gopen(hid_t loc_id, const char *groupname)
herr_t my_H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t *start, const hsize_t *stride, const hsize_t *count, const hsize_t *block)
herr_t my_H5Dread(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, void *buf, const char *datasetname)
hid_t my_H5Fopen(const char *fname, unsigned int flags, hid_t fapl_id)
herr_t my_H5Gclose(hid_t group_id, const char *groupname)
size_t my_H5Tget_size(hid_t datatype_id)
herr_t my_H5Dset_extent(hid_t dset_id, const hsize_t size[])
hid_t my_H5Gcreate(hid_t loc_id, const char *groupname, size_t size_hint)
herr_t my_H5Pclose(hid_t plist)
hid_t my_H5Screate_simple(int rank, const hsize_t *current_dims, const hsize_t *maximum_dims)
herr_t my_H5Fclose(hid_t file_id, const char *fname)
herr_t my_H5Dclose(hid_t dataset_id, const char *datasetname)
hid_t my_H5Fcreate(const char *fname, unsigned int flags, hid_t fcpl_id, hid_t fapl_id)
hid_t my_H5Dopen_if_existing(hid_t file_id, const char *datasetname)
hid_t my_H5Dcreate(hid_t loc_id, const char *datasetname, hid_t type_id, hid_t space_id, hid_t dcpl_id)
herr_t my_H5Sclose(hid_t dataspace_id, H5S_class_t type)
void write_scalar_attribute(hid_t handle, const char *attr_name, const void *buf, hid_t mem_type_id)
herr_t my_H5Dwrite(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, const void *buf, const char *datasetname)
void write_string_attribute(hid_t handle, const char *attr_name, const char *buf)
#define COMPRESSION_CHUNKSIZE
int MaxFilesWithConcurrentIO
enum restart_options RestartFlag
int ComovingIntegrationOn
void myflush(FILE *fstream)