筑波大学計算科学研究センター CCS HPCサマーセミナー 「MPI」

¤†HKÁ¥žK›¡ĸşĹš
CCS HPCIJŐšĸőŁš
ìMPIí
WÓ½
[email protected]
¤†HKHKÛĴĶĽŒ`C¦
Á¥žK›¡ĸşĹš
"lœŔŚ@#Á¥
ţPCĮřĶĹŤ
•! Á¥ńšŀďŋŝĸļIJĊœŔŚĉ{bûĠť˜«
4­ĉg¬
•! ńšŀĎœŔŚď—gĥĮĸĶ
•! ńšŀĊďŃļĿŞšĮÐčĜĞ`Ch
•! ïĢěğPCĮřĶĹ
˜«4­
P
P
P
P
M
M
M
M
MPI – The Message Passing
Interface
•! œļĸšĵÐħşĹšʼnĨšĶĎ}Š
•! 1992VĜĞ}Š,ˆ+×J
•! 1994VťMPI-1.0ŚŚšĶ
–! ŏšĹŊśČ#řħŊřŚťĥŋŚİšĴŘş
–! 8ćĎÐŔšŀťıŜĮĽĦŊiťÐŀœħşťŋŝĸ
ĶĿŏŝĵ
–! 100ĎÙmôM²
–! |séhttp://www.mpi-forum.org/
•! MPI-2.2ô2009V9u茌šĶë623ōšĵ
–! ³Âéhttp://phase.hpcc.jp/phase/mpi-j/ml/
SPMD – Single Program,
Multiple Data
•! ”ČğŋŝĸļIJĉ5ŋŝįřŒģ¢č
N¸ţcf. SIMDŤ
•! 5ŋŝįřŒĉ”ČğľšĹģ!
•! œļĸšĵÐĉŋŝįřŒØĎ˜ģ
¸ð
˜«4­
P
P
P
M
A[100:149]
P
M A[50:99]
M
A[0:49]
M
A[150:199]
MPIN¸Ŕľś
•! (5ĎŤŋŝĸĶģ»mĎŋŝĸļIJĉÉ+
–! ŋŝĸĶØďţÐôČ÷ĠĐŤ5wüČï
•! 3ŋŝĸĶď>vĎŋŝĸĶ“2ģęć
•! MPIčĜĞŋŝĸĶØĎÐģ¸ð
˜«4­
P
)
M
(
M
P
)
)
)
M
P
(
P
(
(
M
ıőŖłİšĹţŧŤ
•! Ðŀœħş
ŋŝĸĶ
0
ŋŝĸĶ
1
ŋŝĸĶ
2
–! ŋŝĸĶĎß4
ıőŖłİšĹ
–! ŋŝĸĶmťŋŝĸĶ“2ţřşĮŤ
–! ŋŝĸĶĿŏŝĵ
•! €Śşįť€œļĴŖťĿšřĶťįřʼn
•! MPI_COMM_WORLD
–! ŋŝĸĶģ8ė$wıőŖłİšĹ
ıőŖłİšĹţŨŤ
•! ß=ÐĎçĶıšŋèţÐŀœħşŤģ¶‘
čb0µ
•! ŋŝĸĶĎ")
–! 2/3ĎŋŝĸĶĉI‚Cť1/3ĎŋŝĸĶĉ€Ď
$wÁ¥
•! ħşĿřıőŖłİšĹĊħşĹšıőŖłİš
Ĺ
ß=Ð
•! ıőŖłİšĹč8ĕĠğŋŝĸĶØĉĎœļĸš
ĵÐ
•! ņŚĥ5wţľšĹÌÏČüŤ
•! HAľšĹÐ
–! kÏţbroadcastŤťĭŕijţgatherŤťĶĬŕĹţscatterŤť
ŋŝĸĶĒĎĭŕijţallgatherŤťÌ°ţalltoallŤ
•! ¯§ÐţŚĺĮĴŘşŤ
–! ¯§ţ®;ťtHČċŤťĶĬŕşţŋŜʼnĦļĮĶÁ¥Ť
HAľšĹÐ
P0
P1
P2
P3
•! kÏ
–! śšĿŋŝĸĶĎA[*]ģŋŝĸĶčÌÏ
•! ĭŕij
–! ŋŝĸĶØĉ"lüăÓ"Ô#ģŒMŋŝĸĶčßĘğ
–! allgatherďŋŝĸĶčßĘğ
•! ĶĬŕĹ
–! śšĿŋŝĸĶĎA[*]ģŋŝĸĶØĉ"lûĀğ
•! Alltoall
–! ŋŝĸĶóĝŋŝĸĶčĶĬŕĹŠĭŕijþğ
–! €Ô#A["l][*]!AT["l][*]
allgather
•! 3ŋŝĸĶĎÓ"Ô#ģßĘĈŋŝĸĶĉ
Ô#Ċþğ
!"#
!$#
!%#
!&#
alltoall
•! ţ¸o7čŤ"lüăÔ#ģ̰þğ
P0
P0
P1
P1
P2
P2
P3
P3
1Q1Ð
•! Point-to-PointÐĊę:ĐĠğ
•! ŋŝĸĶĎōĥØĉĎľšĹÌÏ
–! ŋŝĸĶAďŋŝĸĶBčľšĹģÏţsendŤ
–! ŋŝĸĶBďţŋŝĸĶAóĝŤľšĹģ/ţrecvŤ
ŋŝĸĶA
ŋŝĸĶB
MPI_Send
Ïã
A
MPI_Recv
/
ãA
1Q1ÐţŨŤ
•! @ĎïăľšĹĎÔ#ģÌÏ
–! BxľšĹ@
•! MPI_INTťMPI_DOUBLEťMPI_BYTEťŦæŦæŦ
–! {ÑťŌĮĹťŗšijM²ľšĹ@
•! ıőŖłİšĹťœļĸšĵĹįťÏ/ŋŝĸĶřş
ĮĉsendĊrecvĎQ^ģ„M
1Q1ÐţũŤ
•! ŊŝļĮ@Ð
–! ÏņļʼnĤô &0µĊČĆăĝϪ
–! /ņļʼnĤô&0µĊČĆăĝ/ª
•! MPI_Send(A, . . .)ôcĆĈõăĝAģFrü
Ĉę·ï
–! 5ŋŝĸĶĎАĎņļʼnĤčıňšûĠă
Ą÷óę
–! œļĸšĵĎÏďÃûĠČï
àŊŝļĮ@1Q1Ð
•! àŊŝļĮ@Ð
–! post-send, complete-send
–! post-receive, complete-receive
•! Post-{send,recv}ĉÏ/iģ×J
•! Complete-{send,recv}ĉLZą
•! Á¥ĊÐĎĪšņřļŋģ0µč
–! ŐśĻĶŜļŀĉę0µĄôťüĐüĐĜĞ*Ž–
1Q1ÐĎÐŔšŀ
•! ŊŝļĮ@ťàŊŝļĮ@ÐĎāĠĂĠčĎÐ
Ŕšŀôîğ
–! }ŠŔšŀ
•! MPI!¦ôÏœļĸšĵģņļʼnĤŚşįþğóċðó„Mþğë
&´ďņļʼnĤŚşįûĠğùĊģMüĈďï÷Čï
–! ņļʼnĤŔšŀ
•! ÏœļĸšĵďņļʼnĤŚşįûĠğ
•! Ïďŝšīśčª
–! 5wŔšŀ
•! ÏďQ^þğ/ô•¸ûĠăĝLţřşľŊšÐŤ
•! Ïďńşŝšīśčª
–! ReadyŔšŀ
•! Q^þğ/ô•¸ûĠĈïğĊõĄ÷ÏôJĕğ
•! Ï/ĎŅşŀĴĨšĮģ™÷ğ
œļĸšĵĎh
•! ŊŝļĮ@
"
MPI_Send(ÏêľšĹ)
MPI_Recv(/êľšĹ)
"
•! MPI_SendôņļʼnĤŚşįû
ĠğD4ĎĖN¸0µ
–! ûĠČïD4ďľļŀŝļĮ
•! MPI_Sendrecvģ&þğ
•! àŊŝļĮ@
"
MPI_Isend(ÏêľšĹêŚĮĩĶĿ)
MPI_Recv(/êľšĹ)
MPI_Waitall(ŚĮĩĶĿ)
"
•! ]ÿN¸0µ
•! ŏšĹŊś
1Q1Ðχa‹ţŧŤ
•! œļĸšĵ'šâ
–! ţ2´ØĉďŤœļĸšĵďÎïËûĠČï
–! 3´ØĉďÎïËûĠğ0µ_ôîğ
'šâď
ÃûĠČï
'šâď
ÃûĠğ
P2ďÏó
ĹįģfMþğ
]¼ôîğ
P0
P1
P0
P1
P2
1Q1Ðχa‹ţŨŤ
•! U_
–! Ð!čòïĈU_ďÃûĠČï
P2ďP1čÏ
P0ďP1čÏ
P0
P1
P2
P1ďP0óĝĎœļĸšĵĐóĞ/üêP2óĝĎœļĸš
ĵôstarvationģYõÉùþ0µ_vĞ
#!ĎţŧŤūŎĶĿ6¹
#include <stdio.h>
#include <mpi.h>
int
main(int argc, char *argv[])
{
int rank, len;
char name[MPI_MAX_PROCESSOR_NAME];
}
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Get_processor_name(name, &len);
printf("%03d %s\n", rank, name);
MPI_Finalize();
return (0);
¿Ä
•! mpi.hģħşĮśšŀ
•! 3ŋŝĸĶďmainóĝŋŝįřŒôN¸
•! SPMD (single program, multiple data)
–! -ĎŋŝįřŒģ3ńšŀĉN¸
–! 3ŋŝįřŒďÒðľšĹţćĕĞêN¸ûĠĈïğŋŝĸ
ĶĎľšĹŤģĥĮĸĶþğ
•! $w,
–! MPI_Init
¿Äţ¬õŤ
'! ŋŝĸĶřşĮ“2Ď.\
(! !"#$%&''$()*+)*!+,-.**,/.0123#456789:#
(! ıőŖłİšĹ*!+,-.**,/.012čQüť¶řşĮģ.\
(! ıőŖłİšĹď;<6=>?ĪŊĵĨĮĿťPďÙmĉĥĮĸĶ
'! ńšŀ6ģ.\
(! !"#$,-.$/(&0-11&($*)'-)76@?3#4A?79:#
'! t[č?BCDĎ(ĉêŋŝĸļIJĉŢ
!"#$23*)435-)9:#
ıőŖłİšĹčQþği
C7D#!"#$%&''$135-)*!+,-;@@#E;@@3#C7D#
FGCH?9:#
'! ıőŖłİšĹE;@@ĎŋŝĸĶįśšŋĎ®
mģGCH?čÍþ
C7D#!"#$%&''$()*+)*!+,-;@@#E;@@3#C7D#
F56789:#
'! ıőŖłİšĹE;@@ĎŋŝĸĶįśšŋčò
÷ğ¶ŋŝĸĶĎřşĮ“2ģ5678čÍþ
#!ĎţŨŤū®;Á¥
6&(783797:;737<7=:::;73>>?7
7@7>97AB3C7
=7
D7
E7
F7
=:::7
>7
=7
D7
DG:7
>7
DG=7
G::7
>7
G:=7
HG:7
>7
>7
@7
HG=7
@7
=:::7
>7
IC7EA>J?#K@<CLMN#
#
J;>OA?#PQ$"""#R#S,!TU:#
#
C7D#@6C7)C7D#65VE3#EM65#F65VWQU9#
X#
####J;>OA?#G>@3#@YG>@:#
#
####!"#$#*3.)465VE3465VW9:#
####@YG>@#Z#"L":#
####[;5#)C#Z#":#C#K#$"""#R#S,!T:#C\\9#
#@YG>@#\Z#PQCU:#
####!"#$I-JK0-)4@YG>@3#4G>@3#$3#*!+,2.]^1T3#
#*!+,_]*3#"3#*!+,-.**,/.0129:#
####!"#$23*)435-)9:#
####5?D>57#)"9:#
`#
¿Ä
•! OÀûĠăľšĹď3ŋŝĸļIJĉÕ»üĈ.ĝĠğ
–! 1ŋŝĸĶĉďŋŝĸĶmN_PEĉ)Ćă"ģœ
•! Á¥ŠÐ
–!
–!
–!
–!
–!
–!
–!
3ŋŝĸļIJĉÓ";ģÁ¥üĈêßÁ
ıŜĮĽĦŊÐ
ééMPI_Reduce(&mysum, &sum, 1, MPI_DOUBLE,
ééééæééMPI_SUM, 0, MPI_COMM_WORLD);
ıőŖłİšĹďMPI_COMM_WORLDģfM
3ŋŝĸĶĎMPI_DOUBLEĎ¼©mŧĎmysumčQü
ŚĺĮĴŘşĎĹħŋďMPI_SUMť«yďřşĮ0Ďsumč
#!ĎţũŤū-<C#
'! "üĈê9ŽģƒĘğŋŝįřŒ
'! *!+-aĎĽĶĿŋŝįřŒ
(! Fm7Ďģ^E6GD#
(! t[č5?J>Eb;7#
(! Á¥ďêŋŝĸĶúĊčåđåđčĚĆĈïğ
####c#
#####!"#$L0)1.)473#$3#*!+,+Sd3#"3#*!+,-.**,/.0129:#
#
####M#Z#$L"#R#7:#
for (i = 1; i <= n; i++)
####G>@#Z#"L":#
####[;5#)C#Z#@YCJ#\#$:#C#KZ#7:#C#\Z#7>@<5;EG9X#
#B#Z#M#F#)C#e#"Lf9:#
#G>@#\Z#[)B9:#
####`#
####@Y<C#Z#M#F#G>@:#
#####
####!"#$I-JK0-)4@Y<C3#4<C3#$3#*!+,2.]^1T3##
##################*!+,_]*3#"3#*!+,-.**,/.0129:#
ß=Ðg#ŊŝšŀĬŕĶĿ
!"#$L0)1.87
ŊŝšŀĬŕĶĿÏ/ņļʼnĤĎĥŀŜĶ
77M&3J7777777NJ).)$OKP-(Q7777RR7Ŋ
ææ3*.77777777770&K*.Q77777777777RR7Ŋ
ŊŝšŀĬŕĶĿľšĹĎm
ææ!"#$S).).T/-7J).)$.T/-Q7777777RR7Ŋ
ŊŝšŀĬŕĶĿľšĹĎ@8N=?7
773*.77777777771&K(0-Q7777777777RR7Ŋ
ŊŝšŀĬŕĶĿŋŝĸĶĎřşĮ
ææ!"#$%&''777770&''K*30).&(77777RR7Ï
Ï/ģ¸ðįśšŋ
?;7
1&K(0-7
ŋŝĸĶĉN¸ûĠČöĈďČĝČï
ß=Ðg#ŚĺĮĴŘş
!"#$I-JK0-87
3ńšŀĎ!«yôz¨ûĠĈïğĥŀŜĶ
77M&3J7777777N/)(U)4$(-1K4.Q7RR73
ææM&3J7777777N(-1K4.Q777777777777777RR7ß
ßÁ«yģz¨þğĥŀŜĶ
ææ3*.77777777770&K*.Q7777777777777777777RR7ľ
ľšĹĎm
ææ!"#$S).).T/-7J).)$.T/-Q7777777RR7ľ
ľšĹĎ@8N=?7
ŚľŖšĶĪōŜšĴŘşĎfM8ND?7
77!"#$V/7777777&/-().&(Q777777RR7Ś
773*.7777777777J-1U*)U&*Q777777777RR7ß
ßÁ«yģ\ğŋŝĸĶ
ææ!"#$%&''777770&''K*30).&(77777RR7Ï
Ï/ģ¸ðįśšŋ
?;7
/)(U)4$(-1K4.7
(-1K4.7
J-1U*)U&*7
ŋŝĸĶĉN¸ûĠČöĈďČĝČï
ģŋŝĸĶĉ/÷.ğD4ďê!"#$A44(-JK0-7
I-1K4.ģ
/* cpi mpi version */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <mpi.h>
double
f(double a)
{
return (4.0 / (1.0 + a * a));
}
int
main(int argc, char *argv[])
{
int n = 0, myid, numprocs, i;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x;
double startwtime = 0.0, endwtime;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Get_processor_name(processor_name, &namelen);
fprintf(stderr, "Process %d on %s\n", myid, processor_name);
if (argc > 1)
n = atoi(argv[1]);
startwtime = MPI_Wtime();
/* broadcast 'n' */
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (n <= 0) {
fprintf(stderr, "usage: %s #partition\n", *argv);
MPI_Abort(MPI_COMM_WORLD, 1);
}
}
/* calculate each part of pi */
h = 1.0 / n;
sum = 0.0;
for (i = myid + 1; i <= n; i += numprocs){
x = h * (i - 0.5);
sum += f(x);
}
mypi = h * sum;
/* sum up each part of pi */
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (myid == 0) {
printf("pi is approximately %.16f, Error is %.16f\n",
pi, fabs(pi - PI25DT));
endwtime = MPI_Wtime();
printf("wall clock time = %f\n",
endwtime - startwtime);
}
MPI_Finalize();
return (0);
#!ĎţŪŤūA6<A6E?#
'! 16<A6E?oŸXĎܖ¿…
(! S1Ďh‹ĎU?ĉê><J6D?üĈïöŋŝįř
Œ
(! .AJĊ7?iģaüĈ—(Ďģıňš
(! @–ČãA")
(! t[čTģĊğ
¸#")ĊÞgÐ
•! €ãAģŊŝļ
Į")
•! E’Ď¼©ďÞĎ
ŋŝĸĶôrn
•! E’ľšĹģÞg
ŋŝĸĶčÌÏ
P0
P1
P2
P3
ŊŝļĮ@$Q$Ð
'! _?7JR0?E?CW?#
MPI_Send(
void
*send_data_buffer, // ÏľšĹôz¨ûĠĈïğœŔŚĎĥŀŜĶ
ææint
count,
// ÏľšĹĎm
ææMPI_Datatype data_type,
// ÏľšĹĎ@(*1)
int
destination,
// ÏŋŝĸĶĎřşĮ
ææint
tag,
// ÏľšĹĎÆ%ģ¸ðĹį
ééMPI_Comm
communicator
// Ï/ģ¸ðįśšŋŦ
);
MPI_Recv(
void
*recv_data_buffer, // /ľšĹôz¨ûĠğœŔŚĎĥŀŜĶ
ææint
count,
// /ľšĹĎm
ææMPI_Datatype data_type,
// /ľšĹĎ@(*1)
int
source,
// ÏŋŝĸĶĎřşĮ
ææint
tag,
// /ľšĹĎÆ%ģ¸ðăĘĎĹįŦ
ééMPI_Comm
communicator,
// Ï/ģ¸ðįśšŋŦ
ééMPI_Status
*status
// /čÙþğ`Cģz¨þğFmĎĥŀŜĶ
);
œļĸšĵÐ
•! œļĸšĵďľšĹĥŀŜĶĊIJħķ
–! @ôîğéMPI_INTťMPI_DOUBLEť"
–! BinaryĎD4ďêMPI_BYTEĉêIJħķčbytemģfM
•! Source/destinationďêŋŝĸĶ“2ţrankŤĊĹį
ģfM
–! ÏģfMüČïD4ďMPI_ANY_SOURCEģfM
–! 5ýĹįģeĆĈïğSendĊRecvôŐļĻ
–! ċĎĜðČĹįĉęRecvüăïD4ďMPI_ANY_TAGģ
fM
•! StatusĉťNÝč/üăœļĸšĵIJħķťĹįť
ÏČċô"óğ
àŊŝļĮ@Ð
'! _?7JR5?EWģN¸üĈê[ĉªģĻĨļĮþğÐo…
(! Ð!ôºĉ¸ñğD4ďÁ¥ĊÐ!ĎĪšņřļŋô0µ
3*.7!"#$#1-*J87M&3J7NOK6Q73*.70&K*.Q7!"#$S).).T/-7J).).T/-Q7
é!"#$%&''70&''Q7!"#$I-XK-1.7N(-XK-1.7?7
ééæ3*.7J-1.Q73*.7.)WQé
3*.7!"#$#(-0M87M&3J7NOK6Q73*.70&K*.Q7!"#$S).).T/-7J).).T/-Q7
73*.71&K(0-Q73*.7.)WQ7!"#$%&''70&''Q7!"#$I-XK-1.7N(-XK-1.7?7
3*.7!"#$Y)3.787!"#$I-XK-1.7N(-XK-1.Q7!"#$@.).K17N1.).K1?7
ŋŝĸĶĿŏŝĵ
C7D#!"#$%)(.$0(-).-)*!+,-;@@#E;@@,;AJ3#C7D#
7JC@G3#C7D#FJC@G3#C7D#F<?5C;JG3#C7D#5?;5J?53#
*!+,-;@@#FE;@@,E65D9:#
'! 7JC@G€ĎŅħŇšĬŖšŊĎĿŏŝĵģę
ćıőŖłİšĹE;@@,E65Dģb
'! JC@GďāĠĂĠπĎŋŝĸĶm
'! <?5C;JGďāĠĂĠπô9w–óċðó
'! 5?;5J?5ďnpĎıőŖłİšĹĉ5678Ďâ“
ģFrþğóċðó
ĴʼnĿÐϘd
C7D#!"#$%)(.$1Z3[)*!+,-;@@#E;@@3#C7D#
JC5?Eb;73#C7D#JCG<3#C7D#F5678,G;>5E?3#C7D#
F5678,J?GD9:#
'! JC5?Eb;7ďĴʼnĿþğ€
(! 7JC@G€ĉîĠĐ"Ŭ7JC@Ge$#
'! JCG<Ą÷ĴʼnĿüăĊõť/÷.Ğô
5678,G;>5E?ťÏô5678,J?GDčÍğ
'! 9w–ĉďČïD4ťE’ģÊñğĊ
*!+,!0.-,S]11ôÍûĠğ
!"#$%&$'&%()#*+,$)--#+%./-#0,+#12,3.4#%.2#1'*4#"!#
!"#$%)(.$1Z3[)E;@@3#"3#$3#4J;i73#4><9:#
#
!"#+)$5#0+,6#2,3.#"!#
!"#$#(-0M)4>>QB,GD65De$UQ$U3#j_+kT3#*!+,2.]^1T3#J;i73#dPl,$3#
#E;@@3#45?=$9:#
!"#+)$5#0+,6#'*#"!#
!"#$#(-0M)4>>QB,?7JUQ$U3#j_+kT3#*!+,2.]^1T3#><3#dPl,%3#
#E;@@3#45?=%9:#
#
!"#-).2#(,#2,3.#"!#
!"#$@-*J)4>QB,GD65DUQ$U3#j_+kT3#*!+,2.]^1T3#J;i73#dPl,%3#E;@@9:#
!"#-).2#(,#'*#"!!
!"#$@-*J)4>QB,?7Je$UQ$U3#j_+kT3#*!+,2.]^1T3#><3#dPl,$3#E;@@9:#
#
!"#$Y)3.)45?=$3#4GD6D>G$9:#
!"#$Y)3.)45?=%3#4GD6D>G%9:#
£ţ"Ċ7>@<5;EGe$9ĎŋŝĸļIJčćïĈď*!+,!0.-,S]11ôfMûĠ
Œ%Č!ď]¼Čï
/*
* Laplace equation with explicit method
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
/* square region */
#define XSIZE 256
#define YSIZE 256
#define PI 3.1415927
#define NITER 10000
double u[XSIZE + 2][YSIZE + 2], uu[XSIZE + 2][YSIZE + 2];
double time1, time2;
void lap_solve(MPI_Comm);
int myid, numprocs;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
int xsize;
€QÇãA
uuďrnÔ#
void
initialize()
{
int x, y;
}
/* /
for (x = 1; x < XSIZE + 1; x++)
for (y = 1; y < YSIZE + 1; y++)
u[x][y] = sin((x - 1.0) / XSIZE * PI) +
cos((y - 1.0) / YSIZE * PI);
/* /
for (x = 0; x < XSIZE + 2; x++) {
u [x][0] = u [x][YSIZE + 1] = 0.0;
uu[x][0] = uu[x][YSIZE + 1] = 0.0;
}
for (y = 0; y < YSIZE + 2; y++) {
u [0][y] = u [XSIZE + 1][y] = 0.0;
uu[0][y] = uu[XSIZE + 1][y] = 0.0;
}
#define TAG_1 100
#define TAG_2 101
#ifndef FALSE
#define FALSE 0
#endif
void lap_solve(MPI_Comm comm)
{
int x, y, k;
double sum;
double t_sum;
int x_start, x_end;
MPI_Request req1, req2;
MPI_Status status1, status2;
MPI_Comm comm1d;
int down, up;
int periods[1] = { FALSE };
/*
* Create one dimensional cartesian topology with
* nonperiodical boundary
*/
MPI_Cart_create(comm, 1, &numprocs, periods, FALSE, &comm1d);
/* calculate process ranks for 'down' and 'up' */
MPI_Cart_shift(comm1d, 0, 1, &down, &up);
x_start = 1 + xsize * myid;
x_end = 1 + xsize * (myid + 1);
•! Comm1dģ1€Ŀŏŝĵĉb
–! E’ď9w–ĉďČï
•! ĎŋŝĸĶ“2ģup, downč.\
–! E’ĉďMPI_PROC_NULLĊČğ
for (k = 0; k < NITER; k++){
/* old <- new */
for (x = x_start; x < x_end; x++)
for (y = 1; y < YSIZE + 1; y++)
uu[x][y] = u[x][y];
/* recv from down */
MPI_Irecv(&uu[x_start - 1][1], YSIZE, MPI_DOUBLE,
down, TAG_1, comm1d, &req1);
/* recv from up */
MPI_Irecv(&uu[x_end][1], YSIZE, MPI_DOUBLE,
up, TAG_2, comm1d, &req2);
/* send to down */
MPI_Send(&u[x_start][1], YSIZE, MPI_DOUBLE,
down, TAG_2, comm1d);
/* send to up */
MPI_Send(&u[x_end - 1][1], YSIZE, MPI_DOUBLE,
up, TAG_1, comm1d);
MPI_Wait(&req1, &status1);
MPI_Wait(&req2, &status2);
/* update */
for (x = x_start; x < x_end; x++)
for (y = 1; y < YSIZE + 1; y++)
u[x][y] = .25 * (uu[x - 1][y] + uu[x + 1][y] +
uu[x][y - 1] + uu[x][y + 1]);
}
}
/* check sum */
sum = 0.0;
for (x = x_start; x < x_end; x++)
for (y = 1; y < YSIZE + 1; y++)
sum += uu[x][y] - u[x][y];
MPI_Reduce(&sum, &t_sum, 1, MPI_DOUBLE, MPI_SUM, 0, comm1d);
if (myid == 0)
printf("sum = %g\n", t_sum);
MPI_Comm_free(&comm1d);
int
main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Get_processor_name(processor_name, &namelen);
fprintf(stderr, "Process %d on %s\n", myid, processor_name);
}
xsize = XSIZE / numprocs;
if ((XSIZE % numprocs) != 0)
MPI_Abort(MPI_COMM_WORLD, 1);
initialize();
MPI_Barrier(MPI_COMM_WORLD);
time1 = MPI_Wtime();
lap_solve(MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
time2 = MPI_Wtime();
if (myid == 0)
printf("time = %g\n", time2 - time1);
MPI_Finalize();
return (0);
j<þēõ‹
'! Ô#ĎÓüóĆĈïČïĎĉêðĊùġ
Ą÷čþğ
(! Ô#ĎC7J?BĎÁ¥ôáčČğ
(! H¾~Á¥ĉďxÈ–Č‹
'! ŧ€")Ą÷ĄôêŨ€")üăĔðô
*ŽôĜï
(! ÐÖô‰ğ
(! GöĎŋŝĸļIJôñğ
.<?7#_;>5E?#*!+#
'! .<?7*!+#
(! Mm<gRRiiiL;<?7e@<CL;5VR#
'! *!+-a%#
(! Mm<gRRiiie>7CBL@EGL67ALV;WR@<CR@<CEM%R#
'! jP*!++#
(! Mm<gRRiiiLCALCGLGL>eD;8Y;L6ELn<RY6@<CCR#
ışŇħśŠN¸Ď
o
'! ışŇħś
o#@<CEE##c#D?GDLE#c#
(! *!+ĎışŇħśıŐşŀôîğ
(! d+ĉeA@<CģŚşĮþğùĊęĉõğ
'! N¸
o#@<C?B?E#(7#I<5;EG#6L;>D#c#
(! 6L;>DôI<5;EGŋŝĸĶĉN¸ûĠğ
(! (Ď!¦ĉď@<C5>7ô&ûĠťJ?#[6ED;ĊČĆĈïğôťŏš
ĹŊśĉďČï
o#@<C5>7#(7<#I<5;EG#6L;>D#c#
(! N¸ûĠğŋŝĸͱďŐĴş{bʼnĤħśČċĉfMþğ
(! îĝóýĘľšŔşŋŝĸĶģ¢ąøğ]¼ôîğęĎę
ìMPIíŜŏšĿÅä
•! LaplaceĎŋŝįřŒčÙüĈťj<þēõ
‹ţ]¼tRÚĎœŔŚãAϜť2€
")Ťģj<üČûïëŜŏšĿčďŋŝįř
ŒťŋŝįřŒĎÄqťN¸«yťN¸«y
ĎÄqģ8ĘğùĊë