/*! This function determines onto how many files a given snapshot is * distributed. */ int find_files(char *fname) { FILE *fd; char buf[200], buf1[200]; int dummy; sprintf(buf, "%s.%d", fname, 0); sprintf(buf1, "%s", fname); if(All.ICFormat == 3) { sprintf(buf, "%s.%d.hdf5", fname, 0); sprintf(buf1, "%s.hdf5", fname); } #ifndef HAVE_HDF5 if(All.ICFormat == 3) { if(ThisTask == 0) printf("Code wasn't compiled with HDF5 support enabled!\n"); endrun(0); } #endif header.num_files = 0; if(ThisTask == 0) { if((fd = fopen(buf, "r"))) { if(All.ICFormat == 1 || All.ICFormat == 2) { if(All.ICFormat == 2) { fread(&dummy, sizeof(dummy), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); } fread(&dummy, sizeof(dummy), 1, fd); fread(&header, sizeof(header), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); } fclose(fd); #ifdef HAVE_HDF5 if(All.ICFormat == 3) read_header_attributes_in_hdf5(buf); #endif } } MPI_Bcast(&header, sizeof(header), MPI_BYTE, 0, MPI_COMM_WORLD); if(header.num_files > 0) return header.num_files; if(ThisTask == 0) { if((fd = fopen(buf1, "r"))) { if(All.ICFormat == 1 || All.ICFormat == 2) { if(All.ICFormat == 2) { fread(&dummy, sizeof(dummy), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); } fread(&dummy, sizeof(dummy), 1, fd); fread(&header, sizeof(header), 1, fd); fread(&dummy, sizeof(dummy), 1, fd); } fclose(fd); #ifdef HAVE_HDF5 if(All.ICFormat == 3) read_header_attributes_in_hdf5(buf1); #endif header.num_files = 1; } } MPI_Bcast(&header, sizeof(header), MPI_BYTE, 0, MPI_COMM_WORLD); if(header.num_files > 0) return header.num_files; if(ThisTask == 0) { printf("\nCan't find initial conditions file."); printf("neither as '%s'\nnor as '%s'\n", buf, buf1); fflush(stdout); } endrun(0); return 0; }
/*! This function reads a snapshot file and distributes the data it contains * to tasks 'readTask' to 'lastTask'. */ void read_file(char *fname, int readTask, int lastTask) { int blockmaxlen; int i, n_in_file, n_for_this_task, ntask, pc, offset = 0, task; int blksize1, blksize2; MPI_Status status; FILE *fd = 0; int nall, nread; int type, bnr; char label[4], expected_label[4], buf[500]; int nstart, bytes_per_blockelement, npart, nextblock, typelist[6]; enum iofields blocknr; size_t bytes; #ifdef HAVE_HDF5 int rank, pcsum; hid_t hdf5_file = 0, hdf5_grp[6], hdf5_dataspace_in_file; hid_t hdf5_datatype = 0, hdf5_dataspace_in_memory, hdf5_dataset; hsize_t dims[2], count[2], start[2]; #endif #if defined(COSMIC_RAYS) && (!defined(CR_IC)) int CRpop; #endif #define SKIP {my_fread(&blksize1,sizeof(int),1,fd);} #define SKIP2 {my_fread(&blksize2,sizeof(int),1,fd);} if(ThisTask == readTask) { if(All.ICFormat == 1 || All.ICFormat == 2) { if(!(fd = fopen(fname, "r"))) { printf("can't open file `%s' for reading initial conditions.\n", fname); endrun(123); } if(All.ICFormat == 2) { SKIP; #ifdef AUTO_SWAP_ENDIAN_READIC swap_file = blksize1; #endif my_fread(&label, sizeof(char), 4, fd); my_fread(&nextblock, sizeof(int), 1, fd); #ifdef AUTO_SWAP_ENDIAN_READIC swap_Nbyte((char *) &nextblock, 1, 4); #endif printf("Reading header => '%c%c%c%c' (%d byte)\n", label[0], label[1], label[2], label[3], nextblock); SKIP2; } SKIP; #ifdef AUTO_SWAP_ENDIAN_READIC if(All.ICFormat == 1) { if(blksize1 != 256) swap_file = 1; } #endif my_fread(&header, sizeof(header), 1, fd); SKIP2; #ifdef AUTO_SWAP_ENDIAN_READIC swap_Nbyte((char *) &blksize1, 1, 4); swap_Nbyte((char *) &blksize2, 1, 4); #endif if(blksize1 != 256 || blksize2 != 256) { printf("incorrect header format\n"); fflush(stdout); endrun(890); /* Probable error is wrong size of fill[] in header file. Needs to be 256 bytes in total. */ } #ifdef AUTO_SWAP_ENDIAN_READIC swap_header(); #endif } #ifdef HAVE_HDF5 if(All.ICFormat == 3) { read_header_attributes_in_hdf5(fname); hdf5_file = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT); for(type = 0; type < 6; type++) { if(header.npart[type] > 0) { sprintf(buf, "/PartType%d", type); hdf5_grp[type] = H5Gopen(hdf5_file, buf); } } } #endif for(task = readTask + 1; task <= lastTask; task++) { MPI_Ssend(&header, sizeof(header), MPI_BYTE, task, TAG_HEADER, MPI_COMM_WORLD); #ifdef AUTO_SWAP_ENDIAN_READIC MPI_Ssend(&swap_file, sizeof(int), MPI_INT, task, TAG_SWAP, MPI_COMM_WORLD); #endif } } else { MPI_Recv(&header, sizeof(header), MPI_BYTE, readTask, TAG_HEADER, MPI_COMM_WORLD, &status); #ifdef AUTO_SWAP_ENDIAN_READIC MPI_Recv(&swap_file, sizeof(int), MPI_INT, readTask, TAG_SWAP, MPI_COMM_WORLD, &status); #endif } #ifdef INPUT_IN_DOUBLEPRECISION if(header.flag_doubleprecision == 0) { if(ThisTask == 0) printf ("\nProblem: Code compiled with INPUT_IN_DOUBLEPRECISION, but input files are in single precision!\n"); endrun(11); } #else if(header.flag_doubleprecision) { if(ThisTask == 0) printf ("\nProblem: Code not compiled with INPUT_IN_DOUBLEPRECISION, but input files are in double precision!\n"); endrun(10); } #endif if(All.TotNumPart == 0) { if(header.num_files <= 1) for(i = 0; i < 6; i++) { header.npartTotal[i] = header.npart[i]; #ifdef SFR header.npartTotalHighWord[i] = 0; #endif } All.TotN_gas = header.npartTotal[0] + (((long long) header.npartTotalHighWord[0]) << 32); for(i = 0, All.TotNumPart = 0; i < 6; i++) { All.TotNumPart += header.npartTotal[i]; All.TotNumPart += (((long long) header.npartTotalHighWord[i]) << 32); } #ifdef GENERATE_GAS_IN_ICS if(RestartFlag == 0) { All.TotN_gas += header.npartTotal[1]; All.TotNumPart += header.npartTotal[1]; } #endif for(i = 0; i < 6; i++) All.MassTable[i] = header.mass[i]; All.MaxPart = (int) (All.PartAllocFactor * (All.TotNumPart / NTask)); /* sets the maximum number of particles that may */ #ifdef GASRETURN All.MaxPartSph = (int) (All.PartAllocFactor * (All.TotNumPart / NTask)); /* sets the maximum number of particles that may */ #else All.MaxPartSph = (int) (All.PartAllocFactor * (All.TotN_gas / NTask)); /* sets the maximum number of particles that may */ #endif #ifdef INHOMOG_GASDISTR_HINT All.MaxPartSph = All.MaxPart; #endif allocate_memory(); if(!(CommBuffer = mymalloc(bytes = All.BufferSize * 1024 * 1024))) { printf("failed to allocate memory for `CommBuffer' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(2); } if(RestartFlag >= 2) All.Time = All.TimeBegin = header.time; } if(ThisTask == readTask) { for(i = 0, n_in_file = 0; i < 6; i++) n_in_file += header.npart[i]; printf("\nreading file `%s' on task=%d (contains %d particles.)\n" "distributing this file to tasks %d-%d\n" "Type 0 (gas): %8d (tot=%6d%09d) masstab=%g\n" "Type 1 (halo): %8d (tot=%6d%09d) masstab=%g\n" "Type 2 (disk): %8d (tot=%6d%09d) masstab=%g\n" "Type 3 (bulge): %8d (tot=%6d%09d) masstab=%g\n" "Type 4 (stars): %8d (tot=%6d%09d) masstab=%g\n" "Type 5 (bndry): %8d (tot=%6d%09d) masstab=%g\n\n", fname, ThisTask, n_in_file, readTask, lastTask, header.npart[0], (int) (header.npartTotal[0] / 1000000000), (int) (header.npartTotal[0] % 1000000000), All.MassTable[0], header.npart[1], (int) (header.npartTotal[1] / 1000000000), (int) (header.npartTotal[1] % 1000000000), All.MassTable[1], header.npart[2], (int) (header.npartTotal[2] / 1000000000), (int) (header.npartTotal[2] % 1000000000), All.MassTable[2], header.npart[3], (int) (header.npartTotal[3] / 1000000000), (int) (header.npartTotal[3] % 1000000000), All.MassTable[3], header.npart[4], (int) (header.npartTotal[4] / 1000000000), (int) (header.npartTotal[4] % 1000000000), All.MassTable[4], header.npart[5], (int) (header.npartTotal[5] / 1000000000), (int) (header.npartTotal[5] % 1000000000), All.MassTable[5]); fflush(stdout); } ntask = lastTask - readTask + 1; /* to collect the gas particles all at the beginning (in case several snapshot files are read on the current CPU) we move the collisionless particles such that a gap of the right size is created */ for(type = 0, nall = 0; type < 6; type++) { n_in_file = header.npart[type]; n_for_this_task = n_in_file / ntask; if((ThisTask - readTask) < (n_in_file % ntask)) n_for_this_task++; if(type == 0) { if(N_gas + n_for_this_task > All.MaxPartSph) { printf("Not enough space on task=%d for SPH particles (space for %d, need at least %d)\n", ThisTask, All.MaxPartSph, N_gas + n_for_this_task); fflush(stdout); endrun(172); } } nall += n_for_this_task; } if(NumPart + nall > All.MaxPart) { printf("Not enough space on task=%d (space for %d, need at least %d)\n", ThisTask, All.MaxPart, NumPart + nall); fflush(stdout); endrun(173); } memmove(&P[N_gas + nall], &P[N_gas], (NumPart - N_gas) * sizeof(struct particle_data)); nstart = N_gas; for(bnr = 0; bnr < 1000; bnr++) { blocknr = (enum iofields) bnr; if(blocknr == IO_LASTENTRY) break; if(blockpresent(blocknr)) { #ifdef CR_IC if(RestartFlag == 0 && ((blocknr > IO_CR_Q0 && blocknr != IO_BFLD) || (blocknr >= IO_RHO && blocknr <= IO_ACCEL))) #else #ifdef EOS_DEGENERATE if(RestartFlag == 0 && (blocknr > IO_U && blocknr != IO_EOSXNUC)) #else #ifndef CHEMISTRY #ifndef READ_HSML /* normal */ if(RestartFlag == 0 && blocknr > IO_U && blocknr != IO_BFLD && blocknr != IO_Z && blocknr != IO_AGE) #else if(RestartFlag == 0 && blocknr > IO_U && blocknr != IO_BFLD && blocknr != IO_HSML) #endif #else if(RestartFlag == 0 && blocknr > IO_HM) #endif #endif #endif #if defined(DISTORTIONTENSORPS) && !defined(COSMIC_DISTORTION) if(RestartFlag == 0 && (blocknr > IO_U && blocknr != IO_SHEET_ORIENTATION)) if(RestartFlag == 0 && (blocknr > IO_U && blocknr != IO_INIT_DENSITY)) if(RestartFlag == 0 && (blocknr > IO_U && blocknr != IO_CAUSTIC_COUNTER)) #ifdef DISTORTION_READALL if(RestartFlag == 0 && (blocknr > IO_U && blocknr != IO_DISTORTIONTENSORPS)) #endif #endif continue; /* ignore all other blocks in initial conditions */ #ifdef BINISET if(RestartFlag == 0 && blocknr == IO_BFLD) continue; #endif if(ThisTask == readTask) { get_dataset_name(blocknr, buf); printf("reading block %d (%s)...\n", blocknr, buf); fflush(stdout); } bytes_per_blockelement = get_bytes_per_blockelement(blocknr, 1); blockmaxlen = ((int) (All.BufferSize * 1024 * 1024)) / bytes_per_blockelement; npart = get_particles_in_block(blocknr, &typelist[0]); if(npart > 0) { if(blocknr != IO_DMHSML && blocknr != IO_DMDENSITY && blocknr != IO_DMVELDISP && blocknr != IO_DMHSML_V && blocknr != IO_DMDENSITY_V) if(ThisTask == readTask) { if(All.ICFormat == 2) { SKIP; my_fread(&label, sizeof(char), 4, fd); my_fread(&nextblock, sizeof(int), 1, fd); #ifdef AUTO_SWAP_ENDIAN_READIC swap_Nbyte((char *) &nextblock, 1, 4); #endif printf("Reading header => '%c%c%c%c' (%d byte)\n", label[0], label[1], label[2], label[3], nextblock); SKIP2; get_Tab_IO_Label(blocknr, expected_label); if(strncmp(label, expected_label, 4) != 0) { printf("incorrect block-structure!\n"); printf("expected '%c%c%c%c' but found '%c%c%c%c'\n", label[0], label[1], label[2], label[3], expected_label[0], expected_label[1], expected_label[2], expected_label[3]); fflush(stdout); endrun(1890); } } if(All.ICFormat == 1 || All.ICFormat == 2) SKIP; } for(type = 0, offset = 0, nread = 0; type < 6; type++) { n_in_file = header.npart[type]; #ifdef HAVE_HDF5 pcsum = 0; #endif if(typelist[type] == 0) { n_for_this_task = n_in_file / ntask; if((ThisTask - readTask) < (n_in_file % ntask)) n_for_this_task++; offset += n_for_this_task; } else { for(task = readTask; task <= lastTask; task++) { n_for_this_task = n_in_file / ntask; if((task - readTask) < (n_in_file % ntask)) n_for_this_task++; if(task == ThisTask) if(NumPart + n_for_this_task > All.MaxPart) { printf("too many particles. %d %d %d\n", NumPart, n_for_this_task, All.MaxPart); endrun(1313); } do { pc = n_for_this_task; if(pc > blockmaxlen) pc = blockmaxlen; if(ThisTask == readTask) { if(All.ICFormat == 1 || All.ICFormat == 2) { if(blocknr != IO_DMHSML && blocknr != IO_DMDENSITY && blocknr != IO_DMVELDISP && blocknr != IO_DMHSML_V && blocknr != IO_DMDENSITY_V) { my_fread(CommBuffer, bytes_per_blockelement, pc, fd); nread += pc; } else { #ifdef SUBFIND_RESHUFFLE_CATALOGUE read_hsml_files(CommBuffer, pc, blocknr, NumPartPerFile[FileNr] + nread); #endif nread += pc; } } #ifdef HAVE_HDF5 if(All.ICFormat == 3 && pc > 0) { get_dataset_name(blocknr, buf); hdf5_dataset = H5Dopen(hdf5_grp[type], buf); dims[0] = header.npart[type]; dims[1] = get_values_per_blockelement(blocknr); if(dims[1] == 1) rank = 1; else rank = 2; hdf5_dataspace_in_file = H5Screate_simple(rank, dims, NULL); dims[0] = pc; hdf5_dataspace_in_memory = H5Screate_simple(rank, dims, NULL); start[0] = pcsum; start[1] = 0; count[0] = pc; count[1] = get_values_per_blockelement(blocknr); pcsum += pc; H5Sselect_hyperslab(hdf5_dataspace_in_file, H5S_SELECT_SET, start, NULL, count, NULL); switch (get_datatype_in_block(blocknr)) { case 0: hdf5_datatype = H5Tcopy(H5T_NATIVE_UINT); break; case 1: #ifdef INPUT_IN_DOUBLEPRECISION hdf5_datatype = H5Tcopy(H5T_NATIVE_DOUBLE); #else hdf5_datatype = H5Tcopy(H5T_NATIVE_FLOAT); #endif break; case 2: hdf5_datatype = H5Tcopy(H5T_NATIVE_UINT64); break; } H5Dread(hdf5_dataset, hdf5_datatype, hdf5_dataspace_in_memory, hdf5_dataspace_in_file, H5P_DEFAULT, CommBuffer); H5Tclose(hdf5_datatype); H5Sclose(hdf5_dataspace_in_memory); H5Sclose(hdf5_dataspace_in_file); H5Dclose(hdf5_dataset); } #endif } if(ThisTask == readTask && task != readTask && pc > 0) MPI_Ssend(CommBuffer, bytes_per_blockelement * pc, MPI_BYTE, task, TAG_PDATA, MPI_COMM_WORLD); if(ThisTask != readTask && task == ThisTask && pc > 0) MPI_Recv(CommBuffer, bytes_per_blockelement * pc, MPI_BYTE, readTask, TAG_PDATA, MPI_COMM_WORLD, &status); if(ThisTask == task) { empty_read_buffer(blocknr, nstart + offset, pc, type); offset += pc; } n_for_this_task -= pc; } while(n_for_this_task > 0); } } } if(ThisTask == readTask) { if(blocknr != IO_DMHSML && blocknr != IO_DMDENSITY && blocknr != IO_DMVELDISP && blocknr != IO_DMHSML_V && blocknr != IO_DMDENSITY_V) if(All.ICFormat == 1 || All.ICFormat == 2) { SKIP2; #ifdef AUTO_SWAP_ENDIAN_READIC swap_Nbyte((char *) &blksize1, 1, 4); swap_Nbyte((char *) &blksize2, 1, 4); #endif if(blksize1 != blksize2) { printf("incorrect block-sizes detected!\n"); printf("Task=%d blocknr=%d blksize1=%d blksize2=%d\n", ThisTask, blocknr, blksize1, blksize2); if(blocknr == IO_ID) { printf ("Possible mismatch of 32bit and 64bit ID's in IC file and GADGET compilation !\n"); } fflush(stdout); endrun(1889); } } } } } } #ifdef SAVE_HSML_IN_IC_ORDER MyIDType IdCount = 0; for(type = 0, offset = 0; type < 6; type++) { n_in_file = header.npart[type]; for(task = readTask; task <= lastTask; task++) { n_for_this_task = n_in_file / ntask; if((task - readTask) < (n_in_file % ntask)) n_for_this_task++; if(ThisTask == task) { int i; for(i = 0; i < n_for_this_task; i++) P[nstart + offset + i].ID_ic_order = NumPartPerFile[FileNr] + IdCount + i; offset += n_for_this_task; } IdCount += n_for_this_task; } } #endif for(type = 0; type < 6; type++) { n_in_file = header.npart[type]; n_for_this_task = n_in_file / ntask; if((ThisTask - readTask) < (n_in_file % ntask)) n_for_this_task++; NumPart += n_for_this_task; if(type == 0) N_gas += n_for_this_task; } if(ThisTask == readTask) { if(All.ICFormat == 1 || All.ICFormat == 2) fclose(fd); #ifdef HAVE_HDF5 if(All.ICFormat == 3) { for(type = 5; type >= 0; type--) if(header.npart[type] > 0) H5Gclose(hdf5_grp[type]); H5Fclose(hdf5_file); } #endif } #if defined(COSMIC_RAYS) && (!defined(CR_IC)) for(i = 0; i < n_for_this_task; i++) { if(P[i].Type != 0) { break; } for(CRpop = 0; CRpop < NUMCRPOP; CRpop++) { SphP[i].CR_C0[CRpop] = 0.0; SphP[i].CR_q0[CRpop] = 1.0e10; } } #endif }
/*! This function reads a snapshot file and distributes the data it contains * to tasks 'readTask' to 'lastTask'. */ void read_file(char *fname, int readTask, int lastTask) { int blockmaxlen; int i, n_in_file, n_for_this_task, ntask, pc, offset = 0, task; int blksize1, blksize2; MPI_Status status; FILE *fd = 0; int nall; int type; char label[4]; int nstart, bytes_per_blockelement, npart, nextblock, typelist[6]; enum iofields blocknr; #ifdef HAVE_HDF5 char buf[500]; int rank, pcsum; hid_t hdf5_file, hdf5_grp[6], hdf5_dataspace_in_file; hid_t hdf5_datatype, hdf5_dataspace_in_memory, hdf5_dataset; hsize_t dims[2], count[2], start[2]; #endif #define SKIP {my_fread(&blksize1,sizeof(int),1,fd);} #define SKIP2 {my_fread(&blksize2,sizeof(int),1,fd);} if(ThisTask == readTask) { if(All.ICFormat == 1 || All.ICFormat == 2) { if(!(fd = fopen(fname, "r"))) { printf("can't open file `%s' for reading initial conditions.\n", fname); endrun(123); } if(All.ICFormat == 2) { SKIP; my_fread(&label, sizeof(char), 4, fd); my_fread(&nextblock, sizeof(int), 1, fd); printf("Reading header => '%c%c%c%c' (%d byte)\n", label[0], label[1], label[2], label[3], nextblock); SKIP2; } SKIP; my_fread(&header, sizeof(header), 1, fd); SKIP2; if(blksize1 != 256 || blksize2 != 256) { printf("incorrect header format\n"); fflush(stdout); endrun(890); } } #ifdef HAVE_HDF5 if(All.ICFormat == 3) { read_header_attributes_in_hdf5(fname); hdf5_file = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT); for(type = 0; type < 6; type++) { if(header.npart[type] > 0) { sprintf(buf, "/PartType%d", type); hdf5_grp[type] = H5Gopen(hdf5_file, buf); } } } #endif for(task = readTask + 1; task <= lastTask; task++) MPI_Ssend(&header, sizeof(header), MPI_BYTE, task, TAG_HEADER, MPI_COMM_WORLD); } else MPI_Recv(&header, sizeof(header), MPI_BYTE, readTask, TAG_HEADER, MPI_COMM_WORLD, &status); if(All.TotNumPart == 0) { if(header.num_files <= 1) for(i = 0; i < 6; i++) header.npartTotal[i] = header.npart[i]; All.TotN_gas = header.npartTotal[0] + (((long long) header.npartTotalHighWord[0]) << 32); for(i = 0, All.TotNumPart = 0; i < 6; i++) { All.TotNumPart += header.npartTotal[i]; All.TotNumPart += (((long long) header.npartTotalHighWord[i]) << 32); } for(i = 0; i < 6; i++) All.MassTable[i] = header.mass[i]; All.MaxPart = All.PartAllocFactor * (All.TotNumPart / NTask); /* sets the maximum number of particles that may */ All.MaxPartSph = All.PartAllocFactor * (All.TotN_gas / NTask); /* sets the maximum number of particles that may reside on a processor */ allocate_memory(); if(RestartFlag == 2) All.Time = All.TimeBegin = header.time; } if(ThisTask == readTask) { for(i = 0, n_in_file = 0; i < 6; i++) n_in_file += header.npart[i]; printf("\nreading file `%s' on task=%d (contains %d particles.)\n" "distributing this file to tasks %d-%d\n" "Type 0 (gas): %8d (tot=%6d%09d) masstab=%g\n" "Type 1 (halo): %8d (tot=%6d%09d) masstab=%g\n" "Type 2 (disk): %8d (tot=%6d%09d) masstab=%g\n" "Type 3 (bulge): %8d (tot=%6d%09d) masstab=%g\n" "Type 4 (stars): %8d (tot=%6d%09d) masstab=%g\n" "Type 5 (bndry): %8d (tot=%6d%09d) masstab=%g\n\n", fname, ThisTask, n_in_file, readTask, lastTask, header.npart[0], (int) (header.npartTotal[0] / 1000000000), (int) (header.npartTotal[0] % 1000000000), All.MassTable[0], header.npart[1], (int) (header.npartTotal[1] / 1000000000), (int) (header.npartTotal[1] % 1000000000), All.MassTable[1], header.npart[2], (int) (header.npartTotal[2] / 1000000000), (int) (header.npartTotal[2] % 1000000000), All.MassTable[2], header.npart[3], (int) (header.npartTotal[3] / 1000000000), (int) (header.npartTotal[3] % 1000000000), All.MassTable[3], header.npart[4], (int) (header.npartTotal[4] / 1000000000), (int) (header.npartTotal[4] % 1000000000), All.MassTable[4], header.npart[5], (int) (header.npartTotal[5] / 1000000000), (int) (header.npartTotal[5] % 1000000000), All.MassTable[5]); fflush(stdout); } ntask = lastTask - readTask + 1; /* to collect the gas particles all at the beginning (in case several snapshot files are read on the current CPU) we move the collisionless particles such that a gap of the right size is created */ for(type = 0, nall = 0; type < 6; type++) { n_in_file = header.npart[type]; n_for_this_task = n_in_file / ntask; if((ThisTask - readTask) < (n_in_file % ntask)) n_for_this_task++; nall += n_for_this_task; } memmove(&P[N_gas + nall], &P[N_gas], (NumPart - N_gas) * sizeof(struct particle_data)); nstart = N_gas; for(blocknr = 0; blocknr < IO_NBLOCKS; blocknr++) { if(blockpresent(blocknr)) { if(RestartFlag == 0 && blocknr > IO_U) continue; /* ignore all other blocks in initial conditions */ bytes_per_blockelement = get_bytes_per_blockelement(blocknr); blockmaxlen = ((int) (All.BufferSize * 1024 * 1024)) / bytes_per_blockelement; npart = get_particles_in_block(blocknr, &typelist[0]); if(npart > 0) { if(ThisTask == readTask) { if(All.ICFormat == 2) { SKIP; my_fread(&label, sizeof(char), 4, fd); my_fread(&nextblock, sizeof(int), 1, fd); printf("Reading header => '%c%c%c%c' (%d byte)\n", label[0], label[1], label[2], label[3], nextblock); SKIP2; if(strncmp(label, Tab_IO_Labels[blocknr], 4) != 0) { printf("incorrect block-structure!\n"); printf("expected '%c%c%c%c' but found '%c%c%c%c'\n", label[0], label[1], label[2], label[3], Tab_IO_Labels[blocknr][0], Tab_IO_Labels[blocknr][1], Tab_IO_Labels[blocknr][2], Tab_IO_Labels[blocknr][3]); fflush(stdout); endrun(1890); } } if(All.ICFormat == 1 || All.ICFormat == 2) SKIP; } for(type = 0, offset = 0; type < 6; type++) { n_in_file = header.npart[type]; #ifdef HAVE_HDF5 pcsum = 0; #endif if(typelist[type] == 0) { n_for_this_task = n_in_file / ntask; if((ThisTask - readTask) < (n_in_file % ntask)) n_for_this_task++; offset += n_for_this_task; } else { for(task = readTask; task <= lastTask; task++) { n_for_this_task = n_in_file / ntask; if((task - readTask) < (n_in_file % ntask)) n_for_this_task++; if(task == ThisTask) if(NumPart + n_for_this_task > All.MaxPart) { printf("too many particles\n"); endrun(1313); } do { pc = n_for_this_task; if(pc > blockmaxlen) pc = blockmaxlen; if(ThisTask == readTask) { if(All.ICFormat == 1 || All.ICFormat == 2) my_fread(CommBuffer, bytes_per_blockelement, pc, fd); #ifdef HAVE_HDF5 if(All.ICFormat == 3) { get_dataset_name(blocknr, buf); hdf5_dataset = H5Dopen(hdf5_grp[type], buf); dims[0] = header.npart[type]; dims[1] = get_values_per_blockelement(blocknr); if(dims[1] == 1) rank = 1; else rank = 2; hdf5_dataspace_in_file = H5Screate_simple(rank, dims, NULL); dims[0] = pc; hdf5_dataspace_in_memory = H5Screate_simple(rank, dims, NULL); start[0] = pcsum; start[1] = 0; count[0] = pc; count[1] = get_values_per_blockelement(blocknr); pcsum += pc; H5Sselect_hyperslab(hdf5_dataspace_in_file, H5S_SELECT_SET, start, NULL, count, NULL); switch (get_datatype_in_block(blocknr)) { case 0: hdf5_datatype = H5Tcopy(H5T_NATIVE_UINT); break; case 1: hdf5_datatype = H5Tcopy(H5T_NATIVE_FLOAT); break; case 2: hdf5_datatype = H5Tcopy(H5T_NATIVE_UINT64); break; } H5Dread(hdf5_dataset, hdf5_datatype, hdf5_dataspace_in_memory, hdf5_dataspace_in_file, H5P_DEFAULT, CommBuffer); H5Tclose(hdf5_datatype); H5Sclose(hdf5_dataspace_in_memory); H5Sclose(hdf5_dataspace_in_file); H5Dclose(hdf5_dataset); } #endif } if(ThisTask == readTask && task != readTask) MPI_Ssend(CommBuffer, bytes_per_blockelement * pc, MPI_BYTE, task, TAG_PDATA, MPI_COMM_WORLD); if(ThisTask != readTask && task == ThisTask) MPI_Recv(CommBuffer, bytes_per_blockelement * pc, MPI_BYTE, readTask, TAG_PDATA, MPI_COMM_WORLD, &status); if(ThisTask == task) { empty_read_buffer(blocknr, nstart + offset, pc, type); offset += pc; } n_for_this_task -= pc; } while(n_for_this_task > 0); } } } if(ThisTask == readTask) { if(All.ICFormat == 1 || All.ICFormat == 2) { SKIP2; if(blksize1 != blksize2) { printf("incorrect block-sizes detected!\n"); printf("Task=%d blocknr=%d blksize1=%d blksize2=%d\n", ThisTask, blocknr, blksize1, blksize2); fflush(stdout); endrun(1889); } } } } } } for(type = 0; type < 6; type++) { n_in_file = header.npart[type]; n_for_this_task = n_in_file / ntask; if((ThisTask - readTask) < (n_in_file % ntask)) n_for_this_task++; NumPart += n_for_this_task; if(type == 0) N_gas += n_for_this_task; } if(ThisTask == readTask) { if(All.ICFormat == 1 || All.ICFormat == 2) fclose(fd); #ifdef HAVE_HDF5 if(All.ICFormat == 3) { for(type = 5; type >= 0; type--) if(header.npart[type] > 0) H5Gclose(hdf5_grp[type]); H5Fclose(hdf5_file); } #endif } }
void get_particle_numbers(char *fname, int num_files) { char buf[1000]; int blksize1, blksize2; char label[4]; int nextblock; int i, j; printf("num_files=%d\n", num_files); for(i = 0; i < num_files; i++) { if(num_files > 1) { sprintf(buf, "%s.%d", fname, i); if(All.ICFormat == 3) sprintf(buf, "%s.%d.hdf5", fname, i); } else { sprintf(buf, "%s", fname); if(All.ICFormat == 3) sprintf(buf, "%s.hdf5", fname); } #define SKIP {my_fread(&blksize1,sizeof(int),1,fd);} #define SKIP2 {my_fread(&blksize2,sizeof(int),1,fd);} if(All.ICFormat == 1 || All.ICFormat == 2) { FILE *fd; if(!(fd = fopen(buf, "r"))) { printf("can't open file `%s' for reading initial conditions.\n", buf); endrun(1239); } if(All.ICFormat == 2) { SKIP; #ifdef AUTO_SWAP_ENDIAN_READIC swap_file = blksize1; #endif my_fread(&label, sizeof(char), 4, fd); my_fread(&nextblock, sizeof(int), 1, fd); #ifdef AUTO_SWAP_ENDIAN_READIC swap_Nbyte((char *) &nextblock, 1, 4); #endif SKIP2; } SKIP; #ifdef AUTO_SWAP_ENDIAN_READIC if(All.ICFormat == 1) { if(blksize1 != 256) swap_file = 1; } #endif my_fread(&header, sizeof(header), 1, fd); SKIP2; #ifdef AUTO_SWAP_ENDIAN_READIC swap_Nbyte((char *) &blksize1, 1, 4); swap_Nbyte((char *) &blksize2, 1, 4); #endif if(blksize1 != 256 || blksize2 != 256) { printf("incorrect header format\n"); fflush(stdout); endrun(890); } #ifdef AUTO_SWAP_ENDIAN_READIC swap_header(); #endif fclose(fd); } #ifdef HAVE_HDF5 if(All.ICFormat == 3) { read_header_attributes_in_hdf5(buf); } #endif NumPartPerFile[i] = 0; for(j = 0; j < 6; j++) { #if defined(SUBFIND_RESHUFFLE_CATALOGUE) if(((1 << j) & (FOF_PRIMARY_LINK_TYPES))) #endif NumPartPerFile[i] += header.npart[j]; } printf("File=%4d: NumPart= %d\n", i, (int) (NumPartPerFile[i])); } long long n, sum; for(i = 0, sum = 0; i < num_files; i++) { n = NumPartPerFile[i]; NumPartPerFile[i] = sum; sum += n; } }