GADGET-4
main.cc
Go to the documentation of this file.
1/*******************************************************************************
2 * \copyright This file is part of the GADGET4 N-body/SPH code developed
3 * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4 * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5 *******************************************************************************/
6
12#include "gadgetconfig.h"
13
14#include <gsl/gsl_math.h>
15#include <math.h>
16#include <mpi.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <time.h>
21
22#include "../cooling_sfr/cooling.h"
23#include "../data/allvars.h"
24#include "../data/dtypes.h"
25#include "../half/half.hpp"
26#include "../io/io.h"
27#include "../io/restart.h"
28#include "../io/snap_io.h"
29#include "../logs/logs.h"
30#include "../main/main.h"
31#include "../main/simulation.h"
32#include "../mergertree/mergertree.h"
33#include "../mpi_utils/shared_mem_handler.h"
34#include "../ngenic/ngenic.h"
35#include "../system/system.h"
36#include "../time_integration/driftfac.h"
37
38/* create instances of global objects */
39
42ewald Ewald; /* get an instance of the Ewald correction tables */
44memory Mem; /* our instance of the memory object */
46
55int main(int argc, char **argv)
56{
57 /* find out how many core we have per CPU and which ones we can use */
58 pinning Pin;
59 Pin.detect_topology();
60 Pin.get_core_set();
61
62 /* initialize MPI, this may already impose some pinning */
63 MPI_Init(&argc, &argv);
64
65 MPI_Comm_rank(MPI_COMM_WORLD, &Shmem.World_ThisTask);
66 MPI_Comm_size(MPI_COMM_WORLD, &Shmem.World_NTask);
67
68#if NUMBER_OF_MPI_LISTENERS_PER_NODE > 1
69 MPI_Comm fullsharedmemnode;
70 MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &fullsharedmemnode);
71
72 int fullsharedmemnode_ThisTask, fullsharedmemnode_NTask;
73 MPI_Comm_rank(fullsharedmemnode, &fullsharedmemnode_ThisTask);
74 MPI_Comm_size(fullsharedmemnode, &fullsharedmemnode_NTask);
75
76 int bin;
77 subdivide_evenly_get_bin(fullsharedmemnode_NTask, NUMBER_OF_MPI_LISTENERS_PER_NODE, fullsharedmemnode_ThisTask, &bin);
78
79 MPI_Comm_split(fullsharedmemnode, bin, fullsharedmemnode_ThisTask, &Shmem.SharedMemComm);
80#else
81 MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &Shmem.SharedMemComm);
82#endif
83
85 MPI_Comm_size(Shmem.SharedMemComm, &Shmem.Island_NTask);
86
87 int min_ntask, max_ntask;
88 MPI_Allreduce(&Shmem.Island_NTask, &max_ntask, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
89 MPI_Allreduce(&Shmem.Island_NTask, &min_ntask, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
90 MPI_Allreduce(&Shmem.World_ThisTask, &Shmem.Island_Smallest_WorldTask, 1, MPI_INT, MPI_MIN, Shmem.SharedMemComm);
91
92 if(Shmem.World_ThisTask == 0)
93 printf("Shared memory islands host a minimum of %d and a maximum of %d MPI ranks.\n", min_ntask, max_ntask);
94
95 Shmem.GhostRank = 0;
96
97 if(max_ntask < Shmem.World_NTask)
98 {
99 if(Shmem.Island_ThisTask == Shmem.Island_NTask - 1) // selected the ghost MPI ranks
100 Shmem.GhostRank = 1;
101
102 if(min_ntask > 1)
103 {
104 int comm_ranks;
105 MPI_Allreduce(&Shmem.GhostRank, &comm_ranks, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
106
107 if(Shmem.World_ThisTask == 0)
108 printf("We shall use %d MPI ranks in total for assisting one-sided communication (%d per shared memory node).\n",
110 }
111 else
112 {
113 if(Shmem.World_ThisTask == 0)
114 Terminate("We have shared memory islands with just one MPI rank -- can't put aside this one just for communication");
115 }
116
118 {
119 if(Shmem.World_ThisTask == 0)
120 Terminate(
121 "We have shared memory islands with %d MPI ranks, which is larger than MAX_NUMBER_OF_RANKS_WITH_SHARED_MEMORY=%d\n"
122 "You may consider increasing NUMBER_OF_MPI_LISTENERS_PER_NODE, current value is %d\n",
124 }
125 }
126
127 /* we can now split the communicator into the processing ones, and the ones reserved for communication */
128 MPI_Comm_split(MPI_COMM_WORLD, Shmem.GhostRank, Shmem.World_ThisTask, &Shmem.SimulationComm);
129
130 MPI_Comm_rank(Shmem.SimulationComm, &Shmem.Sim_ThisTask);
131 MPI_Comm_size(Shmem.SimulationComm, &Shmem.Sim_NTask);
132
133 /* Let's now find out for everyone the global rank of the responsible shared memory ghost */
135
136 MPI_Bcast(&Shmem.MyShmRankInGlobal, 1, MPI_INT, Shmem.Island_NTask - 1, Shmem.SharedMemComm);
137
138 if(Shmem.GhostRank == 1)
139 {
141 Shmem.shared_memory_handler(); // note: this call will not return
142 }
143
144 /* creating main simulation object, holding all the data and objects of our simulation */
146
147 Sim.determine_compute_nodes();
148
149 /* initialize the communicator structures of our global objects */
150 Ewald.initcomm(Sim.Communicator); // a global class
151 Logs.initcomm(Sim.Communicator); // a global class
152 All.initcomm(Sim.Communicator); // a global class
153 Mem.initcomm(Sim.Communicator); // a global class
155
156 /* output a welcome message */
157 Sim.hello();
158
159 /* initialize CPU-time/Wallclock-time measurement */
160 Logs.init_cpu_log(&Sim.Sp);
161
162 /* pin the MPI ranks to the available core set */
163 Pin.pin_to_core_set(&Sim);
164
165#ifdef HOST_MEMORY_REPORTING
166 Sim.mpi_report_comittable_memory();
167 Mem.MemoryOnNode = Sim.MemoryOnNode;
168 Mem.SharedMemoryOnNode = Sim.SharedMemoryOnNode;
169#endif
170
171 if(argc < 2)
172 {
173 if(Sim.ThisTask == 0)
174 {
175 printf("\nParameters are missing.\n");
176 printf("Start as ./Gadget4 <ParameterFile> [<RestartFlag>] [<SpecialOptions>]\n");
177 printf("\n");
178 printf(" RestartFlag Action\n");
179 printf(" %2d Read initial conditions and start simulation\n", RST_BEGIN);
180 printf(" %2d Read restart files and resume simulation\n", RST_RESUME);
181 printf(" %2d Restart from specified snapshot dump and resume simulation\n", RST_STARTFROMSNAP);
182 printf(" %2d Run FOF and optionally SUBFIND\n", RST_FOF);
183 printf(" %2d Calculate a matter power spectrum\n", RST_POWERSPEC);
184 printf(" %2d Convert snapshot file to different format [input=ICFormat output=SnapFormat\n", RST_CONVERTSNAP);
185 printf(" %2d Create cosmological initial conditions\n", RST_CREATEICS);
186 printf(" %2d Calculate descendants/progenitors [connecting group catalogues SnapNum-1 and SnapNum]\n",
188 printf(" %2d Arrange halos in merger trees [using group catalogues up to SnapNum]\n", RST_MAKETREES);
189 printf(" %2d Carry out I/O bandwidth test to determine best setting for number of concurrent reads/writes\n",
191 printf(" %2d Rearrange particle-lightcone data in merger tree order <conenr> <firstnum> <lastnum>\n",
193 printf(" %2d Rearrange most-bound snapshot data in merger tree order <firstnum> <lastnum>\n",
195 printf("\n");
196 }
197 Sim.endrun();
198 }
199
200 /* argv[1] holds the parameterfile */
201
202 if(argc >= 3)
203 All.RestartFlag = (enum restart_options)atoi(argv[2]);
204 else
206
207 int restartSnapNum = -1;
208 if(argc >= 4)
209 restartSnapNum = atoi(argv[3]);
210
211 /* Do minimal validation of arguments here rather than in random places in the code */
214 restartSnapNum < 0)
215 {
216 Terminate("Need to give the snapshot number for the chosen option.\n");
217 }
218
219 /* set-up run based on parameterfile */
220 Sim.begrun1(argv[1]);
221
222 /* see if we are loading a restart file or an IC file */
224 {
225 restart Restart{Sim.Communicator};
226 Restart.load(&Sim);
227 All.RestartFlag = RST_RESUME; // prevent that this is overwritten by All.RestartFlag in restart set
228 }
229 else
230 {
231 /* We're reading an IC file. Is it a snapshot or really an IC? */
232 char fname[MAXLEN_PATH_EXTRA];
233
234 if(All.RestartFlag != RST_BEGIN && All.RestartFlag != RST_RESUME && restartSnapNum >= 0)
235 {
237 sprintf(fname, "%s/snapdir_%03d/%s_%03d", All.OutputDir, restartSnapNum, All.SnapshotFileBase, restartSnapNum);
238 else
239 sprintf(fname, "%s%s_%03d", All.OutputDir, All.SnapshotFileBase, restartSnapNum);
240 }
241 else
242 {
243 strcpy(fname, All.InitCondFile);
244 }
245
247 {
249 }
250
252 {
253#ifdef MERGERTREE
254 Sim.MergerTree.descendants_in_postprocessing(restartSnapNum);
255 Sim.endrun();
256#else
257 Terminate("Compile with option MERGERTREE for this option");
258#endif
259 }
260
262 {
263#ifdef MERGERTREE
264 Sim.MergerTree.halotrees_construct(restartSnapNum);
265 Sim.endrun();
266#else
267 Terminate("Compile with option MERGERTREE for this option");
268#endif
269 }
270
272 {
273 Sim.measure_io_bandwidth();
274 Sim.endrun();
275 }
276
278 {
279#if defined(LIGHTCONE) && defined(LIGHTCONE_PARTICLES) && defined(REARRANGE_OPTION)
280 Sim.rearrange_lightcone(argc, argv);
281#else
282 Terminate("need to compile with REARRANGE_OPTION for this option to work\n");
283#endif
284 Sim.endrun();
285 }
286
288 {
289#if defined(MERGERTREE) && defined(REARRANGE_OPTION)
290 Sim.rearrange_snapshot(argc, argv);
291#else
292 Terminate("need to compile with REARRANGE_OPTION for this option to work\n");
293#endif
294 Sim.endrun();
295 }
296
297#ifdef CREATE_GRID
299 Sim.Ngenic.create_grid();
300 else
301#endif
302 {
303 snap_io Snap(&Sim.Sp, Sim.Communicator, All.ICFormat); /* get an I/O object */
304
305 Snap.read_ic(fname);
306 }
307
308 /* If we are supposed to just convert the file, write and exit here. */
310 {
311#ifdef COOLING
312 Sim.CoolSfr.InitCool();
313#endif
314 strcat(All.SnapshotFileBase, "_converted");
315 Sim.mpi_printf("Start writing file %s\nSnapNum %d\n", All.SnapshotFileBase, restartSnapNum);
316
317 snap_io Snap(&Sim.Sp, Sim.Communicator, All.SnapFormat); /* get an I/O object */
318 Snap.write_snapshot(restartSnapNum, NORMAL_SNAPSHOT);
319
320 Sim.endrun();
321 }
322
323 Sim.init(restartSnapNum);
324 }
325
326 Sim.begrun2();
327
328 Sim.run(); /* main simulation loop */
329
330 Sim.endrun(); /* clean up & finalize MPI */
331
332 return 0;
333}
Ewald correction functionality.
Definition: ewald.h:54
Definition: logs.h:28
void init_cpu_log(simparticles *Sp_ptr)
Definition: logs.cc:296
void get_core_set(void)
Definition: pinning.cc:25
void detect_topology(void)
Definition: pinning.cc:33
void pin_to_core_set(setcomm *sc)
Definition: pinning.cc:69
long long MemoryOnNode
Definition: setcomm.h:42
void determine_compute_nodes(void)
Definition: setcomm.h:98
MPI_Comm Communicator
Definition: setcomm.h:31
long long SharedMemoryOnNode
Definition: setcomm.h:43
void initcomm(MPI_Comm Comm)
Definition: setcomm.h:45
MPI_Comm SharedMemComm
void shared_memory_handler(void)
int Island_ThisTask
int Island_NTask
MPI_Comm SimulationComm
int Island_Smallest_WorldTask
int Sim_ThisTask
int MyShmRankInGlobal
int World_ThisTask
Definition: simulation.h:50
void read_ic(const char *fname)
This function reads initial conditions that are in on of the default file formats of Gadget.
Definition: snap_io.cc:289
void write_snapshot(int num, mysnaptype snap_type)
Save snapshot to disk.
Definition: snap_io.cc:559
#define MAXLEN_PATH_EXTRA
Definition: constants.h:301
#define NUMBER_OF_MPI_LISTENERS_PER_NODE
Definition: dtypes.h:126
@ NORMAL_SNAPSHOT
Definition: dtypes.h:306
#define MAX_NUMBER_OF_RANKS_WITH_SHARED_MEMORY
Definition: dtypes.h:130
restart_options
Definition: dtypes.h:312
@ RST_CONVERTSNAP
Definition: dtypes.h:318
@ RST_LCREARRANGE
Definition: dtypes.h:323
@ RST_STARTFROMSNAP
Definition: dtypes.h:315
@ RST_POWERSPEC
Definition: dtypes.h:317
@ RST_CREATEICS
Definition: dtypes.h:319
@ RST_MAKETREES
Definition: dtypes.h:321
@ RST_IOBANDWIDTH
Definition: dtypes.h:322
@ RST_FOF
Definition: dtypes.h:316
@ RST_SNPREARRANGE
Definition: dtypes.h:324
@ RST_BEGIN
Definition: dtypes.h:313
@ RST_RESUME
Definition: dtypes.h:314
@ RST_CALCDESC
Definition: dtypes.h:320
#define Terminate(...)
Definition: macros.h:15
logs Logs
Definition: main.cc:43
memory Mem
Definition: main.cc:44
int main(int argc, char **argv)
Definition: main.cc:55
global_data_all_processes All
Definition: main.cc:40
shmem Shmem
Definition: main.cc:45
ewald Ewald
Definition: main.cc:42
driftfac Driftfac
Definition: main.cc:41
enum restart_options RestartFlag
Definition: allvars.h:68
char OutputDir[MAXLEN_PATH]
Definition: allvars.h:272
char SnapshotFileBase[MAXLEN_PATH]
Definition: allvars.h:272
char InitCondFile[MAXLEN_PATH]
Definition: allvars.h:272
void subdivide_evenly_get_bin(int N, int pieces, int index, int *bin)
Definition: system.cc:70