Added internal infrastructure for dlopen based shared object sources

This commit is contained in:
Andrew Davis 2019-06-13 09:15:21 +01:00 committed by Andrew Davis
parent ae754fa3a8
commit 58d751bfae
4 changed files with 59 additions and 1 deletions

View file

@ -60,6 +60,7 @@ extern std::string path_input; //!< directory where main .xml files r
extern std::string path_output; //!< directory where output files are written
extern std::string path_particle_restart; //!< path to a particle restart file
extern std::string path_source;
extern std::string path_source_library; //!< path to the source shared object
extern std::string path_sourcepoint; //!< path to a source file
extern "C" std::string path_statepoint; //!< path to a statepoint file

View file

@ -59,6 +59,10 @@ private:
//! Initialize source bank from file/distribution
extern "C" void initialize_source();
// as yet uncreated function to sample a source from a shared object
//
// extern "C" Particle::Bank sample_source();
//! Sample a site from all external source distributions in proportion to their
//! source strength
//! \param[inout] seed Pseudorandom seed pointer

View file

@ -74,6 +74,7 @@ std::string path_input;
std::string path_output;
std::string path_particle_restart;
std::string path_source;
std::string path_source_library;
std::string path_sourcepoint;
std::string path_statepoint;

View file

@ -1,6 +1,8 @@
#include "openmc/source.h"
#include <algorithm> // for move
#include <sstream> // for stringstream
#include <dlfcn.h> // for dlopen
#include <fmt/core.h>
#include "xtensor/xadapt.hpp"
@ -71,7 +73,14 @@ SourceDistribution::SourceDistribution(pugi::xml_node node)
fatal_error(fmt::format("Source file '{}' does not exist.",
settings::path_source));
}
} else if (check_for_node(node, "library")) {
settings::path_source_library = get_node_value(node, "library", false, true);
// check if it exists
if (!file_exists(settings::path_source_library)) {
std::stringstream msg;
msg << "Library file " << settings::path_source_library << "' does not exist.";
fatal_error(msg);
}
} else {
// Spatial distribution for external source
@ -261,7 +270,50 @@ void initialize_source()
// Close file
file_close(file_id);
} else if ( settings::path_source_library != "" ) {
// Get the source from a library object
std::stringstream msg;
msg << "Sampling from library source " << settings::path_source << "...";
write_message(msg, 6);
// Open the library
void* source_library = dlopen(settings::path_source_library.c_str(),RTLD_LAZY);
if(!source_library) {
std::stringstream msg("Couldnt open source library " + settings::path_source_library);
fatal_error(msg);
}
// load the symbol
typedef Particle::Bank (*sample_t)();
// reset errors
dlerror();
// get the function from the library
sample_t sample_source = (sample_t) dlsym(source_library, "sample_source");
const char *dlsym_error = dlerror();
if (dlsym_error) {
dlclose(source_library);
fatal_error(dlsym_error);
}
// Generation source sites from specified distribution in the
// library source
for (int64_t i = 0; i < simulation::work_per_rank; ++i) {
// initialize random number seed
int64_t id = simulation::total_gen*settings::n_particles +
simulation::work_index[mpi::rank] + i + 1;
set_particle_seed(id);
// sample external source distribution
simulation::source_bank[i] = sample_source();
}
// release the library
dlclose(source_library);
} else {
// Generation source sites from specified distribution in user input
for (int64_t i = 0; i < simulation::work_per_rank; ++i) {