Skip to content

Commit

Permalink
Converted fission bank to SharedArray type.
Browse files Browse the repository at this point in the history
  • Loading branch information
jtramm committed Jan 23, 2020
1 parent 6bf1529 commit 56e314d
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 45 deletions.
6 changes: 3 additions & 3 deletions include/openmc/bank.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cstdint>
#include <vector>

#include "openmc/shared_array.h"
#include "openmc/particle.h"
#include "openmc/position.h"

Expand All @@ -17,9 +18,8 @@ namespace simulation {

extern std::vector<Particle::Bank> source_bank;

extern std::unique_ptr<Particle::Bank[]> fission_bank;
extern int64_t fission_bank_length;
extern int64_t fission_bank_max;
extern SharedArray<Particle::Bank> fission_bank;

extern std::vector<int64_t> progeny_per_particle;

} // namespace simulation
Expand Down
3 changes: 3 additions & 0 deletions include/openmc/shared_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
//! \file shared_array.h
//! \brief Shared array data structure

#include<memory>


namespace openmc {

//==============================================================================
Expand Down
35 changes: 14 additions & 21 deletions src/bank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@ namespace simulation {

std::vector<Particle::Bank> source_bank;

// The fission bank is allocated as a pointer, rather than a vector, as it will
// The fission bank is allocated as a SharedArray, rather than a vector, as it will
// be shared by all threads in the simulation. It will be allocated to a fixed
// maximum capacity in the init_fission_bank() function. Then, Elements will be
// added to it by performing atomic incrementing captures on the fission_bank_length
// variable. A vector is not appropriate, as use of push_back() and size()
// functions would cause undefined or unintended behavior.
std::unique_ptr<Particle::Bank[]> fission_bank;
int64_t fission_bank_length {0};
int64_t fission_bank_max;
// added to it by using SharedArray's special thread_safe_append() function.
SharedArray<Particle::Bank> fission_bank;

// Each entry in this vector corresponds to the number of progeny produced
// this generation for the particle located at that index. This vector is
Expand All @@ -41,16 +37,13 @@ std::vector<int64_t> progeny_per_particle;
void free_memory_bank()
{
simulation::source_bank.clear();
simulation::fission_bank.reset();
simulation::fission_bank_length = 0;
simulation::fission_bank.clear();
simulation::progeny_per_particle.clear();
}

void init_fission_bank(int64_t max)
{
simulation::fission_bank_max = max;
simulation::fission_bank = std::make_unique<Particle::Bank[]>(max);
simulation::fission_bank_length = 0;
simulation::fission_bank.reserve(max);
simulation::progeny_per_particle.resize(simulation::work_per_rank);
}

Expand Down Expand Up @@ -87,24 +80,24 @@ void sort_fission_bank()
std::vector<Particle::Bank> sorted_bank_holder;

// If there is not enough space, allocate a temporary vector and point to it
if (simulation::fission_bank_length > simulation::fission_bank_max / 2) {
sorted_bank_holder.resize(simulation::fission_bank_length);
if (simulation::fission_bank.size() > simulation::fission_bank.capacity() / 2) {
sorted_bank_holder.resize(simulation::fission_bank.size());
sorted_bank = sorted_bank_holder.data();
} else { // otherwise, point sorted_bank to unused portion of the fission bank
sorted_bank = &simulation::fission_bank[simulation::fission_bank_length];
sorted_bank = &simulation::fission_bank[simulation::fission_bank.size()];
}

// Use parent and progeny indices to sort fission bank
for (int64_t i = 0; i < simulation::fission_bank_length; i++) {
for (int64_t i = 0; i < simulation::fission_bank.size(); i++) {
const auto& site = simulation::fission_bank[i];
int64_t offset = site.parent_id - 1 - simulation::work_index[mpi::rank];
int64_t idx = simulation::progeny_per_particle[offset] + site.progeny_id;
sorted_bank[idx] = site;
}

// Copy sorted bank into the fission bank
std::copy(sorted_bank, sorted_bank + simulation::fission_bank_length,
simulation::fission_bank.get());
std::copy(sorted_bank, sorted_bank + simulation::fission_bank.size(),
simulation::fission_bank.data());
}

//==============================================================================
Expand All @@ -125,12 +118,12 @@ extern "C" int openmc_source_bank(void** ptr, int64_t* n)

extern "C" int openmc_fission_bank(void** ptr, int64_t* n)
{
if (simulation::fission_bank_length == 0) {
if (simulation::fission_bank.size() == 0) {
set_errmsg("Fission bank has not been allocated.");
return OPENMC_E_ALLOCATE;
} else {
*ptr = simulation::fission_bank.get();
*n = simulation::fission_bank_length;
*ptr = simulation::fission_bank.data();
*n = simulation::fission_bank.size();
return 0;
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/eigenvalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,21 @@ void synchronize_bank()

#ifdef OPENMC_MPI
int64_t start = 0;
int64_t n_bank = simulation::fission_bank_length;
int64_t n_bank = simulation::fission_bank.size();
MPI_Exscan(&n_bank, &start, 1, MPI_INT64_T, MPI_SUM, mpi::intracomm);

// While we would expect the value of start on rank 0 to be 0, the MPI
// standard says that the receive buffer on rank 0 is undefined and not
// significant
if (mpi::rank == 0) start = 0;

int64_t finish = start + simulation::fission_bank_length;
int64_t finish = start + simulation::fission_bank.size();
int64_t total = finish;
MPI_Bcast(&total, 1, MPI_INT64_T, mpi::n_procs - 1, mpi::intracomm);

#else
int64_t start = 0;
int64_t finish = simulation::fission_bank_length;
int64_t finish = simulation::fission_bank.size();
int64_t total = finish;
#endif

Expand All @@ -106,7 +106,7 @@ void synchronize_bank()
// extra logic to treat this circumstance, we really want to ensure the user
// runs enough particles to avoid this in the first place.

if (simulation::fission_bank_length == 0) {
if (simulation::fission_bank.size() == 0) {
fatal_error("No fission sites banked on MPI rank " + std::to_string(mpi::rank));
}

Expand Down Expand Up @@ -138,7 +138,7 @@ void synchronize_bank()
int64_t index_temp = 0;
std::vector<Particle::Bank> temp_sites(3*simulation::work_per_rank);

for (int64_t i = 0; i < simulation::fission_bank_length; i++ ) {
for (int64_t i = 0; i < simulation::fission_bank.size(); i++ ) {
const auto& site = simulation::fission_bank[i];

// If there are less than n_particles particles banked, automatically add
Expand Down Expand Up @@ -195,7 +195,7 @@ void synchronize_bank()
// fission bank
sites_needed = settings::n_particles - finish;
for (int i = 0; i < sites_needed; ++i) {
int i_bank = simulation::fission_bank_length - sites_needed + i;
int i_bank = simulation::fission_bank.size() - sites_needed + i;
temp_sites[index_temp] = simulation::fission_bank[i_bank];
++index_temp;
}
Expand Down Expand Up @@ -506,7 +506,7 @@ void shannon_entropy()
// Get source weight in each mesh bin
bool sites_outside;
xt::xtensor<double, 1> p = simulation::entropy_mesh->count_sites(
simulation::fission_bank.get(), simulation::fission_bank_length,
simulation::fission_bank.data(), simulation::fission_bank.size(),
&sites_outside);

// display warning message if there were sites outside entropy box
Expand Down
9 changes: 2 additions & 7 deletions src/physics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "openmc/secondary_uncorrelated.h"
#include "openmc/search.h"
#include "openmc/settings.h"
#include "openmc/shared_array.h"
#include "openmc/simulation.h"
#include "openmc/string_utils.h"
#include "openmc/thermal.h"
Expand Down Expand Up @@ -182,14 +181,10 @@ create_fission_sites(Particle* p, int i_nuclide, const Reaction* rx)
for (int i = 0; i < nu; ++i) {
Particle::Bank* site;
if (use_fission_bank) {
int64_t idx;
#pragma omp atomic capture
idx = simulation::fission_bank_length++;
if (idx >= simulation::fission_bank_max) {
int64_t idx = simulation::fission_bank.thread_safe_append();
if (idx == -1) {
warning("The shared fission bank is full. Additional fission sites created "
"in this generation will not be banked.");
#pragma omp atomic write
simulation::fission_bank_length = simulation::fission_bank_max;
skipped++;
break;
}
Expand Down
8 changes: 2 additions & 6 deletions src/physics_mg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,10 @@ create_fission_sites(Particle* p)
for (int i = 0; i < nu; ++i) {
Particle::Bank* site;
if (use_fission_bank) {
int64_t idx;
#pragma omp atomic capture
idx = simulation::fission_bank_length++;
if (idx >= simulation::fission_bank_max) {
int64_t idx = simulation::fission_bank.thread_safe_append();
if (idx == -1) {
warning("The shared fission bank is full. Additional fission sites created "
"in this generation will not be banked.");
#pragma omp atomic write
simulation::fission_bank_length = simulation::fission_bank_max;
skipped++;
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/simulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ void initialize_generation()
{
if (settings::run_mode == RunMode::EIGENVALUE) {
// Clear out the fission bank
simulation::fission_bank_length = 0;
simulation::fission_bank.resize(0);

// Count source sites if using uniform fission source weighting
if (settings::ufs_on) ufs_count_sites();
Expand Down

0 comments on commit 56e314d

Please sign in to comment.