File read issues - Parallel version of Game of Life

Sam Parsons

For my Parallel Computing class, I am working on a project that parallelizes the Game of Life using MPI. I am specifically implementing exercise 6.13 in "Parallel Programming in C with MPI and OpenMP" by Michael J. Quinn.

I am using the author's pre-written library function, "read_row_striped_matrix". The following is the code for the function:

/*
 *   Process p-1 opens a file and inputs a two-dimensional
 *   matrix, reading and distributing blocks of rows to the
 *   other processes.
 */

void read_row_striped_matrix (
   char        *s,        /* IN - File name */
   void      ***subs,     /* OUT - 2D submatrix indices */
   void       **storage,  /* OUT - Submatrix stored here */
   MPI_Datatype dtype,    /* IN - Matrix element type */
   int         *m,        /* OUT - Matrix rows */
   int         *n,        /* OUT - Matrix cols */
   MPI_Comm     comm)     /* IN - Communicator */
{
   int          datum_size;   /* Size of matrix element */
   int          i;
   int          id;           /* Process rank */
   FILE        *infileptr;    /* Input file pointer */
   int          local_rows;   /* Rows on this proc */
   void       **lptr;         /* Pointer into 'subs' */
   int          p;            /* Number of processes */
   void        *rptr;         /* Pointer into 'storage' */
   MPI_Status   status;       /* Result of receive */
   int          x;            /* Result of read */

   MPI_Comm_size (comm, &p);
   MPI_Comm_rank (comm, &id);
   datum_size = get_size (dtype);

   /* Process p-1 opens file, reads size of matrix,
      and broadcasts matrix dimensions to other procs */

   if (id == (p-1)) {
      infileptr = fopen (s, "r");
      if (infileptr == NULL) *m = 0;
      else {
         fread (m, sizeof(int), 1, infileptr);
         fread (n, sizeof(int), 1, infileptr);
      }      
   }
   MPI_Bcast (m, 1, MPI_INT, p-1, comm);

   if (!(*m)) MPI_Abort (MPI_COMM_WORLD, OPEN_FILE_ERROR);

   MPI_Bcast (n, 1, MPI_INT, p-1, comm);

   local_rows = BLOCK_SIZE(id,p,*m);

   /* Dynamically allocate matrix. Allow double subscripting
      through 'a'. */

   *storage = (void *) my_malloc (id,
       local_rows * *n * datum_size);
   *subs = (void **) my_malloc (id, local_rows * PTR_SIZE);

   lptr = (void *) &(*subs[0]);
   rptr = (void *) *storage;
   for (i = 0; i < local_rows; i++) {
      *(lptr++)= (void *) rptr;
      rptr += *n * datum_size;
   }

   /* Process p-1 reads blocks of rows from file and
      sends each block to the correct destination process.
      The last block it keeps. */

   if (id == (p-1)) {
      for (i = 0; i < p-1; i++) {
         x = fread (*storage, datum_size,
            BLOCK_SIZE(i,p,*m) * *n, infileptr);
         MPI_Send (*storage, BLOCK_SIZE(i,p,*m) * *n, dtype,
            i, DATA_MSG, comm);
      }
      x = fread (*storage, datum_size, local_rows * *n,
         infileptr);
      fclose (infileptr);
   } else
      MPI_Recv (*storage, local_rows * *n, dtype, p-1,
         DATA_MSG, comm, &status);
}

In the beginning of my code, I call "read_row_striped_matrix" like this:

#include <stdio.h>
#include <mpi.h>
#include "MyMPI.h"

typedef int dtype;
#define MPI_TYPE MPI_INT

