I am working on a project where we import a 32x32 or 64x64 PBM image file. Sample is provided below:
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
This is read into a 1D array and processed sequentially. I am attempting to break the 1D array into multiple arrays in a 4x4 pattern. Once broken into "chunks" the temporary smaller arrays will be distributed to multiple processing elements. After each smaller chunk has been processed the "chunks" will be sent back to the primary node to be reassembled.
This is the complete code which is working in a sequential manner:
/* 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);
}
The following should break the large array masterP
into 4x4 "chunks":
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);
}
}
However, my resulting arrays are all 0. Is it improper to say
p[x]=masterP[i+(loopy*j)+1];
Array p
is an array created to be a 4x4 "chunk" of masterP
.
Sample output:
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
Thank you for your help!