00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "xmdf_putil.h"
00010 #include <mpi.h>
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include "xmdf_par.h"
00014
00015 #include <sys/types.h>
00016 #include <sys/stat.h>
00017 #include <fcntl.h>
00018 #include <unistd.h>
00019 #include <string.h>
00020
00021 #include "closeh5.h"
00022
00023
00024
00025
00026
00027 #define ERRORD(A,B,C) ERROR(A,B,C)
00028 #define PRINTM(A) PRINTS("msg",(A))
00029
00030
00031
00032
00033
00034 xid fileinit( char *a_fname, char *a_gname )
00035 {
00036 xid fileID, dataSetID;
00037 closeObjPtr closeobj = closeCreate();
00038 xid ret;
00039
00040 xfiSetComm( MPI_COMM_WORLD );
00041
00042 ret = xfCreateFilePar( a_fname, &fileID, XTRUE, MPI_INFO_NULL );
00043 if (0 > closePush( closeobj, xfCloseFile, ret < 0 ? ret : fileID ))
00044 {
00045 PRINTM( "xfCreateFilePar returned error" );
00046 return ret;
00047 }
00048
00049
00050
00051 ret = xfCreateScalarDataset( fileID, a_gname, "", TS_SECONDS, -1, &dataSetID );
00052 if (0 > closePush( closeobj, xfCloseGroup, ret < 0 ? ret : dataSetID ))
00053 {
00054 PRINTM( "xfCreateScalarDataset returned error" );
00055 return ret;
00056 }
00057
00058 closePush( closeobj, NULL, -1 );
00059 return 0;
00060 }
00061
00062
00063
00064
00065
00066 xid setup (closeObjPtr a_closeobj,
00067 const char *a_filename,
00068 const char *a_groupname,
00069 const int a_mynum,
00070 int *a_totalCount)
00071 {
00072 xid ret;
00073 xid fileID, dataSetID;
00074
00075
00076 ret = xfOpenFilePar(a_filename, &fileID, XFALSE, MPI_INFO_NULL);
00077 if (0 > closePush( a_closeobj, xfCloseFile, ret < 0 ? ret : fileID ))
00078 {
00079 ERRORD( "setup", "xfOpenFilePar returned error", ret );
00080 return ret;
00081 }
00082
00083 PRINTS( "filename", a_filename );
00084 PRINTS( "groupname", a_groupname );
00085
00086
00087 ret = xfOpenGroup(fileID, a_groupname, &dataSetID);
00088 if (0 > closePush( a_closeobj, xfCloseGroup, ret < 0 ? ret : dataSetID ))
00089 {
00090 ERRORD( "setup", "xfOpenGroup returned error", ret );
00091 return ret;
00092 }
00093
00094
00095 {
00096 int num = a_mynum;
00097 MPI_Allreduce( &num,
00098 a_totalCount,
00099 1,
00100 MPI_INT,
00101 MPI_SUM,
00102 MPI_COMM_WORLD );
00103 }
00104 return dataSetID;
00105 }
00106
00107
00108
00109
00110
00111 xid setup2 (closeObjPtr a_closeobj,
00112 const char *a_filename,
00113 const char *a_groupname,
00114 const int a_mynum,
00115 int *a_totalCount)
00116 {
00117 xid ret;
00118 xid fileID, dataSetID;
00119
00120
00121 ret = xfOpenFilePar(a_filename, &fileID, XFALSE, MPI_INFO_NULL);
00122 if (0 > closePush( a_closeobj, xfCloseFile, ret < 0 ? ret : fileID ))
00123 {
00124 ERRORD( "setup", "xfOpenFilePar returned error", ret );
00125 return ret;
00126 }
00127
00128 PRINTS( "filename", a_filename );
00129 PRINTS( "groupname", a_groupname );
00130
00131
00132 ret = xfOpenGroup(fileID, a_groupname, &dataSetID);
00133 if (0 > closePush( a_closeobj, xfCloseGroup, ret < 0 ? ret : dataSetID ))
00134 {
00135 ERRORD( "setup", "xfOpenGroup returned error", ret );
00136 return ret;
00137 }
00138
00139
00140 {
00141 int num = a_mynum;
00142 MPI_Allreduce( &num,
00143 a_totalCount,
00144 1,
00145 MPI_INT,
00146 MPI_SUM,
00147 MPI_COMM_WORLD );
00148 }
00149 return dataSetID;
00150 }
00151
00152
00153
00154
00155
00156 double absd( double a_val )
00157 {
00158 return a_val < 0 ? -a_val : a_val;
00159 }
00160
00161
00162
00163
00164
00165 int testminmax( int a_timesteps,
00166 xid a_dataSetID,
00167 int a_minnotmax,
00168 double a_tolerance,
00169 double *a_expectminmaxs )
00170 {
00171 xid ret;
00172 int ii;
00173 float *minmaxs = malloc(sizeof(float)*a_timesteps);
00174
00175 if (!minmaxs)
00176 {
00177 ERRORD( "testScalar", "malloc", 0 );
00178 return -1;
00179 }
00180
00181 TIMER("pre");
00182 ret = a_minnotmax ?
00183 xfGetDatasetMins( a_dataSetID, a_timesteps, minmaxs ) :
00184 xfGetDatasetMaxs( a_dataSetID, a_timesteps, minmaxs );
00185 TIMER("TIME xfGetDatasetMins/Maxs");
00186 if (ret < 0)
00187 {
00188 free(minmaxs);
00189 ERRORD( "testminmax",
00190 a_minnotmax ?
00191 "xfGetDatasetMins" :
00192 "xfGetDatasetMaxs",
00193 ret );
00194 return ret;
00195 }
00196
00197 for (ii=0; ii<a_timesteps; ii++)
00198 {
00199 if (absd(minmaxs[ii]) > absd(a_expectminmaxs[ii]) * (1+a_tolerance) ||
00200 absd(minmaxs[ii]) < absd(a_expectminmaxs[ii]) * (1-a_tolerance) )
00201 {
00202 ERRORD( "testminmax",
00203 a_minnotmax ?
00204 "read min does not match parallel write at timestep" :
00205 "read max does not match parallel write at timestep",
00206 ii );
00207 PRINTF( "found", minmaxs[ii] );
00208 PRINTF( "expect", a_expectminmaxs[ii] );
00209 PRINTF( "difference", a_expectminmaxs[ii]-minmaxs[ii] );
00210 return -1;
00211 }
00212 }
00213
00214 if (minmaxs) free(minmaxs);
00215
00216 return !0;
00217 }
00218
00219
00220
00221
00222
00223 int testScalar()
00224 {
00225 double *values;
00226 int *indices;
00227 int subnum;
00228 char *filename = "dbl_test.h5";
00229 char *groupname = "myData";
00230 int timesteps = 2;
00231 double average[2];
00232 int rank;
00233 int offset;
00234 double writemins[2];
00235 double writemaxs[2];
00236
00237
00238 {
00239 xid ret = fileinit(filename, groupname);
00240 if (0 > ret)
00241 return ret;
00242 }
00243
00244
00245 subnum = 1000000;
00246 PRINTD( "subnum", subnum );
00247
00248 values = malloc( sizeof(double) * subnum);
00249 indices = malloc( sizeof(int) * subnum );
00250
00251
00252 {
00253 MPI_Comm_rank( MPI_COMM_WORLD, &rank );
00254
00255
00256
00257
00258 MPI_Scan( &subnum, &offset, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
00259 offset -= subnum;
00260
00261 }
00262
00263
00264 {
00265 int ii;
00266 xid ret;
00267 xid dataSetID;
00268 int totalnum;
00269 closeObjPtr closeobj = closeCreate();
00270
00271 dataSetID = setup( closeobj, filename, groupname, subnum, &totalnum );
00272 if (dataSetID < 0) return dataSetID;
00273
00274 PRINTF( "totalnum", totalnum );
00275
00276
00277 for (ii=0; ii<timesteps; ii++)
00278 {
00279
00280 {
00281 int jj;
00282 int pick = 777;
00283
00284 average[ii] = 0;
00285
00286 for (jj = 0; jj<subnum; jj++)
00287 {
00288
00289 indices[jj] = (offset + jj - 3) % totalnum + 1;
00290 values[jj] = indices[jj] + (rank * .01) + (ii * .001);
00291
00292
00293 average[ii] += values[jj]/subnum;
00294 if (jj==0 || writemins[ii]>values[jj]) writemins[ii] = values[jj];
00295 if (jj==0 || writemaxs[ii]<values[jj]) writemaxs[ii] = values[jj];
00296 if( (indices[jj]-1)%subnum == 0 ) pick = jj;
00297 }
00298
00299 PRINTD( "offset", offset );
00300 PRINTD( "pick", pick );
00301 PRINTD( "indices[pick]-1", indices[pick]-1 );
00302 PRINTF( "values[pick]", values[pick] );
00303 average[ii] *= values[pick];
00304 }
00305
00306 TIMER("pre");
00307 xfiPrintDataset( __FILE__, __LINE__, "test", dataSetID);
00308 PRINTD( "totalnum", totalnum );
00309 PRINTD( "subnum", subnum );
00310 PRINTF( "values", values[0] );
00311 PRINTD( "indices", indices[0] );
00312 ret = xfWriteScalarTimestepPar( dataSetID,
00313 0.0,
00314 totalnum,
00315 subnum,
00316 values,
00317 indices,
00318 0 );
00319 TIMER("TIME xfWriteScalarTimestepPar");
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 if (closePush( closeobj, NULL, ret ) < 0)
00332 {
00333 ERRORD( "testScalar", "xfWriteScalarTimestepPar", ret );
00334 return ret;
00335 }
00336 }
00337
00338 closePush( closeobj, NULL, -1 );
00339 }
00340
00341
00342 {
00343 int ii;
00344 xid ret;
00345 xid dataSetID;
00346 int totalnum;
00347 closeObjPtr closeobj = closeCreate();
00348
00349 dataSetID = setup( closeobj, filename, groupname, subnum, &totalnum );
00350 if (dataSetID < 0) return dataSetID;
00351
00352 for (ii=0; ii<timesteps; ii++)
00353 {
00354 TIMER("pre");
00355 PRINTD("dataSetID",(int)dataSetID);
00356 xfiPrintDataset( __FILE__, __LINE__, "read", dataSetID );
00357 {
00358 xid DatasetId = H5Dopen(dataSetID, "Values");
00359 printf( "%s:%d: H5Dopen %d\n", __FILE__, __LINE__, (int)DatasetId );
00360 H5Dclose(DatasetId);
00361 }
00362 ret = xfReadScalarValuesTimestepPar( dataSetID,
00363 ii+1,
00364 offset+1,
00365 subnum,
00366 values,
00367 0 );
00368 {
00369 xid DatasetId = H5Dopen(dataSetID, "Values");
00370 PRINTD( "H5Dopen", DatasetId );
00371 H5Dclose(DatasetId);
00372 }
00373 TIMER("TIME xfReadScalarValuesTimestepPar");
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 if (closePush( closeobj, NULL, ret ) < 0)
00384 {
00385 printf( "%s:%d: ERROR in %s: %d %d %d %d %d %d %d\n",
00386 __FILE__, __LINE__,
00387 "testScalar", ret,
00388 (int)dataSetID,
00389 ii+1,
00390 offset+1,
00391 subnum,
00392 values==0,
00393 0 );
00394 return ret;
00395 }
00396
00397
00398 {
00399 double avg = 0;
00400 int jj;
00401
00402 for (jj = 0; jj<subnum; jj++)
00403 {
00404 avg += values[jj]/subnum;
00405 }
00406 avg *= values[0];
00407
00408 if (avg > average[ii]*(1+.00001) ||
00409 avg < average[ii]*(1-.00001) )
00410 {
00411 ERRORD( "testScalar", "read does not match write for timestep", ii+1 );
00412 PRINTF( "found", avg );
00413 PRINTF( "expected", average[ii] );
00414 PRINTF( "values[0]", values[0] );
00415 }
00416 else
00417 PRINTD( "PASS: parallel read matches parallel write, step ", ii );
00418 }
00419 }
00420
00421 closePush( closeobj, NULL, -1 );
00422 }
00423
00424
00425 MPI_Barrier(MPI_COMM_WORLD);
00426 if (!rank) {
00427 int ii;
00428 xid ret;
00429 xid dataSetID;
00430 xid fileID;
00431 closeObjPtr closeobj = closeCreate();
00432
00433
00434 ret = xfOpenFile(filename, &fileID, XTRUE);
00435 if (0 > closePush( closeobj, xfCloseFile, ret < 0 ? ret : fileID ))
00436 {
00437 PRINTM( "xfOpenFilePar returned error" );
00438 return ret;
00439 }
00440
00441
00442 ret = xfOpenGroup(fileID, groupname, &dataSetID);
00443 if (ret >= 0) ret = dataSetID;
00444 if (0 > closePush( closeobj, xfCloseGroup, ret ))
00445 {
00446 PRINTM( "xfOpenGroup returned error" );
00447 return ret;
00448 }
00449
00450 ret = testminmax( timesteps, dataSetID, XTRUE, 0.001, writemins );
00451 if (ret < 0)
00452 {
00453 ERRORD( "testScalar", "testminmax (min)", ret );
00454 return ret;
00455 }
00456
00457 ret = testminmax( timesteps, dataSetID, XFALSE, 0.001, writemaxs );
00458 if (ret < 0)
00459 {
00460 ERRORD( "testScalar", "testminmax (max)", ret );
00461 return ret;
00462 }
00463
00464 for (ii=0; ii<timesteps; ii++)
00465 {
00466 TIMER("pre");
00467 ret = xfReadScalarValuesTimestepDoublePortion( dataSetID,
00468 ii+1,
00469 1,
00470 subnum,
00471 values );
00472 TIMER("TIME xfReadScalarValuesTimestepDoublePortion");
00473
00474
00475
00476
00477
00478
00479
00480 if (closePush( closeobj, NULL, ret ) < 0)
00481 {
00482 PRINTD( "ERROR in testScalar: xfReadScalarTimestepDoublePortion returned", ret );
00483 return ret;
00484 }
00485
00486
00487 {
00488 double avg = 0;
00489 int jj;
00490
00491 for (jj = 0; jj<subnum; jj++)
00492 {
00493 avg += values[jj]/subnum;
00494 }
00495 avg *= values[0];
00496
00497 if (avg > average[ii]*(1+.00001) ||
00498 avg < average[ii]*(1-.00001) )
00499 {
00500 ERRORD( "testScalar", "read does not match write for timestep", ii+1 );
00501 PRINTF( "found", avg );
00502 PRINTF( "expected", average[ii] );
00503 }
00504 else
00505 PRINTM( "PASS: sequential read matches parallel write" );
00506 }
00507 }
00508
00509 closePush( closeobj, NULL, -1 );
00510 }
00511
00512 return !0;
00513 }
00514
00515
00516
00517
00518
00519 int testVector()
00520 {
00521 double *values;
00522 int valuesRank = 2;
00523 int *indices;
00524 int subnum;
00525 char *filename = "dbl_test.h5";
00526 char *groupname = "myData";
00527
00528
00529 {
00530 xid ret = fileinit(filename, groupname);
00531 if (0 > ret)
00532 return ret;
00533 }
00534
00535
00536 subnum = 100;
00537 PRINTD( "subnum", subnum );
00538
00539 values = malloc( sizeof(*values) * subnum * valuesRank );
00540 indices = malloc( sizeof(*indices) * subnum );
00541
00542
00543 {
00544 int rank;
00545 int offset;
00546
00547 MPI_Comm_rank( MPI_COMM_WORLD, &rank );
00548
00549
00550
00551
00552 MPI_Scan( &subnum, &offset, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
00553 offset -= subnum;
00554
00555 {
00556 int ii;
00557 int jj;
00558
00559 for (ii = 0; ii<subnum; ii++)
00560 {
00561 indices[ii] = offset + ii + 1;
00562
00563 for (jj = 0; jj<valuesRank; jj++)
00564 {
00565
00566 values[ii*valuesRank + jj] = (ii*10 + jj)*10 + rank;
00567 }
00568 }
00569 }
00570 }
00571
00572
00573 {
00574 xid ret;
00575 xid dataSetID;
00576 int totalnum;
00577 closeObjPtr closeobj = closeCreate();
00578
00579 dataSetID = setup( closeobj, filename, groupname, subnum, &totalnum );
00580 if (dataSetID < 0) return dataSetID;
00581
00582 ret = xfWriteVectorTimestepPar( dataSetID,
00583 0.0,
00584 totalnum,
00585 subnum,
00586 valuesRank,
00587 values,
00588 indices,
00589 0 );
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 if (closePush( closeobj, NULL, ret ) < 0)
00617 {
00618 PRINTD( "ERROR in testVector: xfWriteVectorTimestepPar returned", ret );
00619 return ret;
00620 }
00621
00622 printf( "%s:%d: wrote values[5][0-1] = %f %f\n", __FILE__, __LINE__,
00623 values[5*valuesRank + 0],
00624 values[5*valuesRank + 1] );
00625
00626 closePush( closeobj, NULL, -1 );
00627 }
00628
00629
00630 {
00631 xid ret;
00632 xid dataSetID;
00633 int totalnum;
00634 closeObjPtr closeobj = closeCreate();
00635
00636 dataSetID = setup( closeobj, filename, groupname, subnum, &totalnum );
00637 if (dataSetID < 0) return dataSetID;
00638
00639 ret = xfReadScalarValuesTimestepPar( dataSetID,
00640 1,
00641 1,
00642 subnum,
00643 values,
00644 0 );
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654 if (closePush( closeobj, NULL, ret ) < 0)
00655 {
00656 PRINTD( "ERROR in testVector: xfReadVectorTimestepPar returned", ret );
00657 return ret;
00658 }
00659
00660 printf( "%s:%d: wrote values[5][0-1] = %f %f\n", __FILE__, __LINE__,
00661 values[5*valuesRank + 0],
00662 values[5*valuesRank + 1] );
00663
00664 closePush( closeobj, NULL, -1 );
00665 }
00666
00667 return !0;
00668 }
00669
00670 void timeposix()
00671 {
00672 int fd;
00673 char *fname = "data.posix";
00674 int numentries = 3000000;
00675 int memsize = sizeof(double) * numentries;
00676 int uniqueloc = numentries/3;
00677 double *ptr = (double*)malloc(memsize);
00678 int ret;
00679 int offset;
00680 double uniquedata;
00681
00682 uniquedata = deltatime();
00683
00684
00685
00686 fd=open(fname, O_WRONLY|O_CREAT|O_APPEND, 0760);
00687 if (fd < 0 )
00688 {
00689 printf("%s:%d: ERROR: Failed to open file %s\n", __FILE__,__LINE__, fname);
00690 return;
00691 }
00692
00693 memset(ptr, 0, memsize);
00694 ptr[uniqueloc] = uniquedata;
00695 TIMER("PreIsoWrite");
00696 ret = write(fd, ptr, memsize);
00697 offset = lseek(fd, 0, SEEK_CUR);
00698 close(fd);
00699 TIMER("POSTiSOwRITE");
00700 if (ret != memsize)
00701 {
00702 printf("%s:%d: ERROR: Failed to write file %s\n", __FILE__,__LINE__, fname);
00703 return;
00704 }
00705
00706
00707
00708 memset(ptr, 0, memsize);
00709 if (ptr[uniqueloc] == memsize)
00710 {
00711 printf("%s:%d: ERROR: buffer was not cleared\n", __FILE__,__LINE__);
00712 return;
00713 }
00714
00715 fd=open(fname, O_RDONLY, 0760);
00716 if (fd < 0 )
00717 {
00718 printf("%s:%d: ERROR: Failed to open readable file %s\n", __FILE__,__LINE__, fname);
00719 return;
00720 }
00721
00722 ret = lseek(fd, offset-memsize, SEEK_CUR);
00723 if (ret != offset-memsize)
00724 {
00725 printf("%s:%d: ERROR: lseek return value is off by %d\n", __FILE__,__LINE__, offset - memsize - ret);
00726 close(fd);
00727 return;
00728 }
00729
00730 TIMER("PreIsoRead");
00731 ret = read(fd, ptr, memsize);
00732 TIMER("POSTiSOrEAD");
00733 close(fd);
00734 if (ret != memsize)
00735 {
00736 printf("%s:%d: ERROR: Failed to read file %s\n", __FILE__,__LINE__, fname);
00737 return;
00738 }
00739
00740 if (ptr[uniqueloc] != uniquedata)
00741 {
00742 printf("%s:%d: ERROR: data incorrect.\n", __FILE__,__LINE__);
00743 return;
00744 }
00745
00746 printf("%s:%d: PASS PASS PASS.\n", __FILE__,__LINE__);
00747 }
00748
00749
00750
00751
00752
00753 int main(int argc, char **argv)
00754 {
00755 int fail = !0;
00756 int ret;
00757
00758 MPI_Init(&argc, &argv);
00759 TIMER(NULL);
00760
00761 MPI_Barrier(MPI_COMM_WORLD);
00762 timeposix();
00763 MPI_Barrier(MPI_COMM_WORLD);
00764
00765 ret = testScalar(); if (ret < 0) fail = ret;
00766 TIMER("final time");
00767 PRINTD( ret < 0 ? "FAIL" : "ALL PASS", fail );
00768
00769 xfClosePar();
00770 MPI_Finalize();
00771 return fail;
00772 }