#c #parallel-processing #mpi #remote-access #shared-memory
#c #параллельная обработка #mpi #удаленный доступ #разделяемая память
Вопрос:
Я реализую алгоритм, основанный на параллельных вычислениях MPI, но он также требует, чтобы все процессы могли обращаться к двум общим буферам (например, двум массивам matrix), тип данных которых является определяемым пользователем классом. MPI_Win_allocate_shared (который работал в моих испытаниях с массивом doubles или простым классом) не работает: один ранг фактически не может видеть, что другие ранги записывают в буферы, почему??
std::pair <double, double> Options::BinomialPriceAmericanPut(void) {
int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD, amp;rank);
MPI_Comm_size(MPI_COMM_WORLD, amp;size);
// shared buffers to save data for seller and buyer
MPI_Win win_seller, win_buyer;
// size of the local window in bytes
MPI_Aint buff_size;
// pointers that will (locally) point to the shared memory
PWL *seller_buff;
PWL *buyer_buff;
// allocate shared memory
if (rank == 0) {
buff_size = (N 2) * (L 1) * sizeof(PWL);
MPI_Win_allocate_shared(buff_size, sizeof(PWL), MPI_INFO_NULL,
MPI_COMM_WORLD, amp;seller_buff, amp;win_seller);
MPI_Win_allocate_shared(buff_size, sizeof(PWL), MPI_INFO_NULL,
MPI_COMM_WORLD, amp;buyer_buff, amp;win_buyer);
}
else {
int disp_unit;
MPI_Win_allocate_shared(0, sizeof(PWL), MPI_INFO_NULL,
MPI_COMM_WORLD, amp;seller_buff, amp;win_seller);
MPI_Win_allocate_shared(0, sizeof(PWL), MPI_INFO_NULL,
MPI_COMM_WORLD, amp;buyer_buff, amp;win_buyer);
MPI_Win_shared_query(win_seller, 0, amp;buff_size, amp;disp_unit, amp;seller_buff);
MPI_Win_shared_query(win_buyer, 0, amp;buff_size, amp;disp_unit, amp;buyer_buff);
}
// up- and down- move factors
double u = exp( sigma * sqrt(expiry/N) );
// cash accumulation factor
double r = exp( R*expiry / N );
u= 1.2;
r=1.18;
// initialize algorithm
int p(size);
int n = N 2; // number of nodes in the current base level
int s = rank * ( n/p );
int e = (rank==p-1)? n: (rank 1) * ( n/p );
// each core works on e-s nodes in the current level
// compute u and z for both seller and buyer: payoff (0,0) at time N 1
for (int l=s; l<e; l ) {
const double St = S0*pow (u, N 1-2*l);
const double Sa = St * (1 k);
const double Sb = St * (1-k);
// compute functions
PWL u_s( {Line(-Sa, 0), Line(-Sb,0)} );
PWL u_b( {Line(-Sa, 0), Line(-Sb, 0)} );
// fill buffers
seller_buff[l] = u_s;
buyer_buff[l] = u_b;
}
MPI_Barrier(MPI_COMM_WORLD);
// PROVE: here is where I get the error: position [4] is filled by rank 1
// and rank 0 gives a segmentation fault when trying to access it
if (rank==0) {
std::cout << "PROVA: " << std::endl << "tAsk = " <<
seller_buff[4].valueInPoint(0) << std::endl << "tBid = " << -
buyer_buff[4].valueInPoint(0) << std::endl;
}
// etc, freeing windows at the end
Здесь класс PWL:
#ifndef PWL_H_
#define PWL_H_
/* Class containing information about piecewise linear functions */
#include "Line.h"
#include <vector>
#include <iostream>
#define MINIMIZE_EPIGRAPH 0 // removes parallel lines keeping the one with highest intercept
#define MAXIMIZE_EPIGRAPH 1 // removes parallel lines keeping the one with lowest intercept
typedef std::vector<Line> lines_vector;
class PWL {
friend PWL maxPWL (const PWL amp; f1, const PWL amp; f2);
friend PWL minPWL (const PWL amp; f1, const PWL amp; f2);
friend PWL operator/ (const PWL amp; f, double c);
public:
// vector of lines constituting the piecewise linear function
lines_vector lines;
// vector of abscissas of intersections among lines
std::vector<double> x_intersections;
// helper function giving the idx of the piece containing x
size_t piece_of_interest (const double x ) const;
public:
// default constructor
PWL () {
lines.push_back( Line(0,0) );
check_lines();
}
PWL (const int epi) {
lines.push_back( Line(0,0) );
check_lines(epi);
}
// constructor passing vector of lines: it computes x_intersections
PWL (const lines_vector amp; v): lines(v) {
check_lines();
}
PWL (const lines_vector amp; v, const int epi): lines(v) {
check_lines(epi);
}
// evaluate function in a point
double valueInPoint (const double x) const;
// restrict function slopes within a given interval
PWL restrict_slopes (const double l_bound, const double u_bound);
// return the opposite of the piecewise linear function
PWL opposite() const;
// check if there are two consecutive parallel lines with different intercept
// and compute x_intersections
void check_lines (const int epigraph = MINIMIZE_EPIGRAPH);
// getter
lines_vector get_lines() const {return lines;}
std::vector<double> get_intersections() const {return x_intersections;}
};
// maximum between piecewise linear functions
PWL maxPWL (const PWL amp; f1, const PWL amp; f2);
// minimum between piecewise linear functions
PWL minPWL (const PWL amp; f1, const PWL amp; f2);
// maximum between two lines in a given interval [a,b]
PWL maxLines (const Line amp; l1, const Line amp; l2, double a, double b);
// divide the function by a constant (operator overloading)
PWL operator/ (const PWL amp; f, double c);
#endif
Комментарии:
1. Содержимое
x_intersections
вектора очень маловероятно в разделяемой памяти.2. Почему? Будучи просто вектором double … у вас есть идеи о том, как заставить это работать?
3. Если вы знаете максимальный размер, то объявите его как массив (фиксированного размера) вместо вектора (неизвестного размера).
4. К сожалению, я этого не знаю, поскольку класс моделирует кусочно-линейные функции, которые могут иметь любое количество линейных частей