NAMD
TestArray.C
Go to the documentation of this file.
1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <climits>
5 #include <cmath>
6 #include "TestArray.h"
7 
8 static const int LABEL_SIZE = 116;
9 
11  const char *filename,
12  const char *label,
13  const void *array,
14  int elemsize,
15  int length,
16  int isfp // is floating point?
17  ) {
18  const char *stype = "unknown";
19  if ( isfp && elemsize==8 ) stype = "double";
20  else if ( isfp && elemsize==4 ) stype = "float";
21  else if ( !isfp && elemsize==8 ) stype = "int64";
22  else if ( !isfp && elemsize==4 ) stype = "int32";
23  else if ( !isfp && elemsize==2 ) stype = "int16";
24  else if ( !isfp && elemsize==1 ) stype = "int8";
25  printf("Writing %s array of length %d to binary file %s\n",
26  stype, length, filename);
27  FILE *fp = fopen(filename, "wb");
28  if ( fp == 0 ) return -1;
29  char padbuf[LABEL_SIZE] = { 0 };
30  strncpy(padbuf, label, LABEL_SIZE-1);
31  fwrite(padbuf, 1, LABEL_SIZE, fp);
32  fwrite(&isfp, sizeof(int), 1, fp);
33  fwrite(&elemsize, sizeof(int), 1, fp);
34  fwrite(&length, sizeof(int), 1, fp);
35  fwrite(array, elemsize, length, fp);
36  fclose(fp);
37  fflush(stdout);
38  return 0;
39 }
40 
41 #ifdef TEST_ARRAY_STANDALONE
42 
43 typedef char int8;
44 typedef short int16;
45 typedef int int32;
46 typedef long long int int64;
47 
48 //
49 // Pass unitialized pointers for label and array buffer.
50 // Storage allocated based on file content.
51 //
52 int TestArray_read(
53  const char *filename,
54  char **p_label,
55  void **p_buffer,
56  int *p_isfp, // set to nonzero if file indicates floating point
57  int *p_elemsize,
58  int *p_length
59  ) {
60  FILE *fp = fopen(filename, "rb");
61  if ( fp == 0 ) return -1;
62  char *label = (char *) malloc(LABEL_SIZE);
63  int isfp, elemsize, length;
64  fread(label, 1, LABEL_SIZE, fp);
65  fread(&isfp, sizeof(int), 1, fp);
66  fread(&elemsize, sizeof(int), 1, fp);
67  fread(&length, sizeof(int), 1, fp);
68  void *buffer = malloc(elemsize * length);
69  fread(buffer, elemsize, length, fp);
70  fclose(fp);
71  *p_label = label;
72  *p_buffer = buffer;
73  *p_isfp = isfp;
74  *p_elemsize = elemsize;
75  *p_length = length;
76  return 0;
77 }
78 
79 //
80 // Free label and array buffer memory allocated by file reader.
81 //
82 void TestArray_free_memory(
83  char *label,
84  void *buffer
85  ) {
86  free(label);
87  free(buffer);
88 }
89 
90 //
91 // Read ith of sz-sized elements from buf. Return as double.
92 //
93 double TestArray_read_elem_double(void *buf, int i, int sz) {
94  double x;
95  void *p = (void *) ((const char *) buf + i*sz);
96  switch (sz) {
97  case 4:
98  x = *((float *) p);
99  break;
100  case 8:
101  x = *((double *) p);
102  break;
103  default:
104  fprintf(stderr,
105  "Unrecognized element size %d for floating point array\n", sz);
106  exit(1);
107  }
108  return x;
109 }
110 
111 //
112 // Read ith of sz-sized elements from buf. Return as double.
113 //
114 int64 TestArray_read_elem_int(void *buf, int i, int sz) {
115  int64 n;
116  void *p = (void *) ((const char *) buf + i*sz);
117  switch (sz) {
118  case 1:
119  n = *((int8 *) p);
120  break;
121  case 2:
122  n = *((int16 *) p);
123  break;
124  case 4:
125  n = *((int32 *) p);
126  break;
127  case 8:
128  n = *((int64 *) p);
129  break;
130  default:
131  fprintf(stderr,
132  "Unrecognized element size %d for integer array\n", sz);
133  exit(1);
134  }
135  return n;
136 }
137 
138 int main(int argc, const char *argv[]) {
139  if (sizeof(int8) != 1 ||
140  sizeof(int16) != 2 ||
141  sizeof(int32) != 4 ||
142  sizeof(int64) != 8) {
143  fprintf(stderr, "Integer sizes are incorrect. Must rebuild.\n");
144  exit(1);
145  }
146  if (argc < 3) {
147  fprintf(stderr, "Compare two binary files created using TestArray.\n");
148  fprintf(stderr, "Syntax: %s file1 file2 [first_index] [last_index]\n",
149  argv[0]);
150  exit(1);
151  }
152  const char *fname1 = argv[1];
153  const char *fname2 = argv[2];
154  int first = 0;
155  int last = INT_MAX;
156  if (argc > 3) first = atoi(argv[3]);
157  if (argc > 4) last = atoi(argv[4]);
158 
159  char *label1, *label2;
160  void *buffer1, *buffer2;
161  int isfp1, isfp2;
162  int elemsize1, elemsize2;
163  int length1, length2;
164 
165  if ( TestArray_read(fname1, &label1, &buffer1,
166  &isfp1, &elemsize1, &length1) ) {
167  fprintf(stderr, "Unable to read first file %s\n", fname1);
168  exit(1);
169  }
170 
171  if ( TestArray_read(fname2, &label2, &buffer2,
172  &isfp2, &elemsize2, &length2) ) {
173  fprintf(stderr, "Unable to read second file %s\n", fname2);
174  exit(1);
175  }
176 
177  if ( isfp1 != isfp2 ) {
178  fprintf(stderr, "Trying to compare floating point and integer data\n");
179  exit(1);
180  }
181 
182  if (last >= length1) last = length1-1;
183  if (last >= length2) last = length2-1;
184 
185  printf("%s\n%s\n", label1, label2);
186  if (isfp1) {
187  printf("%6s %14s %14s %14s %14s\n",
188  "index", "file1", "file2", "abserr", "relerr");
189  for (int i=first; i <= last; i++) {
190  double a = TestArray_read_elem_double(buffer1, i, elemsize1);
191  double b = TestArray_read_elem_double(buffer2, i, elemsize2);
192  double abserr = a - b;
193  double relerr = (a != 0 ? fabs(abserr) / fabs(a) : 0);
194  printf("%6d %14.8f %14.8f %14.8f %14e\n",
195  i, a, b, abserr, relerr);
196  }
197  }
198  else {
199  printf("%6s %14s %14s %14s\n",
200  "index", "file1", "file2", "abserr");
201  for (int i=first; i <= last; i++) {
202  int64 a = TestArray_read_elem_int(buffer1, i, elemsize1);
203  int64 b = TestArray_read_elem_int(buffer2, i, elemsize2);
204  int64 abserr = a - b;
205  printf("%6d %14ld %14ld %14ld\n", i, a, b, abserr);
206  }
207  }
208 
209  TestArray_free_memory(label1, buffer1);
210  TestArray_free_memory(label2, buffer2);
211 
212  return 0;
213 }
214 
215 #endif // TEST_ARRAY_STANDALONE
short int32
Definition: dumpdcd.c:24
int TestArray_write_helper(const char *filename, const char *label, const void *array, int elemsize, int length, int isfp)
Definition: TestArray.C:10
static const int LABEL_SIZE
Definition: TestArray.C:8
long long int64
Definition: common.h:34
int main(int argc, char *argv[])
Definition: diffbinpdb.c:15
gridSize x