Пример #1
0
/*----------------------------------------------------------------------*/
void w_serial_finish_lattice(w_serial_site_writer *state)
{
  /* gf  = file descriptor as opened by w_serial_i */

  gauge_file *gf = state->gf;
  fsu3_matrix *lbuf = state->lbuf;
  FILE *fp = gf->fp;
  gauge_header *gh = gf->header;
  off_t checksum_offset = state->checksum_offset;    /* Location of checksum */
  
  free(lbuf);
  printf("Saved gauge configuration serially to binary file %s\n",
	 gf->filename);
  printf("Time stamp %s\n",gh->time_stamp);
  
  /* Write checksum */
  /* Position file pointer */
  if( g_seek(fp,checksum_offset,SEEK_SET) < 0 ) 
    {
      printf("w_serial: Node %d g_seek %lld failed error %d file %s\n",
	     this_node,(long long)checksum_offset,errno,gf->filename);
      fflush(stdout);terminate(1);
    }
  write_checksum(SERIAL,gf);

} /* w_serial_finish_lattice */
Пример #2
0
/*----------------------------------------------------------------------*/
void w_serial_start_lattice(gauge_file *gf, w_serial_site_writer *state,
			    int input_prec)
{
  /* gf  = file descriptor as opened by w_serial_i */
  /* state of the writer for a single site */

  FILE *fp;
  gauge_header *gh;
  off_t offset;             /* File stream pointer */
  off_t coord_list_size;    /* Size of coordinate list in bytes */
  off_t head_size;          /* Size of header plus coordinate list */
  off_t checksum_offset;    /* Location of checksum */
  off_t gauge_check_size;   /* Size of checksum record */

  if(gf->parallel)
    printf("w_serial_start_lattice: Attempting serial write to parallel file \n");
  
  outputbuf = (fsu3_matrix *)malloc(MAX_BUF_LENGTH*4*sizeof(fsu3_matrix));
  if(outputbuf == NULL)
    {
      printf("w_serial: Node 0 can't malloc outputbuf\n"); 
      fflush(stdout);terminate(1);
    }
  
  fp = gf->fp;
  gh = gf->header;
  
  /* No coordinate list was written because fields are to be written
     in standard coordinate list order */
  
  coord_list_size = 0;
  head_size = gh->header_bytes + coord_list_size;
  
  checksum_offset = head_size;
  
  gauge_check_size = sizeof(gf->check.sum29) + sizeof(gf->check.sum31);
  
  offset = head_size + gauge_check_size;
  
  if( g_seek(fp,offset,SEEK_SET) < 0 ) 
    {
      printf("w_serial: Node %d g_seek %lld failed error %d file %s\n",
	     this_node,(long long)offset,errno,gf->filename);
      fflush(stdout);terminate(1);
    }

  /* initialize checksums */
  gf->check.sum31 = 0;
  gf->check.sum29 = 0;

  state->gf              = gf;
  state->buf_length      = 0;
  state->siterank        = 0;
  state->rank29          = 0;
  state->rank31          = 0;
  state->lbuf            = outputbuf;
  state->checksum_offset = checksum_offset;
  state->prec            = input_prec;
} /* w_serial_start_lattice */
Пример #3
0
// -----------------------------------------------------------------
// Only node 0 reads the gauge configuration gf from a binary file
static void r_serial(gauge_file *gf) {
  FILE *fp = gf->fp;
  gauge_header *gh = gf->header;
  char *filename = gf->filename;
  int byterevflag = gf->byterevflag;

  off_t offset = 0;           // File stream pointer
  off_t gauge_check_size;     // Size of gauge configuration checksum record
  off_t coord_list_size;      // Size of coordinate list in bytes
  off_t head_size;            // Size of header plus coordinate list
  off_t checksum_offset = 0;  // Where we put the checksum
  int rcv_rank, rcv_coords, destnode, stat, idest = 0;
  int k, x, y, z, t;
  int buf_length = 0, where_in_buf = 0;
  gauge_check test_gc;
  u_int32type *val;
  int rank29, rank31;
  fmatrix *lbuf = NULL;   // Only allocate on node0
  fmatrix tmat[4];

  if (this_node == 0) {
    // Compute offset for reading gauge configuration
    if (gh->magic_number == GAUGE_VERSION_NUMBER)
      gauge_check_size = sizeof(gf->check.sum29) + sizeof(gf->check.sum31);
    else
      gauge_check_size = 0;

    if (gf->header->order == NATURAL_ORDER)
      coord_list_size = 0;
    else
      coord_list_size = sizeof(int32type) * volume;
    checksum_offset = gf->header->header_bytes + coord_list_size;
    head_size = checksum_offset + gauge_check_size;

    // Allocate single-precision read buffer
    if (gf->parallel)
      printf("r_serial: Attempting serial read from parallel file\n");

    lbuf = malloc(MAX_BUF_LENGTH * 4 * sizeof(*lbuf));
    if (lbuf == NULL) {
      printf("r_serial: node%d can't malloc lbuf\n", this_node);
      fflush(stdout);
      terminate(1);
    }

    /* Position file for reading gauge configuration */
    offset = head_size;

    if (g_seek(fp, offset, SEEK_SET) < 0) {
      printf("r_serial: node0 g_seek %lld failed error %d file %s\n",
             (long long)offset, errno, filename);
      fflush(stdout);
      terminate(1);
    }
    buf_length = 0;
    where_in_buf = 0;
  }

  // All nodes initialize checksums
  test_gc.sum29 = 0;
  test_gc.sum31 = 0;
  // Count 32-bit words mod 29 and mod 31 in order of appearance on file
  // Here all nodes see the same sequence because we read serially
  rank29 = 0;
  rank31 = 0;

  g_sync();

  // node0 reads and deals out the values
  for (rcv_rank = 0; rcv_rank < volume; rcv_rank++) {
    /* If file is in coordinate natural order, receiving coordinate
       is given by rank. Otherwise, it is found in the table */
    if (gf->header->order == NATURAL_ORDER)
      rcv_coords = rcv_rank;
    else
      rcv_coords = gf->rank2rcv[rcv_rank];

    x = rcv_coords % nx;
    rcv_coords /= nx;
    y = rcv_coords % ny;
    rcv_coords /= ny;
    z = rcv_coords % nz;
    rcv_coords /= nz;
    t = rcv_coords % nt;

    // The node that gets the next set of gauge links
    destnode = node_number(x, y, z, t);

    // node0 fills its buffer, if necessary
    if (this_node == 0) {
      if (where_in_buf == buf_length) {  /* get new buffer */
        /* new buffer length  = remaining sites, but never bigger
           than MAX_BUF_LENGTH */
        buf_length = volume - rcv_rank;
        if (buf_length > MAX_BUF_LENGTH)
          buf_length = MAX_BUF_LENGTH;

        // Now do read
        stat = (int)g_read(lbuf, 4 * sizeof(fmatrix), buf_length, fp);
        if (stat != buf_length) {
          printf("r_serial: node%d gauge configuration read error %d file %s\n",
                 this_node, errno, filename);
          fflush(stdout);
          terminate(1);
        }
        where_in_buf = 0;  // Reset counter
      }  // End of the buffer read

      if (destnode == 0) {  // Just copy links
        idest = node_index(x, y, z, t);
        // Save 4 matrices in tmat for further processing
        memcpy(tmat, &lbuf[4 * where_in_buf], 4 * sizeof(fmatrix));
      }
      else {                // Send to correct node
        send_field((char *)&lbuf[4 * where_in_buf],
                   4 * sizeof(fmatrix), destnode);
      }
      where_in_buf++;
    }

    // The node that contains this site reads the message
    else {  // All nodes other than node 0
      if (this_node == destnode) {
        idest = node_index(x, y, z, t);
        // Receive 4 matrices in temporary space for further processing
        get_field((char *)tmat, 4 * sizeof(fmatrix), 0);
      }
    }

    /* The receiving node does the byte reversal and then checksum,
       if needed.  At this point tmat contains the input matrices
       and idest points to the destination site structure. */
    if (this_node == destnode) {
      if (byterevflag == 1)
        byterevn((int32type *)tmat,
                 4 * sizeof(fmatrix) / sizeof(int32type));
      // Accumulate checksums
      for (k = 0, val = (u_int32type *)tmat;
           k < 4*(int)sizeof(fmatrix) / (int)sizeof(int32type);
           k++, val++) {
        test_gc.sum29 ^= (*val)<<rank29 | (*val)>>(32 - rank29);
        test_gc.sum31 ^= (*val)<<rank31 | (*val)>>(32 - rank31);
        rank29++;
        if (rank29 >= 29)
          rank29 = 0;
        rank31++;
        if (rank31 >= 31)
          rank31 = 0;
      }
      // Copy 4 matrices to generic-precision lattice[idest]
      f2d_4mat(tmat, &lattice[idest].link[0]);
    }
    else {
      rank29 += 4 * sizeof(fmatrix) / sizeof(int32type);
      rank31 += 4 * sizeof(fmatrix) / sizeof(int32type);
      rank29 %= 29;
      rank31 %= 31;
    }
  }
Пример #4
0
void r_check(gauge_file *gf, float *max_deviation)
{
  /* gf  = gauge configuration file structure */

  FILE *fp;
  gauge_header *gh;
  char *filename;
  int byterevflag;

  off_t offset ;            /* File stream pointer */
  off_t gauge_check_size;   /* Size of gauge configuration checksum record */
  off_t coord_list_size;    /* Size of coordinate list in bytes */
  off_t head_size;          /* Size of header plus coordinate list */
  off_t checksum_offset;    /* Where we put the checksum */
  int rcv_rank, rcv_coords;
  int destnode;
  int i,k;
  int x,y,z,t;
  int buf_length,where_in_buf;
  gauge_check test_gc;
  u_int32type *val;
  int rank29,rank31;
  su3_matrix *lbuf;
  su3_matrix work[4];
  float deviation;

  char myname[] = "r_check";

  fp = gf->fp;
  gh = gf->header;
  filename = gf->filename;
  byterevflag = gf->byterevflag;

  if(this_node == 0)
    {
      /* Compute offset for reading gauge configuration */

      /* (1996 gauge configuration files had a 32-bit unused checksum 
	 record before the gauge link data) */
      if(gh->magic_number == GAUGE_VERSION_NUMBER)
	gauge_check_size = sizeof(gf->check.sum29) + 
	  sizeof(gf->check.sum31);
      else if(gh->magic_number == GAUGE_VERSION_NUMBER_1996)
	gauge_check_size =  4;
      else
	gauge_check_size = 0;
      
      if(gf->header->order == NATURAL_ORDER)coord_list_size = 0;
      else coord_list_size = sizeof(int32type)*volume;
      checksum_offset = gf->header->header_bytes + coord_list_size;
      head_size = checksum_offset + gauge_check_size;
      
      /* Allocate space for read buffer */

      if(gf->parallel)
	printf("%s: Attempting serial read from parallel file \n",myname);

      lbuf = (su3_matrix *)malloc(MAX_BUF_LENGTH*4*sizeof(su3_matrix));
      if(lbuf == NULL)
	{
	  printf("%s: Node %d can't malloc lbuf\n",myname,this_node);
	  fflush(stdout);
	  terminate(1);
	}
  
      /* Position file for reading gauge configuration */
      
      offset = head_size;

      if( g_seek(fp,offset,SEEK_SET) < 0 ) 
	{
	  printf("%s: Node 0 g_seek %ld failed error %d file %s\n",
		 myname,(long)offset,errno,filename);
	  fflush(stdout);terminate(1);   
	}

      buf_length = 0;
      where_in_buf = 0;
      
    }

  /* all nodes initialize checksums */
  test_gc.sum29 = 0;
  test_gc.sum31 = 0;
  /* counts 32-bit words mod 29 and mod 31 in order of appearance
     on file */
  /* Here all nodes see the same sequence because we read serially */
  rank29 = 0;
  rank31 = 0;
  *max_deviation = 0;

  g_sync();

  /* Node 0 reads and deals out the values */

  for(rcv_rank=0; rcv_rank<volume; rcv_rank++)
    {
      /* If file is in coordinate natural order, receiving coordinate
         is given by rank. Otherwise, it is found in the table */

      if(gf->header->order == NATURAL_ORDER)
	rcv_coords = rcv_rank;
      else
	rcv_coords = gf->rank2rcv[rcv_rank];

      x = rcv_coords % nx;   rcv_coords /= nx;
      y = rcv_coords % ny;   rcv_coords /= ny;
      z = rcv_coords % nz;   rcv_coords /= nz;
      t = rcv_coords % nt;

      /* The node that gets the next set of gauge links */
      destnode=node_number(x,y,z,t);
      
      if(this_node==0){
	/* Node 0 fills its buffer, if necessary */
	if(where_in_buf == buf_length)
	  {  /* get new buffer */
	    /* new buffer length  = remaining sites, but never bigger 
	       than MAX_BUF_LENGTH */
	    buf_length = volume - rcv_rank;
	    if(buf_length > MAX_BUF_LENGTH)buf_length = MAX_BUF_LENGTH;
	    /* then do read */
	    
	    if( (int)g_read(lbuf,4*sizeof(su3_matrix),buf_length,fp) != buf_length)
	      {
		printf("%s: node %d gauge configuration read error %d file %s\n",
		       myname,this_node,errno,filename); 
		fflush(stdout); terminate(1);
	      }
	    where_in_buf = 0;  /* reset counter */
	  }  /*** end of the buffer read ****/

	if(destnode==0){	/* just copy links */
	  i = node_index(x,y,z,t);
	  memcpy((void *)&work[0],
		 (void *)&lbuf[4*where_in_buf], 4*sizeof(su3_matrix));
	}
	else {		/* send to correct node */
	  send_field((char *)&lbuf[4*where_in_buf],
		     4*sizeof(su3_matrix),destnode);
	}
	where_in_buf++;
      }
      
      /* The node which contains this site reads message */
      else {	/* for all nodes other than node 0 */
	if(this_node==destnode){
	  i = node_index(x,y,z,t);
	  get_field((char *)&work[0],4*sizeof(su3_matrix),0);
	}
      }

      /* The receiving node does the byte reversal and then checksum,
         if needed */

      if(this_node==destnode)
	{
	  if(byterevflag==1)
	    byterevn((int32type *)&work[0],
		     4*sizeof(su3_matrix)/sizeof(int32type));
	  /* Accumulate checksums */
	  for(k = 0, val = (u_int32type *)&work[0]; 
	      k < 4*(int)sizeof(su3_matrix)/(int)sizeof(int32type); k++, val++)
	    {
	      test_gc.sum29 ^= (*val)<<rank29 | (*val)>>(32-rank29);
	      test_gc.sum31 ^= (*val)<<rank31 | (*val)>>(32-rank31);
	      rank29++; if(rank29 >= 29)rank29 = 0;
	      rank31++; if(rank31 >= 31)rank31 = 0;
	    }
	  deviation = ck_unitarity(work,x,y,z,t);
	  if(deviation > *max_deviation)*max_deviation = deviation;
	}
      else
	{
	  rank29 += 4*sizeof(su3_matrix)/sizeof(int32type);
	  rank31 += 4*sizeof(su3_matrix)/sizeof(int32type);
	  rank29 %= 29;
	  rank31 %= 31;
	}
    }
Пример #5
0
// -----------------------------------------------------------------
// Only node0 writes the gauge configuration to a binary file gf
static void w_serial(gauge_file *gf) {
  register int i, j;
  int rank29, rank31, buf_length, tbuf_length;
  int x, y, z, t, currentnode, newnode;
  FILE *fp = NULL;
  gauge_header *gh = NULL;
  fmatrix *lbuf = NULL;
  fmatrix *tbuf = malloc(nx * 4 * sizeof(*tbuf));
  off_t offset;               // File stream pointer
  off_t coord_list_size;      // Size of coordinate list in bytes
  off_t head_size;            // Size of header plus coordinate list
  off_t checksum_offset = 0;  // Location of checksum
  off_t gauge_check_size;     // Size of checksum record

  // tbuf holds message buffer space for the x dimension
  // of the local hypercube (needs at most 4nx matrices)
  if (tbuf == NULL) {
    printf("w_serial: node%d can't malloc tbuf\n", this_node);
    terminate(1);
  }

  // Only allocate lbuf on node0
  if (this_node == 0) {
    if (gf->parallel)
      printf("w_serial: Attempting serial write to parallel file\n");

    lbuf = malloc(MAX_BUF_LENGTH * 4 * sizeof(*lbuf));
    if (lbuf == NULL) {
      printf("w_serial: Node 0 can't malloc lbuf\n");
      fflush(stdout);
      terminate(1);
    }

    fp = gf->fp;
    gh = gf->header;

    // No coordinate list written
    // Fields to be written in standard coordinate list order
    coord_list_size = 0;
    head_size = gh->header_bytes + coord_list_size;

    checksum_offset = head_size;

    gauge_check_size = sizeof(gf->check.sum29) + sizeof(gf->check.sum31);

    offset = head_size + gauge_check_size;

    if (fseeko(fp, offset, SEEK_SET) < 0) {
      printf("w_serial: node%d g_seek %lld failed error %d file %s\n",
             this_node, (long long)offset, errno, gf->filename);
      fflush(stdout);
      terminate(1);
    }
  }

  // Buffered algorithm for writing fields in serial (lexicographic) order
  // Initialize checksums
  gf->check.sum31 = 0;
  gf->check.sum29 = 0;
  // Count 32-bit words mod 29 and mod 31 in order of appearance on file
  // Here only node 0 uses these values -- both start at 0
  i = 4 * sizeof(fmatrix) / sizeof(int32type) * sites_on_node * this_node;
  rank29 = i % 29;
  rank31 = i % 31;

  g_sync();
  currentnode = 0;  // The node delivering data
  buf_length = 0;
  tbuf_length = 0;
  for (j = 0, t = 0; t < nt; t++) {
    for (z = 0; z < nz; z++) {
      for (y = 0; y < ny; y++) {
        for (x = 0; x < nx; x++, j++) {
          // The node providing the next site
          newnode = node_number(x, y, z, t);
          if (newnode != currentnode || x == 0) {
            // We are switching to a new node or have exhausted a line of nx
            // Sweep any data in the retiring node's tbuf to the node0 lbuf
            if (tbuf_length > 0) {
              if (currentnode != 0)
                send_buf_to_node0(tbuf, tbuf_length, currentnode);

              // node0 flushes tbuf, accumulates checksum
              // and writes lbuf if it is full
              if (this_node == 0) {
                flush_tbuf_to_lbuf(gf, &rank29, &rank31, lbuf, &buf_length,
                                                         tbuf, tbuf_length);
                if (buf_length > MAX_BUF_LENGTH - nx)
                  flush_lbuf_to_file(gf, lbuf, &buf_length);
              }
              tbuf_length = 0;
            }

            // node0 sends a few bytes to newnode as a clear to send signal
            if (newnode != currentnode) {
              if (this_node == 0 && newnode != 0)
                send_field((char *)tbuf, 32, newnode);
              if (this_node == newnode && newnode != 0)
                get_field((char *)tbuf, 32, 0);
              currentnode = newnode;
            }
          }

          // The node with the data just appends to its tbuf
          if (this_node == currentnode) {
            i = node_index(x, y, z, t);
            d2f_4mat(&lattice[i].link[0], &tbuf[4 * tbuf_length]);
          }

          if (this_node == currentnode || this_node == 0)
            tbuf_length++;
        }
      }
    }
  }

  // Purge any remaining data
  if (tbuf_length > 0) {
    if (currentnode != 0)
      send_buf_to_node0(tbuf, tbuf_length, currentnode);
  }

  if (this_node == 0) {
    flush_tbuf_to_lbuf(gf, &rank29, &rank31, lbuf, &buf_length,
                       tbuf, tbuf_length);
    flush_lbuf_to_file(gf, lbuf, &buf_length);
  }

  g_sync();
  free(tbuf);

  if (this_node == 0) {
    free(lbuf);
    printf("Saved gauge configuration serially to binary file %s\n",
        gf->filename);
    printf("Time stamp %s\n", gh->time_stamp);

    // Write checksum
    // Position file pointer
    if (g_seek(fp, checksum_offset, SEEK_SET) < 0) {
      printf("w_serial: node%d g_seek %lld failed error %d file %s\n",
             this_node, (long long)checksum_offset, errno, gf->filename);
      fflush(stdout);
      terminate(1);
    }
    write_checksum(SERIAL, gf);
  }
}