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
|
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*-
//
// Simple mpi example: simulate sampling/averaging on multiple nodes and gathering the results.
//
// MPI C++ API version of file contributed by Jianping Hua
//
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
//
// GPL'ed
#include <mpi.h> // mpi header file
#include <RInside.h> // for the embedded R via RInside
int main(int argc, char *argv[]) {
MPI::Init(argc, argv); // mpi initialization
int myrank = MPI::COMM_WORLD.Get_rank(); // obtain current node rank
int nodesize = MPI::COMM_WORLD.Get_size(); // obtain total nodes running.
int sndcnt = 1, rcvcnt = 1; // # of elements in send/recv buffer
double sendValue; // value to be collected in current node
double *allvalues = new double[nodesize]; // to save all results
// simulation info
// to sample from a uniform distribution
int rangeMin = 0, rangeMax = 10; // range of uniform distribution
int sampleSize = 2; // points in each sample
try {
RInside R(argc, argv); // create an embedded R instance
std::stringstream txt;
txt << "x <- " << rangeMin << std::endl;
R.parseEvalQ( txt.str() ); // assign x with lower range of uniform distribution
txt << "y <- " << rangeMax << std::endl;
R.parseEvalQ( txt.str() ); // assign y with upper range of uniform distribution
txt << "n <- " << sampleSize << std::endl;
R.parseEvalQ( txt.str() ); // assign n with the size of sample
std::string evalstr = "mean(runif(n,x,y))"; // sampling, compute the mean
Rcpp::NumericVector m = R.parseEval(evalstr); // eval str, convert result to NumericVector
sendValue = m( 0 ); // assign the return value to the variable to be gathered
//gather together values from all processes to allvalues
MPI::COMM_WORLD.Gather((const void*)&sendValue, sndcnt, MPI::DOUBLE, (void*)allvalues, rcvcnt, MPI::DOUBLE, 0);
// show what inidividual node's contribution
std::cout << "node " << myrank << " has mean " << m(0) << std::endl;
} catch(std::exception& ex) {
std::cerr << "Exception caught: " << ex.what() << std::endl;
} catch(...) {
std::cerr << "Unknown exception caught" << std::endl;
}
// show gathered results in node 0
if ( myrank == 0 ) {
std::cout << "values of all " << nodesize << " trials: " << std::endl;
for ( int i = 0; i < nodesize; i++ )
std::cout << allvalues[ i ] << ", ";
std::cout << std::endl;
}
// clean up
delete[] allvalues;
MPI::Finalize(); // mpi finalization
exit(0);
}
|