Repository navigation
Expand file tree
/
Copy pathmessage_passing.h
More file actions
90 lines (76 loc) · 2.99 KB
/
Copy pathmessage_passing.h
File metadata and controls
90 lines (76 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#ifndef OPENMC_MESSAGE_PASSING_H
#define OPENMC_MESSAGE_PASSING_H
#include <cstddef>
#include <cstdint>
#ifdef OPENMC_MPI
#include <mpi.h>
#endif
#include "openmc/vector.h"
namespace openmc {
namespace mpi {
extern int rank;
extern int n_procs;
extern bool master;
#ifdef OPENMC_MPI
extern MPI_Datatype source_site;
extern MPI_Datatype collision_track_site;
extern MPI_Comm intracomm;
//==============================================================================
// Template struct used to map types to MPI datatypes
// By having a single static data member, the template can
// be specialized for each type we know of. The specializations appear in the
// .cpp file since they are definitions.
//==============================================================================
template<typename T>
struct MPITypeMap {
static const MPI_Datatype mpi_type;
};
//! Broadcast a contiguous array without narrowing the element count.
//
//! \param buffer Input buffer on the root process, output on other processes
//! \param count Number of elements in the buffer
//! \param datatype MPI datatype of each element
//! \param type_size Size of each element in bytes
//! \param root Rank of the root process
//! \param comm Communicator over which to perform the broadcast
void broadcast_buffer(void* buffer, std::size_t count, MPI_Datatype datatype,
std::size_t type_size, int root, MPI_Comm comm);
template<typename T>
void broadcast(T* buffer, std::size_t count, int root, MPI_Comm comm)
{
broadcast_buffer(
buffer, count, MPITypeMap<T>::mpi_type, sizeof(T), root, comm);
}
//! Reduce an array without narrowing the element count.
//
//! \param sendbuf Input buffer, or MPI_IN_PLACE on the root process
//! \param recvbuf Output buffer on the root process; ignored on other processes
//! \param count Number of elements in each buffer
//! \param op Operation to apply during the reduction
//! \param root Rank of the root process
//! \param comm Communicator over which to perform the reduction
void reduce_buffer(const void* sendbuf, void* recvbuf, std::size_t count,
MPI_Datatype datatype, std::size_t type_size, MPI_Op op, int root,
MPI_Comm comm);
template<typename T>
void reduce(const void* sendbuf, T* recvbuf, std::size_t count, MPI_Op op,
int root, MPI_Comm comm)
{
reduce_buffer(sendbuf, recvbuf, count, MPITypeMap<T>::mpi_type, sizeof(T), op,
root, comm);
}
#endif
// Calculates global indices of the bank particles
// across all ranks using a parallel scan. This is used to write
// the surface source file in parallel runs. It will probably
// be used in the future for other types of bank like particles
// in flight used to kick off transient simulations.
//
// More abstractly, this just takes a number from each MPI rank,
// and returns a vector which is the exclusive parallel scan across
// all of those numbers, having a length of the number of MPI ranks
// plus one.
vector<int64_t> calculate_parallel_index_vector(int64_t size);
} // namespace mpi
} // namespace openmc
#endif // OPENMC_MESSAGE_PASSING_H