int main(int argc, char *argv[]) {

  dtype** matrix;         /* Doubly-subscripted array */
  dtype*  storage;        /* Local portion of array elements */
  int     proc_id;        /* Process Rank */
  int     row_count;      /* Number of rows in matrix */
  int     col_count;      /* Number of columns in matrix */
  int     proc_count;     /* Number of processes */ 
  int     i;              /* Used with for loop */

  MPI_Init                (&argc, &argv);
  MPI_Comm_rank           (MPI_COMM_WORLD, &proc_id);
  MPI_Comm_size           (MPI_COMM_WORLD, &proc_count); 


  read_row_striped_matrix (argv[3], (void *) &matrix, (void *) &storage, MPI_TYPE, 
    &row_count, &col_count, MPI_COMM_WORLD);

  ....

The problem is, my implementation was getting stuck in an infinite loop. So I started debugging by testing to see if the data was being read from the text file correctly. My text file named "file_input.txt" contains the following input, where the first number (5) represents the number of rows, and the second number (also 5) represents the number of cols, and the rest of the data are the values in the matrix:

5 5 0 0 1 0 1 0 0 1 ...

I inserted the following printf statements in the section of library code where the length and height was being read from the text file:

if (id == (p-1))    
    printf("The name of the file is %s\n", s);
    infileptr = fopen (s, "r");
    if (infileptr == NULL) *m = 0;
    else {
        printf("The value of m is %d\n", *m);

        size_t ret_val      = fread (m, sizeof(int), 1, infileptr);
        size_t next_ret_val = fread (n, sizeof(int), 1, infileptr);

        printf("The total # of elements successfully read is: %d\n", ret_val);
        printf("The total # of elements successfully read is: %d\n", next_ret_val);

        printf("The value of m is %d\n", *m);
        printf("The value of n is %d\n", *n);
   }
}

For executing "project_3 5 5 file_input.txt", The output of the program is:

The name of the file is: file_input.txt
The value of m is 0
The total number of elements successfully read is: 1
The total number of elements successfully read is: 1
The value of m is: 540549176
The value of n is: 540090416
...

From what I observe, the name of the file was read in correctly, and the value of m (0) is correct before calling fread. fread is reading in the correct # of elements for both m and n, but the values are "540549176" and "540090416" instead of 5 and 5. When I try changing the numbers in the beginning of the text file to say, "3 and 4" for example, the value of m and n does not change.

Does anybody have any idea why the first two integers are not being read in from the text file correctly? Thanks in advance.

Rob Latham

You have two options here:

  • this program is expecting binary input. so you need to produce binary input somehow. "5" is an ascii character with the hex value 0x35 (decimal 53). When you fread sizeof(int), you are actually going to pull in 2 characters.

  • you can edit the program to parse ascii text but this is kind of annoying. First you read in a line of the file, then you tokenize it, then you convert each token into integers. Are you coming from a perl/python background? This text conversion stuff is nearly automatic in scripting languages. nothing is automatic in C

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

C Game of life issues

From Dev

Segmentation Fault Issues in Game of Life Implementation

From Dev

Segmentation Fault Issues in Game of Life Implementation

From Dev

Conway's Game of Life Applying Rules of Life Issues Android

From Dev

Game of Life: Cannot read property 'state' of undefined

From Dev

Game of Life Parallel.For loop doesnt work as it is supposed to

From Dev

About PHP parallel file read/write

From Dev

Parallel read the contents of a zipped file without extraction

From Dev

Game of Life: find neighbours

From Dev

conways game of life in ruby

From Dev

Python - Conways Game of life

From Dev

Python, and The Game of Life Rules

From Dev

Game of Life Processing

From Dev

Conways Game of Life not updating

From Dev

multithreaded game of life in c

From Dev

Game of Life, C checking life conditions

From Dev

Confusing error in Game Of Life program

From Dev

Game Of Life, FileIO Storing boards

From Dev

Python Conway's Game of Life

From Dev

Conway's Game Of Life In C

From Dev

Game of Life in D Programming Language

From Dev

Game of life Oscillators and Spaceships not working

From Dev

Constructing borders for rectangles in Game of life

From Dev

Conway's game of life error

From Dev

How to read all lines of a file in parallel in Java 8

From Dev

Can I read 1 big CSV file in parallel in R?

From Dev

How can two text files be read in parallel by a batch file?

From Dev

Using shell arrays to read every N lines in parallel of a file

From Dev

Multiple read from a txt file in bash (parallel processing )