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);
330 void 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);
363 #ifdef GADGET2_HEADER
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))
414 void 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;
556 void 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++;
670 void 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);
817 void 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];
827 int rank = 0, pcsum = 0;
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++)
1002 n_for_this_task = n_type[type];
1004 for(
int p = writeTask; p <= lastTask; p++)
1011 while(n_for_this_task > 0)
1013 int pc = n_for_this_task;
1015 if(pc > blockmaxlen)
1019 fill_write_buffer(blocknr, &offset, pc, type, CommBuffer);
1021 if(
ThisTask == writeTask && task != writeTask)
1036 count[1] = get_values_per_blockelement(blocknr);
1042 dims[1] = get_values_per_blockelement(blocknr);
1045 my_H5Dwrite(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_memory, hdf5_dataspace_in_file,
1046 H5P_DEFAULT, CommBuffer, dname);
1052 if(bytes_per_blockelement_in_file != bytes_per_blockelement)
1054 char *CommAuxBuffer =
1055 (
char *)
Mem.mymalloc(
"CommAuxBuffer", bytes_per_blockelement_in_file * pc);
1056 type_cast_data((
char *)CommBuffer, bytes_per_blockelement, (
char *)CommAuxBuffer,
1057 bytes_per_blockelement_in_file, pc, blocknr);
1058 my_fwrite(CommAuxBuffer, bytes_per_blockelement_in_file, pc, fd);
1059 Mem.myfree(CommAuxBuffer);
1062 my_fwrite(CommBuffer, bytes_per_blockelement, pc, fd);
1066 n_for_this_task -= pc;
1075 if(chunksize > 0 || IO_Fields[blocknr].compression_on)
1109 sprintf(buf,
"%s.hdf5", fname);
1117 void IO_Def::append_file(
char *fname,
int writeTask,
int lastTask,
void *CommBuffer,
int numfilesperdump,
int chunksize)
1121 hid_t hdf5_file = 0, hdf5_grp[
N_DataGroups], hdf5_headergrp = 0, hdf5_dataspace_memory;
1122 hid_t hdf5_dataspace_in_file = 0, hdf5_dataset = 0;
1123 hsize_t dims[2], count[2], start[2];
1124 int rank = 0, pcsum = 0;
1127 Terminate(
"appending to files only works with HDF5 format\n");
1132 n_previous[n] = n_type[n];
1140 sprintf(buf,
"%s.hdf5", fname);
1142 hdf5_file =
my_H5Fopen(buf, H5F_ACC_RDWR, H5P_DEFAULT);
1144 hdf5_headergrp =
my_H5Gopen(hdf5_file,
"/Header");
1152 if(n_previous[type] == 0)
1160 for(
int blocknr = 0; blocknr <
N_IO_Fields; blocknr++)
1162 polling(numfilesperdump);
1164 if(IO_Fields[blocknr].type_in_file_output !=
FILE_NONE)
1166 unsigned int bytes_per_blockelement = get_bytes_per_memory_blockelement(blocknr, 0);
1167 int blockmaxlen = (int)(
COMMBUFFERSIZE / bytes_per_blockelement);
1168 long long npart_in_block = get_particles_in_block(blocknr, npart, typelist);
1169 hid_t hdf5_memory_datatype = get_hdf5_memorytype_of_block(blocknr);
1171 get_dataset_name(blocknr, dname);
1173 if(npart_in_block > 0)
1183 hid_t hdf5_file_datatype = get_hdf5_outputtype_of_block(blocknr);
1185 dims[0] = npart[type] + n_previous[type];
1186 dims[1] = get_values_per_blockelement(blocknr);
1194 if(n_previous[type] == 0)
1198 hsize_t maxdims[2] = {H5S_UNLIMITED, dims[1]};
1202 hid_t prop = H5Pcreate(H5P_DATASET_CREATE);
1203 hsize_t chunk_dims[2] = {0, dims[1]};
1204 chunk_dims[0] = chunksize;
1205 H5Pset_chunk(prop, rank, chunk_dims);
1207 hdf5_dataset =
my_H5Dcreate(hdf5_grp[type], dname, hdf5_file_datatype, hdf5_dataspace_in_file, prop);
1212 my_H5Dcreate(hdf5_grp[type], dname, hdf5_file_datatype, hdf5_dataspace_in_file, H5P_DEFAULT);
1213 write_dataset_attributes(hdf5_dataset, blocknr);
1227 for(
int task = writeTask, offset = 0; task <= lastTask; task++)
1229 int n_for_this_task;
1233 n_for_this_task = n_type[type];
1235 for(
int p = writeTask; p <= lastTask; p++)
1242 while(n_for_this_task > 0)
1244 int pc = n_for_this_task;
1246 if(pc > blockmaxlen)
1250 fill_write_buffer(blocknr, &offset, pc, type, CommBuffer);
1252 if(
ThisTask == writeTask && task != writeTask)
1261 start[0] = pcsum + n_previous[type];
1265 count[1] = get_values_per_blockelement(blocknr);
1271 dims[1] = get_values_per_blockelement(blocknr);
1274 my_H5Dwrite(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_memory, hdf5_dataspace_in_file,
1275 H5P_DEFAULT, CommBuffer, dname);
1280 n_for_this_task -= pc;
1284 if(
ThisTask == writeTask && npart[type] > 0)
1308 sprintf(buf,
"%s.hdf5", fname);
1313 void IO_Def::type_cast_data(
char *src,
int src_bytes_per_element,
char *target,
int target_bytes_per_element,
int len,
int blocknr)
1315 switch(IO_Fields[blocknr].type_in_memory)
1322 if(target_bytes_per_element > src_bytes_per_element)
1324 if(target_bytes_per_element != 2 * src_bytes_per_element)
1325 Terminate(
"something is odd here: target_bytes_per_element=%d != 2 * src_bytes_per_element=%d", target_bytes_per_element,
1326 src_bytes_per_element);
1328 int fac = src_bytes_per_element /
sizeof(int);
1329 int *sp = (
int *)src;
1330 long long *tp = (
long long *)target;
1331 for(
int i = 0; i < len * fac; i++)
1336 if(src_bytes_per_element != 2 * target_bytes_per_element)
1337 Terminate(
"something is odd here: src_bytes_per_element=%d != 2 * target_bytes_per_element=%d", src_bytes_per_element,
1338 target_bytes_per_element);
1339 int fac = src_bytes_per_element /
sizeof(
long long);
1340 long long *sp = (
long long *)src;
1341 int *tp = (
int *)target;
1342 for(
int i = 0; i < len * fac; i++)
1351 if((target_bytes_per_element % 8) == 0 &&
1352 (src_bytes_per_element % 4) == 0)
1354 int fac = src_bytes_per_element /
sizeof(float);
1355 float *sp = (
float *)src;
1356 double *tp = (
double *)target;
1357 for(
int i = 0; i < len * fac; i++)
1360 else if((target_bytes_per_element % 4) == 0 && (src_bytes_per_element % 8) == 0)
1362 int fac = src_bytes_per_element /
sizeof(double);
1363 double *sp = (
double *)src;
1364 float *tp = (
float *)target;
1365 for(
int i = 0; i < len * fac; i++)
1368 else if((target_bytes_per_element & 8) == 0 && (src_bytes_per_element % 2) == 0)
1370 int fac = src_bytes_per_element /
sizeof(
half);
1372 double *tp = (
double *)target;
1373 for(
int i = 0; i < len * fac; i++)
1376 else if((target_bytes_per_element % 2) == 0 && (src_bytes_per_element % 8) == 0)
1378 int fac = src_bytes_per_element /
sizeof(double);
1379 double *sp = (
double *)src;
1381 for(
int i = 0; i < len * fac; i++)
1386 Terminate(
"Strange conversion requested: target_bytes_per_element=%d src_bytes_per_element=%d\n",
1387 target_bytes_per_element, src_bytes_per_element);
1402 void IO_Def::read_file(
const char *fname,
int filenr,
int readTask,
int lastTask,
void *CommBuffer)
1406 unsigned int blksize1, blksize2, bytes_per_blockelement_in_file = 0;
1407 hid_t hdf5_file = 0, hdf5_grp[
N_DataGroups], hdf5_dataspace_in_file;
1408 hid_t hdf5_dataspace_in_memory, hdf5_dataset;
1421 if(!(fd = fopen(fname,
"r")))
1422 Terminate(
"can't open file `%s' for reading initial conditions.\n", fname);
1428 my_fread(&blksize1,
sizeof(
int), 1, fd);
1430 my_fread(&nextblock,
sizeof(
int), 1, fd);
1431 my_fread(&blksize2,
sizeof(
int), 1, fd);
1434 my_fread(&blksize1,
sizeof(
int), 1, fd);
1436 my_fread(&blksize2,
sizeof(
int), 1, fd);
1441 for(
int task = readTask + 1; task <= lastTask; task++)
1448 read_file_header(fname, filenr, readTask, lastTask, n_type, npart, &nstart);
1454 hdf5_file =
my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
1468 for(
int blocknr = 0; blocknr <
N_IO_Fields; blocknr++)
1476 unsigned int bytes_per_blockelement = get_bytes_per_memory_blockelement(blocknr, 1);
1477 int blockmaxlen = (int)(
COMMBUFFERSIZE / bytes_per_blockelement);
1478 long long npart_in_block = get_particles_in_block(blocknr, npart, &typelist[0]);
1479 hid_t hdf5_memory_datatype = get_hdf5_memorytype_of_block(blocknr);
1481 get_dataset_name(blocknr, dname);
1483 if(npart_in_block > 0)
1486 mpi_printf(
"READIC: reading block %d (%s)...\n", blocknr, dname);
1493 get_Tab_IO_Label(blocknr, expected_label);
1494 find_block(expected_label, fd);
1499 my_fread(&blksize1,
sizeof(
int), 1, fd);
1500 bytes_per_blockelement_in_file = blksize1 / npart_in_block;
1511 int n_in_file = npart[type];
1514 long long nprevious = 0;
1515 for(
int t = 0; t < type; t++)
1519 for(
int nr = 0; nr < filenr; nr++)
1522 if(typelist[type] == 0)
1524 int ntask = lastTask - readTask + 1;
1525 int n_for_this_task = n_in_file / ntask;
1526 if((
ThisTask - readTask) < (n_in_file % ntask))
1529 offset += n_for_this_task;
1533 for(
int task = readTask; task <= lastTask; task++)
1535 int ntask = lastTask - readTask + 1;
1536 int n_for_this_task = n_in_file / ntask;
1537 if((task - readTask) < (n_in_file % ntask))
1542 int pc = n_for_this_task;
1544 if(pc > blockmaxlen)
1551 if(bytes_per_blockelement_in_file != bytes_per_blockelement)
1553 char *CommAuxBuffer =
1554 (
char *)
Mem.mymalloc(
"CommAuxBuffer", bytes_per_blockelement_in_file * pc);
1555 my_fread(CommAuxBuffer, bytes_per_blockelement_in_file, pc, fd);
1556 type_cast_data((
char *)CommAuxBuffer, bytes_per_blockelement_in_file, (
char *)CommBuffer,
1557 bytes_per_blockelement, pc, blocknr);
1558 Mem.myfree(CommAuxBuffer);
1561 my_fread(CommBuffer, bytes_per_blockelement, pc, fd);
1568 hsize_t dims[2], count[2], start[2];
1570 dims[0] = npart[type];
1571 dims[1] = get_values_per_blockelement(blocknr);
1586 count[1] = get_values_per_blockelement(blocknr);
1592 if(hdf5_dataset < 0)
1596 printf(
"\tDataset %s not present for particle type %d, using zero.\n", dname, type);
1597 memset(CommBuffer, 0, dims[0] * dims[1] *
my_H5Tget_size(hdf5_memory_datatype));
1601 hid_t hdf5_file_datatype = H5Dget_type(hdf5_dataset);
1604 H5Tclose(hdf5_file_datatype);
1606 my_H5Dread(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_in_memory,
1607 hdf5_dataspace_in_file, H5P_DEFAULT, CommBuffer, dname);
1610 my_H5Sclose(hdf5_dataspace_in_memory, H5S_SIMPLE);
1615 if(
ThisTask == readTask && task != readTask && pc > 0)
1624 if(blocknr == 0 && IO_Fields[blocknr].array ==
A_P)
1626 for(
int n = 0; n < pc; n++)
1630 if(blocknr == 0 && IO_Fields[blocknr].array ==
A_MTRP)
1632 for(
int n = 0; n < pc; n++)
1639 empty_read_buffer(blocknr, nstart + offset, pc, type, nprevious, CommBuffer);
1644 n_for_this_task -= pc;
1647 while(n_for_this_task > 0);
1655 my_fread(&blksize2,
sizeof(
int), 1, fd);
1657 if(blksize1 != blksize2)
1660 sprintf(buf,
"incorrect block-sizes detected!\n Task=%d blocknr=%d blksize1=%d blksize2=%d\n",
ThisTask,
1661 blocknr, blksize1, blksize2);
1663 strcat(buf,
"Possible mismatch of 32bit and 64bit ID's in IC file and GADGET compilation !\n");
1674 long long n_in_file = npart[type];
1675 int ntask = lastTask - readTask + 1;
1676 int n_for_this_task = n_in_file / ntask;
1677 if((
ThisTask - readTask) < (n_in_file % ntask))
1713 void IO_Def::distribute_file(
int nfiles,
int *filenr,
int *master,
int *last)
1715 int tasks_per_file =
NTask / nfiles;
1716 int tasks_left =
NTask % nfiles;
1720 int group =
ThisTask / tasks_per_file;
1721 *master = group * tasks_per_file;
1722 *last = (group + 1) * tasks_per_file - 1;
1727 double tpf = ((double)
NTask) / nfiles;
1730 for(
int i = 0; i < nfiles; i++)
1732 *master = *last + 1;
1733 *last = (i + 1) * tpf;
1757 int IO_Def::get_bytes_per_memory_blockelement(
int blocknr,
int mode)
1762 int bytes_per_blockelement = 0;
1764 IO_Field *field = &IO_Fields[blocknr];
1766 switch(field->type_in_memory)
1769 bytes_per_blockelement = field->values_per_block *
sizeof(int);
1772 bytes_per_blockelement = field->values_per_block *
sizeof(
long long);
1775 bytes_per_blockelement = field->values_per_block *
sizeof(
MyIDType);
1778 bytes_per_blockelement = field->values_per_block *
sizeof(
MyIntPosType);
1781 bytes_per_blockelement = field->values_per_block *
sizeof(float);
1784 bytes_per_blockelement = field->values_per_block *
sizeof(double);
1787 bytes_per_blockelement = field->values_per_block *
sizeof(
MyFloat);
1790 bytes_per_blockelement = field->values_per_block *
sizeof(
MyDouble);
1793 bytes_per_blockelement = field->values_per_block *
sizeof(
long long);
1797 return bytes_per_blockelement;
1800 hid_t IO_Def::get_hdf5_outputtype_of_block(
int blocknr)
1802 hid_t hdf5_datatype = 0;
1804 switch(IO_Fields[blocknr].type_in_file_output)
1807 hdf5_datatype = H5T_NATIVE_INT;
1810 hdf5_datatype = H5T_NATIVE_INT64;
1813 #ifdef OUTPUT_IN_DOUBLEPRECISION
1814 hdf5_datatype = H5T_NATIVE_DOUBLE;
1816 hdf5_datatype = H5T_NATIVE_FLOAT;
1820 #if defined(IDS_32BIT)
1821 hdf5_datatype = H5T_NATIVE_UINT32;
1822 #elif defined(IDS_48BIT)
1825 hdf5_datatype = H5T_NATIVE_UINT64;
1829 #if defined(POSITIONS_IN_32BIT)
1830 hdf5_datatype = H5T_NATIVE_UINT32;
1831 #elif defined(POSITIONS_IN_64BIT)
1832 hdf5_datatype = H5T_NATIVE_UINT64;
1838 hdf5_datatype = H5T_NATIVE_DOUBLE;
1841 hdf5_datatype = H5T_NATIVE_FLOAT;
1851 return hdf5_datatype;
1854 hid_t IO_Def::get_hdf5_memorytype_of_block(
int blocknr)
1856 hid_t hdf5_datatype = 0;
1858 switch(IO_Fields[blocknr].type_in_memory)
1861 hdf5_datatype = H5T_NATIVE_INT;
1864 hdf5_datatype = H5T_NATIVE_INT64;
1868 hdf5_datatype = H5T_NATIVE_UINT32;
1870 hdf5_datatype = H5T_NATIVE_UINT64;
1874 #ifdef POSITIONS_IN_32BIT
1875 hdf5_datatype = H5T_NATIVE_UINT32;
1876 #elif defined(POSITIONS_IN_64BIT)
1877 hdf5_datatype = H5T_NATIVE_UINT64;
1883 hdf5_datatype = H5T_NATIVE_FLOAT;
1886 hdf5_datatype = H5T_NATIVE_DOUBLE;
1895 hdf5_datatype = H5T_NATIVE_INT64;
1899 return hdf5_datatype;
1910 int IO_Def::get_values_per_blockelement(
int blocknr)
1915 return IO_Fields[blocknr].values_per_block;
1928 long long IO_Def::get_particles_in_block(
int blocknr,
long long *npart_file,
int *typelist)
1930 long long npart = 0;
1935 switch(IO_Fields[blocknr].typelist)
1938 for(
int i = 0; i <
NTYPES; i++)
1940 typelist[i] = (
All.
MassTable[i] == 0 && npart_file[i] > 0);
1941 npart += npart_file[i] * typelist[i];
1947 for(
int i = 0; i <
NTYPES; i++)
1949 typelist[i] = (npart_file[i] > 0);
1954 npart += npart_file[i] * typelist[i];
1960 for(
int i = 0; i <
NTYPES; i++)
1962 typelist[i] = (npart_file[i] > 0);
1966 npart += npart_file[i] * typelist[i];
1972 npart = npart_file[0];
1978 npart = npart_file[1];
1984 npart = npart_file[2];
1995 npart = npart_file[0];
2001 npart = npart_file[1];
2007 npart = npart_file[2];
2013 npart = npart_file[
NTYPES];
2019 npart = npart_file[
NTYPES + 1];
2020 typelist[
NTYPES + 1] = 1;
2027 if((IO_Fields[blocknr].typelist & (1 << i)) && npart_file[i] > 0)
2030 npart += npart_file[i];
2049 void IO_Def::get_Tab_IO_Label(
int blocknr,
char *label)
2054 strcpy(label, IO_Fields[blocknr].label);
2064 void IO_Def::get_dataset_name(
int blocknr,
char *buf)
2069 strcpy(buf, IO_Fields[blocknr].datasetname);
2072 void IO_Def::write_dataset_attributes(hid_t hdf5_dataset,
int blocknr)
2077 if(IO_Fields[blocknr].hasunit == 0)
2106 void IO_Def::write_parameters_attributes_in_hdf5(hid_t handle)
2126 void IO_Def::find_block(
char *label, FILE *fd)
2128 unsigned int blocksize = 0, blksize;
2129 char blocklabel[5] = {
" "};
2133 my_fread(&blksize, sizeof(int), 1, fd); \
2138 while(!feof(fd) && blocksize == 0)
2144 Terminate(
"Incorrect Format (blksize=%u)!\n", blksize);
2149 my_fread(&blocksize,
sizeof(
int), 1, fd);
2153 if(strncmp(label, blocklabel,
LABEL_LEN) != 0)
2155 fseek(fd, blocksize, 1);
2161 Terminate(
"Block '%c%c%c%c' not found !\n", label[0], label[1], label[2], label[3]);
2166 long long nleft = count;
2167 long long offleft = offset;
2168 long long nskip = 0;
2170 for(
int filenr = 0; filenr < num_files && nleft > 0; filenr++)
2178 if(nloc - offleft > nleft)
2181 nread = nloc - offleft;
2196 for(
int filenr = 0; filenr < num_files; filenr++)
2199 printf(
"filenr=%d: nloc=%lld\n", filenr, nloc);
2201 Terminate(
"Not all desired entries read: nleft=%lld type=%d\n", nleft, type);
2206 long long storage_offset,
int num_files)
2208 int bytes_per_blockelement_in_file = 0;
2209 hid_t hdf5_file = 0, hdf5_grp = 0, hdf5_dataspace_in_file;
2210 hid_t hdf5_dataspace_in_memory, hdf5_dataset;
2217 sprintf(fname,
"%s.%d.hdf5", basename, filenr);
2219 sprintf(fname,
"%s.%d", basename, filenr);
2224 sprintf(fname,
"%s.hdf5", basename);
2226 sprintf(fname,
"%s", basename);
2232 hdf5_file =
my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
2239 if(!(fd = fopen(fname,
"r")))
2240 Terminate(
"can't open file `%s' for reading initial conditions.\n", fname);
2242 unsigned int blksize1, blksize2;
2248 my_fread(&blksize1,
sizeof(
int), 1, fd);
2250 my_fread(&nextblock,
sizeof(
int), 1, fd);
2251 my_fread(&blksize2,
sizeof(
int), 1, fd);
2254 my_fread(&blksize1,
sizeof(
int), 1, fd);
2256 my_fread(&blksize2,
sizeof(
int), 1, fd);
2265 for(
int blocknr = 0; blocknr <
N_IO_Fields; blocknr++)
2269 unsigned int blksize1, blksize2;
2271 int bytes_per_blockelement = get_bytes_per_memory_blockelement(blocknr, 1);
2272 long long npart_in_block = get_particles_in_block(blocknr, npart, &typelist[0]);
2273 hid_t hdf5_memory_datatype = get_hdf5_memorytype_of_block(blocknr);
2275 get_dataset_name(blocknr, dname);
2277 if(npart_in_block > 0 && typelist[type] > 0 && IO_Fields[blocknr].read_flag !=
SKIP_ON_READ)
2282 get_Tab_IO_Label(blocknr, expected_label);
2283 find_block(expected_label, fd);
2288 my_fread(&blksize1,
sizeof(
int), 1, fd);
2289 bytes_per_blockelement_in_file = blksize1 / npart_in_block;
2292 void *CommBuffer = (
char *)
Mem.mymalloc(
"CommBuffer", bytes_per_blockelement * count);
2296 fseek(fd, bytes_per_blockelement_in_file * offset, SEEK_CUR);
2298 if(bytes_per_blockelement_in_file != bytes_per_blockelement)
2300 char *CommAuxBuffer = (
char *)
Mem.mymalloc(
"CommAuxBuffer", bytes_per_blockelement_in_file * count);
2301 my_fread(CommAuxBuffer, bytes_per_blockelement_in_file, count, fd);
2302 type_cast_data((
char *)CommAuxBuffer, bytes_per_blockelement_in_file, (
char *)CommBuffer, bytes_per_blockelement,
2304 Mem.myfree(CommAuxBuffer);
2307 my_fread(CommBuffer, bytes_per_blockelement, count, fd);
2309 fseek(fd, bytes_per_blockelement_in_file * (npart_in_block - offset - count), SEEK_CUR);
2311 my_fread(&blksize2,
sizeof(
int), 1, fd);
2312 if(blksize1 != blksize2)
2315 sprintf(buf,
"incorrect block-sizes detected!\n Task=%d blocknr=%d blksize1=%d blksize2=%d\n",
ThisTask,
2316 blocknr, blksize1, blksize2);
2318 strcat(buf,
"Possible mismatch of 32bit and 64bit ID's in IC file and GADGET compilation !\n");
2327 hsize_t dims[2], nelem[2], start[2];
2329 dims[0] = npart[type];
2330 dims[1] = get_values_per_blockelement(blocknr);
2345 nelem[1] = get_values_per_blockelement(blocknr);
2350 if(hdf5_dataset < 0)
2353 printf(
"\tDataset %s not present for particle type %d, using zero.\n", dname, type);
2354 memset(CommBuffer, 0, dims[0] * dims[1] *
my_H5Tget_size(hdf5_memory_datatype));
2358 hid_t hdf5_file_datatype = H5Dget_type(hdf5_dataset);
2360 H5Tclose(hdf5_file_datatype);
2362 my_H5Dread(hdf5_dataset, hdf5_memory_datatype, hdf5_dataspace_in_memory, hdf5_dataspace_in_file, H5P_DEFAULT,
2366 my_H5Sclose(hdf5_dataspace_in_memory, H5S_SIMPLE);
2370 empty_read_buffer(blocknr, storage_offset, count, type, 0, CommBuffer);
2372 Mem.myfree(CommBuffer);
2378 my_fread(&blksize1,
sizeof(
int), 1, fd);
2379 bytes_per_blockelement_in_file = blksize1 / npart_in_block;
2380 fseek(fd, bytes_per_blockelement_in_file * npart_in_block, SEEK_CUR);
2381 my_fread(&blksize2,
sizeof(
int), 1, fd);
2382 if(blksize1 != blksize2)
2385 sprintf(buf,
"incorrect block-sizes detected!\n Task=%d blocknr=%d blksize1=%d blksize2=%d\n",
ThisTask,
2386 blocknr, blksize1, blksize2);
2388 strcat(buf,
"Possible mismatch of 32bit and 64bit ID's in IC file and GADGET compilation !\n");
2410 void IO_Def::rename_file_to_bak_if_it_exists(
char *fname)
2416 char *p = strrchr(fin,
'/');
2420 sprintf(buf,
"%s/bak-%s", fin, p + 1);
2423 sprintf(buf,
"bak-%s", fname);
2425 if(FILE *fcheck = fopen(fname,
"r"))
2429 if(!fopen(buf,
"r"))
2441 for(
int filenr = 0; filenr < num_files; filenr++)
2447 sprintf(buf,
"%s.%d", fname, filenr);
2448 if(file_format == 3)
2449 sprintf(buf,
"%s.%d.hdf5", fname, filenr);
2453 sprintf(buf,
"%s", fname);
2454 if(file_format == 3)
2455 sprintf(buf,
"%s.hdf5", fname);
2458 if(file_format == 3)
2462 else if(file_format == 1 || file_format == 2)
2466 if(!(fd = fopen(buf,
"r")))
2467 Terminate(
"can't open file `%s' for reading initial conditions.\n", fname);
2469 int blksize1, blksize2;
2471 if(file_format == 2)
2475 my_fread(&blksize1,
sizeof(
int), 1, fd);
2476 my_fread(&label,
sizeof(
char), 4, fd);
2477 my_fread(&nextblock,
sizeof(
int), 1, fd);
2478 printf(
"READIC: Reading header => '%c%c%c%c' (%d byte)\n", label[0], label[1], label[2], label[3], nextblock);
2479 my_fread(&blksize2,
sizeof(
int), 1, fd);
2482 my_fread(&blksize1,
sizeof(
int), 1, fd);
2484 my_fread(&blksize2,
sizeof(
int), 1, fd);
2486 if(blksize1 != blksize2)
2487 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)
virtual void * get_base_address_of_structure(enum arrays array, int index)=0
void write_multiple_files(char *fname, int numfilesperdump, int append_flag=0, int chunk_size=0)
long long * ntype_in_files
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)