Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F91677267
pi_p2p_sync.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
Wed, Nov 13, 09:14
Size
2 KB
Mime Type
text/x-c
Expires
Fri, Nov 15, 09:14 (2 d)
Engine
blob
Format
Raw Data
Handle
22305842
Attached To
R7871 phys-743-exercises
pi_p2p_sync.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
;
auto
next
=
(
prank
+
1
)
%
psize
;
auto
prev
=
(
prank
-
1
+
psize
)
%
psize
;
for
(
int
p
=
0
;
p
<
psize
-
1
;
++
p
)
{
if
(
prank
%
2
==
0
)
{
MPI_Ssend
(
&
send
,
1
,
MPI_DOUBLE
,
next
,
0
,
MPI_COMM_WORLD
);
MPI_Recv
(
&
recv
,
1
,
MPI_DOUBLE
,
prev
,
0
,
MPI_COMM_WORLD
,
MPI_STATUS_IGNORE
);
}
else
{
MPI_Recv
(
&
recv
,
1
,
MPI_DOUBLE
,
prev
,
0
,
MPI_COMM_WORLD
,
MPI_STATUS_IGNORE
);
MPI_Ssend
(
&
send
,
1
,
MPI_DOUBLE
,
next
,
0
,
MPI_COMM_WORLD
);
}
sum
+=
recv
;
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_Finalize
();
return
0
;
}
Event Timeline
Log In to Comment