Hello everyone, please I need clarification about some sections of John Conway's Game of life code written in C that is parallelized with OpenMp. The code is below, please if any of the questions is too elementary please don't be offended.
#include <stdio.h>
#include <string.h>
#include <omp.h>
#define NR 15
#define NC 15
int mod(int x, int y) { return x % y; }
char alivep(int neighbours, char alive) {
if (alive && (neighbours == 2 || neighbours == 3)) return 1;
else {
if (neighbours == 3) return 1; else return 0;
}
}
#define SWAP_BOARDS( b1, b2 ) do { \
char* temp = b1; \
b1 = b2; \
b2 = temp; \
} while(0)
#define BOARD( G, X, Y ) ((G)[NC*(X)+(Y)])
char* sequential_game_of_life(char* outgrid, char* ingrid,
const int nrows, const int ncols, const int gens_max) {
int curgen, t;
for (curgen = 0; curgen < gens_max; curgen++)
{
#pragma omp parallel
{
#pragma omp for
for (t = 0; t < nrows * ncols; t++)
{
int i = t / ncols;
int j = t % ncols;
const int inorth = mod(i - 1, nrows);
const int isouth = mod(i + 1, nrows);
const int jwest = mod(j - 1, ncols);
const int jeast = mod(j + 1, ncols);
const char neighbor_count =
BOARD(ingrid, inorth, jwest) +
BOARD(ingrid, inorth, j) +
BOARD(ingrid, inorth, jeast) +
BOARD(ingrid, i, jwest) +
BOARD(ingrid, i, jeast) +
BOARD(ingrid, isouth, jwest) +
BOARD(ingrid, isouth, j) +
BOARD(ingrid, isouth, jeast);
BOARD(outgrid, i, j) = alivep(neighbor_count, BOARD(ingrid, i, j));
}
}
SWAP_BOARDS(outgrid, ingrid);
}
return outgrid;
}
void print_board(char* ingrid, int nrows, int ncols)
{
for (int i = 0; i < nrows; ++i)
{
for (int j = 0; j < ncols; ++j)
{
printf("%c", BOARD(ingrid, i, j) == 0 ? '.' : '*');
}
printf("\n");
}
}
int main() {
const int GENS_MAX = 20;
char ingrid[NR * NC];
char outgrid[NR * NC];
memset(ingrid, 0, NR * NC * sizeof(ingrid[0]));
memset(outgrid, 0, NR * NC * sizeof(outgrid[0]));
ingrid[5 * NC + 4] = 1;
ingrid[5 * NC + 5] = 1;
ingrid[5 * NC + 6] = 1;
ingrid[5 * NC + 7] = 1;
printf("Initial board\n");
print_board(ingrid, NR, NC);
char* out = sequential_game_of_life(outgrid, ingrid, NR, NC, GENS_MAX);
printf("Final board\n");
print_board(out, NR, NC);
}
Question 1 - (This has nothing to do the parallel section) At the BOARD definition -
#define BOARD( G, X, Y ) ((G)[NC*(X)+(Y)])
Why is the index cast to "G" or what is "G" ? If this code was written in Java "G" would have been used to upcast or downcast either a primitive, wrapper class data or an object reference.
Question 2 - (In the parallel section)
#pragma omp parallel
{
#pragma omp for
for (t = 0; t < nrows * ncols; t++)
{
int i = t / ncols;
int j = t % ncols;
Why is for int i the pointer t is divided by the number of columns and for int j the pointer t a modulus operator is applied to the number of columns as shown above ?
Question 3 - The calculated constant values of inorth, isouth, jwest, jeast in this part of the code
#pragma omp parallel
{
#pragma omp for
for (t = 0; t < nrows * ncols; t++)
{
int i = t / ncols;
int j = t % ncols;
const int inorth = mod(i - 1, nrows);
const int isouth = mod(i + 1, nrows);
const int jwest = mod(j - 1, ncols);
const int jeast = mod(j + 1, ncols);
Are they the positions of those cells in the game ?
Thanks for any help inadvance.
What I have tried:
I have worked on every other part of the code and I totally understand all other parts.