Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F122330962
pi_p2p_persistent.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Jul 17, 06:08
Size
2 KB
Mime Type
text/x-c
Expires
Sat, Jul 19, 06:08 (2 d)
Engine
blob
Format
Raw Data
Handle
27442876
Attached To
R7871 phys-743-exercises
pi_p2p_persistent.cc
View Options
/*
This exercise is taken from the class Parallel Programming Workshop (MPI,
OpenMP and Advanced Topics) at HLRS given by Rolf Rabenseifner
*/
#include <chrono>
#include <cstdio>
#include <cmath>
#include <mpi.h>
using clk = std::chrono::high_resolution_clock;
using second = std::chrono::duration<double>;
using time_point = std::chrono::time_point<clk>;
inline int digit(double x, int n) {
return std::trunc(x * std::pow(10., n)) - std::trunc(x * std::pow(10., n - 1)) *10.;
}
inline double f(double a) { return (4. / (1. + a * a)); }
const int n = 10000000;
int main(int /* argc */ , char ** /* argv */) {
int i;
double dx, x, sum, pi;
MPI_Init(NULL, NULL);
int prank, psize;
MPI_Comm_rank(MPI_COMM_WORLD, &prank);
MPI_Comm_size(MPI_COMM_WORLD, &psize);
auto t1 = clk::now();
auto ln = n/psize + (prank < n % psize ? 1 : 0);
auto i_start = prank * ln + (prank < n % psize ? 0 : n % psize);
auto i_end = i_start + ln;
/* calculate pi = integral [0..1] 4 / (1 + x**2) dx */
dx = 1. / n;
double lsum = 0.0;
for (i = i_start; i < i_end; i++) {
x = 1. * i * dx;
lsum = lsum + f(x);
}
double send, recv;
send = sum = lsum;
MPI_Request request[2];
auto next = (prank + 1) % psize;
auto prev = (prank - 1 + psize) % psize;
MPI_Send_init(&send, 1, MPI_DOUBLE, next, 13, MPI_COMM_WORLD, request);
MPI_Recv_init(&recv, 1, MPI_DOUBLE, prev, 13, MPI_COMM_WORLD, request + 1);
for (int p = 0 ; p < psize -1; ++p) {
MPI_Startall(2, request);
MPI_Wait(request + 1, MPI_STATUS_IGNORE);
sum += recv;
MPI_Wait(request, MPI_STATUS_IGNORE);
send = recv;
}
pi = dx * sum;
second elapsed = clk::now() - t1;
if (prank == 0) {
std::printf("computed pi = %.16g\n", pi);
std::printf("wall clock time (chrono) = %.4gs\n", elapsed.count());
std::printf("n mpi process = %.d\n", psize);
for(int d = 1; d <= 15; ++d) {
std::printf("%d", digit(pi, d));
}
}
MPI_Request_free(request);
MPI_Request_free(request + 1);
MPI_Finalize();
return 0;
}
Event Timeline
Log In to Comment