Substitute r_utils.*

This commit is contained in:
Max Lübke 2020-12-15 14:20:25 +01:00
parent 89276a4e81
commit 3203bbe70e
No known key found for this signature in database
GPG Key ID: D3201E51647D1199
9 changed files with 1252 additions and 973 deletions

140
.gitignore vendored Normal file
View File

@ -0,0 +1,140 @@
# Created by https://www.toptal.com/developers/gitignore/api/c,c++,r,cmake
# Edit at https://www.toptal.com/developers/gitignore?templates=c,c++,r,cmake
### C ###
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
### C++ ###
# Prerequisites
# Compiled Object files
*.slo
# Precompiled Headers
# Compiled Dynamic libraries
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
# Executables
### CMake ###
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
### CMake Patch ###
# External projects
*-prefix/
### R ###
# History files
.Rhistory
.Rapp.history
# Session Data files
.RData
# User-specific files
.Ruserdata
# Example code in package build process
*-Ex.R
# Output files from R CMD build
/*.tar.gz
# Output files from R CMD check
/*.Rcheck/
# RStudio files
.Rproj.user/
# produced vignettes
vignettes/*.html
vignettes/*.pdf
# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
.httr-oauth
# knitr and R markdown default cache directories
*_cache/
/cache/
# Temporary files created by R markdown
*.utf8.md
*.knit.md
# R Environment Variables
.Renviron
### R.Bookdown Stack ###
# R package: bookdown caching files
/*_files/
# End of https://www.toptal.com/developers/gitignore/api/c,c++,r,cmake

View File

@ -3,12 +3,10 @@ cmake_minimum_required(VERSION 3.9)
project(POET VERSION 0.1)
add_executable(poet kin.cpp)
# Not needed until now
# specify the C++ standard
#set(CMAKE_CXX_STANDARD 11)
#set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(MPI REQUIRED)
@ -87,15 +85,19 @@ find_path(R_RInside_INCLUDE_DIR RInside.h
list(APPEND R_INCLUDE_DIRS ${R_RInside_INCLUDE_DIR})
#include found directories for the whole scope (will be changed with modularization)
include_directories(${R_INCLUDE_DIRS} ${MPI_CXX_INCLUDE_DIRS})
include_directories(${MPI_CXX_INCLUDE_DIRS})
#define program libraries
add_library(Worker STATIC worker.cpp)
target_link_libraries(Worker MPI::MPI_CXX)
add_library(DHT STATIC DHT.cpp dht_wrapper.cpp)
target_link_libraries(DHT crypto)
add_library(POET_Libs OBJECT util/RRuntime.cpp dht_wrapper.cpp worker.cpp DHT.cpp)
target_include_directories(POET_Libs PUBLIC ${R_INCLUDE_DIRS})
target_link_libraries(POET_Libs ${R_LIBRARIES} MPI::MPI_CXX crypto)
add_library(R_UTILS STATIC r_utils.cpp)
#add_library(DHT OBJECT DHT.cpp dht_wrapper.cpp)
#target_link_libraries(DHT crypto R_Wrapper)
target_link_libraries(poet PUBLIC Worker DHT R_UTILS ${R_LIBRARIES} MPI::MPI_CXX)
#add_library(Worker OBJECT worker.cpp)
#target_link_libraries(Worker ${R_LIBRARIES} MPI::MPI_CXX R_Wrapper)
add_executable(poet kin.cpp)
target_link_libraries(poet PUBLIC MPI::MPI_CXX POET_Libs)

View File

@ -1,6 +1,8 @@
#include "dht_wrapper.h"
#include <openssl/md5.h>
using namespace poet;
/*init globals*/
bool dht_enabled;
int dht_snaps;
@ -37,7 +39,7 @@ uint64_t get_md5(int key_size, void *key) {
return retval;
}
double Round_off(RInside &R, double N, double n) {
double Round_off(RRuntime R, double N, double n) {
double result;
R["roundsig"] = n;
R["roundin"] = N;
@ -50,7 +52,7 @@ double Round_off(RInside &R, double N, double n) {
/*
* Stores fuzzed version of key in fuzzing_buffer
*/
void fuzz_for_dht(RInside &R, int var_count, void *key, double dt) {
void fuzz_for_dht(RRuntime R, int var_count, void *key, double dt) {
unsigned int i = 0;
//introduce fuzzing to allow more hits in DHT
for (i = 0; i < (unsigned int)var_count; i++) {
@ -82,7 +84,7 @@ void fuzz_for_dht(RInside &R, int var_count, void *key, double dt) {
fuzzing_buffer[var_count] = dt;
}
void check_dht(RInside &R, int length, std::vector<bool> &out_result_index, double *work_package) {
void check_dht(RRuntime R, int length, std::vector<bool> &out_result_index, double *work_package) {
void *key;
int res;
int var_count = prop_type_vector.size();
@ -114,7 +116,7 @@ void check_dht(RInside &R, int length, std::vector<bool> &out_result_index, doub
}
}
void fill_dht(RInside &R, int length, std::vector<bool> &result_index, double *work_package, double *results) {
void fill_dht(RRuntime R, int length, std::vector<bool> &result_index, double *work_package, double *results) {
void *key;
void *data;
int res;

View File

@ -1,18 +1,18 @@
#pragma once
#include <RInside.h>
#include "util/RRuntime.h"
#include <string>
#include <vector>
#include <math.h>
#include "DHT.h"
using namespace std;
using namespace Rcpp;
using namespace poet;
/*Functions*/
uint64_t get_md5(int key_size, void* key);
void fuzz_for_dht(RInside &R, int var_count, void *key, double dt);
void check_dht(RInside &R, int length, std::vector<bool> &out_result_index, double *work_package);
void fill_dht(RInside &R, int length, std::vector<bool> &result_index, double *work_package, double *results);
void fuzz_for_dht(RRuntime R, int var_count, void *key, double dt);
void check_dht(RRuntime R, int length, std::vector<bool> &out_result_index, double *work_package);
void fill_dht(RRuntime R, int length, std::vector<bool> &result_index, double *work_package, double *results);
void print_statistics();
int table_to_file(char* filename);
int file_to_table(char* filename);

File diff suppressed because it is too large Load Diff

56
src/util/RRuntime.cpp Normal file
View File

@ -0,0 +1,56 @@
#include "RRuntime.h"
#include <RInside.h>
#include <Rcpp.h>
#include <string>
using namespace poet;
/**
* Convert a R dataframe into a C continious memory area.
*
* @param varname Name of the R internal variable name.
*/
void RRuntime::to_C_domain(double *buffer) {
size_t rowCount = dfbuff.nrow();
size_t colCount = dfbuff.ncol();
for (size_t i = 0; i < rowCount; i++) {
for (size_t j = 0; j < colCount; j++) {
/* Access column vector j and extract value of line i */
Rcpp::DoubleVector col = dfbuff[j];
buffer[i * colCount + j] = col[i];
}
}
}
/**
* Convert continious C memory area into R dataframe and puts it into R runtime.
*
* @param buffer Pointer to memory area which should be converted into R
* dataframe.
* @param skeleton Defines the raw data frame structure and muste be defined
* inside the R runtime beforehand.
* @param varname Name of the R internal variable name.
*/
void RRuntime::from_C_domain(double *buffer) {
size_t rowCount = dfbuff.nrow();
size_t colCount = dfbuff.ncol();
for (size_t i = 0; i < rowCount; i++) {
for (size_t j = 0; j < colCount; j++) {
/* Access column vector j and extract value of line i */
Rcpp::DoubleVector col = dfbuff[j];
col[i] = buffer[i * colCount + j];
}
}
}
void RRuntime::setBufferDataFrame(std::string dfname) {
this->dfbuff = parseEval(dfname);
}
Rcpp::DataFrame RRuntime::getBufferDataFrame() { return this->dfbuff; }
size_t RRuntime::getBufferNCol() { return (this->dfbuff).ncol(); }
size_t RRuntime::getBufferNRow() { return (this->dfbuff).nrow(); }

36
src/util/RRuntime.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef RRUNTIME_H
#define RRUNTIME_H
#include <RInside.h>
#include <Rcpp.h>
#include <string>
namespace poet {
/**
* RRuntime is a wrapper class around a RInside (R) runtime and provides several
* simplified methods to use R commands inside POET.
*
* If an instance of RRuntime is created a R runtime will also be spawned.
*/
class RRuntime : public RInside {
public:
/**
* Constructor of class RRuntime calling constructor of RInside.
*/
RRuntime(const int argc, const char *const argv[]) : RInside(argc, argv){};
void to_C_domain(double *buffer);
void from_C_domain(double *buffer);
void setBufferDataFrame(std::string dfname);
Rcpp::DataFrame getBufferDataFrame();
size_t getBufferNCol();
size_t getBufferNRow();
private:
Rcpp::DataFrame dfbuff;
};
} // namespace poet
#endif // RRUNTIME_H

View File

@ -1,277 +1,294 @@
#include "worker.h"
#include "dht_wrapper.h"
#include "global_buffer.h"
#include "r_utils.h"
#include <mpi.h>
#include "util/RRuntime.h"
#include <iostream>
#include <mpi.h>
#include <Rcpp.h>
void worker_function(RInside& R)
{
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Status probe_status;
int count;
using namespace poet;
using namespace Rcpp;
int local_work_package_size;
int iteration;
double dt, current_sim_time;
void worker_function(RRuntime R) {
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Status probe_status;
int count;
double idle_a, idle_b;
double cummul_idle = 0.f;
int local_work_package_size;
int iteration;
double dt, current_sim_time;
double dht_get_start=0, dht_get_end=0;
double dht_fill_start=0, dht_fill_end=0;
double phreeqc_time_start=0, phreeqc_time_end=0;
int phreeqc_count = 0;
double idle_a, idle_b;
double cummul_idle = 0.f;
//timing[0] -> phreeqc
//timing[1] -> dht_get
//timing[2] -> dht_fill
double timing[3];
timing[0] = 0.0;
timing[1] = 0.0;
timing[2] = 0.0;
double dht_get_start = 0, dht_get_end = 0;
double dht_fill_start = 0, dht_fill_end = 0;
double phreeqc_time_start = 0, phreeqc_time_end = 0;
int phreeqc_count = 0;
//dht_perf[0] -> hits
//dht_perf[1] -> miss
//dht_perf[2] -> collisions
uint64_t dht_perf[3];
// timing[0] -> phreeqc
// timing[1] -> dht_get
// timing[2] -> dht_fill
double timing[3];
timing[0] = 0.0;
timing[1] = 0.0;
timing[2] = 0.0;
if (dht_enabled)
{
dht_flags.resize(work_package_size, true); //set size
dht_flags.assign(work_package_size, true); //assign all elements to true (default)
dht_hits = 0;
dht_miss = 0;
dht_collision = 0;
// dht_perf[0] -> hits
// dht_perf[1] -> miss
// dht_perf[2] -> collisions
uint64_t dht_perf[3];
if (dht_enabled) {
dht_flags.resize(work_package_size, true); // set size
dht_flags.assign(work_package_size,
true); // assign all elements to true (default)
dht_hits = 0;
dht_miss = 0;
dht_collision = 0;
// MDL: This code has now been moved to kin.cpp
// /*Load significance vector from R setup file (or set default)*/
// bool signif_vector_exists = R.parseEval("exists('signif_vector')");
// if (signif_vector_exists)
// {
// dht_significant_digits_vector = as<std::vector<int>>(R["signif_vector"]);
// } else
// {
// dht_significant_digits_vector.assign(dht_object->key_size / sizeof(double), dht_significant_digits);
// }
// MDL: This code has now been moved to kin.cpp
// /*Load significance vector from R setup file (or set default)*/
// bool signif_vector_exists = R.parseEval("exists('signif_vector')");
// if (signif_vector_exists)
// {
// dht_significant_digits_vector =
// as<std::vector<int>>(R["signif_vector"]);
// } else
// {
// dht_significant_digits_vector.assign(dht_object->key_size /
// sizeof(double), dht_significant_digits);
// }
// /*Load property type vector from R setup file (or set default)*/
// bool prop_type_vector_exists = R.parseEval("exists('prop_type')");
// if (prop_type_vector_exists)
// {
// prop_type_vector = as<std::vector<string>>(R["prop_type"]);
// } else
// {
// prop_type_vector.assign(dht_object->key_size / sizeof(double), "normal");
// }
}
// /*Load property type vector from R setup file (or set default)*/
// bool prop_type_vector_exists = R.parseEval("exists('prop_type')");
// if (prop_type_vector_exists)
// {
// prop_type_vector = as<std::vector<string>>(R["prop_type"]);
// } else
// {
// prop_type_vector.assign(dht_object->key_size / sizeof(double),
// "normal");
// }
}
//initialization of helper variables
iteration = 0;
dt = 0;
current_sim_time = 0;
local_work_package_size = 0;
// initialization of helper variables
iteration = 0;
dt = 0;
current_sim_time = 0;
local_work_package_size = 0;
/*worker loop*/
while(1)
{
/*Wait for Message*/
idle_a = MPI_Wtime();
MPI_Probe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &probe_status);
idle_b = MPI_Wtime();
/*worker loop*/
while (1) {
/*Wait for Message*/
idle_a = MPI_Wtime();
MPI_Probe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &probe_status);
idle_b = MPI_Wtime();
if (probe_status.MPI_TAG == TAG_WORK)
{ /* do work */
if (probe_status.MPI_TAG == TAG_WORK) { /* do work */
cummul_idle += idle_b - idle_a;
cummul_idle += idle_b - idle_a;
/* get number of doubles sent */
MPI_Get_count(&probe_status, MPI_DOUBLE, &count);
/* get number of doubles sent */
MPI_Get_count(&probe_status, MPI_DOUBLE, &count);
/* receive */
MPI_Recv(mpi_buffer, count, MPI_DOUBLE, 0, TAG_WORK, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* receive */
MPI_Recv(mpi_buffer, count, MPI_DOUBLE, 0, TAG_WORK, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
//decrement count of work_package by BUFFER_OFFSET
count -= BUFFER_OFFSET;
//check for changes on all additional variables given by the 'header' of mpi_buffer
if (mpi_buffer[count] != local_work_package_size) { //work_package_size
local_work_package_size = mpi_buffer[count];
R["work_package_size"] = local_work_package_size;
R.parseEvalQ("mysetup$work_package_size <- work_package_size");
}
if (mpi_buffer[count+1] != iteration) { //current iteration of simulation
iteration = mpi_buffer[count+1];
R["iter"] = iteration;
R.parseEvalQ("mysetup$iter <- iter");
}
if (mpi_buffer[count+2] != dt) { //current timestep size
dt = mpi_buffer[count+2];
R["dt"] = dt;
R.parseEvalQ("mysetup$dt <- dt");
}
if (mpi_buffer[count+3] != current_sim_time) { //current simulation time ('age' of simulation)
current_sim_time = mpi_buffer[count+3];
R["simulation_time"] = current_sim_time;
R.parseEvalQ("mysetup$simulation_time <- simulation_time");
}
/* 4th double value is currently a placeholder */
// if (mpi_buffer[count+4] != placeholder) {
// placeholder = mpi_buffer[count+4];
// R["mysetup$placeholder"] = placeholder;
// }
// decrement count of work_package by BUFFER_OFFSET
count -= BUFFER_OFFSET;
// check for changes on all additional variables given by the 'header' of
// mpi_buffer
if (mpi_buffer[count] != local_work_package_size) { // work_package_size
local_work_package_size = mpi_buffer[count];
R["work_package_size"] = local_work_package_size;
R.parseEvalQ("mysetup$work_package_size <- work_package_size");
}
if (mpi_buffer[count + 1] !=
iteration) { // current iteration of simulation
iteration = mpi_buffer[count + 1];
R["iter"] = iteration;
R.parseEvalQ("mysetup$iter <- iter");
}
if (mpi_buffer[count + 2] != dt) { // current timestep size
dt = mpi_buffer[count + 2];
R["dt"] = dt;
R.parseEvalQ("mysetup$dt <- dt");
}
if (mpi_buffer[count + 3] !=
current_sim_time) { // current simulation time ('age' of simulation)
current_sim_time = mpi_buffer[count + 3];
R["simulation_time"] = current_sim_time;
R.parseEvalQ("mysetup$simulation_time <- simulation_time");
}
/* 4th double value is currently a placeholder */
// if (mpi_buffer[count+4] != placeholder) {
// placeholder = mpi_buffer[count+4];
// R["mysetup$placeholder"] = placeholder;
// }
/* get df with right structure to fill in work package */
R.parseEvalQ("tmp2 <- head(mysetup$state_C, work_package_size)");
// R.parseEval("print(rownames(tmp2)[1:5])");
// R.parseEval("print(head(tmp2, 2))");
// R.parseEvalQ("tmp2$id <- as.double(rownames(tmp2))");
/* get df with right structure to fill in work package */
R.parseEvalQ("skeleton <- head(mysetup$state_C, work_package_size)");
// R.parseEval("print(rownames(tmp2)[1:5])");
// R.parseEval("print(head(tmp2, 2))");
// R.parseEvalQ("tmp2$id <- as.double(rownames(tmp2))");
Rcpp::DataFrame buffer = R.parseEval("tmp2");
//Rcpp::DataFrame buffer = R.parseEval("tmp2");
R.setBufferDataFrame("skeleton");
if (dht_enabled)
{
// DEBUG
// cout << "RANK " << world_rank << " start checking DHT\n";
if (dht_enabled) {
// DEBUG
// cout << "RANK " << world_rank << " start checking DHT\n";
//resize helper vector dht_flags of work_package_size changes
if ((int) dht_flags.size() != local_work_package_size) {
dht_flags.resize(local_work_package_size, true); //set size
dht_flags.assign(local_work_package_size, true); //assign all elements to true (default)
}
dht_get_start = MPI_Wtime();
check_dht(R, local_work_package_size, dht_flags, mpi_buffer);
dht_get_end = MPI_Wtime();
//DEBUG
//cout << "RANK " << world_rank << " checking DHT complete \n";
R["dht_flags"] = as<LogicalVector>(wrap(dht_flags));
//R.parseEvalQ("print(head(dht_flags))");
}
/* work */
convert_C_buffer_2_R_Dataframe(mpi_buffer, buffer);
R["work_package_full"] = buffer;
//R["work_package"] = buffer;
//DEBUG
//R.parseEvalQ("print(head(work_package_full))");
//R.parseEvalQ("print( c(length(dht_flags), nrow(work_package_full)) )");
if (dht_enabled)
{
R.parseEvalQ("work_package <- work_package_full[dht_flags,]");
} else {
R.parseEvalQ("work_package <- work_package_full");
}
//DEBUG
// R.parseEvalQ("print(head(work_package),2)");
// R.parseEvalQ("rownames(work_package) <- work_package$id");
// R.parseEval("print(paste('id %in% colnames(work_package)', 'id' %in% colnames(work_package)");
// R.parseEvalQ("id_store <- rownames(work_package)"); //"[, ncol(work_package)]");
// R.parseEvalQ("work_package$id <- NULL");
R.parseEvalQ("work_package <- as.matrix(work_package)");
unsigned int nrows = R.parseEval("nrow(work_package)");
if (nrows > 0)
{
/*Single Line error Workaround*/
if (nrows <=1)
{
//duplicate line to enable correct simmulation
R.parseEvalQ("work_package <- work_package[rep(1:nrow(work_package), times = 2), ]");
}
phreeqc_count++;
phreeqc_time_start = MPI_Wtime();
// MDL
// R.parseEvalQ("print('Work_package:\n'); print(head(work_package , 2)); cat('RCpp: worker_function:', local_rank, ' \n')");
R.parseEvalQ("result <- as.data.frame(slave_chemistry(setup=mysetup, data = work_package))");
phreeqc_time_end = MPI_Wtime();
// R.parseEvalQ("result$id <- id_store");
} else
{
//cout << "Work-Package is empty, skipping phreeqc!" << endl;
}
if (dht_enabled)
{
R.parseEvalQ("result_full <- work_package_full");
if (nrows > 0)
R.parseEvalQ("result_full[dht_flags,] <- result");
} else {
R.parseEvalQ("result_full <- result");
}
Rcpp::DataFrame result = R.parseEval("result_full");
convert_R_Dataframe_2_C_buffer(mpi_buffer_results, result);
/* send results to master */
MPI_Request send_req;
MPI_Isend(mpi_buffer_results, count, MPI_DOUBLE, 0, TAG_WORK, MPI_COMM_WORLD, &send_req);
if (dht_enabled)
{
dht_fill_start = MPI_Wtime();
fill_dht(R, local_work_package_size, dht_flags, mpi_buffer, mpi_buffer_results);
dht_fill_end = MPI_Wtime();
timing[1] += dht_get_end - dht_get_start;
timing[2] += dht_fill_end - dht_fill_start;
}
timing[0] += phreeqc_time_end - phreeqc_time_start;
MPI_Wait(&send_req,MPI_STATUS_IGNORE);
} else if (probe_status.MPI_TAG == TAG_FINISH)
{ /* recv and die */
/* before death, submit profiling/timings to master*/
MPI_Recv(NULL, 0, MPI_DOUBLE, 0, TAG_FINISH, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
//timings
MPI_Send(timing, 3, MPI_DOUBLE, 0, TAG_TIMING, MPI_COMM_WORLD);
MPI_Send(&phreeqc_count, 1, MPI_INT, 0, TAG_TIMING, MPI_COMM_WORLD);
MPI_Send(&cummul_idle, 1, MPI_DOUBLE, 0, TAG_TIMING, MPI_COMM_WORLD);
if(dht_enabled)
{
//dht_perf
dht_perf[0] = dht_hits;
dht_perf[1] = dht_miss;
dht_perf[2] = dht_collision;
MPI_Send(dht_perf, 3, MPI_UNSIGNED_LONG_LONG, 0, TAG_DHT_PERF, MPI_COMM_WORLD);
}
break;
} else if ((probe_status.MPI_TAG == TAG_DHT_STATS)) {
MPI_Recv(NULL, 0, MPI_DOUBLE, 0, TAG_DHT_STATS, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
print_statistics();
MPI_Barrier(MPI_COMM_WORLD);
} else if ((probe_status.MPI_TAG == TAG_DHT_STORE)) {
char* outdir;
MPI_Get_count(&probe_status, MPI_CHAR, &count);
outdir = (char *) calloc(count + 1, sizeof(char));
MPI_Recv(outdir, count, MPI_CHAR, 0, TAG_DHT_STORE, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
int res = table_to_file((char *) outdir);
if (res != DHT_SUCCESS) {
if (world_rank == 2) cerr << "CPP: Worker: Error in writing current state of DHT to file (TAG_DHT_STORE)" << endl;
} else {
if (world_rank == 2) cout << "CPP: Worker: Successfully written DHT to file " << outdir << endl;
}
free(outdir);
MPI_Barrier(MPI_COMM_WORLD);
// resize helper vector dht_flags of work_package_size changes
if ((int)dht_flags.size() != local_work_package_size) {
dht_flags.resize(local_work_package_size, true); // set size
dht_flags.assign(local_work_package_size,
true); // assign all elements to true (default)
}
dht_get_start = MPI_Wtime();
check_dht(R, local_work_package_size, dht_flags, mpi_buffer);
dht_get_end = MPI_Wtime();
// DEBUG
// cout << "RANK " << world_rank << " checking DHT complete \n";
R["dht_flags"] = as<LogicalVector>(wrap(dht_flags));
// R.parseEvalQ("print(head(dht_flags))");
}
/* work */
R.from_C_domain(mpi_buffer);
//convert_C_buffer_2_R_Dataframe(mpi_buffer, buffer);
R["work_package_full"] = R.getBufferDataFrame();
// R["work_package"] = buffer;
// DEBUG
// R.parseEvalQ("print(head(work_package_full))");
// R.parseEvalQ("print( c(length(dht_flags), nrow(work_package_full)) )");
if (dht_enabled) {
R.parseEvalQ("work_package <- work_package_full[dht_flags,]");
} else {
R.parseEvalQ("work_package <- work_package_full");
}
// DEBUG
// R.parseEvalQ("print(head(work_package),2)");
// R.parseEvalQ("rownames(work_package) <- work_package$id");
// R.parseEval("print(paste('id %in% colnames(work_package)', 'id' %in%
// colnames(work_package)"); R.parseEvalQ("id_store <-
// rownames(work_package)"); //"[, ncol(work_package)]");
// R.parseEvalQ("work_package$id <- NULL");
R.parseEvalQ("work_package <- as.matrix(work_package)");
unsigned int nrows = R.parseEval("nrow(work_package)");
if (nrows > 0) {
/*Single Line error Workaround*/
if (nrows <= 1) {
// duplicate line to enable correct simmulation
R.parseEvalQ("work_package <- work_package[rep(1:nrow(work_package), "
"times = 2), ]");
}
phreeqc_count++;
phreeqc_time_start = MPI_Wtime();
// MDL
// R.parseEvalQ("print('Work_package:\n'); print(head(work_package ,
// 2)); cat('RCpp: worker_function:', local_rank, ' \n')");
R.parseEvalQ("result <- as.data.frame(slave_chemistry(setup=mysetup, "
"data = work_package))");
phreeqc_time_end = MPI_Wtime();
// R.parseEvalQ("result$id <- id_store");
} else {
// cout << "Work-Package is empty, skipping phreeqc!" << endl;
}
if (dht_enabled) {
R.parseEvalQ("result_full <- work_package_full");
if (nrows > 0)
R.parseEvalQ("result_full[dht_flags,] <- result");
} else {
R.parseEvalQ("result_full <- result");
}
R.setBufferDataFrame("result_full");
//Rcpp::DataFrame result = R.parseEval("result_full");
//convert_R_Dataframe_2_C_buffer(mpi_buffer_results, result);
R.to_C_domain(mpi_buffer_results);
/* send results to master */
MPI_Request send_req;
MPI_Isend(mpi_buffer_results, count, MPI_DOUBLE, 0, TAG_WORK,
MPI_COMM_WORLD, &send_req);
if (dht_enabled) {
dht_fill_start = MPI_Wtime();
fill_dht(R, local_work_package_size, dht_flags, mpi_buffer,
mpi_buffer_results);
dht_fill_end = MPI_Wtime();
timing[1] += dht_get_end - dht_get_start;
timing[2] += dht_fill_end - dht_fill_start;
}
timing[0] += phreeqc_time_end - phreeqc_time_start;
MPI_Wait(&send_req, MPI_STATUS_IGNORE);
} else if (probe_status.MPI_TAG == TAG_FINISH) { /* recv and die */
/* before death, submit profiling/timings to master*/
MPI_Recv(NULL, 0, MPI_DOUBLE, 0, TAG_FINISH, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
// timings
MPI_Send(timing, 3, MPI_DOUBLE, 0, TAG_TIMING, MPI_COMM_WORLD);
MPI_Send(&phreeqc_count, 1, MPI_INT, 0, TAG_TIMING, MPI_COMM_WORLD);
MPI_Send(&cummul_idle, 1, MPI_DOUBLE, 0, TAG_TIMING, MPI_COMM_WORLD);
if (dht_enabled) {
// dht_perf
dht_perf[0] = dht_hits;
dht_perf[1] = dht_miss;
dht_perf[2] = dht_collision;
MPI_Send(dht_perf, 3, MPI_UNSIGNED_LONG_LONG, 0, TAG_DHT_PERF,
MPI_COMM_WORLD);
}
break;
} else if ((probe_status.MPI_TAG == TAG_DHT_STATS)) {
MPI_Recv(NULL, 0, MPI_DOUBLE, 0, TAG_DHT_STATS, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
print_statistics();
MPI_Barrier(MPI_COMM_WORLD);
} else if ((probe_status.MPI_TAG == TAG_DHT_STORE)) {
char *outdir;
MPI_Get_count(&probe_status, MPI_CHAR, &count);
outdir = (char *)calloc(count + 1, sizeof(char));
MPI_Recv(outdir, count, MPI_CHAR, 0, TAG_DHT_STORE, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
int res = table_to_file((char *)outdir);
if (res != DHT_SUCCESS) {
if (world_rank == 2)
cerr << "CPP: Worker: Error in writing current state of DHT to file "
"(TAG_DHT_STORE)"
<< endl;
} else {
if (world_rank == 2)
cout << "CPP: Worker: Successfully written DHT to file " << outdir
<< endl;
}
free(outdir);
MPI_Barrier(MPI_COMM_WORLD);
}
}
}

View File

@ -1,11 +1,10 @@
#pragma once
#include <RInside.h>
#include "util/RRuntime.h"
using namespace std;
using namespace Rcpp;
using namespace poet;
/*Functions*/
void worker_function(RInside &R);
void worker_function(RRuntime R);
/*Globals*/