mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-21 06:25:30 -04:00
650 lines
30 KiB
ReStructuredText
650 lines
30 KiB
ReStructuredText
.. _methods_parallel:
|
|
|
|
===============
|
|
Parallelization
|
|
===============
|
|
|
|
Due to the computationally-intensive nature of Monte Carlo methods, there has
|
|
been an ever-present interest in parallelizing such simulations. Even in the
|
|
`first paper`_ on the Monte Carlo method, John Metropolis and Stanislaw Ulam
|
|
recognized that solving the Boltzmann equation with the Monte Carlo method could
|
|
be done in parallel very easily whereas the deterministic counterparts for
|
|
solving the Boltzmann equation did not offer such a natural means of
|
|
parallelism. With the introduction of `vector computers`_ in the early 1970s,
|
|
general-purpose parallel computing became a reality. In 1972, Troubetzkoy et
|
|
al. designed a Monte Carlo code to be run on the first vector computer, the
|
|
ILLIAC-IV [Troubetzkoy]_. The general principles from that work were later
|
|
refined and extended greatly through the `work of Forrest Brown`_ in the
|
|
1980s. However, as Brown's work shows, the `single-instruction multiple-data`_
|
|
(SIMD) parallel model inherent to vector processing does not lend itself to the
|
|
parallelism on particles in Monte Carlo simulations. Troubetzkoy et
|
|
al. recognized this, remarking that "the order and the nature of these physical
|
|
events have little, if any, correlation from history to history," and thus
|
|
following independent particle histories simultaneously using a SIMD model is
|
|
difficult.
|
|
|
|
The difficulties with vector processing of Monte Carlo codes led to the adoption
|
|
of the `single program multiple data`_ (SPMD) technique for parallelization. In
|
|
this model, each different process tracks a particle independently of other
|
|
processes, and between fission source generations the processes communicate data
|
|
through a `message-passing interface`_. This means of parallelism was enabled by
|
|
the introduction of message-passing standards in the late 1980s and early 1990s
|
|
such as PVM_ and MPI_. The SPMD model proved much easier to use in practice and
|
|
took advantage of the inherent parallelism on particles rather than
|
|
instruction-level parallelism. As a result, it has since become ubiquitous for
|
|
Monte Carlo simulations of transport phenomena.
|
|
|
|
Thanks to the particle-level parallelism using SPMD techniques, extremely high
|
|
parallel efficiencies could be achieved in Monte Carlo codes. Until the last
|
|
decade, even the most demanding problems did not require transmitting large
|
|
amounts of data between processors, and thus the total amount of time spent on
|
|
communication was not significant compared to the amount of time spent on
|
|
computation. However, today's computing power has created a demand for
|
|
increasingly large and complex problems, requiring a greater number of particles
|
|
to obtain decent statistics (and convergence in the case of criticality
|
|
calculations). This results in a correspondingly higher amount of communication,
|
|
potentially degrading the parallel efficiency. Thus, while Monte Carlo
|
|
simulations may seem `embarrassingly parallel`_, obtaining good parallel scaling
|
|
with large numbers of processors can be quite difficult to achieve in practice.
|
|
|
|
.. _fission-bank-algorithms:
|
|
|
|
-----------------------
|
|
Fission Bank Algorithms
|
|
-----------------------
|
|
|
|
Master-Slave Algorithm
|
|
----------------------
|
|
|
|
Monte Carlo particle transport codes commonly implement a SPMD model by having
|
|
one master process that controls the scheduling of work and the remaining
|
|
processes wait to receive work from the master, process the work, and then send
|
|
their results to the master at the end of the simulation (or a source iteration
|
|
in the case of an eigenvalue calculation). This idea is illustrated in
|
|
:ref:`figure-master-slave`.
|
|
|
|
.. _figure-master-slave:
|
|
|
|
.. figure:: ../_images/master-slave.png
|
|
:align: center
|
|
:figclass: align-center
|
|
|
|
Communication pattern in master-slave algorithm.
|
|
|
|
Eigenvalue calculations are slightly more difficult to parallelize than fixed
|
|
source calculations since it is necessary to converge on the fission source
|
|
distribution and eigenvalue before tallying. In the
|
|
:ref:`method-successive-generations`, to ensure that the results are
|
|
reproducible, one must guarantee that the process by which fission sites are
|
|
randomly sampled does not depend on the number of processors. What is typically
|
|
done is the following:
|
|
|
|
1. Each compute node sends_ its fission bank sites to a master process;
|
|
|
|
2. The master process sorts or orders the fission sites based on a unique
|
|
identifier;
|
|
|
|
3. The master process samples :math:`N` fission sites from the ordered array
|
|
of :math:`M` sites; and
|
|
|
|
4. The master process broadcasts_ all the fission sites to the compute
|
|
nodes.
|
|
|
|
The first and last steps of this process are the major sources of communication
|
|
overhead between cycles. Since the master process must receive :math:`M` fission
|
|
sites from the compute nodes, the first step is necessarily serial. This step
|
|
can be completed in :math:`O(M)` time. The broadcast step can benefit from
|
|
parallelization through a tree-based algorithm. Despite this, the communication
|
|
overhead is still considerable.
|
|
|
|
To see why this is the case, it is instructive to look at a hypothetical
|
|
example. Suppose that a calculation is run with :math:`N = 10,000,000` neutrons
|
|
across 64 compute nodes. On average, :math:`M = 10,000,000` fission sites will
|
|
be produced. If the data for each fission site consists of a spatial location
|
|
(three 8 byte real numbers) and a unique identifier (one 4 byte integer), the
|
|
memory required per site is 28 bytes. To broadcast 10,000,000 source sites to 64
|
|
nodes will thus require transferring 17.92 GB of data. Since each compute node
|
|
does not need to keep every source site in memory, one could modify the
|
|
algorithm from a broadcast to a scatter_. However, for practical reasons
|
|
(e.g. work self-scheduling), this is normally not done in production Monte Carlo
|
|
codes.
|
|
|
|
.. _nearest-neighbors-algorithm:
|
|
|
|
Nearest Neighbors Algorithm
|
|
---------------------------
|
|
|
|
To reduce the amount of communication required in a fission bank synchronization
|
|
algorithm, it is desirable to move away from the typical master-slave algorithm
|
|
to an algorithm whereby the compute nodes communicate with one another only as
|
|
needed. This concept is illustrated in :ref:`figure-nearest-neighbor`.
|
|
|
|
.. _figure-nearest-neighbor:
|
|
|
|
.. figure:: ../_images/nearest-neighbor.png
|
|
:align: center
|
|
:figclass: align-center
|
|
|
|
Communication pattern in nearest neighbor algorithm.
|
|
|
|
Since the source sites for each cycle are sampled from the fission sites banked
|
|
from the previous cycle, it is a common occurrence for a fission site to be
|
|
banked on one compute node and sent back to the master only to get sent back to
|
|
the same compute node as a source site. As a result, much of the communication
|
|
inherent in the algorithm described previously is entirely unnecessary. By
|
|
keeping the fission sites local, having each compute node sample fission sites,
|
|
and sending sites between nodes only as needed, one can cut down on most of the
|
|
communication. One algorithm to achieve this is as follows:
|
|
|
|
1. An exclusive scan is performed on the number of sites banked, and the
|
|
total number of fission bank sites is broadcasted to all compute nodes. By
|
|
picturing the fission bank as one large array distributed across multiple
|
|
nodes, one can see that this step enables each compute node to determine the
|
|
starting index of fission bank sites in this array. Let us call the starting
|
|
and ending indices on the :math:`i`-th node :math:`a_i` and :math:`b_i`,
|
|
respectively;
|
|
|
|
2. Each compute node samples sites at random from the fission bank using the
|
|
same starting seed. A separate array on each compute node is created that
|
|
consists of sites that were sampled local to that node, i.e. if the index of
|
|
the sampled site is between :math:`a_i` and :math:`b_i`, it is set aside;
|
|
|
|
3. If any node sampled more than :math:`N/p` fission sites where :math:`p`
|
|
is the number of compute nodes, the extra sites are put in a separate array
|
|
and sent to all other compute nodes. This can be done efficiently using the
|
|
allgather_ collective operation;
|
|
|
|
4. The extra sites are divided among those compute nodes that sampled fewer
|
|
than :math:`N/p` fission sites.
|
|
|
|
However, even this algorithm exhibits more communication than necessary since
|
|
the allgather will send fission bank sites to nodes that don't necessarily
|
|
need any extra sites.
|
|
|
|
One alternative is to replace the allgather with a series of sends. If
|
|
:math:`a_i` is less than :math:`iN/p`, then send :math:`iN/p - a_i` sites to the
|
|
left adjacent node. Similarly, if :math:`a_i` is greater than :math:`iN/p`, then
|
|
receive :math:`a_i - iN/p` from the left adjacent node. This idea is applied to
|
|
the fission bank sites at the end of each node's array as well. If :math:`b_i`
|
|
is less than :math:`(i+1)N/p`, then receive :math:`(i+1)N/p - b_i` sites from
|
|
the right adjacent node. If :math:`b_i` is greater than :math:`(i+1)N/p`, then
|
|
send :math:`b_i - (i+1)N/p` sites to the right adjacent node. Thus, each compute
|
|
node sends/receives only two messages under normal circumstances.
|
|
|
|
The following example illustrates how this algorithm works. Let us suppose we
|
|
are simulating :math:`N = 1000` neutrons across four compute nodes. For this
|
|
example, it is instructive to look at the state of the fission bank and source
|
|
bank at several points in the algorithm:
|
|
|
|
1. The beginning of a cycle where each node has :math:`N/p` source sites;
|
|
|
|
2. The end of a cycle where each node has accumulated fission sites;
|
|
|
|
3. After sampling, where each node has some amount of source sites usually
|
|
not equal to :math:`N/p`;
|
|
|
|
4. After redistribution, each node again has :math:`N/p` source sites for
|
|
the next cycle;
|
|
|
|
At the end of each cycle, each compute node needs 250 fission bank sites to
|
|
continue on the next cycle. Let us suppose that :math:`p_0` produces 270 fission
|
|
banks sites, :math:`p_1` produces 230, :math:`p_2` produces 290, and :math:`p_3`
|
|
produces 250. After each node samples from its fission bank sites, let's assume
|
|
that :math:`p_0` has 260 source sites, :math:`p_1` has 215, :math:`p_2` has 280,
|
|
and :math:`p_3` has 245. Note that the total number of sampled sites is 1000 as
|
|
needed. For each node to have the same number of source sites, :math:`p_0` needs
|
|
to send its right-most 10 sites to :math:`p_1`, and :math:`p_2` needs to send
|
|
its left-most 25 sites to :math:`p_1` and its right-most 5 sites to
|
|
:math:`p_3`. A schematic of this example is shown in
|
|
:ref:`figure-neighbor-example`. The data local to each node is given a different
|
|
hatching, and the cross-hatched regions represent source sites that are
|
|
communicated between adjacent nodes.
|
|
|
|
.. _figure-neighbor-example:
|
|
|
|
.. figure:: ../_images/nearest-neighbor-example.png
|
|
:align: center
|
|
:figclass: align-center
|
|
|
|
Example of nearest neighbor algorithm.
|
|
|
|
.. _master-slave-cost:
|
|
|
|
Cost of Master-Slave Algorithm
|
|
------------------------------
|
|
|
|
While the prior considerations may make it readily apparent that the novel
|
|
algorithm should outperform the traditional algorithm, it is instructive to look
|
|
at the total communication cost of the novel algorithm relative to the
|
|
traditional algorithm. This is especially so because the novel algorithm does
|
|
not have a constant communication cost due to stochastic fluctuations. Let us
|
|
begin by looking at the cost of communication in the traditional algorithm
|
|
|
|
As discussed earlier, the traditional algorithm is composed of a series of sends
|
|
and typically a broadcast. To estimate the communication cost of the algorithm,
|
|
we can apply a simple model that captures the essential features. In this model,
|
|
we assume that the time that it takes to send a message between two nodes is
|
|
given by :math:`\alpha + (sN)\beta`, where :math:`\alpha` is the time it takes
|
|
to initiate the communication (commonly called the latency_), :math:`\beta` is
|
|
the transfer time per unit of data (commonly called the bandwidth_), :math:`N`
|
|
is the number of fission sites, and :math:`s` is the size in bytes of each
|
|
fission site.
|
|
|
|
The first step of the traditional algorithm is to send :math:`p` messages to the
|
|
master node, each of size :math:`sN/p`. Thus, the total time to send these
|
|
messages is
|
|
|
|
.. math::
|
|
:label: t-send
|
|
|
|
t_{\text{send}} = p\alpha + sN\beta.
|
|
|
|
Generally, the best parallel performance is achieved in a weak scaling scheme
|
|
where the total number of histories is proportional to the number of
|
|
processors. However, we see that when :math:`N` is proportional to :math:`p`,
|
|
the time to send these messages increases proportionally with :math:`p`.
|
|
|
|
Estimating the time of the broadcast is complicated by the fact that different
|
|
MPI implementations may use different algorithms to perform collective
|
|
communications. Worse yet, a single implementation may use a different algorithm
|
|
depending on how many nodes are communicating and the size of the message. Using
|
|
multiple algorithms allows one to minimize latency for small messages and
|
|
minimize bandwidth for long messages.
|
|
|
|
We will focus here on the implementation of broadcast in the MPICH_
|
|
implementation. For short messages, MPICH uses a `binomial tree`_ algorithm. In
|
|
this algorithm, the root process sends the data to one node in the first step,
|
|
and then in the subsequent, both the root and the other node can send the data
|
|
to other nodes. Thus, it takes a total of :math:`\lceil \log_2 p \rceil` steps
|
|
to complete the communication. The time to complete the communication is
|
|
|
|
.. math::
|
|
:label: t-short
|
|
|
|
t_{\text{short}} = \lceil \log_2 p \rceil \left ( \alpha + sN\beta \right ).
|
|
|
|
This algorithm works well for short messages since the latency term scales
|
|
logarithmically with the number of nodes. However, for long messages, an
|
|
algorithm that has lower bandwidth has been proposed by Barnett_ and implemented
|
|
in MPICH. Rather than using a binomial tree, the broadcast is divided into a
|
|
scatter and an allgather. The time to complete the scatter is :math:` \log_2 p
|
|
\: \alpha + \frac{p-1}{p} N\beta` using a binomial tree algorithm. The allgather
|
|
is performed using a ring algorithm that completes in :math:`p-1) \alpha +
|
|
\frac{p-1}{p} N\beta`. Thus, together the time to complete the broadcast is
|
|
|
|
.. math::
|
|
:label: t-broadcast
|
|
|
|
t_{\text{long}} = \left ( \log_2 p + p - 1 \right ) \alpha + 2 \frac{p-1}{p}
|
|
sN\beta.
|
|
|
|
The fission bank data will generally exceed the threshold for switching from
|
|
short to long messages (typically 8 kilobytes), and thus we will use the
|
|
equation for long messages. Adding equations :eq:`t-send` and :eq:`t-broadcast`,
|
|
the total cost of the series of sends and the broadcast is
|
|
|
|
.. math::
|
|
:label: t-old
|
|
|
|
t_{\text{old}} = \left ( \log_2 p + 2p - 1 \right ) \alpha + \frac{3p-2}{p}
|
|
sN\beta.
|
|
|
|
Cost of Nearest Neighbor Algorithm
|
|
----------------------------------
|
|
|
|
With the communication cost of the traditional fission bank algorithm
|
|
quantified, we now proceed to discuss the communication cost of the proposed
|
|
algorithm. Comparing the cost of communication of this algorithm with the
|
|
traditional algorithm is not trivial due to fact that the cost will be a
|
|
function of how many fission sites are sampled on each node. If each node
|
|
samples exactly :math:`N/p` sites, there will not be communication between nodes
|
|
at all. However, if any one node samples more or less than :math:`N/p` sites,
|
|
the deviation will result in communication between logically adjacent nodes. To
|
|
determine the expected deviation, one can analyze the process based on the
|
|
fundamentals of the Monte Carlo process.
|
|
|
|
The steady-state neutron transport equation for a multiplying medium can be
|
|
written in the form of an eigenvalue problem,
|
|
|
|
.. math::
|
|
:label: NTE
|
|
|
|
S(\mathbf{r})= \frac{1}{k} \int F(\mathbf{r}' \rightarrow
|
|
\mathbf{r})S(\mathbf{r}')\: d\mathbf{r},
|
|
|
|
where :math:`\mathbf{r}` is the spatial coordinates of the neutron,
|
|
:math:`S(\mathbf{r})` is the source distribution defined as the expected number
|
|
of neutrons born from fission per unit phase-space volume at :math:`\mathbf{r}`,
|
|
:math:`F( \mathbf{r}' \rightarrow \mathbf{r})` is the expected number of
|
|
neutrons born from fission per unit phase space volume at :math:`\mathbf{r}`
|
|
caused by a neutron at :math:`\mathbf{r}`, and :math:`k` is the eigenvalue. The
|
|
fundamental eigenvalue of equation :eq:`NTE` is known as :math:`k_{eff}`, but
|
|
for simplicity we will simply refer to it as :math:`k`.
|
|
|
|
In a Monte Carlo criticality simulation, the power iteration method is applied
|
|
iteratively to obtain stochastic realizations of the source distribution and
|
|
estimates of the :math:`k`-eigenvalue. Let us define :math:`\hat{S}^{(m)}` to be
|
|
the realization of the source distribution at cycle :math:`m` and
|
|
:math:`\hat{\epsilon}^{(m)}` be the noise arising from the stochastic nature of
|
|
the tracking process. We can write the stochastic realization in terms of the
|
|
fundamental source distribution and the noise component as (see `Brissenden and
|
|
Garlick`_):
|
|
|
|
.. math::
|
|
:label: source
|
|
|
|
\hat{S}^{(m)}(\mathbf{r})= N S(\mathbf{r}) + \sqrt{N}
|
|
\hat{\epsilon}^{(m)}(\mathbf{r}),
|
|
|
|
where :math:`N` is the number of particle histories per cycle. Without loss of
|
|
generality, we shall drop the superscript notation indicating the cycle as it is
|
|
understood that the stochastic realization is at a particular cycle. The
|
|
expected value of the stochastic source distribution is simply
|
|
|
|
.. math::
|
|
:label: expected-value-source
|
|
|
|
E \left[ \hat{S}(\mathbf{r})\right] = N S (\mathbf{r})
|
|
|
|
since :math:`E \left[ \hat{\epsilon}(\mathbf{r})\right] = 0`. The noise in the
|
|
source distribution is due only to :math:`\hat{\epsilon}(\mathbf{r})` and thus
|
|
the variance of the source distribution will be
|
|
|
|
.. math::
|
|
:label: var-source
|
|
|
|
\text{Var} \left[ \hat{S}(\mathbf{r})\right] = N \text{Var} \left[
|
|
\hat{\epsilon}(\mathbf{r}) \right].
|
|
|
|
Lastly, the stochastic and true eigenvalues can be written as integrals over all
|
|
phase space of the stochastic and true source distributions, respectively, as
|
|
|
|
.. math::
|
|
:label: k-to-source
|
|
|
|
\hat{k} = \frac{1}{N} \int \hat{S}(\mathbf{r}) \: d\mathbf{r} \quad
|
|
\text{and} \quad k = \int S(\mathbf{r}) \: d\mathbf{r},
|
|
|
|
noting that :math:`S(\mathbf{r})` is :math:`O(1)`. One should note that the
|
|
expected value :math:`k` calculated by Monte Carlo power iteration (i.e. the
|
|
method of successive generations) will be biased from the true fundamental
|
|
eigenvalue of equation :eq:`NTE` by :math:`O(1/N)` (see `Brissenden and
|
|
Garlick`_), but we will assume henceforth that the number of particle histories
|
|
per cycle is sufficiently large to neglect this bias.
|
|
|
|
With this formalism, we now have a framework within which we can determine the
|
|
properties of the distribution of expected number of fission sites. The explicit
|
|
form of the source distribution can be written as
|
|
|
|
.. math::
|
|
:label: source-explicit
|
|
|
|
\hat{S}(\mathbf{r}) = \sum_{i=1}^{M} w_i \delta( \mathbf{r} - \mathbf{r}_i )
|
|
|
|
where :math:`\mathbf{r}_i` is the spatial location of the :math:`i`-th fission
|
|
site, :math:`w_i` is the statistical weight of the fission site at
|
|
:math:`\mathbf{r}_i`, and :math:`M` is the total number of fission sites. It is
|
|
clear that the total weight of the fission sites is simply the integral of the
|
|
source distribution. Integrating equation :eq:`source` over all space, we obtain
|
|
|
|
.. math::
|
|
:label: source-integrated
|
|
|
|
\int \hat{S}(\mathbf{r}) \: d\mathbf{r} = N \int S(\mathbf{r}) \:
|
|
d\mathbf{r} + \sqrt{N} \int \hat{\epsilon}(\mathbf{r}) \: d\mathbf{r} .
|
|
|
|
Substituting the expressions for the stochastic and true eigenvalues from
|
|
equation :eq:`k-to-source`, we can relate the stochastic eigenvalue to the
|
|
integral of the noise component of the source distribution as
|
|
|
|
.. math::
|
|
:label: noise-integral
|
|
|
|
N\hat{k} = Nk + \sqrt{N} \int \hat{\epsilon}(\mathbf{r}) \: d\mathbf{r}.
|
|
|
|
Since the expected value of :math:`\hat{\epsilon}` is zero, the expected value
|
|
of its integral will also be zero. We thus see that the variance of the integral
|
|
of the source distribution, i.e. the variance of the total weight of fission
|
|
sites produced, is directly proportional to the variance of the integral of the
|
|
noise component. Let us call this term :math:`\sigma^2` for simplicity:
|
|
|
|
.. math::
|
|
:label: variance-sigma2
|
|
|
|
\text{Var} \left[ \int \hat{S}(\mathbf{r}) \right ] = N \sigma^2.
|
|
|
|
The actual value of :math:`\sigma^2` will depend on the physical nature of the
|
|
problem, whether variance reduction techniques are employed, etc. For instance,
|
|
one could surmise that for a highly scattering problem, :math:`\sigma^2` would
|
|
be smaller than for a highly absorbing problem since more collisions will lead
|
|
to a more precise estimate of the source distribution. Similarly, using implicit
|
|
capture should in theory reduce the value of :math:`\sigma^2`.
|
|
|
|
Let us now consider the case where the :math:`N` total histories are divided up
|
|
evenly across :math:`p` compute nodes. Since each node simulates :math:`N/p`
|
|
histories, we can write the source distribution as
|
|
|
|
.. math::
|
|
:label: source-node
|
|
|
|
\hat{S}_i(\mathbf{r})= \frac{N}{p} S(\mathbf{r}) + \sqrt{\frac{N}{p}}
|
|
\hat{\epsilon}_i(\mathbf{r}) \quad \text{for} \quad i = 1, \dots, p
|
|
|
|
Integrating over all space and simplifying, we can obtain an expression for the
|
|
eigenvalue on the :math:`i`-th node:
|
|
|
|
.. math::
|
|
:label: k-i-hat
|
|
|
|
\hat{k}_i = k + \sqrt{\frac{p}{N}} \int \hat{\epsilon}_i(\mathbf{r}) \:
|
|
d\mathbf{r}.
|
|
|
|
It is easy to show from this expression that the stochastic realization of the
|
|
global eigenvalue is merely the average of these local eigenvalues:
|
|
|
|
.. math::
|
|
:label: average-k-as-sum
|
|
|
|
\hat{k} = \frac{1}{p} \sum_{i=1}^p \hat{k}_i.
|
|
|
|
As was mentioned earlier, at the end of each cycle one must sample :math:`N`
|
|
sites from the :math:`M` sites that were created. Thus, the source for the next
|
|
cycle can be seen as the fission source from the current cycle divided by the
|
|
stochastic realization of the eigenvalue since it is clear from equation
|
|
:eq:`k-to-source` that :math:`\hat{k} = M/N`. Similarly, the number of sites
|
|
sampled on each compute node that will be used for the next cycle is
|
|
|
|
.. math::
|
|
:label: sites-per-node
|
|
|
|
M_i = \frac{1}{\hat{k}} \int \hat{S}_i(\mathbf{r}) \: d\mathbf{r} =
|
|
\frac{N}{p} \frac{\hat{k}_i}{\hat{k}}.
|
|
|
|
While we know conceptually that each compute node will under normal
|
|
circumstances send two messages, many of these messages will overlap. Rather
|
|
than trying to determine the actual communication cost, we will instead attempt
|
|
to determine the maximum amount of data being communicated from one node to
|
|
another. At any given cycle, the number of fission sites that the :math:`j`-th
|
|
compute node will send or receive (:math:`\Lambda_j`) is
|
|
|
|
.. math::
|
|
:label: Lambda
|
|
|
|
\Lambda_j = \left | \sum_{i=1}^j M_i - \frac{jN}{p} \right |.
|
|
|
|
Noting that :math:`jN/p` is the expected value of the summation, we can write
|
|
the expected value of :math:`\Lambda_j` as the mean absolute deviation of the
|
|
summation:
|
|
|
|
.. math::
|
|
:label: mean-dev-lambda
|
|
|
|
E \left [ \Lambda_j \right ] = E \left [ \left | \sum_{i=1}^j M_i -
|
|
\frac{jN}{p} \right | \right ] = \text{MD} \left [ \sum_{i=1}^j M_i \right ]
|
|
|
|
where :math:`\text{MD}` indicates the mean absolute deviation of a random
|
|
variable. The mean absolute deviation is an alternative measure of variability.
|
|
|
|
In order to ascertain any information about the mean deviation of :math:`M_i`,
|
|
we need to know the nature of its distribution. Thus far, we have said nothing
|
|
of the distributions of the random variables in question. The total number of
|
|
fission sites resulting from the tracking of :math:`N` neutrons can be shown to
|
|
be normally distributed via the :ref:`central-limit-theorem` (provided that
|
|
:math:`N` is sufficiently large) since the fission sites resulting from each
|
|
neutron are "sampled" from independent, identically-distributed random
|
|
variables. Thus, :math:`\hat{k}` and :math:`\int \hat{S} (\mathbf{r}) \:
|
|
d\mathbf{r}` will be normally distributed as will the individual estimates of
|
|
these on each compute node.
|
|
|
|
Next, we need to know what the distribution of :math:`M_i` in equation
|
|
:eq:`sites-per-node` is or, equivalently, how :math:`\hat{k}_i / \hat{k}` is
|
|
distributed. The distribution of a ratio of random variables is not easy to
|
|
calculate analytically, and it is not guaranteed that the ratio distribution is
|
|
normal if the numerator and denominator are normally distributed. For example,
|
|
if :math:`X` is a standard normal distribution and :math:`Y` is also standard
|
|
normal distribution, then the ratio :math:`X/Y` has the standard `Cauchy
|
|
distribution`_. The reader should be reminded that the Cauchy distribution has
|
|
no defined mean or variance. That being said, Geary_ has shown that, for the
|
|
case of two normal distributions, if the denominator is unlikely to assume
|
|
values less than zero, then the ratio distribution is indeed approximately
|
|
normal. In our case, :math:`\hat{k}` absolutely cannot assume a value less than
|
|
zero, so we can be reasonably assured that the distribution of :math:`M_i` will
|
|
be normal.
|
|
|
|
For a normal distribution with mean :math:`\mu` and distribution function
|
|
:math:`f(x)`, it can be shown that
|
|
|
|
.. math::
|
|
:label: mean-dev-to-stdev
|
|
|
|
\int_{-\infty}^{\infty} f(x) \left | x - \mu \right | \: dx =
|
|
\sqrt{\frac{2}{\pi} \int_{-\infty}^{\infty} f(x) \left ( x - \mu \right )^2
|
|
\: dx}
|
|
|
|
and thus the mean absolute deviation is :math:`\sqrt{2/\pi}` times the standard
|
|
deviation. Therefore, to evaluate the mean absolute deviation of :math:`M_i`, we
|
|
need to first determine its variance. Substituting equation
|
|
:eq:`average-k-as-sum` into equation :eq:`sites-per-node`, we can rewrite
|
|
:math:`M_i` solely in terms of :math:`\hat{k}_1, \dots, \hat{k}_p`:
|
|
|
|
.. math::
|
|
:label: M-i
|
|
|
|
M_i = \frac{N \hat{k}_i}{\sum\limits_{j=1}^p \hat{k}_j}.
|
|
|
|
Since we know the variance of :math:`\hat{k}_i`, we can use the error
|
|
propagation law to determine the variance of :math:`M_i`:
|
|
|
|
.. math::
|
|
:label: M-variance
|
|
|
|
\text{Var} \left [ M_i \right ] = \sum_{j=1}^p \left ( \frac{\partial
|
|
M_i}{\partial \hat{k}_j} \right )^2 \text{Var} \left [ \hat{k}_j \right ] +
|
|
\sum\limits_{j \neq m} \sum\limits_{m=1}^p \left ( \frac{\partial
|
|
M_i}{\partial \hat{k}_j} \right ) \left ( \frac{\partial M_i}{\partial
|
|
\hat{k}_m} \right ) \text{Cov} \left [ \hat{k}_j, \hat{k}_m \right ]
|
|
|
|
where the partial derivatives are evaluated at :math:`\hat{k}_j = k`. Since
|
|
:math:`\hat{k}_j` and :math:`\hat{k}_m` are independent if :math:`j \neq m`,
|
|
their covariance is zero and thus the second term cancels out. Evaluating the
|
|
partial derivatives, we obtain
|
|
|
|
.. math::
|
|
:label: M-variance-2
|
|
|
|
\text{Var} \left [ M_i \right ] = \left ( \frac{N(p-1)}{kp^2} \right )^2
|
|
\frac{p\sigma^2}{N} + \sum_{j \neq i} \left ( \frac{-N}{kp^2} \right )^2
|
|
\frac{p\sigma^2}{N} = \frac{N(p-1)}{k^2p^2} \sigma^2.
|
|
|
|
Through a similar analysis, one can show that the variance of
|
|
:math:`\sum_{i=1}^j M_i` is
|
|
|
|
.. math::
|
|
:label: sum-M-variance
|
|
|
|
\text{Var} \left [ \sum_{i=1}^j M_i \right ] = \frac{Nj(p-j)}{k^2p^2}
|
|
\sigma^2
|
|
|
|
Thus, the expected amount of communication on node :math:`j`, i.e. the mean
|
|
absolute deviation of :math:`\sum_{i=1}^j M_i` is proportional to
|
|
|
|
.. math::
|
|
:label: communication-cost
|
|
|
|
E \left [ \Lambda_j \right ] = \sqrt{\frac{2Nj(p-j)\sigma^2}{\pi k^2p^2}}.
|
|
|
|
This formula has all the properties that one would expect based on intuition:
|
|
|
|
1. As the number of histories increases, the communication cost on each node
|
|
increases as well;
|
|
|
|
2. If :math:`p=1`, i.e. if the problem is run on only one compute node, the
|
|
variance will be zero. This reflects the fact that exactly :math:`N` sites
|
|
will be sampled if there is only one node.
|
|
|
|
3. For :math:`j=p`, the variance will be zero. Again, this says that when
|
|
you sum the number of sites from each node, you will get exactly :math:`N`
|
|
sites.
|
|
|
|
We can determine the node that has the highest communication cost by
|
|
differentiating equation :eq:`communication-cost` with respect to :math:`j`,
|
|
setting it equal to zero, and solving for :math:`j`. Doing so yields
|
|
:math:`j_{\text{max}} = p/2`. Interestingly, substituting :math:`j = p/2` in
|
|
equation :eq:`communication-cost` shows us that the maximum communication cost
|
|
is actually independent of the number of nodes:
|
|
|
|
.. math::
|
|
:label: maximum-communication
|
|
|
|
E \left [ \Lambda_{j_{\text{max}}} \right ] = \sqrt{ \frac{N\sigma^2}{2\pi
|
|
k^2}}.
|
|
|
|
.. only:: html
|
|
|
|
.. rubric:: References
|
|
|
|
.. [Troubetzkoy] E. Troubetzkoy, H. Steinberg, and M. Kalos, "Monte Carlo
|
|
Radiation Penetration Calculations on a Parallel Computer,"
|
|
*Trans. Am. Nucl. Soc.*, **17**, 260 (1973).
|
|
|
|
.. _first paper: https://doi.org/10.2307/2280232
|
|
|
|
.. _work of Forrest Brown: https://deepblue.lib.umich.edu/handle/2027.42/24996
|
|
|
|
.. _Brissenden and Garlick: https://doi.org/10.1016/0306-4549(86)90095-2
|
|
|
|
.. _MPICH: https://www.mpich.org
|
|
|
|
.. _binomial tree: https://www.mcs.anl.gov/~thakur/papers/ijhpca-coll.pdf
|
|
|
|
.. _Geary: https://doi.org/10.2307/2342070
|
|
|
|
.. _Barnett: https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.7772
|
|
|
|
.. _single-instruction multiple-data: https://en.wikipedia.org/wiki/SIMD
|
|
|
|
.. _vector computers: https://en.wikipedia.org/wiki/Vector_processor
|
|
|
|
.. _single program multiple data: https://en.wikipedia.org/wiki/SPMD
|
|
|
|
.. _message-passing interface: https://en.wikipedia.org/wiki/Message_Passing_Interface
|
|
|
|
.. _PVM: https://www.csm.ornl.gov/pvm/pvm_home.html
|
|
|
|
.. _MPI: https://www.mcs.anl.gov/research/projects/mpi/
|
|
|
|
.. _embarrassingly parallel: https://en.wikipedia.org/wiki/Embarrassingly_parallel
|
|
|
|
.. _sends: https://www.mpich.org//static/docs/latest/www3/MPI_Send.html
|
|
|
|
.. _broadcasts: https://www.mpich.org//static/docs/latest/www3/MPI_Bcast.html
|
|
|
|
.. _scatter: https://www.mpich.org//static/docs/latest/www3/MPI_Scatter.html
|
|
|
|
.. _allgather: https://www.mpich.org//static/docs/latest/www3/MPI_Allgather.html
|
|
|
|
.. _Cauchy distribution: https://en.wikipedia.org/wiki/Cauchy_distribution
|
|
|
|
.. _latency: https://en.wikipedia.org/wiki/Latency_(engineering)#Packet-switched_networks
|
|
|
|
.. _bandwidth: https://en.wikipedia.org/wiki/Bandwidth_(computing)
|