32x32 または 64x64 の PBM イメージ ファイルをインポートするプロジェクトに取り組んでいます。以下にサンプルを示します。
P1
# CREATOR: GIMP PNM Filter Version 1.1
32 32
01111110000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000001000000000000
00000000000001100000000000000000
00001100000000100011100000000000
00001100000000000000000000000000
00000011000000000000000000000000
00000011000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000011100000
01000101001000000000000000000000
01000101010000011100000000000000
01000101100000111000000000000000
01000101010000000000000000000000
01000101001000000000000000000000
00111001001000000000000001000000
00000000000000000000000001000000
00000000000000000000000001000000
00000000000000000000000000000000
00000000010000000000000000000000
00000000001000000000000000000000
00000000111000000000000000000000
00000000000000000000000110000000
00000000000000000000001001000000
00110000000000000000000110000000
01100000000000000110000000001000
00100000000000000110000000001100
00000000000000011000000000001100
00000000000000011000000000000100
00000000000000000000000000000000
これは 1D 配列に読み込まれ、順次処理されます。1D 配列を 4x4 パターンの複数の配列に分割しようとしています。「チャンク」に分割されると、一時的な小さな配列が複数の処理要素に分散されます。小さなチャンクが処理されるたびに、「チャンク」はプライマリ ノードに送り返され、再構築されます。
これは、シーケンシャルに動作する完全なコードです。
/* life.c
Play Conway's Game of Life
Reads a P1 file in, outputs a P1 file.
Does as many timesteps as stated on the command line.
Uses a classic 1-element fake zone internally.
Jan. 30, 2013 by H. Dietz
*/
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
unsigned char *
read_P1(int *xdim, int *ydim)
{
register int c, x, y;
register unsigned char *p;
if ((c = getchar()) != 'P') {
pbm_bad:
fprintf(stderr, "Bad PBM input\n");
exit(1);
}
if ((c = getchar()) != '1') goto pbm_bad;
c = getchar();
#define Eat_Space \
while ((c == ' ') || \
(c == '\t') || \
(c == '\n') || \
(c == '\r') || \
(c == '#')) { \
if (c == '#') while ((c = getchar()) != '\n') ; \
c = getchar(); \
}
Eat_Space; /* Eat white space and comments */
#define Get_Number(n) \
{ \
if ((c < '0') || (c > '9')) goto pbm_bad; \
\
n = (c - '0'); \
c = getchar(); \
while ((c >= '0') && (c <= '9')) { \
n *= 10; \
n += (c - '0'); \
c = getchar(); \
} \
}
Get_Number(*xdim); /* Get image width */
Eat_Space; /* Eat white space and comments */
Get_Number(*ydim); /* Get image height */
p = ((unsigned char *)
calloc(((*xdim + 2) * (*ydim + 2)),
sizeof(unsigned char)));
if (p == 0) goto pbm_bad;
Eat_Space;
for (y=0; y<*ydim; ++y) {
for (x=0; x<*xdim; ++x) {
Eat_Space;
switch (c) {
case '1': p[x+1+((y+1)*(*xdim+2))] = 1; break;
case '0': /* 0 from calloc() */ break;
default: goto pbm_bad;
}
c = getchar();
}
}
return(p);
}
#undef Eat_Space
#undef Get_Number
write_P1(register int xdim,
register int ydim,
register unsigned char *p)
{
register int x, y, pos = 0;
printf("P1\n"
"# CREATOR: P1IO\n"
"%d %d\n",
xdim,
ydim);
for (y=0; y<ydim; ++y) {
for (x=0; x<xdim; ++x) {
int c = "01"[ p[x+1+((y+1)*(xdim+2))] != 0 ];
putchar(c);
/* Keep lines even matrices */
if ( (++pos)%xdim == 0) {
putchar('\n');
}
}
}
putchar('\n');
}
int main(int argc, char **argv)
{
if(MPI_Init(&argc, &argv) != MPI_SUCCESS){
exit(1);
}
int xdim, ydim;
int iproc, nproc;
register unsigned char *p, *q, *masterP;
register int x, y, i, j, t, divisions, timesteps;
divisions = 4;
MPI_Comm_size(MPI_COMM_WORLD, &nproc); //nproc = number of PE
MPI_Comm_rank(MPI_COMM_WORLD, &iproc); //iproc = position out of nproc
if (argc != 2) {
fprintf(stderr, "Usage: %s timesteps\n", argv[0]);
exit(2);
}
timesteps = atoi(argv[1]);
/* Carve p into 4x4 and send to 15 processing elements. PE0 will
handle one chunk on its own */
//if(iproc == 0){
int masterx, mastery;
/* Read the initial state image */
masterP = read_P1(&masterx, &mastery);
xdim = (masterx/divisions);
ydim = (mastery/divisions);
/* Make a temporary array to send each chunk of the image */
p = ((unsigned char *)calloc((((xdim)+2) * ((ydim)+2)),
sizeof(unsigned char)));
if (p == 0) {
fprintf(stderr, "Calloc failed\n");
exit(3);
}
printf("Check master P\n");
write_P1(masterx, mastery, masterP);
int loopx , loopy;
int cnt = 0;
for(loopy = 0; loopy < divisions; ++loopy){
for(loopx = 0; loopx < divisions; ++loopx){
x=1;
//Fill p
for (j=(loopy*ydim)+1; j<((loopy+1)*ydim+2); ++j){
for( i=(loopx*xdim)+1; i<((loopx+1)*xdim+2); ++i){
//printf("j: %d i: %d\n",j,i);
p[x]=masterP[i+(loopy*j)+1];
printf("%d",p[x]);
x++;
}
}
//Print P contents
printf("\nIteration Y:%d X:%d\n",loopy, loopx);
write_P1(xdim, ydim, p);
}
}
//MPI_Send(p, sizeof(temp), MPI_UNSIGNED_CHAR, pe_num, 0, MPI_COMM_WORLD);
//++pe_num;
//}/* End IProc 0's business */
/* Make a target image (with blank fake zone) */
q = ((unsigned char *)
calloc(((xdim + 2) * (ydim + 2)),
sizeof(unsigned char)));
if (q == 0) {
fprintf(stderr, "Calloc failed\n");
exit(3);
}
/* Iterate over the timesteps */
for (t=0; t<timesteps; ++t) {
#ifdef VERBOSE
fprintf(stderr, "Timestep %d...\n", t);
#endif
for (y=0; y<ydim; ++y) {
for (x=0; x<xdim; ++x) {
#define FAKE(P, X, Y) P[((X)+1)+(((Y)+1)*(xdim+2))]
register int live = FAKE(p, x-1, y-1) +
FAKE(p, x, y-1) +
FAKE(p, x+1, y-1) +
FAKE(p, x-1, y) +
FAKE(p, x+1, y) +
FAKE(p, x-1, y+1) +
FAKE(p, x, y+1) +
FAKE(p, x+1, y+1);
/* Apply Conway's rules...
(yes, I know this is clever code!)
*/
FAKE(q, x, y) = ((live == 3) ||
((live == 2) &&
FAKE(p, x, y)));
}
}
/* Swap our notion of p and q...
this saves us copying every timestep
*/
{
register unsigned char *pt = p;
p = q;
q = pt;
}
} /* End iterate timestep for block */
/* Done; write-out results */
write_P1(masterx, mastery, q);
exit(0);
}
次の例では、大きな配列masterP
を 4x4 の「チャンク」に分割する必要があります。
int loopx , loopy;
int cnt = 0;
for(loopy = 0; loopy < divisions; ++loopy){
for(loopx = 0; loopx < divisions; ++loopx){
x=1;
//Fill p
for (j=(loopy*ydim)+1; j<((loopy+1)*ydim+2); ++j){
for( i=(loopx*xdim)+1; i<((loopx+1)*xdim+2); ++i){
//printf("j: %d i: %d\n",j,i);
p[x]=masterP[i+(loopy*j)+1];
printf("%d",p[x]);
x++;
}
}
//Print P contents
printf("\nIteration Y:%d X:%d\n",loopy, loopx);
write_P1(xdim, ydim, p);
}
}
しかし、私の結果の配列はすべて0です。言うのは不適切ですか
p[x]=masterP[i+(loopy*j)+1];
Arrayp
は、 の 4x4 の「チャンク」になるように作成された配列ですmasterP
。
出力例:
P1
# CREATOR: GIMP PNM Filter Version 1.1
32 32
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000001000000000000
00000000000001100000000000000000
00001100000000100011100000000000
00001100000000000000000000000000
00000011000000000000000000000000
00000011000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000011100000
01000101001000000000000000000000
01000101010000011100000000000000
01000101100000111000000000000000
01000101010000000000000000000000
01000101001000000000000000000000
00111001001000000000000001000000
00000000000000000000000001000000
00000000000000000000000001000000
00000000000000000000000000000000
00000000010000000000000000000000
00000000001000000000000000000000
00000000111000000000000000000000
00000000000000000000000110000000
00000000000000000000001001000000
00110000000000000000000110000000
01100000000000000110000000001000
001000000000000001100000000000001100
00000000000000011000000000000100
00000000000000000000000000000000
Check master P
P1
# CREATOR: P1IO
32 32
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000001000000000000
00000000000001100000000000000000
00001100000000100011100000000000
00001100000000000000000000000000
00000011000000000000000000000000
00000011000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000011100000
01000101001000000000000000000000
01000101010000011100000000000000
01000101100000111000000000000000
01000101010000000000000000000000
01000101001000000000000000000000
00111001001000000000000001000000
00000000000000000000000001000000
00000000000000000000000001000000
00000000000000000000000000000000
00000000010000000000000000000000
00000000001000000000000000000000
00000000111000000000000000000000
00000000000000000000000110000000
00000000000000000000001001000000
00110000000000000000000110000000
01100000000000000110000000001000
00100000000000000110000000001100
00000000000000011000000000001100
00000000000000011000000000000100
00000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:0 X:0
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:0 X:1
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:0 X:2
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:0 X:3
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:1 X:0
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:1 X:1
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:1 X:2
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:1 X:3
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:2 X:0
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:2 X:1
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:2 X:2
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:2 X:3
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:3 X:0
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:3 X:1
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:3 X:2
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000
Iteration Y:3 X:3
P1
# CREATOR: P1IO
8 8
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
P1
# CREATOR: P1IO
32 32
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000100000
11011100011111100111110000000000
11110001111110011111000111111000
00000000000101111100000000000111
00000000000000000010000000110111
01111110010000000100000001111110
00000100000000100000001101110000
00000000000000000000000000000000
00000000000000000001111100011111
01111100011111000111110001111100
11110000111100011111000111110001
11000111111001111100011111100111
00011111100111110001111110011111
01111110011111000111111001111100
11111001111100011111100111110001
11100111110001111110011111000111
10011111000111111001111100011111
01111100000000000111110001111110
11110001111110000000000000000100
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
ご協力ありがとうございました!