/* For FNAL we base the detection on the number of elements per site */ int io_detect_fm(char *filename){ FILE *fp; int status, words; int32type magic_no, revmagic_no, gmtime_stamp, size_of_element, elem_per_site; int byterevflag = 0; /* Node 0 reads and checks */ if(this_node == 0){ fp = g_open(filename,"rb"); if(fp == NULL)status = -2; else { words = g_read(&magic_no, sizeof(int32type), 1, fp); if(words != 1)status = -3; else { revmagic_no = magic_no; byterevn(&revmagic_no, 1); status = -1; if(revmagic_no == IO_UNI_MAGIC)byterevflag = 1; if(magic_no == IO_UNI_MAGIC || revmagic_no == IO_UNI_MAGIC){ g_read(&gmtime_stamp, sizeof(gmtime_stamp), 1, fp); g_read(&size_of_element, sizeof(int32type), 1, fp); g_read(&elem_per_site, sizeof(int32type), 1, fp); if(byterevflag){ byterevn(&size_of_element, 1); byterevn(&elem_per_site, 1); } if(size_of_element != sizeof(float))status = -1; else if(elem_per_site == sizeof(fsu3_matrix)/sizeof(float)) status = FILE_TYPE_KS_FMPROP; else if(elem_per_site == sizeof(fwilson_propagator)/sizeof(float) || elem_per_site == sizeof(fwilson_vector)/sizeof(float)) status = FILE_TYPE_W_FMPROP; else if(elem_per_site == 4*sizeof(fsu3_matrix)/sizeof(float)) status = FILE_TYPE_GAUGE_FNAL; } } } g_close(fp); } /* Node 0 broadcasts the result */ broadcast_bytes((char *)&status, sizeof(int)); /* All nodes return the same value */ return status; }
// ----------------------------------------------------------------- // Subroutine for reading site list from gauge configuration file // Only node0 reads this list void read_site_list(gauge_file *gf) { /* All nodes allocate space for site list table, if file is not in natural order */ if (gf->header->order != NATURAL_ORDER) { gf->rank2rcv = malloc(volume * sizeof(int32type)); if (gf->rank2rcv == NULL) { printf("read_site_list: Can't malloc rank2rcv table\n"); terminate(1); } // Only node0 reads the site list if (this_node == 0) { /* Reads receiving site coordinate if file is not in natural order */ if ((int)fread(gf->rank2rcv,sizeof(int32type), volume,gf->fp) != volume) { printf("read_site_list: Node %d site list read error %d\n", this_node,errno); terminate(1); } if (gf->byterevflag == 1) byterevn(gf->rank2rcv, volume); } // Broadcast result to all nodes broadcast_bytes((char *)gf->rank2rcv, volume * sizeof(int32type)); } else gf->rank2rcv = NULL; // If no site list }
// ----------------------------------------------------------------- int sread_byteorder(int byterevflag, FILE* fp, void *src, size_t size, char *myname, char *descrip) { int status = sread_data(fp,src,size,myname,descrip); if (byterevflag == 1) byterevn((int32type *)src, size / sizeof(int32type)); return status; }
int io_detect(char *filename, file_table ft[], int ntypes){ FILE *fp; int i, status, words; int32type magic_no; int32type revmagic_no; char editfilename[513]; /* Node 0 reads and checks */ if(this_node == 0){ fp = g_open(filename,"rb"); if(fp == NULL){ /* Special provision for partition or multifile format. Try adding the extension to the filename */ strncpy(editfilename,filename,504); editfilename[504] = '\0'; /* Just in case of truncation */ strcat(editfilename,".vol0000"); fp = g_open(editfilename,"rb"); } if(fp == NULL)status = -2; else { words = g_read(&magic_no, sizeof(int32type), 1, fp); g_close(fp); if(words != 1)status = -3; else { revmagic_no = magic_no; byterevn(&revmagic_no, 1); status = -1; for(i = 0; i < ntypes; i++){ if(ft[i].magic_no == magic_no || ft[i].magic_no == revmagic_no) { status = ft[i].type; break; } } } } } /* Node 0 broadcasts the result */ broadcast_bytes((char *)&status, sizeof(int)); /* All nodes return the same value */ return status; }
static int read_cmplx_fm_source_hdr(cmplx_source_file *csf, int source_type) { cmplx_source_header *csh = csf->header; int *dims = csh->dims; int32type t_stamp; int32type size_of_element; int32type tmp, elements_per_site; int32type order; int byterevflag = 0; char myname[] = "read_cmplx_fm_source_hdr"; if( sizeof(float) != sizeof(int32type)) { printf("%s: Can't byte reverse\n", csf->filename); printf("requires size of int32type(%d) = size of float(%d)\n", (int)sizeof(int32type),(int)sizeof(float)); terminate(1); } if(sread_data(csf->fp,&csh->magic_number,sizeof(int32type), myname,"magic_no")) terminate(1); tmp = csh->magic_number; if(csh->magic_number == IO_UNI_MAGIC) byterevflag = 0; else { byterevn((int32type *)&csh->magic_number,1); if(csh->magic_number == IO_UNI_MAGIC) { byterevflag = 1; /** printf("Reading with byte reversal\n"); **/ } else { /* Restore magic number as originally read */ csh->magic_number = tmp; /* End of the road. */ printf("%s: Unrecognized magic number in source file header.\n", csf->filename); printf("Expected %x but read %x\n", IO_UNI_MAGIC,tmp); terminate(1); } }; if(sread_byteorder(byterevflag,csf->fp,&t_stamp, sizeof(t_stamp),myname,"t_stamp"))terminate(1); if(sread_byteorder(byterevflag,csf->fp,&size_of_element, sizeof(int32type),myname,"size_of_element"))terminate(1); if(sread_byteorder(byterevflag,csf->fp,&elements_per_site, sizeof(int32type),myname,"elements_per_site"))terminate(1); if(sread_byteorder(byterevflag,csf->fp,dims, 4*sizeof(int32type),myname,"dimensions"))terminate(1); /* Consistency checks */ if ( nx != dims[0] || ny != dims[1] || nz != dims[2] || 1 != dims[3] ){ printf("Source field dimensions %d %d %d %d are incompatible with this lattice %d %d %d %d\n", dims[0], dims[1], dims[2], dims[3], nx, ny, nz, nt); terminate(1); } if( source_type == COMPLEX_FIELD_FM_FILE ){ if( size_of_element != sizeof(float) || elements_per_site != 2 /* complex field */) { printf(" File %s is not a complex field", csf->filename); printf(" got size_of_element %d and elements_per_site %d\n", size_of_element, elements_per_site); terminate(1); } } else { printf("Unknown source type %d\n",source_type); terminate(1); } /* The site order parameter is ignored */ if(sread_byteorder(byterevflag,csf->fp,&order,sizeof(int32type), myname,"order parameter"))terminate(1); return byterevflag; }
static void r_source_cmplx_fm(cmplx_source_file *csf, field_offset dest_site, complex *dest_field, int t0) { int rcv_rank, rcv_coords, status; int destnode; int x,y,z,t,i=0, byterevflag,a; int tmin, tmax; struct { fcomplex q; char pad[PAD_SEND_BUF]; /* Introduced because some switches perform better if message lengths are longer */ } cmsg; int buf_length=0, where_in_buf=0; fcomplex *cbuff=NULL; complex *c; fcomplex cfix; int vol3 = nx*ny*nz; int source_type; byterevflag = csf->byterevflag; source_type = csf->type; if(this_node == 0) { if(source_type == COMPLEX_FIELD_FM_FILE) cbuff = (fcomplex *)malloc(MAX_BUF_LENGTH*sizeof(fcomplex)); else { printf("r_source_cmplx_fm: Unknown source type %d\n", source_type); fflush(stdout); terminate(1); } buf_length = 0; where_in_buf = 0; } /* end of if(this_node == 0)*/ g_sync(); /* If requested, we replicate the source function on ALL time slices */ /* Otherwise we read only to time slice t0 */ if(t0 == ALL_T_SLICES){ tmin = 0; tmax = nt-1; } else { tmin = t0; tmax = t0; } /* Node 0 reads and deals out the values */ status = 0; /* Iterate only over timeslice t0 */ for(rcv_rank=0; rcv_rank<vol3; rcv_rank++) { /* We do only natural (lexicographic) order here */ rcv_coords = rcv_rank; x = rcv_coords % nx; rcv_coords /= nx; y = rcv_coords % ny; rcv_coords /= ny; z = rcv_coords % nz; 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 = vol3 - rcv_rank; if(buf_length > MAX_BUF_LENGTH) buf_length = MAX_BUF_LENGTH; /* then do read */ a=(int)g_read(cbuff,sizeof(fcomplex),buf_length,csf->fp); if( a != buf_length) { if(status == 0) printf(" node %d source file read error %d file %s\n", this_node, errno, csf->filename); fflush(stdout); status = 1; } where_in_buf = 0; /* reset counter */ } /*** end of the buffer read ****/ /* Save data in msg.q for further processing */ cmsg.q = cbuff[where_in_buf]; } /* Loop either over all time slices or just one time slice */ for(t = tmin; t <= tmax; t++){ destnode=node_number(x,y,z,t); if(this_node == 0){ /* node 0 doesn't send to itself */ if(destnode != 0){ /* send to correct node */ send_field((char *)&cmsg, sizeof(cmsg), destnode); } } /* if(this_node==0) */ else { /* for all nodes other than node 0 */ if(this_node==destnode){ get_field((char *)&cmsg, sizeof(cmsg),0); } } /* The receiving node does the byte reversal. At this point msg contains the input vectors and i points to the destination site structure */ if(this_node==destnode) { /* Byte reverse a copy, since we may need to reuse cmsg.q */ cfix = cmsg.q; if(byterevflag==1){ byterevn((int32type *)&cfix, sizeof(fcomplex)/sizeof(int32type)); } /* Now copy the site data into the destination converting to generic precision if needed */ i = node_index(x,y,z,t); if(dest_site == (field_offset)(-1)) c = dest_field + i; else c = (complex *)F_PT(&lattice[i],dest_site); c->real = cfix.real; c->imag = cfix.imag; //printf("C %d %d %d %g %g\n", // x, y, z, cmsg.q.real, cmsg.q.imag); } /* if this_node == destnode */ } /* t */ where_in_buf++; } /* rcv_rank, irecord */ if(cbuff != NULL)free(cbuff); cbuff = NULL; }
void load_scalar_smear(Real *data, int dim, char filename[]) { FILE *fp ; size_t nobj = (size_t) dim ; int magic_number = 43241 ; enum rev_choices { byte_rev , do_nothing } ; int byte_rev_flag = do_nothing ; char myname[] = "load_scalar_smear"; /* Memory for some header information ***/ size_t three_object = (size_t) 3 ; int32type header_data[3] ; /** open the file ****/ if( (fp = fopen(filename ,"rb")) == NULL ) { printf("ERROR:%s: Could not open the file %s\n",myname,filename); terminate(1); } /*** read in the header information *********/ if( fread(header_data,sizeof(int32type),three_object,fp) != three_object ) { printf("There was an error during the reading of the smearing function HEADER \n"); terminate(1); } /*** check the header information ****/ if( header_data[0] != magic_number ) { printf("Reading with byte reversal\n") ; byte_rev_flag = byte_rev ; } if( byte_rev_flag == byte_rev ) byterevn( (int32type*) header_data , three_object ) ; if( header_data[0] != magic_number ) { printf("ERROR:%s: Mismatch of the magic numbers for the smearing function \n",myname); printf("file = %d code = %d\n",header_data[0],magic_number); terminate(1); } if( header_data[1] != dim ) { printf("ERROR: %s: amount of data mismatch between file and code \n",myname); printf("file = %d code = %d \n",header_data[1], dim ); terminate(1); } if( header_data[2] != nx ) { printf("ERROR: %s: mismatch between code and file linear dimension\n",myname); printf("file = %d code = %d\n", header_data[2],nx); terminate(1); } /*** read the smearing function ***/ if( fread(data,sizeof(Real),nobj,fp) != nobj ) { printf("%s: There was an error during the reading of the smearing function \n",myname); terminate(1); } if( byte_rev_flag == byte_rev ) byterevn( (int32type*) data , nobj ) ; /*** close the file ***/ if( fclose(fp) != 0 ) { printf("%s: There was an error during the closing of %s \n",myname,filename); terminate(1); } printf("%s: I have read a smearing function from the file %s\n",myname,filename); }
// ----------------------------------------------------------------- // Access from node0 only int read_gauge_hdr(gauge_file *gf) { FILE *fp = gf->fp; gauge_header *gh = gf->header; int32type tmp, btmp; int j, stat, byterevflag = 0; char myname[] = "read_gauge_hdr"; // Read header, do byte reversal, if necessary, and check consistency // Read and verify magic number stat = sread_data(fp, &gh->magic_number, sizeof(gh->magic_number), myname, "magic number"); if (stat != 0) terminate(1); tmp = gh->magic_number; btmp = gh->magic_number; byterevn((int32type *)&btmp, 1); /** See if header chunk is BEGI = 1111836489 for big endian or the byte reverse 1229407554 for little endian **/ if (tmp == GAUGE_VERSION_NUMBER) byterevflag = 0; else if (btmp == GAUGE_VERSION_NUMBER) { byterevflag = 1; gh->magic_number = btmp; // printf("Reading with byte reversal\n"); if (sizeof(float) != sizeof(int32type)) { printf("read_gauge_hdr: Can't byte reverse\n"); printf("requires size of int32type(%d) = size of float(%d)\n", (int)sizeof(int32type), (int)sizeof(float)); terminate(1); } } else if (tmp == LIME_MAGIC_NO || btmp == LIME_MAGIC_NO) { // LIME format suggests a SciDAC file // Print error, set flag and return printf("%s: Looks like a SciDAC-formatted file\n", myname); gh->magic_number = LIME_MAGIC_NO; return 0; } else { // End of the road printf("read_gauge_hdr: Unrecognized magic number in gauge header\n"); printf("Expected %x but read %x\n", GAUGE_VERSION_NUMBER, tmp); printf("Expected %s but read %d\n", (char *)GAUGE_VERSION_NUMBER, tmp); terminate(1); return byterevflag; } // Read and process header information // Get lattice dimensions stat = sread_byteorder(byterevflag, fp, gh->dims, sizeof(gh->dims), myname, "dimensions"); if (stat != 0) terminate(1); // Check lattice dimensions for consistency if (gh->dims[0] != nx || gh->dims[1] != ny || gh->dims[2] != nz || gh->dims[3] != nt) { /* So we can use this routine to discover the dimensions, we provide that if nx = ny = nz = nt = -1 initially we don't die */ if (nx != -1 || ny != -1 || nz != -1 || nt != -1) { printf("%s: Incorrect lattice dimensions ",myname); for (j = 0; j < NDIMS; j++) printf("%d ", gh->dims[j]); printf("\n"); fflush(stdout); terminate(1); } else { nx = gh->dims[0]; ny = gh->dims[1]; nz = gh->dims[2]; nt = gh->dims[3]; volume = nx * ny * nz * nt; } } // Read date and time stamp stat = sread_data(fp, gh->time_stamp, sizeof(gh->time_stamp), myname, "time stamp"); if (stat != 0) terminate(1); // Read header byte length gh->header_bytes = sizeof(gh->magic_number) + sizeof(gh->dims) + sizeof(gh->time_stamp) + sizeof(gh->order); // Read data order stat = sread_byteorder(byterevflag, fp, &gh->order, sizeof(gh->order), myname, "order parameter"); if (stat != 0) terminate(1); return byterevflag; }
void r_prop_w_fm(char *filename, field_offset dest) { FILE *fp; int destnode; int x,y,z,t,i, byterevflag, c0,s0,c1,s1; wilson_matrix q; int32type tmp, magic_number,elements_per_site; int32type size_of_element, order, dims[4]; int32type t_stamp; site *s; wilson_propagator *qp; /*READING FILE HEADER*/ if(this_node==0){ fp = fopen(filename,"rb"); if(fp==NULL){ printf("Can't open propagator file %s, error %d\n",filename,errno); terminate(1); } if(fread(&magic_number,sizeof(int32type),1,fp) != 1) { printf("error in reading magic number from file %s\n", filename); terminate(1); } tmp=magic_number; if(magic_number == IO_UNI_MAGIC) byterevflag=0; else { byterevn((int32type *)&magic_number,1); if(magic_number == IO_UNI_MAGIC) { byterevflag=1; printf("Reading with byte reversal\n"); if( sizeof(float) != sizeof(int32type)) { printf("%s: Can't byte reverse\n", filename); printf("requires size of int32type(%d) = size of float(%d)\n", (int)sizeof(int32type),(int)sizeof(float)); terminate(1); } } else { /* Restore magic number as originally read */ magic_number = tmp; /* End of the road. */ printf("%s: Unrecognized magic number in prop file header.\n", filename); printf("Expected %x but read %x\n", IO_UNI_MAGIC,tmp); terminate(1); } }; if(fread(&t_stamp,sizeof(t_stamp),1,fp) != 1) { printf("error in reading time stamp from file %s\n", filename); terminate(1); } if(fread(&size_of_element,sizeof(int32type),1,fp) != 1) { printf("error in reading size of element from file %s\n", filename); terminate(1); } if(fread(&elements_per_site,sizeof(int32type),1,fp) != 1) { printf("error in reading elements per site from file %s\n", filename); terminate(1); } if(psread_byteorder(byterevflag,0,fp,dims,sizeof(dims), filename,"dimensions")!=0) terminate(1); if( dims[0]!=nx || dims[1]!=ny || dims[2]!=nz || dims[3]!=nt ) { printf(" Incorrect lattice size %d,%d,%d,%d\n", dims[0], dims[1], dims[2], dims[3]); terminate(1); } if( size_of_element != sizeof(float) || elements_per_site != 288 /* wilson_propagator */) { printf(" file %s is not a wilson propagator in arch_fm format\n", filename); terminate(1); } if(psread_byteorder(byterevflag,0,fp,&order,sizeof(int32type), filename,"order parameter")!=0) terminate(1); } /*if this_node==0*/ printf("fm prop header\n magic number %x\n timestamp %x\n size of elem %d\n el per site %d\n dim %d, %d, %d, %d\n order %d\nbyterevflag %d\n\n", magic_number, t_stamp, size_of_element, elements_per_site, dims[0],dims[1],dims[2],dims[3], order,byterevflag); for(t=0;t<nt;t++)for(z=0;z<nz;z++)for(y=0;y<ny;y++)for(x=0;x<nx;x++){ destnode=node_number(x,y,z,t); /* Node 0 reads, and sends site to correct node */ if(this_node==0){ if(psread_byteorder(byterevflag,0,fp,&q,sizeof(wilson_matrix), filename,"reading the wilson propagator\n")!=0) terminate(1); if(destnode==0){ /* just copy links */ i = node_index(x,y,z,t); for(s0=0;s0<4;s0++)for(c0=0;c0<3;c0++) for(s1=0;s1<4;s1++)for(c1=0;c1<3;c1++) { s = &lattice[i]; qp = (wilson_propagator *)F_PT(s,dest); qp->c[c0].d[s0].d[s1].c[c1].real = q.d[s0].c[c0].d[s1].c[c1].real; qp->c[c0].d[s0].d[s1].c[c1].imag = q.d[s0].c[c0].d[s1].c[c1].imag; } } else { /* send to correct node */ send_field((char *)&q, sizeof(wilson_matrix),destnode); } } /* The node which contains this site reads message */ else { /* for all nodes other than node 0 */ if(this_node==destnode){ get_field((char *)&q, sizeof(wilson_matrix),0); i = node_index(x,y,z,t); for(s0=0;s0<4;s0++)for(c0=0;c0<3;c0++) for(s1=0;s1<4;s1++)for(c1=0;c1<3;c1++) { s = &lattice[i]; qp = (wilson_propagator *)F_PT(s,dest); qp->c[c0].d[s0].d[s1].c[c1].real = q.d[s0].c[c0].d[s1].c[c1].real; qp->c[c0].d[s0].d[s1].c[c1].imag = q.d[s0].c[c0].d[s1].c[c1].imag; } } } } g_sync(); if(this_node==0){ printf("Restored wilson propagator from binary file %s, magic number %x\n", filename, IO_UNI_MAGIC); fclose(fp); fflush(stdout); } }
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; } }
// ----------------------------------------------------------------- // 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; } }