예제 #1
0
/* Utility for printing the record info */
void QIO_print_record_info(QIO_RecordInfo *record_info){

  printf("Record header: datatype %s recordtype %d \n",
	 QIO_get_datatype(record_info),
	 QIO_get_recordtype(record_info));
  printf("precision %s colors %d spins %d count %d\n",
	 QIO_get_precision(record_info),
	 QIO_get_colors(record_info),
	 QIO_get_spins(record_info),
	 QIO_get_datacount(record_info));
  
  if(QIO_get_recordtype(record_info) == QIO_HYPER){
    int i;
    int n = QIO_get_hyper_spacetime(record_info);
    int *lower = QIO_get_hyperlower(record_info);
    int *upper = QIO_get_hyperupper(record_info);
    printf("Hypercube lower");
    for(i = 0; i < n; i++){
      printf(" %d",lower[i]);
    }
    printf("\n");
    printf("Hypercube upper");
    for(i = 0; i < n; i++){
      printf(" %d",upper[i]);
    }
    printf("\n");
  }
}
예제 #2
0
파일: QIO_info_private.c 프로젝트: ssyr/qio
void QIO_encode_record_info(QIO_String *record_string, 
			  QIO_RecordInfo *record_info){
  char *buf;
  int remainder,n;
  char recordinfo_tags[QIO_MAXVALUESTRING];
  QIO_RecordInfoWrapper wrapper = QIO_RECORD_INFO_WRAPPER;

  /* Start by creating string of inner tags */
  buf = recordinfo_tags;
  remainder = QIO_MAXVALUESTRING;

  /* Build inner tag string by appending tags */
  *buf = '\0';
  buf = QIO_encode_as_string(buf,&record_info->version, &remainder);
  buf = QIO_encode_as_string(buf,&record_info->date, &remainder);
  buf = QIO_encode_as_int   (buf,&record_info->recordtype, &remainder);
  if(QIO_get_recordtype(record_info) == QIO_HYPER){
    buf = QIO_encode_as_int    (buf,&record_info->spacetime, &remainder);
    n = record_info->spacetime.value;
    buf = QIO_encode_as_intlist(buf,&record_info->hyperlower, n, &remainder);
    buf = QIO_encode_as_intlist(buf,&record_info->hyperupper, n, &remainder);
  }
  buf = QIO_encode_as_string(buf,&record_info->datatype, &remainder);
  buf = QIO_encode_as_string(buf,&record_info->precision, &remainder);
  buf = QIO_encode_as_int   (buf,&record_info->colors, &remainder);
  buf = QIO_encode_as_int   (buf,&record_info->spins, &remainder);
  buf = QIO_encode_as_int   (buf,&record_info->typesize, &remainder);
  buf = QIO_encode_as_int   (buf,&record_info->datacount, &remainder);

  /* Insert inner tag string into file wrapper structure */
  QIO_insert_record_tag_string(&wrapper, recordinfo_tags);

  /* Now build final XML string */
  QIO_string_realloc(record_string, QIO_STRINGALLOC);
  buf  = QIO_string_ptr(record_string);
  remainder = QIO_string_length(record_string);
  
  /* Begin with xml info stuff */
  strncpy(buf,QIO_XMLINFO,remainder);
  buf[remainder-1] = '\0';
  n = strlen(buf);
  remainder -= n;
  buf += n;
  if(remainder < 0){
    printf("QIO_encode_record_info: record_string overflow\n");
  }
  else{
    /* Conclude by appending the wrapped tag string */
    buf = QIO_encode_as_string (buf,&wrapper.recordinfo_tags, &remainder);
  }
}
예제 #3
0
int QIO_generic_read_record_data(QIO_Reader *in, 
	     void (*put)(char *buf, size_t index, int count, void *arg),
	     size_t datum_size, int word_size, void *arg,
  	     DML_Checksum *checksum, uint64_t *nbytes)
{
  char myname[] = "QIO_generic_read_record_data";
  int count;
  LRL_RecordReader *lrl_record_in;
  size_t datum_size_info;
  DML_Layout *layout = in->layout;
  int this_node = layout->this_node; 
  int status;
  int recordtype; 
  int latdim;
  QIO_RecordInfo *record_info = &in->record_info;

  /* List of acceptable binary data LIME types */
  int ntypes = 2;
  /* Avoid a compiler bug */
  LIME_type lime_type0 = QIO_LIMETYPE_BINARY_DATA;
  LIME_type lime_type1 = QIO_LIMETYPE_ILDG_BINARY_DATA;
  LIME_type lime_type_list[2] = {lime_type0, lime_type1};
  //  LIME_type lime_type_list[2] = {
  //    QIO_LIMETYPE_BINARY_DATA,
  //    QIO_LIMETYPE_ILDG_BINARY_DATA
  //  };
  LIME_type lime_type;


  /* It is an error to call for the data before reading the info
     in a given record */
  if(in->read_state != QIO_RECORD_DATA_NEXT){
    printf("%s(%d): Bad read state %d\n",myname,this_node,in->read_state);
    return QIO_ERR_INFO_MISSED;
  }

  /* Add record type and subset data to layout structure */
  recordtype = QIO_get_recordtype(record_info);
  layout->recordtype = recordtype;
  status = DML_insert_subset_data(layout, 
				  QIO_get_hyperlower(record_info),
				  QIO_get_hyperupper(record_info),
				  QIO_get_hyper_spacetime(record_info));
  if(status != 0)
    return QIO_ERR_BAD_SUBSET;

  /* Require consistency between the byte count obtained from the
     private record metadata and the datum_size and count parameters
     (per site for field or hypercube data or total for global data) */
  count = QIO_get_datacount(record_info);
  if(datum_size !=  QIO_get_typesize(record_info) * count)
    {
      printf("%s(%d): requested byte count %lu disagrees with the record %d * %d\n",
	     myname,this_node,(unsigned long)datum_size,
	     QIO_get_typesize(record_info), count);
      
      if(this_node == layout->master_io_node)
	QIO_print_record_info(record_info);
      
      return QIO_ERR_BAD_READ_BYTES;
    }
  
  
  /* Verify byte count per site (for field or hypercube) or total (for
     global) */
  datum_size_info = QIO_get_typesize(record_info) * count;

  if(datum_size != datum_size_info){
    printf("%s(%d): byte count mismatch request %lu != actual %lu\n",
	   myname, this_node, (unsigned long)datum_size, 
	   (unsigned long)datum_size_info);

    return QIO_ERR_BAD_READ_BYTES;
  }

  if(QIO_verbosity() >= QIO_VERB_DEBUG){
    printf("%s(%d): Calling QIO_open_read_field\n",myname,this_node);fflush(stdout);
  }

  /* Nodes read the field */

  /* Scan ahead and open the record with one of the listed LIME types */
  lrl_record_in = QIO_open_read_field(in, recordtype, datum_size, 
         lime_type_list, ntypes, &lime_type, &status);
  if(status != QIO_SUCCESS)return status;

  if(QIO_verbosity() >= QIO_VERB_DEBUG){
    printf("%s(%d): Calling QIO_read_field_data\n",
	   myname,this_node);fflush(stdout);
  }

  /* Then read the data and close the record */
  status = QIO_read_field_data(in, lrl_record_in, recordtype, 
			       put, count, datum_size, word_size, 
			       arg, checksum, nbytes);
  if(status != QIO_SUCCESS){
    printf("%s(%d): Error reading field data\n",myname,this_node);
    return status;
  }

  if(QIO_verbosity() >= QIO_VERB_DEBUG){
    printf("%s(%d): done reading field\n",myname,this_node);fflush(stdout);
  }

  /* Copy most recent node checksum into reader */
  memcpy(&(in->last_checksum), checksum, sizeof(DML_Checksum));

  if(this_node == layout->master_io_node){
    if(QIO_verbosity() >= QIO_VERB_REG){
      printf("%s(%d): Read field\n",myname,this_node);
      QIO_print_record_info(record_info);
    }
  }
      
  in->read_state = QIO_RECORD_CHECKSUM_NEXT;
  return QIO_SUCCESS;
}
예제 #4
0
int QIO_read_record_data(QIO_Reader *in, 
	     void (*put)(char *buf, size_t index, int count, void *arg),
	     size_t datum_size, int word_size, void *arg){


  char myname[] = "QIO_read_record_data";
  DML_Checksum checksum;
  uint64_t nbytes, expect_bytes;
  QIO_ChecksumInfo *checksum_info_expect;
  size_t buf_size;
  size_t volume;
  int this_node = in->layout->this_node;
  int status;
  int recordtype = QIO_get_recordtype(&(in->record_info));

  if(QIO_verbosity() >= QIO_VERB_DEBUG){
    printf("%s(%d): Calling QIO_generic_read_record_data\n",
	   myname,this_node);fflush(stdout);
  }

  status = QIO_generic_read_record_data(in, put, datum_size, word_size, arg,
					&checksum, &nbytes);
  if(status != QIO_SUCCESS)return status;

  /* Total number of sites in this record */
  volume = in->layout->subsetvolume;

  /* Compute the number of bytes read by all nodes */
  DML_sum_uint64_t(&nbytes);

  /* Check that the record size matches the expected size of the data */
  if(recordtype == QIO_GLOBAL){
    buf_size = datum_size; /* Global data */
    expect_bytes = buf_size;
  }
  else { /* Field data */
    expect_bytes = ((uint64_t)volume) * datum_size;
  }
  
  if(nbytes != expect_bytes){
    printf("%s(%d): bytes read %lu != expected rec_size %lu\n",
	   myname, in->layout->this_node,
	   (unsigned long)nbytes, (unsigned long)expect_bytes);
    return QIO_ERR_BAD_READ_BYTES;
  }
  
  /* Combine checksums over all nodes */
  DML_checksum_combine(&checksum);

  /* Copy most recent combined checksum into reader */
  memcpy(&(in->last_checksum), &checksum, sizeof(DML_Checksum));

  /* Everyone calls this. It changes the state machine */
  checksum_info_expect = QIO_read_checksum(in);
  if(this_node == in->layout->master_io_node)
    {
      if(in->format == QIO_SCIDAC_NATIVE){
	if(checksum_info_expect == NULL)return QIO_ERR_CHECKSUM_INFO;
	status = QIO_compare_checksum(this_node, 
				      checksum_info_expect, &checksum);
	if(status != QIO_SUCCESS)return status;
      }
    }

  /* Checksum info expect may be NULL on non master node.
     This is not an error. Freeing it is */
  if( checksum_info_expect != NULL ) { 
    QIO_destroy_checksum_info(checksum_info_expect);
  }

  if(QIO_verbosity() >= QIO_VERB_DEBUG){
    printf("%s(%d): done with QIO_read_record_data\n",
	   myname,in->layout->this_node);fflush(stdout);
  }
  
  return QIO_SUCCESS;
}
예제 #5
0
파일: QIO_info_private.c 프로젝트: ssyr/qio
/* Compare only fields that occur in the expected record info */
int QIO_compare_record_info(QIO_RecordInfo *found, QIO_RecordInfo *expect){
  char myname[] = "QIO_compare_record_info";

  if(QIO_defined_recordtype(expect))
    if(!QIO_defined_recordtype(found) &&
       QIO_get_recordtype(found)  != QIO_get_recordtype(expect))
      {
	printf("%s:Recordtype flag mismatch expected %d found %d \n",myname,
	       QIO_get_recordtype(expect),QIO_get_recordtype(found));
	return QIO_ERR_REC_INFO;
      }

  if(QIO_defined_datatype(expect))
    if(!QIO_defined_datatype(found) && 
       strncmp(QIO_get_datatype(found),QIO_get_datatype(expect),
	       QIO_MAXVALUESTRING))
      {
	printf("%s:Datatype mismatch expected %s found %s \n",myname,
	       QIO_get_datatype(expect),QIO_get_datatype(found));
	return QIO_ERR_REC_INFO;
      }

  if(QIO_defined_precision(expect))
    if(!QIO_defined_precision(found) &&
       strncmp(QIO_get_precision(found),QIO_get_precision(expect),
	       QIO_MAXVALUESTRING))
      {
	printf("%s:Precision mismatch expected %s found %s \n",myname,
	       QIO_get_precision(expect),QIO_get_precision(found));
	return QIO_ERR_REC_INFO;
      }

  if(QIO_defined_colors(expect))
    if(!QIO_defined_colors(found) &&
       QIO_get_colors(found) != QIO_get_colors(expect))
      {
	printf("%s:Colors mismatch expected %d found %d \n",myname,
	       QIO_get_colors(expect),QIO_get_colors(found));
	return QIO_ERR_REC_INFO;
      }

  if(QIO_defined_spins(expect))
    if(!QIO_defined_spins(found) &&
       QIO_get_spins(found)  != QIO_get_spins(expect))
      {
	printf("%s:Spins mismatch expected %d found %d \n",myname,
	       QIO_get_spins(expect),QIO_get_spins(found));
	return QIO_ERR_REC_INFO;
      }

  if(QIO_defined_typesize(expect))
    if(!QIO_defined_typesize(found) &&
       QIO_get_typesize(found) != QIO_get_typesize(expect))
      {
	printf("%s:Typesize mismatch expected %d found %d \n",myname,
	       QIO_get_typesize(expect),QIO_get_typesize(found));
	return QIO_ERR_REC_INFO;
      }

  if(QIO_defined_datacount(expect))
    if(!QIO_defined_datacount(found) &&
       QIO_get_datacount(found) != QIO_get_datacount(expect))
      {
	printf("%s:Datacount mismatch expected %d found %d \n",myname,
	       QIO_get_datacount(expect),QIO_get_datacount(found));
	return QIO_ERR_REC_INFO;
      }

  return QIO_SUCCESS;
}
예제 #6
0
파일: QIO_info_private.c 프로젝트: ssyr/qio
int QIO_decode_record_info(QIO_RecordInfo *record_info, 
			QIO_String *record_string){
  char *parse_pt = QIO_string_ptr(record_string);
  char *tmp_pt;
  char tag[QIO_MAXTAG];
  char tags_string[QIO_MAXVALUESTRING];
  char value_string[QIO_MAXVALUESTRING];
  int errors = 0;
  QIO_RecordInfoWrapper wrapper = QIO_RECORD_INFO_WRAPPER;
  QIO_RecordInfo templ = QIO_RECORD_INFO_TEMPLATE;
  char *left_angle;

  /* Compatibility */
  QIO_RecordInfo_v1p0 record_info_v1p0 = QIO_RECORD_INFO_TEMPLATE_v1p0;

  /* Initialize record info structure from a template */
  memcpy(record_info, &templ, sizeof(QIO_RecordInfo));

  /* Start parsing record_string */
  /* Check leading tag, which is probably the info phrase "<?xml ...?>" */
  /* We ignore it if it is there */
  tmp_pt = QIO_next_tag(parse_pt, tag, &left_angle);
  if(strcmp(tag,QIO_QUESTXML)==0){
    /* Found ?xml, so resume parsing after the closing ">", ignoring
       the field. Otherwise, leave the parse_pt at its initial value */
    parse_pt = tmp_pt;
  }

  /* Open top-level tag (wrapper) and extract string containing tags */
  parse_pt = QIO_get_tag_value(parse_pt, tag, tags_string);
  QIO_decode_as_string (tag, tags_string, &wrapper.recordinfo_tags);

  /* If outer wrapper has bad tag, exit with error status */
  if(QIO_check_string_occur(&wrapper.recordinfo_tags))
    return QIO_BAD_XML;
  /* Otherwise start parsing the string of tags */
  parse_pt = QIO_get_record_info_tag_string(&wrapper);

  /* Scan string until null character is reached */
  while(*parse_pt){
    parse_pt = QIO_get_tag_value(parse_pt, tag, value_string);
    
    QIO_decode_as_string (tag,value_string,&record_info->version);
    QIO_decode_as_string (tag,value_string,&record_info->date);
    QIO_decode_as_int    (tag,value_string,&record_info->recordtype);
    QIO_decode_as_int    (tag,value_string,&record_info->spacetime);
    QIO_decode_as_intlist(tag,value_string,&record_info->hyperlower); 
    QIO_decode_as_intlist(tag,value_string,&record_info->hyperupper); 
    QIO_decode_as_string (tag,value_string,&record_info->datatype);
    QIO_decode_as_string (tag,value_string,&record_info->precision);
    QIO_decode_as_int    (tag,value_string,&record_info->colors);
    QIO_decode_as_int    (tag,value_string,&record_info->spins);
    QIO_decode_as_int    (tag,value_string,&record_info->typesize);
    QIO_decode_as_int    (tag,value_string,&record_info->datacount);
    /* compatibility */	 
    QIO_decode_as_int    (tag,value_string,&record_info_v1p0.globaldata);
  }

  /* Backward compatibility */

  /* Convert version 1.0 record_info structure to version 1.1 */

  if(strcmp("1.0",QIO_get_record_info_version(record_info)) == 0){

    /* Version 1.1 added a new record type: hypercube subset and
       requires a list of lower and upper coordinate bounds to specify
       the hypercube.  These parameters are ignored with the
       QIO_GLOBAL and QIO_FIELD record types, the only ones used in
       version 1, so we don't need to set default values. */

    /* An earlier defective version (also labeled 1.0) was missing the
       "globaldata" parameter altogether. */
    /* If the old globaldata tag is missing, insert a default value */
    
    if(QIO_check_int_occur(&record_info_v1p0.globaldata) != 0){
      record_info_v1p0.globaldata.occur = 1;
      /* Default is "field" record type */
      record_info_v1p0.globaldata.value = QIO_FIELD;
    }

    /* Also the "globaldata" member was renamed "recordtype".  So just
       copy the old parameter value. */

    record_info->recordtype.occur = 1;
    record_info->recordtype.value = QIO_get_globaldata(&record_info_v1p0);

  }

  /* Check for completeness */
  
  errors += QIO_check_string_occur(&record_info->version);
  errors += QIO_check_int_occur   (&record_info->recordtype);
  errors += QIO_check_string_occur(&record_info->datatype);
  errors += QIO_check_string_occur(&record_info->precision);
  errors += QIO_check_int_occur   (&record_info->typesize);
  errors += QIO_check_int_occur   (&record_info->datacount);

  /* Requirements for hypercube record type */

  if(QIO_get_recordtype(record_info) == QIO_HYPER){
    errors += QIO_check_int_occur (&record_info->spacetime);
    errors += QIO_check_intarray_occur (&record_info->hyperlower);
    errors += QIO_check_intarray_occur (&record_info->hyperupper);
  }

  return errors;
}