BioDynaMo  v1.05.119-a4ff3934
multi_simulation.cc
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
15 #ifdef USE_MPI
16 
17 #include "mpi.h"
18 
19 #include "TROOT.h"
20 #include "TSystem.h"
21 
22 #include <cstdlib>
23 #include <fstream>
24 
31 
32 namespace bdm {
33 namespace experimental {
34 
35 MultiSimulation::MultiSimulation(int argc, const char** argv)
36  : argc_(argc), argv_(argv) {
37  // MPI_Init needs a non-const version of argv, so we make a deep copy
38  argv_copy_ = (char**)malloc((argc_ + 1) * sizeof(char*));
39  for (int i = 0; i < argc_; ++i) {
40  size_t length = strlen(argv_[i]) + 1;
41  argv_copy_[i] = (char*)malloc(length);
42  memcpy(argv_copy_[i], argv_[i], length);
43  }
44  argv_copy_[argc_] = nullptr;
45 }
46 
47 MultiSimulation::MultiSimulation(int argc, const char** argv, TimeSeries* real)
48  : MultiSimulation(argc, argv) {
49  // Register the real data to the database
50  auto* db = Database::GetInstance();
51  db->data_ = real;
52 }
53 
54 MultiSimulation::~MultiSimulation() {
55  for (int i = 0; i < argc_; ++i) {
56  free(argv_copy_[i]);
57  }
58  free(argv_copy_);
59 }
60 
61 int MultiSimulation::Execute(const TSimulate& simulate_call) {
62  int worldsize, provided, myrank;
63  MPI_Init_thread(&argc_, &argv_copy_, MPI_THREAD_MULTIPLE, &provided);
64  if (provided < MPI_THREAD_MULTIPLE) {
65  Log::Error("MPI_Init_thread",
66  "The threading support level is lesser than that demanded.");
67  MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
68  }
69  MPI_Comm_size(MPI_COMM_WORLD, &worldsize);
70  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
71 
72  ROOT::EnableThreadSafety();
73 
74  int status;
75  if (myrank == 0) {
76  // Make a copy of the default parameters
77  Simulation simulation(argc_, argv_);
78  Param default_params = *(simulation.GetParam());
79 
80  // Start the Master routine
81  MultiSimulationManager pem(
82  worldsize, &default_params, [&](Param* params, TimeSeries* result) {
83  return simulate_call(argc_, argv_, result, params);
84  });
85 
86  status = pem.Start();
87  } else {
88  omp_set_num_threads(2);
89  // Start the Worker routine (`params` to be received by Master)
90  Worker w(myrank, [&](Param* params, TimeSeries* result) {
91  return simulate_call(argc_, argv_, result, params);
92  });
93  status = w.Start();
94  }
95 
96  MPI_Finalize();
97  return status;
98 }
99 
100 } // namespace experimental
101 } // namespace bdm
102 
103 #endif // USE_MPI
bdm
Definition: agent.cc:39
optimization_param.h
multi_simulation.h
bdm::experimental::Database::GetInstance
static Database * GetInstance()
Definition: database.h:31
time_series.h
command_line_options.h
bdm::Log::Error
static void Error(const std::string &location, const Args &... parts)
Prints error message.
Definition: log.h:79
database.h
multi_simulation_manager.h