示例#1
0
void test() {
  int multipnm=1;
  job_t job;


  while (multipnm==1) {
    job_init(&job);

    job.cfg.out_format=XML;
    job.cfg.cfilter = filter;
    job.src.fname = "patch00000.pgm";   // TODO

    multipnm=readpgm(job.src.fname, &job.src.p, job.cfg.verbose);
 
    if (multipnm<0) break; 

    pgm2asc(&job);

    int linecounter = 0;
  const char *line;
  line = getTextLine(linecounter++);
  while (line) {
    //fputs(line, stdout);
    //Interpret line here

    line = getTextLine(linecounter++);
  }
  free_textlines();
    job_free(&job);
  }
  return;
}
示例#2
0
文件: gocr.c 项目: rainlabs/gocr-ruby
static int read_picture(job_t *job) {
  int rc=0;
  assert(job);

  if (strstr(job->src.fname, ".pcx"))
    readpcx(job->src.fname, &job->src.p, job->cfg.verbose);
  else
    rc=readpgm(job->src.fname, &job->src.p, job->cfg.verbose);
  return rc; /* 1 for multiple images, -1 on error, 0 else */
}
//
// Programa de binarização de imagems pgm, que recebe o nome
// dos ficheiros pela linha de comando
//	
int main(int argc, char **argv){
  int height, width, i, j, datasize;
  unsigned char **imptr, *dp, limiar;

  printf("Lendo imagem '%s'...\n", argv[1]);
  imptr=readpgm(argv[1],&width,&height);
  printf("\tOk.\n\n");
  
  datasize=width*height;
  if(!(dp=(unsigned char *)calloc(sizeof(char),datasize))){
	fprintf(stderr,"writepgm: calloc error\n");
	exit(0);
    }
  for (i=0;i<height;i++)
    for (j=0;j<width;j++)
      dp[i*width+j]=imptr[i][j];

  #define LIMIAR 128
  if (argc<4)
  {
    limiar = LIMIAR;
    printf("Nao foi indicado na linha de comandos o limiar a utilizar.\n");
    printf("\tSera usado o valor por defeito %u.\n", limiar);
  }
  else limiar = (unsigned char) atoi(argv[3]);

  printf("Executando a funcao 'bin_img()' com o limiar %u...\n", 
limiar);
  bin_img(dp, width, height, limiar);
  printf("\tFim.\n\n");  

  for(i=0;i<height;i++)
      for(j=0;j<width;j++)
	imptr[i][j]=dp[i*width+j];

  printf("Guardando o resultado no ficheiro '%s'...\n", argv[2]);
  writepgm(imptr,width,height,argv[2]);
  printf("\tOk.\n\n");
}
示例#4
0
int main(int argn, char *argv[])
{
  char *inam, *onam;
  pix bild;
  int ox, oy, dx, dy, x, y, i, vvv = 0;

#ifdef HAVE_PAM_H
  pnm_init(&argn, argv);
#endif
  // skip options
  for (i = 1; i < argn; i++) {
    if (argv[i][0] != '-')
      break;
    if (!strcmp(argv[i], "-?"))
      help();
    else if (!strcmp(argv[i], "-help"))
      help();
    else if (!strcmp(argv[i], "-shrink"))
      vvv |= 2;
    else if (!strcmp(argv[i], "-pbm"))
      vvv |= 4;
    else
      printf("unknown option: %s\n", argv[i]);
  }

  if (argn - i != 6)
    help();
  inam = argv[i++];
  onam = argv[i++];
  ox = atoi(argv[i++]);
  oy = atoi(argv[i++]);
  dx = atoi(argv[i++]);
  dy = atoi(argv[i++]);
  printf("# in=%s out=%s offs=%d,%d len=%d,%d vvv=%d\n",
	 inam, onam, ox, oy, dx, dy, vvv);

  // ----- read picture
  if (strstr(inam, ".pbm") ||
      strstr(inam, ".pgm") ||
      strstr(inam, ".ppm") ||
      strstr(inam, ".pnm") ||
      strstr(inam, ".pam"))
    readpgm(inam, &bild, 1);
  else if (strstr(inam, ".pcx"))
    readpcx(inam, &bild, 1);
  else if (strstr(inam, ".tga"))
    readtga(inam, &bild, ((vvv > 1) ? 0 : 1));
  else {
    printf("Error: unknown suffix\n");
    exit(1);
  }
  if (ox < 0 || ox >= bild.x)
    ox = 0;
  if (oy < 0 || ox >= bild.y)
    oy = 0;
  if (dx <= 0 || ox + dx > bild.x)
    dx = bild.x - ox;
  if (dy <= 0 || oy + dy > bild.y)
    dy = bild.y - oy;
  if ((vvv & 2) == 2 && bild.bpp == 1) {	// -shrink
    int x, y;
    printf("# shrinking PGM:   offs=%d,%d len=%d,%d\n", ox, oy, dx, dy);
    for (y = 0; y < dy; y++) {	// shrink upper border
      for (x = 0; x < dx; x++)
	if (bild.p[x + ox + (y + oy) * bild.x] < 127)
	  break;
      if (x < dx) {
	if (y > 0)
	  y--;
	oy += y;
	dy -= y;
	break;
      }
    }
    for (y = 0; y < dy; y++) {	// shrink lower border
      for (x = 0; x < dx; x++)
	if (bild.p[ox + x + (oy + dy - y - 1) * bild.x] < 127)
	  break;
      if (x < dx) {
	if (y > 0)
	  y--;
	dy -= y;
	break;
      }
    }
    for (x = 0; x < dx; x++) {	// shrink left border
      for (y = 0; y < dy; y++)
	if (bild.p[x + ox + (y + oy) * bild.x] < 127)
	  break;
      if (y < dy) {
	if (x > 0)
	  x--;
	ox += x;
	dx -= x;
	break;
      }
    }
    for (x = 0; x < dx; x++) {	// shrink right border
      for (y = 0; y < dy; y++)
	if (bild.p[ox + dx - x - 1 + (oy + y) * bild.x] < 127)
	  break;
      if (y < dy) {
	if (x > 0)
	  x--;
	dx -= x;
	break;
      }
    }
  }
  printf("# final dimension: offs=%d,%d len=%d,%d bpp=%d\n",
	 ox, oy, dx, dy, bild.bpp);

/* bbg: could be changed to memmoves */
  // ---- new size
  for (y = 0; y < dy; y++)
    for (x = 0; x < dx; x++)
      for (i = 0; i < 3; i++)
	bild.p[i + bild.bpp * (x + dx * y)] =
	  bild.p[i + bild.bpp * (x + ox + (y + oy) * bild.x)];
  bild.x = dx;
  bild.y = dy;
  // ---- write internal picture of textsite 
  printf("# write %s\n", onam);
  if (strstr(onam, ".pbm"))
    writepbm(onam, &bild);
  else if (strstr(onam, ".pgm"))
    writepgm(onam, &bild);
  else if (strstr(onam, ".ppm"))
    writeppm(onam, &bild);
  else if (strstr(onam, ".pnm"))
    writepgm(onam, &bild);
  else
    printf("Error: unknown suffix");
  free( bild.p );
}
int main(int argc, char* argv[]) {
  // Initialize MPI
  MPI_Init(&argc, &argv);

  // Get the communicator and process information
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &np);

  // Print rank and hostname
  MPI_Get_processor_name(my_name, &my_name_len);
  printf("Rank %i is running on %s\n", rank, my_name );

  // Initialize the pretty printer
  init_pprintf( rank );
  pp_set_banner( "main" );
  if( rank==0 )
  pprintf( "Welcome to Conway's Game of Life!\n" );

  
  // Determine the partitioning
  nrows = np;
  ncols = 1;

  
  int steps;
  
  MPI_Status status;
  if( np != nrows * ncols )
  {
    if( rank==0 )
      pprintf("Error: %ix%i partitioning requires %i np (%i provided)\n", 
        nrows, ncols, nrows * ncols, np );
    MPI_Finalize();
    return 1;
  }
  my_col = 0;
  my_row = rank;

  if(!readpgm("life.pgm"))
  {
    if( rank==0 )
    pprintf( "An error occured while reading the pgm file\n" );
    MPI_Finalize();
    return 1;
  }
  int j=0;
    for( int y=1; y<local_height+1; y++ )
    {
      for( int x=1; x<local_width+1; x++ )
      {
        if( field_a[ y * field_width + x ] )
        {
          j++;
        }
      }
    }
   // pprintf( "%i local buggies\n", i );
    int total_initial;
    MPI_Allreduce( &j, &total_initial, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
    if( rank==0 )
      pprintf( "%i total initial buggies\n", total_initial );
  // we have field_a and field_b with ghost nodes
  /* set ghost nodes to be DEAD */
      //printf("Rank: %d : : field_width = %d field_height = %d local_width = %d local_height = %d\n",rank,field_width,field_height,local_width,local_height );
  
     //printf("field_a[%d] = %d\n",7,field_a[12] );
  for(steps = 0; steps<NSTEPS; steps++){
    for( int x=0; x<field_width; x++ )
      {
        field_a[x] = DEAD;
        field_a[(field_height-1) * field_width + x] = DEAD;
      }
   

      
      for(int y=0; y<field_height; y++)
      {
        field_a[y * field_width] = DEAD;
      }
      for(int y=0; y<field_height; y++)
      {
        field_a[y * field_width + (field_width - 1) ] = DEAD;
      }

       for( int x=0; x<field_width * field_height; x++ ){
        //printf("Rank: %d field_a[%d] = %d\n",rank,x,field_a[x] );
      }
     //while(1){}

      
        if(rank < np-1){
          //printf("inside mpi send\n");
          MPI_Send(&field_a[(field_height-2)*field_width],field_width, MPI_INT, rank+1, 0 ,MPI_COMM_WORLD);
        }
        if(rank > 0){
          MPI_Send(&field_a[1 * field_width],field_width, MPI_INT, rank-1, 1 ,MPI_COMM_WORLD);
        }
        if(rank >0){
          //dummy_field_a = (int *)malloc( field_width * sizeof(int));
          MPI_Recv(&field_a[0], field_width, MPI_INT, rank-1, 0, MPI_COMM_WORLD, &status);
          //int count = 0;
        
        }
        
        
        if(rank < np-1){
          //dummy_field_a1 = (int *)malloc( field_width * sizeof(int));
          MPI_Recv(&field_a[((field_height-1) * field_width)], field_width, MPI_INT, rank+1, 1, MPI_COMM_WORLD, &status);
            
        }
        //while(1){}
        int x,y;
        for(y=0; y<field_height; y++ )
        {
        for(x=0; x<field_width; x++ )
          {
            
          //printf("Rank:%d field_a[%d]=%d\t", rank, (y*field_width + x),field_a[y*field_width + x]);
          }
          //printf("\n");
        }
        //while(1){}

    for( int y=1; y<field_height-1; y++ )
    {
      for( int x=1; x<field_width-1; x++ )
      {
          //int neighbors = 0;
          int ll = y * field_width + x;
          //neighbors[ll] = 0;
          int lx_N = (x);
          int ly_N = (y-1);
          int ll_N = (ly_N * field_width + lx_N );
          //printf("Rank : %d ll_N = %d field_a[ll_N] = %d\n",rank,ll_N,field_a[ll_N] );
          
          int lx_S = (x);
          int ly_S = (y+1);
          int ll_S = (ly_S * field_width + lx_S );
         // printf("Rank : %d ll_S = %d field_a[ll_S] = %d\n",rank,ll_S,field_a[ll_S] );
          

          int lx_E = (x+1);
          int ly_E = (y);
          int ll_E = (ly_E * field_width + lx_E );
          //printf("Rank : %d ll_E = %d field_a[ll_E] = %d\n",rank,ll_E ,field_a[ll_E]);
          
          
          int lx_W = (x-1);
          int ly_W = (y);
          int ll_W = (ly_W * field_width + lx_W );
          //printf("Rank : %d ll_W = %d field_a[ll_W] = %d\n",rank,ll_W ,field_a[ll_W]);
          
          int lx_NW = (x-1);
          int ly_NW = (y-1);
          int ll_NW = (ly_NW * field_width + lx_NW );
          //printf("Rank : %d ll_NW = %d field_a[ll_NW] = %d\n",rank,ll_NW,field_a[ll_NW] );
          
          int lx_NE = (x+1);
          int ly_NE = (y-1);
          int ll_NE = (ly_NE * field_width + lx_NE );
          //printf("Rank : %d ll_NE = %d field_a[ll_NE] = %d\n",rank,ll_NE ,field_a[ll_NE]);
          

          int lx_SW = (x-1);
          int ly_SW = (y+1);
          int ll_SW = (ly_SW * field_width + lx_SW );
          //printf("Rank : %d ll_SW = %d field_a[ll_SW] = %d\n",rank,ll_SW,field_a[ll_SW] );
          //neighbors[ll] = neighbors[ll] + field_a[ll_SW];

          
          int lx_SE = (x+1);
          int ly_SE = (y+1);
          int ll_SE = (ly_SE * field_width + lx_SE );
          //printf("Rank : %d ll_SE = %d field_a[ll_SE] = %d\n",rank,ll_SE,field_a[ll_SW] );
          
          
          int neighbors = field_a[ll_N] + field_a[ll_S] + field_a[ll_E] + field_a[ll_W] + field_a[ll_NW] + field_a[ll_NE] + field_a[ll_SW] + field_a[ll_SE] ;

          //printf("Rank : %d neighbors = %d of ll %d\n",rank, neighbors ,ll);

          
          if (field_a[ll] == ALIVE && (neighbors < TWO || neighbors > THREE)){
            field_b[ll]= DEAD;
            //printf("rank %d field_b[%d] = %d\n",rank,ll,field_b[ll] );
          }
          else if(field_a[ll] == ALIVE && (neighbors == TWO || neighbors == THREE)){
            field_b[ll] = ALIVE;
            //printf("rank %d field_b[%d] = %d\n",rank,ll,field_b[ll] );
          }
          else if (field_a[ll] == DEAD && neighbors == THREE){
            field_b[ll] = field_a[ll]+1;
            //printf("rank %d field_b[%d] = %d\n",rank,ll,field_b[ll] );
          }
          else{
            field_b[ll] = field_a[ll];
            //printf("rank %d field_b[%d] = %d\n",rank,ll,field_b[ll] );
          }
         
          
      }
    }
   
    
    for(int p=1; p<field_height-1; p++){
      for(int q=1; q<field_width-1; q++){
        int ll = p*field_width + q;
        field_a[ll] = field_b[ll];
      }
    }
    

    // Count the life forms. Note that we count from [1,1] - [height+1,width+1];
    // we need to ignore the ghost row!
    int i=0;
    for( int y=1; y<local_height+1; y++ )
    {
      for( int x=1; x<local_width+1; x++ )
      {
        if( field_a[ y * field_width + x ] )
        {
          i++;
        }
      }
    }
    int *temp_field_a = (int *)malloc( local_width * local_height * sizeof(int));
    int temp = 0;
    for(int j=1; j<local_height+1; j++){
      for(int k=1;k<local_width+1; k++){
        temp_field_a[temp] = field_a[j * field_width + k];
        //printf("Rank : %d temp_field_a[%d] = %d\n",rank,temp,temp_field_a[temp] );
        temp ++;
        
      }
    }

   // pprintf( "%i local buggies\n", i );
    int total;
    MPI_Allreduce( &i, &total, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
    if( rank==0 )
      pprintf( "%i total buggies\n", total );

    
    int height_main = local_height * np;
    int width_main = local_width * 1;
    int *anim = (int *)malloc( width_main * height_main * sizeof(int));
    //printf("height_main = %d and width_main = %d\n",height_main,width_main );

    
    /**************** writing into .pgm file and create animation *******************/
    MPI_Gather(temp_field_a,local_height*local_width,MPI_INT,anim,local_height*local_width,MPI_INT,0,MPI_COMM_WORLD); //Gather local matrices
    /********************************************************************************/
    if(rank == 0){
      for(int k=0;k< width_main*height_main; k++){
        //printf("anim[%d] = %d\n",k,anim[k] );
      }
    }
    /********** write into .pgm file *********************/
    if(rank ==0){
    char filename[1000];
    FILE *pgmfile;
    sprintf(filename, "test%d.pbm", steps);
    pgmfile = fopen(filename, "wb");
    if (pgmfile == NULL) {
        perror("cannot open file to write");
        exit(EXIT_FAILURE);
    }
 
    fprintf(pgmfile, "P1 ");
    fprintf(pgmfile, "%d %d ", width_main, height_main);
    fprintf(pgmfile, "%d ", 1);
    for(int y=0;y<height_main;y++)
          {
            for(int x=0;x<width_main;x++)
            {
              fputc(anim[y*width_main +x]+48, pgmfile );   
                          
            }
            
          }
        fclose(pgmfile);
    /*****************************************************/
      }
  }

    
    
  // Free the fields
  if( field_a != NULL ) free( field_a );
  if( field_b != NULL ) free( field_b );

  // Finalize MPI and terminate
  if( rank==0 )
    pprintf( "Terminating normally\n" );
  MPI_Finalize();
  return 0;
} 
示例#6
0
int main (int argc, char **argv)
{
    struct arguments arguments;

    /* Parse our arguments; every option seen by parse_opt will
       be reflected in arguments. */
    argp_parse (&argp, argc, argv, 0, 0, &arguments); 

    int run_type;
    run_type = 0; //default is serial
    if (sscanf (arguments.args[0], "%i", &run_type)!=1) {}

    int iterations;
    iterations = 0; //default is serial
    if (sscanf (arguments.args[1], "%i", &iterations)!=1) {}

    int count_when;
    count_when = 1000;
    if (sscanf (arguments.args[2], "%i", &count_when)!=1) {}

    char print_list[200]; //used for input list
    if (sscanf (arguments.args[3], "%s", &print_list)!=1) {}

    // printf("Print list = %s\n", print_list);

    //Extract animation list from arguments
    char char_array[20][12] = { NULL };   //seperated input list
    int animation_list[20][2] = { NULL }; //integer input list start,range
    char *tok = strtok(print_list, ",");

    //counters
    int i,j,k,x,y,ii,jj;
    ii = 0;
    jj = 0;

    //Loop over tokens parsing our commas
    int tok_len = 0;
    while (tok != NULL)
    {
        //first loop parses out commas
        tok_len = strlen(tok);
        for (jj=0;jj<tok_len;jj++)
        {
            char_array[ii][jj] = tok[jj];
        }

        // printf("Tok = %s\n", char_array[ii]);
        tok = strtok(NULL, ",");
        ii++;
    }

    //looking for a range input, convert to ints
    int stop;
    for (ii=0;ii<20;ii++)
    {
        //convert first number to int
        tok = strtok(char_array[ii], "-");
        if (tok != NULL)
        {
            animation_list[ii][0] = atoi(tok);
            tok = strtok(NULL, ",");
        }
        
        //look for second number, add to range
        if (tok != NULL)
        {
            stop = atoi(tok);
            animation_list[ii][1] = stop - animation_list[ii][0];
        }

        // if (rank == 0)
        // {
        //     printf("Animation_list = %i, %i\n", 
        //         animation_list[ii][0], animation_list[ii][1]);

        // }
    }
    
    
    

    //should an animation be generated
    //prints a bunch of .pgm files, have to hand
    //make the gif...
    int animation;
    animation = arguments.animation;

    //verbose?
    int verbose;
    verbose = arguments.verbose;
    // printf("VERBOSE = %i",verbose);
    if (verbose>0 && verbose<=10)
    {
        verbose = 1;
    }

    

    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    // Get the number of processes
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    // Get the rank of the process
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    // Get the name of the processor
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

    //Print run information, exit on bad command line input
    if (rank == 0 && verbose == 1)
    {
        printf("Verbose=%i, RunType=%i, Iterations=%i, CountWhen=%i, Animation=%i\n",
            verbose,run_type,iterations,count_when, animation);
    }
    if (world_size>1 && run_type ==0)
    {
        printf("Runtype and processors count not consistant\n");
        MPI_Finalize();
        exit(0);
    }
    if (world_size==1 && run_type>0)
    {
        printf("Runtype and processors count not consistant\n");
        MPI_Finalize();
        exit(0);
    }
    if (count_when <= 0)
    {
        if (rank == 0)
        {
            printf("Invalid count interval, positive integers only\n");
        }
        MPI_Finalize();
        exit(0);
    }

     //serial
    if (world_size == 1 && run_type == 0)
    {

        ncols=1;
        nrows=1;
    }
    //Blocked
    else if (world_size>1 && run_type == 1)
    {
        ncols = 1;
        nrows = world_size;
        my_col = 0;
        my_row = rank;
    }
    //Checker
    else if (world_size>1 && run_type == 2)
    {
        ncols = (int)sqrt(world_size);
        nrows = (int)sqrt(world_size);

        my_row = rank/nrows;
        my_col = rank-my_row*nrows;

        if (ncols*nrows!=world_size)
        {
            if (rank == 0)
            {
                printf("Number of processors must be square, Exiting\n");
            }
            MPI_Finalize();
            exit(0);
        }
    }

    // if (verbose == 1)
    // {
    //     printf("WR,row,col=%i,%i,%i\n",rank,my_row,my_col);
    // }

    
    //////////////////////READ IN INITIAL PGM////////////////////////////////
    if(!readpgm("life.pgm"))
    {
        // printf("WR=%d,HERE2\n",rank);
        if( rank==0 )
        {
            pprintf( "An error occured while reading the pgm file\n" );
        }
        MPI_Finalize();
        return 1;
    }

    // Count the life forms. Note that we count from [1,1] - [height+1,width+1];
    // we need to ignore the ghost row!
    i = 0;
    for(y=1; y<local_height+1; y++ )
    {
        for(x=1; x<local_width+1; x++ )
        {
            if( field_a[ y * field_width + x ] )
            {
                i++;
            }
        }
    }
    // pprintf( "%i local buggies\n", i );

    int total;
    MPI_Allreduce( &i, &total, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
    if( rank==0  && verbose == 1 )
    {
        pprintf( "%i total buggies\n", total );
    }
    

    
    // printf("WR=%d, Row=%d, Col=%d\n",rank,my_row,my_col);

    //Row and column size per processor
    int rsize, csize; 
    rsize = local_width;
    csize = local_height;


    if (rank == 0 && verbose == 1)
    {
        printf("rsize,csize,NP = %d, %d, %d\n",rsize,csize,world_size);
    }
    
    //Create new derived datatype for writing to files
    MPI_Datatype submatrix;

    int array_of_gsizes[2];
    int array_of_distribs[2];
    int array_of_dargs[2];
    int array_of_psize[2];

    if (run_type == 1)
    {
        if (rank == 0)
        {
            printf("g0,g1 = %i,%i\n", local_height*ncols, local_width);
            printf("p0,p1 = %i,%i\n", nrows, ncols);
        }
        array_of_gsizes[0] = local_height*ncols;
        array_of_gsizes[1] = local_width;
        array_of_distribs[0] = MPI_DISTRIBUTE_BLOCK;
        array_of_distribs[1] = MPI_DISTRIBUTE_BLOCK;
        array_of_dargs[0] = MPI_DISTRIBUTE_DFLT_DARG;
        array_of_dargs[1] = MPI_DISTRIBUTE_DFLT_DARG;
        array_of_psize[0] = nrows;
        array_of_psize[1] = ncols;
        // int order = MPI_ORDER_C;

        //size,rank,ndims,array_gsizes,array_distribs,array_args,array_psizes
        //order,oldtype,*newtype
        MPI_Type_create_darray(world_size, rank, 2, array_of_gsizes, array_of_distribs,
                array_of_dargs, array_of_psize, MPI_ORDER_C, MPI_UNSIGNED_CHAR, &submatrix);
        MPI_Type_commit(&submatrix);
    }
    else if (run_type == 2)
    {
        if (rank == 0)
        {
            printf("g0,g1 = %i,%i\n", local_height*ncols, local_width*nrows);
            printf("p0,p1 = %i,%i\n", nrows, ncols);
        }
        array_of_gsizes[0] = local_height*ncols;
        array_of_gsizes[1] = local_width*nrows;
        array_of_distribs[0] = MPI_DISTRIBUTE_BLOCK;
        array_of_distribs[1] = MPI_DISTRIBUTE_BLOCK;
        array_of_dargs[0] = MPI_DISTRIBUTE_DFLT_DARG;
        array_of_dargs[1] = MPI_DISTRIBUTE_DFLT_DARG;
        array_of_psize[0] = nrows;
        array_of_psize[1] = ncols;
        // int order = MPI_ORDER_C;

        //size,rank,ndims,array_gsizes,array_distribs,array_args,array_psizes
        //order,oldtype,*newtype
        MPI_Type_create_darray(world_size, rank, 2, array_of_gsizes, array_of_distribs,
                array_of_dargs, array_of_psize, MPI_ORDER_C, MPI_UNSIGNED_CHAR, &submatrix);
        MPI_Type_commit(&submatrix);
    }



    MPI_Barrier(MPI_COMM_WORLD);

    //////////////////ALLOCATE ARRAYS, CREATE DATATYPES/////////////////////

    //Create new column derived datatype
    MPI_Datatype column;
    //count, blocklength, stride, oldtype, *newtype
    MPI_Type_hvector(csize, 1, sizeof(unsigned char), MPI_UNSIGNED_CHAR, &column);
    MPI_Type_commit(&column);

    //Create new row derived datatype
    MPI_Datatype row;
    //count, blocklength, stride, oldtype, *newtype
    MPI_Type_hvector(rsize, 1, sizeof(unsigned char), MPI_UNSIGNED_CHAR, &row);
    MPI_Type_commit(&row);

    //allocate arrays and corner storage
    unsigned char *section;
    unsigned char *neighbors;
    //to use
    unsigned char *top;
    unsigned char *bot;
    unsigned char *left;
    unsigned char *right;
    //to send
    unsigned char *ttop;
    unsigned char *tbot;
    unsigned char *tleft;
    unsigned char *tright;
    //MALLOC!!
    section = (unsigned char*)malloc(rsize*csize*sizeof(unsigned char));
    neighbors = (unsigned char*)malloc(rsize*csize*sizeof(unsigned char));
    top = (unsigned char*)malloc(rsize*sizeof(unsigned char));
    bot = (unsigned char*)malloc(rsize*sizeof(unsigned char));
    left = (unsigned char*)malloc(csize*sizeof(unsigned char));
    right = (unsigned char*)malloc(csize*sizeof(unsigned char));
    ttop = (unsigned char*)malloc(rsize*sizeof(unsigned char));
    tbot = (unsigned char*)malloc(rsize*sizeof(unsigned char));
    tleft = (unsigned char*)malloc(csize*sizeof(unsigned char));
    tright = (unsigned char*)malloc(csize*sizeof(unsigned char));

    //corners
    unsigned char topleft,topright,botleft,botright; //used in calculations
    unsigned char ttopleft,ttopright,tbotleft,tbotright; 
    topleft = 255;
    topright = 255;
    botleft = 255;
    botright = 255;

    //used for animation, each process will put there own result in and then
    //each will send to process 1 which will add them up
    unsigned char* full_matrix;
    unsigned char* full_matrix_buffer;
    if (animation == 1)
    {
        int msize1 = rsize*ncols*csize*nrows;
        full_matrix = (unsigned char*)malloc(msize1*sizeof(unsigned char));
        full_matrix_buffer = (unsigned char*)malloc(msize1*sizeof(unsigned char));
        for (i=0; i<msize1; i++)
        {
            full_matrix[i] = 0;
            full_matrix_buffer[i] = 0;
        }
    }

    
    // printf("Rsize,Lsize,Fsize=%i %i %i,Csize,Lsize,Fsize=%i %i %i\n",rsize,local_width,field_width,csize,local_height,field_height);

    //Serial initialize vars
    int count = 0;
    if (world_size == 1 && run_type == 0)
    {
        for (i=0;i<csize;i++)
        {
            for (j=0;j<rsize;j++)
            {
                section[i*rsize + j] = 255;
                
                if (field_a[(i+1)*(2+rsize) + j + 1])
                {
                    section[i*rsize + j] = 0;
                    count += 1;
                }
                else
                {
                    section[i*rsize + j] = 255;
                }

                top[j] = 255;
                bot[j] = 255;
                ttop[j] = 255;
                tbot[j] = 255;
            }
            right[i] = 255;
            left[i] = 255;
            tright[i] = 255;
            tleft[i] = 255;
        }
        // printf("COUNT 4 = %d\n", count);
    }

    //Blocked/Checkered initializing variables
    else if (world_size > 1 && (run_type == 1 || run_type == 2))
    {
        //initialize
        for (i=0;i<csize;i++)
        {
            for (j=0;j<rsize;j++)
            {
                section[i*rsize + j] = 255;
                
                if (field_a[(i+1)*(2+rsize) + j + 1])
                {
                    section[i*rsize + j] = 0;
                    count += 1;
                }
                else
                {
                    section[i*rsize + j] = 255;
                }

                top[j] = 255;
                bot[j] = 255;
                ttop[j] = 255;
                tbot[j] = 255;
            }
            right[i] = 255;
            left[i] = 255;
            tright[i] = 255;
            tleft[i] = 255;
        }

        // MPI_Allreduce( &count, &total, 1, MPI_UNSIGNED_CHAR, MPI_SUM, MPI_COMM_WORLD );
        // if (rank == 0)
        // {
        //     printf("COUNT 4 = %d\n", total);
        // }
        
    }


    //header/footer for mpio writes
    char header1[15];
    header1[0] = 0x50;
    header1[1] = 0x35;
    header1[2] = 0x0a;
    header1[3] = 0x35;
    header1[4] = 0x31;
    header1[5] = 0x32;
    header1[6] = 0x20;
    header1[7] = 0x35;
    header1[8] = 0x31;
    header1[9] = 0x32;
    header1[10] = 0x0a;
    header1[11] = 0x32;
    header1[12] = 0x35;
    header1[13] = 0x35;
    header1[14] = 0x0a;

    char footer;
    footer = 0x0a;

    //make a frame or not?
    int create_frame = 0;

    //send to 
    int send_to;
    int receive_from;
    int info[5];
    info[2] = rank;
    info[3] = rsize;
    info[4] = csize;
    unsigned char info2[4];
    info2[0] = topleft;
    info2[1] = topright;
    info2[2] = botleft;
    info2[3] = botright;

    int current_count;
    int location;

    //Gameplay
    for (k=0;k<iterations;k++)
    {
        //Count buggies
        if (k%count_when==0)
        {
            if (verbose == 1)
            {
                current_count = rsize*csize-count_buggies(rsize,csize,section);
                MPI_Allreduce( &current_count, &total, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
                if (rank == 0)
                {
                    printf("Iteration=%5d,  Count=%6d\n", k,total);
                }
                ////corner debug
                // printf("WR,tl,tr,bl,br = %d %d %d %d %d\n", rank, topleft, topright, botleft, botright);
            }
        }

        
        //Write to file serially for comparison
        //If animation is requested
        if (animation == 1 && run_type == 0)
        {
            //Put smaller matrix part into larger matrix
            for (i=0; i<csize; i++)
            {
                for (j=0; j<rsize; j++)
                {
                    location = (my_row*csize*rsize*ncols + my_col*rsize + 
                                    i*rsize*ncols + j);

                    full_matrix_buffer[location] = section[i*rsize+j];
                }
                // if (rank == 0)
                // {
                //     printf("Location = %d\n", location);
                // }
            }

            //Gather matrix
            MPI_Reduce(full_matrix_buffer, full_matrix, rsize*ncols*csize*nrows, 
                MPI_UNSIGNED_CHAR, MPI_SUM, 0, MPI_COMM_WORLD);

            
            if (rank == 0 && run_type == 0)
            {
                write_matrix_to_pgm(k, rsize*ncols, csize*nrows, full_matrix);
            }
        }
        //mpio write pgm
        else if (animation == 1 && (run_type == 1 || run_type == 2))
        {
            //default is no frame
            create_frame = 0;
            for (ii=0;ii<20;ii++)
            {
                for (jj=0;jj<animation_list[ii][1]+1;jj++)
                {
                    // if (rank == 0)
                    // {
                    //     printf("a,ii,j,k= %i,%i,%i,%i, Frame? = %i\n",
                    //         animation_list[ii][0],ii,jj,k,(animation_list[ii][0]+jj-k)==0);
                    // }
                    if ((animation_list[ii][0] + jj - k) == 0)
                    {

                        create_frame = 1;
                        break;
                    }
                }
            }

            if (create_frame == 1)
            {
               //dynamic filename with leading zeroes for easy conversion to gif
                char buffer[128];
                snprintf(buffer, sizeof(char)*128, "Animation/frame%04d.pgm", k);

                /* open the file, and set the view */
                MPI_File file;
                MPI_File_open(MPI_COMM_WORLD, buffer, 
                              MPI_MODE_CREATE|MPI_MODE_WRONLY,
                              MPI_INFO_NULL, &file);

                MPI_File_set_view(file, 0,  MPI_UNSIGNED_CHAR, MPI_UNSIGNED_CHAR, 
                                       "native", MPI_INFO_NULL);

                //write header
                MPI_File_write(file, &header1, 15, MPI_CHAR, MPI_STATUS_IGNORE);

                //write matrix
                MPI_File_set_view(file, 15,  MPI_UNSIGNED_CHAR, submatrix, 
                                       "native", MPI_INFO_NULL);

                MPI_File_write_all(file, section, rsize*csize, 
                        MPI_UNSIGNED_CHAR, MPI_STATUS_IGNORE);

                //write footer (trailing newline)
                MPI_File_set_view(file, 15+rsize*ncols*csize*nrows,  
                        MPI_UNSIGNED_CHAR, MPI_UNSIGNED_CHAR, 
                        "native", MPI_INFO_NULL);

                MPI_File_write(file, &footer, 1, MPI_CHAR, MPI_STATUS_IGNORE); 
            } 
        }


        // BLOCKED COMMUNITATION //
        if (run_type == 1)
        {
            //change bot (send top) to account for middle area
            //alternate to avoid locking
            send_to = rank - 1;
            receive_from = rank + 1;

            //figure out what to send
            //top and bottom
            for (i=0;i<rsize;i++)
            {
                ttop[i] = section[i];
                tbot[i] = section[rsize*(csize-1)+i];
            }

            //left n right
            for (i=0;i<csize;i++)
            {
                tleft[i] = section[0 + rsize*i];
                tright[i] = section[rsize-1 + rsize*i];
            }

            //send top, receive bot
            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0)
                {
                    MPI_Send(ttop, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from >= 0)
                {
                    MPI_Recv(bot, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {

                if (receive_from<world_size && receive_from >= 0)
                {
                    MPI_Recv(bot, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0)
                {
                    MPI_Send(ttop, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //change top to account for middle area
            //alternate to avoid locking
            send_to = rank + 1;
            receive_from = rank - 1;

            //send bot, receive top
            if (rank%2==0)
            {
                // printf("%d, %d, %d\n", rank, send_to, receive_from);
                if (send_to<world_size && send_to>=0)
                {
                    MPI_Send(tbot, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
                
                if (receive_from<world_size && receive_from >= 0)
                {
                    MPI_Recv(top, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {
                // printf("%d, %d, %d\n", rank, send_to, receive_from);
                if (receive_from<world_size && receive_from >= 0)
                {
                    //*data,count,type,from,tag,comm,mpi_status
                    MPI_Recv(top, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }

                if (send_to<world_size && send_to>=0)
                {
                    //*data,count,type,to,tag,comm
                    MPI_Send(tbot, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
            }
        }

        // CHECKERED COMMUNITATION //
        else if (run_type == 2)
        {
            //figure out what to send
            //top and bottom
            for (i=0;i<rsize;i++)
            {
                ttop[i] = section[i];
                tbot[i] = section[rsize*(csize-1)+i];
            }

            //left n right
            for (i=0;i<csize;i++)
            {
                tleft[i] = section[0 + rsize*i];
                tright[i] = section[rsize-1 + rsize*i];
            }

            //corners
            ttopleft = tleft[0];
            tbotleft = tleft[csize-1];
            ttopright = tright[0];
            tbotright = tright[csize-1];

            //Send top, receive bot
            send_to = rank - nrows;
            receive_from = rank + nrows;
            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0)
                {
                    MPI_Send(ttop, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0)
                {
                    MPI_Recv(bot, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {

                if (receive_from<world_size && receive_from>=0)
                {
                    MPI_Recv(bot, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0)
                {
                    MPI_Send(ttop, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //Send bot, receive top
            send_to = rank + nrows;
            receive_from = rank - nrows;
            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0)
                {
                    MPI_Send(tbot, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0)
                {
                    MPI_Recv(top, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {

                if (receive_from<world_size && receive_from>=0)
                {
                    MPI_Recv(top, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0)
                {
                    MPI_Send(tbot, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //Send left, receive right
            send_to = rank - 1;
            receive_from = rank + 1;

            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row)
                {
                    MPI_Send(tleft, 1, column, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row)
                {
                    MPI_Recv(right, 1, column, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row)
                {
                    MPI_Recv(right, 1, column, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row)
                {
                    MPI_Send(tleft, 1, column, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //Send right, receive left
            send_to = rank + 1;
            receive_from = rank - 1;

            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row)
                {
                    MPI_Send(tright, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row)
                {
                    MPI_Recv(left, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row)
                {
                    MPI_Recv(left, 1, row, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row)
                {
                    MPI_Send(tright, 1, row, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //Send topright, receive botleft
            send_to = rank - ncols + 1;
            receive_from = rank + ncols - 1;

            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row-1)
                {
                    MPI_Send(&ttopright, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row+1)
                {
                    MPI_Recv(&botleft, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row+1)
                {
                    MPI_Recv(&botleft, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row-1)
                {
                    MPI_Send(&ttopright, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //Send topleft, receive botright
            send_to = rank - ncols - 1;
            receive_from = rank + ncols + 1;

            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row-1)
                {
                    MPI_Send(&ttopleft, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row+1)
                {
                    MPI_Recv(&botright, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row+1)
                {
                    MPI_Recv(&botright, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row-1)
                {
                    MPI_Send(&ttopleft, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //Send botleft, receive topright
            send_to = rank + ncols - 1;
            receive_from = rank - ncols + 1;

            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row+1)
                {
                    MPI_Send(&tbotleft, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row-1)
                {
                    MPI_Recv(&topright, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row-1)
                {
                    MPI_Recv(&topright, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row+1)
                {
                    MPI_Send(&tbotleft, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
            }

            //Send botright, receive topleft
            send_to = rank + ncols + 1;
            receive_from = rank - ncols - 1;

            if (rank%2==0)
            {
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row+1)
                {
                    MPI_Send(&tbotright, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row-1)
                {
                    MPI_Recv(&topleft, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
            }
            else if (rank%2==1)
            {
                if (receive_from<world_size && receive_from>=0 && receive_from/nrows==my_row-1)
                {
                    MPI_Recv(&topleft, 1, MPI_UNSIGNED_CHAR, receive_from, 0, MPI_COMM_WORLD,
                        MPI_STATUS_IGNORE);
                }
                if (send_to<world_size && send_to>=0 && send_to/nrows==my_row+1)
                {
                    MPI_Send(&tbotright, 1, MPI_UNSIGNED_CHAR, send_to, 0, MPI_COMM_WORLD);
                }
            }


            info2[0] = topleft;
            info2[1] = topright;
            info2[2] = botleft;
            info2[3] = botright;

        }
 
        // if (rank == 1){
        //     print_matrix(rsize, 1, top);
        //     print_matrix(rsize, csize, section);
        //     print_matrix(rsize, 1, bot);
        //     printf("\n");
        // }
        // printf("wr=%d,iteration=%d,maxval=%d, 11\n", rank, k,(csize-1)*rsize-1+rsize);
        


        /////////// CELL UPDATES /////////////////
        //count neighbor
        for (i=0;i<csize;i++)
        {
            for (j=0; j<rsize; j++)
            {
                info[0] = i;
                info[1] = j;
                neighbors[i*rsize+j] = count_neighbors(info, info2, section, 
                                    top, bot, left, right);
                // printf("%i",neighbors[i*rsize+j]);
            }
            // printf("\n");
        }

        //update cells
        current_count = 0;
        for (i=0;i<csize;i++)
        {
            for (j=0; j<rsize; j++)
            {
                //cell currently alive
                if (section[i*rsize+j] == 0)
                {
                    //2 or 3 neighbors lives, else die
                    if (neighbors[i*rsize+j] < 2 || 
                        neighbors[i*rsize+j] > 3)
                    {
                        section[i*rsize+j] = 255;
                    }
                }
                else
                {
                    //Exactly 3 neighbors spawns new life
                    if (neighbors[i*rsize+j] == 3)
                    {
                        section[i*rsize+j] = 0;
                    }
                }
            }
        }
    }

    MPI_Barrier(MPI_COMM_WORLD);
    sleep(0.5);
    //free malloc stuff
    if( field_a != NULL ) free( field_a );
    if( field_b != NULL ) free( field_b );
    free(section);
    free(neighbors);
    free(top);
    free(bot);
    free(left);
    free(right);

    MPI_Finalize();
    exit (0);
}