00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <hdf5.h>
00005 #include "H5Part.h"
00006
00007 #ifdef IPPL_XT3
00008 # define SEEK_END 2
00009 #endif
00010
00011 static unsigned h5part_debug=0;
00012
00013
00014 herr_t H5PartIOcounter(hid_t group_id,
00015 const char *member_name,
00016 void *operator_data);
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 H5PartFile *H5PartOpenFileParallel(const char *filename,unsigned flags
00038 #ifdef PARALLEL_IO
00039 , MPI_Comm comm
00040 #endif
00041 ){
00042 H5PartFile *f=(H5PartFile*)malloc(sizeof(H5PartFile));
00043 #ifdef PARALLEL_IO
00044 MPI_Info info = MPI_INFO_NULL;
00045 #endif
00046 f->xfer_prop = f->create_prop = f->access_prop=H5P_DEFAULT;
00047 #ifdef PARALLEL_IO
00048 MPI_Comm_size(comm,&f->nprocs);
00049 MPI_Comm_rank(comm,&f->myproc);
00050 f->pnparticles=(long long*)malloc(sizeof(long long)*f->nprocs);
00051
00052 f->access_prop = H5Pcreate(H5P_FILE_ACCESS);
00053 if(H5Pset_fapl_mpio(f->access_prop,comm,info)<0){
00054 fprintf(stderr,"Total failure trying to setup mpi-io for access\n");
00055 exit(0);
00056 }
00057
00058
00059 f->create_prop = H5P_DEFAULT;
00060
00061
00062
00063 f->xfer_prop = H5Pcreate(H5P_DATASET_XFER);
00064 H5Pset_dxpl_mpio(f->xfer_prop,H5FD_MPIO_COLLECTIVE);
00065 f->comm = comm;
00066 #endif
00067 if(flags==H5PART_READ){
00068 f->file=H5Fopen(filename,H5F_ACC_RDONLY,f->access_prop);
00069
00070
00071 }
00072 else if(flags==H5PART_WRITE){
00073 f->file=H5Fcreate(filename,H5F_ACC_TRUNC,f->create_prop,f->access_prop);
00074 }
00075 else {
00076 f->file=-1;
00077 fprintf(stderr,"H5Open: Invalid file access type %d\n",flags);
00078 }
00079 if(f->file<=0) {
00080 free(f);
00081 fprintf(stderr,"H5Open: File open failed for file [%s]\n",
00082 filename);
00083 exit(0);
00084 return 0;
00085 }
00086 #ifdef PARALLEL_IO
00087 else {
00088 if(h5part_debug) fprintf(stderr,"Proc[%u] Opened file %s val=%d\n",
00089 f->myproc,filename,f->file);
00090 }
00091 #endif
00092 f->mode=flags;
00093 f->maxstep=0;
00094 f->timegroup=0;
00095 f->timestep=0;
00096 f->shape=0;
00097 f->diskshape=H5S_ALL;
00098 f->memshape=H5S_ALL;
00099 f->viewstart=-1;
00100 f->viewend=-1;
00101 return f;
00102 }
00103
00104 H5PartFile *H5PartOpenFile(const char *filename,unsigned flags){
00105 H5PartFile *f=(H5PartFile*)malloc(sizeof(H5PartFile));
00106
00107
00108 f->xfer_prop = f->create_prop = f->access_prop=H5P_DEFAULT;
00109 #ifdef PARALLEL_IO
00110 f->pnparticles=0;
00111 f->comm = MPI_COMM_WORLD;
00112 f->nprocs=1;
00113 f->myproc=0;
00114 #endif
00115 if(flags==H5PART_READ){
00116
00117
00118 f->file = H5Fopen(filename,H5F_ACC_RDONLY,H5P_DEFAULT);
00119 if(f->file==-1){
00120 fprintf(stderr,"H5Open: File %s not found\n",filename);
00121 }
00122 }
00123 else if(flags==H5PART_WRITE){
00124 f->file=H5Fcreate(filename,H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);
00125 }
00126 else {
00127 f->file=-1;
00128 fprintf(stderr,"H5Open: Invalid file access type %d\n",flags);
00129 }
00130 if(f->file<0) {
00131 free(f);
00132 fprintf(stderr,"H5Open: File open failed for file [%s]\n",
00133 filename);
00134 return 0;
00135 }
00136 f->mode=flags;
00137 f->maxstep=0;
00138 f->timegroup=0;
00139 f->timestep=0;
00140 f->shape=0;
00141 f->diskshape=H5S_ALL;
00142 f->memshape=H5S_ALL;
00143 f->viewstart=-1;
00144 f->viewend=-1;
00145 return f;
00146 }
00147 int H5PartFileIsValid(H5PartFile *f){
00148 if(f->file > 0) return 1;
00149 else return 0;
00150 }
00151
00152
00153
00154 void H5PartCloseFile(H5PartFile *f){
00155 if(f->shape>0) H5Sclose(f->shape); f->shape=0;
00156 if(f->timegroup>0) H5Gclose(f->timegroup); f->timegroup=0;
00157 if(f->diskshape!=H5S_ALL) H5Sclose(f->diskshape);
00158 #ifdef PARALLEL_IO
00159 if(f->pnparticles) free(f->pnparticles);
00160 #endif
00161 if(f->xfer_prop!=H5P_DEFAULT) {
00162 H5Pclose(f->xfer_prop); f->xfer_prop=H5P_DEFAULT;
00163 }
00164 if(f->access_prop!=H5P_DEFAULT) {
00165 H5Pclose(f->access_prop); f->access_prop=H5P_DEFAULT;
00166 }
00167 if(f->create_prop!=H5P_DEFAULT) {
00168 H5Pclose(f->create_prop); f->create_prop=H5P_DEFAULT;
00169 }
00170 if(f->file) H5Fclose(f->file); f->file=0;
00171 free(f);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 void H5PartSetNumParticles(H5PartFile *f,long long nparticles){
00184 hssize_t start[1];
00185 hsize_t stride[1],count[1],total;
00186 register int i,r;
00187
00188 #ifndef PARALLEL_IO
00189
00190
00191
00192
00193 if(f->nparticles==nparticles) return;
00194 #endif
00195 if(f->diskshape!=H5S_ALL) H5Sclose(f->diskshape);
00196 if(f->memshape!=H5S_ALL) H5Sclose(f->memshape);
00197 f->memshape=f->diskshape = H5S_ALL;
00198 if(f->shape) H5Sclose(f->shape);
00199 f->nparticles=(hsize_t)nparticles;
00200 #ifndef PARALLEL_IO
00201 f->shape=H5Screate_simple(1,
00202 &(f->nparticles),
00203 NULL);
00204 #else
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 MPI_Allgather(&nparticles,1,MPI_LONG_LONG,f->pnparticles,1,MPI_LONG_LONG,f->comm);
00215
00216 if(f->myproc==0 && h5part_debug){
00217 puts("AllGather: Particle offsets:\n");
00218 for(i=0;i<f->nprocs;i++)
00219 printf("\tnp=%u\n",f->pnparticles[i]);
00220 }
00221
00222 stride[0]=1;
00223 start[0]=0;
00224 for(i=0;i<f->myproc;i++) start[0]+=f->pnparticles[i];
00225 total=0;
00226 for(i=0;i<f->nprocs;i++) total+=f->pnparticles[i];
00227 f->shape = H5Screate_simple(1,&total,&total);
00228 f->diskshape = H5Screate_simple(1,&total,&total);
00229 {
00230 hsize_t dmax=H5S_UNLIMITED;
00231 f->memshape = H5Screate_simple(1,&(f->nparticles),&dmax);
00232 }
00233
00234 if(f->shape<0 || f->memshape<0 || f->diskshape<0){
00235 fprintf(stderr,"Abort: shape construction failed\n");
00236 if(f->shape<0) fprintf(stderr,"\tf->shape\n");
00237 if(f->diskshape<0) fprintf(stderr,"\tf->diskshape\n");
00238 if(f->memshape<0) fprintf(stderr,"\tf->memshape\n");
00239 exit(0);
00240 }
00241 count[0]=nparticles;
00242
00243 r=H5Sselect_hyperslab(f->diskshape,H5S_SELECT_SET,start,stride,count,NULL);
00244 if(r<0){
00245 fprintf(stderr,"Abort: Selection Failed!\n");
00246 exit(0);
00247 }
00248 if(f->timegroup<0){
00249 H5PartSetStep(f,0);
00250 }
00251 #endif
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 int H5PartWriteDataFloat64(H5PartFile *f,char *name,double *array){
00264 register int r;
00265 hid_t dataset;
00266 if(f->mode==H5PART_READ){
00267 fprintf(stderr,"H5PartWriteDataFloat64: Error! Attempting to write to read-only file\n");
00268 return 0;
00269 }
00270
00271
00272 if(f->timegroup<=0) {fprintf(stderr,"Eeeerrrrroooorrrr!!!!\n");}
00273 dataset = H5Dcreate(f->timegroup,name,H5T_NATIVE_DOUBLE,f->shape,H5P_DEFAULT);
00274 if(dataset<0)
00275 fprintf(stderr,"Dataset open failed for name=[%s] step=%u!\n",
00276 name,f->timestep);
00277 r=H5Dwrite(dataset,H5T_NATIVE_DOUBLE,f->memshape,f->diskshape,H5P_DEFAULT,array);
00278 H5Dclose(dataset);
00279 return r;
00280 }
00281 int H5PartWriteDataInt64(H5PartFile *f,char *name,long long *array){
00282 register int r;
00283 hid_t dataset;
00284
00285
00286 if(f->mode==H5PART_READ){
00287 fprintf(stderr,"H5PartWriteDataFloat64: Error! Attempting to write to read-only file\n");
00288 return 0;
00289 }
00290 if(f->timegroup<=0) {fprintf(stderr,"Eeeerrrrroooorrrr!!!!\n");}
00291 dataset = H5Dcreate(f->timegroup,name,H5T_NATIVE_INT64,f->shape,H5P_DEFAULT);
00292 if(dataset<0){
00293 fprintf(stderr,"Dataset open failed for name=[%s] step=%u!\n",
00294 name,f->timestep);
00295 exit(0);
00296 }
00297 r=H5Dwrite(dataset,H5T_NATIVE_INT64,f->memshape,f->diskshape,H5P_DEFAULT,array);
00298 if(r<0) {
00299 fprintf(stderr,"Attempt to write dataset failed!\n");
00300 exit(0);
00301 }
00302 H5Dclose(dataset);
00303 return r;
00304 }
00305 int H5PartWriteFileAttribString(H5PartFile *f,char *name,
00306 char *attrib){
00307 if(f->mode==H5PART_READ){
00308 fprintf(stderr,"H5PartWriteDataFloat64: Error! Attempting to write to read-only file\n");
00309 return 0;
00310 }
00311 return H5PartWriteFileAttrib(f,name,H5T_NATIVE_CHAR,attrib,strlen(attrib)+1);
00312 }
00313 int H5PartWriteStepAttribString(H5PartFile *f,char *name,
00314 char *attrib){
00315 if(f->mode==H5PART_READ){
00316 fprintf(stderr,"H5PartWriteDataFloat64: Error! Attempting to write to read-only file\n");
00317 return 0;
00318 }
00319 return H5PartWriteStepAttrib(f,name,H5T_NATIVE_CHAR,attrib,strlen(attrib)+1);
00320 }
00321 int H5PartWriteStepAttrib(H5PartFile *f,char *name,
00322 hid_t type,void *value,int nelem){
00323 register int r;
00324 hid_t attrib;
00325 hid_t space;
00326 hsize_t len;
00327 if(f->mode==H5PART_READ){
00328 fprintf(stderr,"H5PartWriteDataFloat64: Error! Attempting to write to read-only file\n");
00329 return 0;
00330 }
00331
00332
00333 if(f->timegroup<=0) {fprintf(stderr,"Eeeerrrrroooorrrr!!!!\n");}
00334 len = nelem;
00335 space = H5Screate_simple(1,&len,NULL);
00336 attrib = H5Acreate(f->timegroup,name,type,space,H5P_DEFAULT);
00337 r=H5Awrite(attrib,type,value);
00338 H5Aclose(attrib);
00339 H5Sclose(space);
00340 return r;
00341 }
00342
00343 int H5PartWriteAttrib(H5PartFile *f,char *name,
00344 hid_t type,void *value,int nelem){
00345 if(f->mode==H5PART_READ){
00346 fprintf(stderr,"H5PartWriteDataFloat64: Error! Attempting to write to read-only file\n");
00347 return 0;
00348 }
00349 return H5PartWriteStepAttrib(f,name,type,value,nelem);
00350 }
00351
00352
00353 int H5PartWriteFileAttrib(H5PartFile *f,char *name,
00354 hid_t type,void *value,int nelem){
00355 register int r;
00356 hid_t attrib,rootgroup;
00357 hid_t space;
00358 hsize_t len;
00359 if(f->mode==H5PART_READ){
00360 fprintf(stderr,"H5PartWriteDataFloat64: Error! Attempting to write to read-only file\n");
00361 return 0;
00362 }
00363 if(h5part_debug) fprintf(stderr,"Create a File attribute[%s] step=%u\n",
00364 name,f->timestep);
00365 if(f->file<=0) {
00366 fprintf(stderr,"Eeeerrrrroooorrrr!!!! File is not open!\n");
00367 return 0;
00368 }
00369 len = nelem;
00370 space = H5Screate_simple(1,&len,NULL);
00371 if(space<=0) {
00372 fprintf(stderr,"Eeeerrrrroooorrrr!!!! Could not create space with len!\n",(unsigned)len);
00373 return 0;
00374 }
00375 rootgroup = H5Gopen(f->file,"/");
00376 attrib = H5Acreate(rootgroup,name,type,space,H5P_DEFAULT);
00377 H5Gclose(rootgroup);
00378 if(attrib<=0) {
00379 fprintf(stderr,"Eeeerrrrroooorrrr!!!! Attribute Creation Failed!\n");
00380 return 0;
00381 }
00382 r=H5Awrite(attrib,type,value);
00383 H5Aclose(attrib);
00384 H5Sclose(space);
00385 return r;
00386 }
00387 herr_t H5PartAttribcounter(hid_t group_id,
00388 const char *member_name,
00389 void *operator_data){
00390 int *count = (int*)operator_data;
00391 (*count)++;
00392 return 0;
00393 }
00394 int H5PartGetNumStepAttribs(H5PartFile *f){
00395 return H5Aget_num_attrs(f->timegroup);
00396 }
00397 int H5PartGetNumFileAttribs(H5PartFile *f){
00398
00399
00400 int nattribs;
00401 hid_t rootgroup=H5Gopen(f->file,"/");;
00402 nattribs=H5Aget_num_attrs(rootgroup);
00403
00404
00405 H5Gclose(rootgroup);
00406 return nattribs;
00407 }
00408
00409 hid_t H5PartNormType(hid_t type){
00410 H5T_class_t tclass = H5Tget_class(type);
00411 int size = H5Tget_size(type);
00412 switch(tclass){
00413 case H5T_INTEGER:
00414 if(size==8) return H5T_NATIVE_INT64;
00415 else if(size==1) return H5T_NATIVE_CHAR;
00416 else fprintf(stderr,"Unknown type %u. Cannot infer normalized type\n",type);
00417 break;
00418 case H5T_FLOAT:
00419 return H5T_NATIVE_DOUBLE;
00420 break;
00421 }
00422 return -1;
00423 }
00424
00425 void H5PartGetStepAttribInfo(H5PartFile *f,int idx,
00426 char *name,size_t maxname,hid_t *type,int *nelem){
00427 hid_t attrib=H5Aopen_idx(f->timegroup,idx);
00428 hid_t mytype=H5Aget_type(attrib);
00429 hid_t space = H5Aget_space(attrib);
00430 if(nelem)
00431 *nelem=H5Sget_simple_extent_npoints(space);
00432 if(name)
00433 H5Aget_name(attrib,maxname,name);
00434 if(type)
00435 *type=H5PartNormType(mytype);
00436
00437
00438
00439
00440 H5Sclose(space);
00441 H5Tclose(mytype);
00442 H5Aclose(attrib);
00443 }
00444 void H5PartGetFileAttribInfo(H5PartFile *f,int idx,
00445 char *name,size_t maxname,hid_t *type,int *nelem){
00446 hid_t attrib=H5Aopen_idx(f->file,idx);
00447 hid_t mytype=H5Aget_type(attrib);
00448 hid_t space = H5Aget_space(attrib);
00449 if(nelem)
00450 *nelem=H5Sget_simple_extent_npoints(space);
00451 if(name)
00452 H5Aget_name(attrib,maxname,name);
00453 if(type)
00454 *type=H5PartNormType(mytype);
00455
00456
00457
00458
00459 H5Sclose(space);
00460 H5Tclose(mytype);
00461 H5Aclose(attrib);
00462 }
00463
00464 int H5PartReadStepAttrib(H5PartFile *f,char *name,void *data){
00465
00466 hid_t attrib=H5Aopen_name(f->timegroup,name);
00467 hid_t mytype;
00468 hid_t space;
00469 hsize_t nelem;
00470 hid_t type;
00471
00472 if(attrib<=0) return -1;
00473 mytype=H5Aget_type(attrib);
00474 space = H5Aget_space(attrib);
00475 nelem=H5Sget_simple_extent_npoints(space);
00476 type=H5PartNormType(mytype);
00477
00478
00479
00480
00481 H5Aread(attrib,type,data);
00482 H5Sclose(space);
00483 H5Tclose(mytype);
00484 H5Aclose(attrib);
00485 return 1;
00486 }
00487
00488 void H5PartReadAttrib(H5PartFile *f,char *name,void *data){
00489
00490 H5PartReadStepAttrib(f,name,data);
00491 }
00492
00493
00494
00495
00496 int H5PartReadFileAttrib(H5PartFile *f,char *name,void *data){
00497 hid_t attrib=H5Aopen_name(f->file,name);
00498 hid_t mytype;
00499 hid_t space;
00500 hsize_t nelem;
00501 hid_t type;
00502 if(attrib<0) return -1;
00503 mytype=H5Aget_type(attrib);
00504 space = H5Aget_space(attrib);
00505 nelem=H5Sget_simple_extent_npoints(space);
00506 type=H5PartNormType(mytype);
00507
00508
00509
00510
00511 H5Aread(attrib,type,data);
00512 H5Sclose(space);
00513 H5Tclose(mytype);
00514 H5Aclose(attrib);
00515 return 1;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 void H5PartSetStep(H5PartFile *f,int step){
00531 char name[128];
00532 #ifdef PARALLEL_IO
00533 if(h5part_debug) printf("Proc[%u] SetStep to %u for file %u\n",f->myproc,step,f->file);
00534 #else
00535 if(h5part_debug) fprintf(stderr,"SetStep to %d for file\n",step);
00536 #endif
00537 f->timestep=step;
00538 if(f->timegroup>0) {
00539 H5Gclose(f->timegroup);
00540 }
00541 f->timegroup=-1;
00542 sprintf(name,"Particles#%u",f->timestep);
00543
00544
00545 if(f->mode==H5PART_READ) {
00546
00547 f->timegroup=H5Gopen(f->file,name);
00548 }
00549 if(f->timegroup<=0){
00550
00551
00552 if(f->mode == H5PART_READ){
00553 fprintf(stderr,"Error in H5PartSetStep() Step #%d does not exist!\n",step);
00554 }
00555 f->timegroup = H5Gcreate(f->file,name,-1);
00556 if(f->timegroup<0) {
00557 #ifdef PARALLEL_IO
00558 fprintf(stderr,"p[%u] timegroup creation failed!\n",
00559 f->myproc);
00560 #endif
00561 return;
00562 }
00563 }
00564
00565
00566
00567
00568
00569 }
00570
00571
00572
00573
00574
00575
00576
00577
00578 herr_t H5PartIOcounter(hid_t group_id,
00579 const char *member_name,
00580 void *operator_data){
00581 int *count = (int*)operator_data;
00582 H5G_stat_t objinfo;
00583
00584 if(!strncmp(member_name,"Particles",9)) (*count)++;
00585 return 0;
00586 }
00587 herr_t H5PartDScounter(hid_t group_id,
00588 const char *member_name,
00589 void *operator_data){
00590 int *count = (int*)operator_data;
00591 H5G_stat_t objinfo;
00592
00593 if(H5Gget_objinfo(group_id,
00594 member_name,
00595 1 ,
00596 &objinfo)<0) {
00597 return 0;
00598 }
00599 if(objinfo.type==H5G_DATASET) (*count)++;
00600 return 0;
00601 }
00602
00603 typedef struct H5IO_getname_t {
00604 int index,count;
00605 char *name;
00606 }H5IO_getname_t;
00607
00608 herr_t H5IOgetname(hid_t group_id,
00609 const char *member_name,
00610 void *operator_data){
00611 H5IO_getname_t *getn = (H5IO_getname_t*)operator_data;
00612
00613 H5G_stat_t objinfo;
00614
00615 if(H5Gget_objinfo(group_id,
00616 member_name,
00617 1 ,
00618 &objinfo)<0) return 0;
00619
00620 if(objinfo.type!=H5G_DATASET)
00621 return 0;
00622 if(getn->index==getn->count){
00623 strcpy(getn->name,member_name);
00624 return 1;
00625 }
00626 getn->count++;
00627 return 0;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636 int H5PartGetNumSteps(H5PartFile *f){
00637
00638 int count=0;
00639 int idx=0;
00640 while(H5Giterate(f->file,
00641 "/",
00642 &idx,
00643 H5PartIOcounter,
00644 &count)<0){}
00645 return count;
00646 }
00647 int H5PartGetNumDatasets(H5PartFile *f){
00648 int count=0;
00649 int idx=0;
00650 char name[128];
00651
00652
00653 sprintf(name,"Particles#%u",f->timestep);
00654 while(H5Giterate(f->file,
00655 name,
00656 &idx,
00657 H5PartDScounter,
00658 &count)<0){}
00659 return count;
00660 }
00661 int H5PartGetDatasetName(H5PartFile *f,
00662 int _index,
00663 char *name,
00664 int maxlen){
00665 H5IO_getname_t getn;
00666 int idx=_index;
00667 char gname[128];
00668 sprintf(gname,"Particles#%u",f->timestep);
00669 getn.index=_index; getn.name=name; getn.count=_index;
00670 while(H5Giterate(f->file,
00671 gname,
00672 &idx,
00673 H5IOgetname,
00674 &getn)<0){}
00675 return 1;
00676 }
00677
00678 hid_t H5PartGetDiskShape(H5PartFile *f,hid_t dataset){
00679 hid_t space = H5Dget_space(dataset);
00680 if(h5part_debug) fprintf(stderr,"H5PartGetDiskShape\n");
00681 if(H5PartHasView(f)){
00682 int r;
00683 hsize_t total, stride, count;
00684 hssize_t range[2];
00685 if(h5part_debug) fprintf(stderr,"\tSelection is available\n");
00686
00687 range[0]=f->viewstart;
00688 range[1]=f->viewend;
00689 count = range[1]-range[0];
00690 stride=1;
00691
00692 if(f->diskshape>0)
00693 r=H5Sselect_hyperslab(f->diskshape,H5S_SELECT_SET,
00694 range,
00695 &stride,&count,NULL);
00696
00697 r=H5Sselect_hyperslab(space,H5S_SELECT_SET,
00698 range,&stride,&count,NULL);
00699 if(h5part_debug) fprintf(stderr,"\tSelection: range=%u:%u, npoints=%u s=%u\n",
00700 (int)range[0],(int)range[1],
00701 (int)H5Sget_simple_extent_npoints(space),
00702 (int)H5Sget_select_npoints(space));
00703 if(r<0){
00704 fprintf(stderr,"Abort: Selection Failed!\n");
00705 return space;
00706 }
00707 }
00708 else {
00709 if(h5part_debug) fprintf(stderr,"\tNo Selection\n");
00710 }
00711 return space;
00712 }
00713
00714 hid_t H5PartGetMemShape(H5PartFile *f,hid_t dataset){
00715 if(h5part_debug) fprintf(stderr,"H5PartGetMemShape\n");
00716 if(H5PartHasView(f)) {
00717 hsize_t dmax=H5S_UNLIMITED;
00718 hsize_t len = f->viewend - f->viewstart;
00719 return H5Screate_simple(1,&len,&dmax);
00720 }
00721 else {
00722 return H5S_ALL;
00723 }
00724 }
00725
00726
00727
00728
00729
00730
00731 herr_t H5PartGetFirstDS(hid_t group_id,
00732 const char *member_name,
00733 void *operator_data){
00734 hid_t *dataset = (hid_t*)operator_data;
00735 H5G_stat_t objinfo;
00736
00737 if(H5Gget_objinfo(group_id,
00738 member_name,
00739 1 ,
00740 &objinfo)<0) {
00741 return 0;
00742 }
00743 if(objinfo.type==H5G_DATASET){
00744 (*dataset)=H5Dopen(group_id,member_name);
00745 return 1;
00746 }
00747 return 0;
00748 }
00749
00750 long long H5PartGetNumParticles(H5PartFile *f){
00751 hid_t space,dataset;
00752 hsize_t nparticles;
00753 int idx=0;
00754 char name[128];
00755
00756
00757 if(f->timegroup<0) {
00758 if(f->timestep<0)
00759 H5PartSetStep(f,0);
00760 else
00761 H5PartSetStep(f,f->timestep);
00762 }
00763 if(f->timegroup<=0){
00764 fprintf(stderr,"Damnit!!! tried to select a timestep %d\n", f->timestep);
00765 exit(0);
00766 }
00767
00768
00769 sprintf(name,"Particles#%u",f->timestep);
00770 while(H5Giterate(f->file,
00771 name,
00772 &idx,
00773 H5PartGetFirstDS,
00774 &dataset)<0){}
00775
00776
00777 space = H5PartGetDiskShape(f,dataset);
00778 if(H5PartHasView(f)){
00779 if(h5part_debug) fprintf(stderr,"\tGetNumParticles::get_selection\n");
00780 nparticles=H5Sget_select_npoints(space);
00781 }
00782 else {
00783 if(h5part_debug) fprintf(stderr,"\tGetNumParticles::get_simple_extent from space\n");
00784 nparticles= H5Sget_simple_extent_npoints(space);
00785 }
00786 if(space!=H5S_ALL) H5Sclose(space);
00787 H5Dclose(dataset);
00788 return (long long)nparticles;
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 void H5PartSetView(H5PartFile *f,long long start,long long end){
00807 hsize_t total, stride, count;
00808 hssize_t range[2];
00809 int r;
00810 if(h5part_debug) fprintf(stderr,"SetView(%d,%d)\n",
00811 (int)start,(int)end);
00812 if(f->mode==H5PART_WRITE){
00813 fprintf(stderr,"H5PartSetView(): SetView does not make sense for write-only files. It is meant to be used for read-only files. (maybe later this will change)\n");
00814 return;
00815 }
00816
00817 f->viewstart=-1;
00818 f->viewend=-1;
00819 if(f->shape!=0){
00820 H5Sclose(f->shape);
00821 f->shape=0;
00822 }
00823 if(f->diskshape!=0 && f->diskshape!=H5S_ALL){
00824 H5Sclose(f->diskshape);
00825 f->diskshape=H5S_ALL;
00826 }
00827 f->diskshape = H5S_ALL;
00828 if(f->memshape!=0 && f->memshape!=H5S_ALL){
00829 H5Sclose(f->memshape);
00830 f->memshape=H5S_ALL;
00831 }
00832 if(start==-1 && end==-1) {
00833 if(h5part_debug) fprintf(stderr,"\tEarly Termination: Unsetting View\n");
00834 return;
00835 }
00836
00837
00838 total=H5PartGetNumParticles(f);
00839 if(h5part_debug) fprintf(stderr,"\tTotal nparticles=%u\n",(int)total);
00840 if(start==-1) start=0;
00841 if(end==-1) end=total;
00842
00843
00844
00845
00846
00847
00848
00849 if(end<start) {
00850 fprintf(stderr,"H5PartSetView(min=%d, max=%d): Nonfatal error. End of view is less than start.\n",
00851 start,end);
00852 end=start;
00853 }
00854 range[0]=start;
00855 range[1]=end;
00856
00857 f->viewstart=range[0];
00858 f->viewend=range[1];
00859 f->nparticles=range[1]-range[0];
00860 if(h5part_debug) fprintf(stderr,"\tRange is now %u:%u\n",(int)range[0],(int)range[1]);
00861
00862
00863
00864 f->shape = H5Screate_simple(1,&total,&total);
00865
00866 f->diskshape= H5Screate_simple(1,&total,&total);
00867 {
00868 hsize_t dmax=H5S_UNLIMITED;
00869 f->memshape = H5Screate_simple(1,&(f->nparticles),&dmax);
00870 }
00871
00872 if(f->shape<0 || f->memshape<0 || f->diskshape<0){
00873 fprintf(stderr,"Abort: shape construction failed\n");
00874 if(f->shape<0) fprintf(stderr,"\tf->shape\n");
00875 if(f->diskshape<0) fprintf(stderr,"\tf->diskshape\n");
00876 if(f->memshape<0) fprintf(stderr,"\tf->memshape\n");
00877 exit(0);
00878 }
00879 if(h5part_debug) fprintf(stderr,"\tcount=%d\n",(int)total);
00880 stride=1;
00881
00882 r=H5Sselect_hyperslab(f->diskshape,H5S_SELECT_SET,range,&stride,&total,NULL);
00883 if(r<0){
00884 fprintf(stderr,"Abort: Selection Failed!\n");
00885 exit(0);
00886 }
00887
00888 }
00889
00890
00891
00892
00893
00894 int H5PartGetView(H5PartFile *f,long long *start,long long *end){
00895 long long range[2];
00896 range[0]=(f->viewstart>=0)?f->viewstart:0;
00897 range[1]=(f->viewend>=0)?f->viewend:H5PartGetNumParticles(f);
00898 if(start) {
00899 *start=range[0];
00900 }
00901 if(end) {
00902 *end=range[1];
00903 }
00904
00905 return range[1]-range[0];
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915 void H5PartSetCanonicalView(H5PartFile *f){
00916
00917
00918
00919 if(f->mode != H5PART_READ){
00920 fprintf(stderr,"H5PartSetCanonicalView(): Views do not make sense for write-only files. It is meant to be used for read-only files. (maybe later this will change)\n");
00921 return;
00922 }
00923 H5PartSetView(f,-1,-1);
00924 #ifdef PARALLEL_IO
00925 if(f->timegroup<0){
00926 H5PartSetStep(f,0);
00927 }
00928
00929
00930
00931
00932
00933 if(H5PartReadStepAttrib(f,"pnparticles",f->pnparticles)<0){
00934
00935 int i;
00936 long long total=0, n = H5PartGetNumParticles(f);
00937 n/=f->nprocs;
00938 f->pnparticles[0]=n;
00939 total=n;
00940 for(i=1;i<f->nprocs;i++){
00941 f->pnparticles[i]=n;
00942 total+=n;
00943 }
00944 }
00945 {
00946 int i;
00947 long long total = 0, n = H5PartGetNumParticles(f);
00948
00949 for(i=0;i<f->myproc;i++){
00950 total+=f->pnparticles[i];
00951 }
00952 H5PartSetView(f,total,total+f->pnparticles[f->myproc]-1);
00953 }
00954 #endif
00955
00956
00957 }
00958
00959
00960
00961
00962
00963
00964
00965
00966 int H5PartReadDataFloat64(H5PartFile *f,char *name,double *array){
00967 hid_t space,memspace,dataset,datatype;
00968 if(!f->timegroup) H5PartSetStep(f,f->timestep);
00969 dataset=H5Dopen(f->timegroup,name);
00970 space = H5PartGetDiskShape(f,dataset);
00971 memspace = H5PartGetMemShape(f,dataset);
00972
00973 H5Dread(dataset,
00974 H5T_NATIVE_DOUBLE,
00975
00976 memspace,
00977 space,
00978 H5P_DEFAULT,
00979 array);
00980 if(space!=H5S_ALL) H5Sclose(space);
00981 if(memspace!=H5S_ALL) H5Sclose(memspace);
00982 H5Dclose(dataset);
00983 return 1;
00984 }
00985
00986 int H5PartReadDataInt64(H5PartFile *f,char *name,long long *array){
00987 hid_t space,memspace,dataset,datatype;
00988 if(!f->timegroup) H5PartSetStep(f,f->timestep);
00989 dataset=H5Dopen(f->timegroup,name);
00990 space = H5PartGetDiskShape(f,dataset);
00991 memspace = H5PartGetMemShape(f,dataset);
00992
00993 H5Dread(dataset,
00994 H5T_NATIVE_INT64,
00995
00996 memspace,
00997 space,
00998 H5P_DEFAULT,
00999 array);
01000 if(space!=H5S_ALL) H5Sclose(space);
01001 if(memspace!=H5S_ALL) H5Sclose(memspace);
01002 H5Dclose(dataset);
01003 return 1;
01004 }
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015 int H5PartReadParticleStep(H5PartFile *f,
01016 int step,
01017 double *x,double *y,double *z,
01018 double *px,double *py,double *pz,
01019 long long *id){
01020 H5PartSetStep(f,step);
01021
01022 H5PartReadDataFloat64(f,"x",x);
01023 H5PartReadDataFloat64(f,"y",y);
01024 H5PartReadDataFloat64(f,"z",z);
01025 H5PartReadDataFloat64(f,"px",px);
01026 H5PartReadDataFloat64(f,"py",py);
01027 H5PartReadDataFloat64(f,"pz",pz);
01028 H5PartReadDataInt64(f,"id",id);
01029 return 1;
01030 }
01031
01032
01033
01034 herr_t H5NameExists(hid_t group_id,
01035 const char *member_name,
01036 void *v){
01037 if(!strcmp(member_name,(char*)v)) return 1;
01038 else return 0;
01039 }
01040
01041 int H5PartFileHasName(H5PartFile *f,
01042 char *dir,char *name){
01043 if(H5Giterate(f->file,
01044 dir,
01045 NULL,
01046 H5NameExists,
01047 (void*)name)<0)
01048 return 1;
01049 else
01050 return 0;
01051 }
01052
01053 int H5PartStashFile(H5PartFile *f,char *filename){
01054 hid_t udata=0,files=0,rgroup=0;
01055 FILE *file;
01056 int returnvalue=0;
01057
01058 rgroup = H5Gopen(f->file,"/");
01059 if(H5PartFileHasName(f,"/","UserData")){
01060 udata = H5Gopen(rgroup,"UserData");
01061 if(H5PartFileHasName(f,"UserData","Files")){
01062 files=H5Gopen(udata,"Files");
01063 }
01064 else {
01065 files = H5Gcreate(udata,"Files",-1);
01066 }
01067 }
01068 else {
01069
01070 udata = H5Gcreate(rgroup,"UserData",-1);
01071 files = H5Gcreate(udata,"Files",-1);
01072 }
01073 if(rgroup) H5Gclose(rgroup); rgroup=0;
01074 if(udata) H5Gclose(udata); udata=0;
01075
01076
01077
01078 file = fopen(filename,"r");
01079 if(file){
01080 hsize_t sz;
01081 char *buffer,*dsname,*dsbuffer;
01082 hid_t fspace,fdata;
01083 fseek(file,0,SEEK_END);
01084 sz = ftell(file);
01085 buffer=(char*)malloc(sz);
01086 fspace=H5Screate_simple(1,&sz,0);
01087
01088 dsbuffer = (char*)malloc(strlen(filename));
01089 strcpy(dsbuffer,filename);
01090 dsname = strrchr(dsbuffer,'/');
01091 if(!dsname) dsname=dsbuffer;
01092 fdata=H5Dcreate(files,dsname,H5T_NATIVE_CHAR,fspace,H5P_DEFAULT);
01093 H5Dwrite(fdata,H5T_NATIVE_CHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer);
01094 H5Dclose(fdata);
01095 H5Sclose(fspace);
01096 fclose(file);
01097 free(buffer); free(dsbuffer);
01098 returnvalue = 1;
01099 }
01100 H5Gclose(files);
01101 return returnvalue;
01102 }
01103
01104 int H5PartUnstashFile(H5PartFile *f,char *filename, char *outputpath){
01105 if(H5PartFileHasName(f,"/","UserData") &&
01106 H5PartFileHasName(f,"/UserData","Files") &&
01107 H5PartFileHasName(f,"/UserData/Files",filename)){
01108
01109 hid_t fdata,fspace,fgroup;
01110 hsize_t sz;
01111 char *buffer,*outname;
01112 FILE *file;
01113 fgroup = H5Gopen(f->file,"/UserData/Files");
01114 fdata = H5Dopen(fgroup,filename);
01115 fspace = H5Dget_space(fdata);
01116 sz = H5Sget_simple_extent_npoints(fspace);
01117 buffer = (char*)malloc(sz);
01118 H5Dread(fdata,H5T_NATIVE_CHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer);
01119 outname = (char*)malloc(strlen(filename) + 8 + outputpath?strlen(outputpath):0);
01120 if(outputpath && strlen(outputpath)>0){
01121 if(outputpath[strlen(outputpath)-1]!='/') sprintf(outname,"%s/%s",outputpath,filename);
01122 else sprintf(outname,"%s%s",outputpath,filename);
01123 }
01124 else {
01125 strcpy(outname,filename);
01126 }
01127 file = fopen(outname,"w");
01128 fwrite(buffer,1,sz,file);
01129 fclose(file);
01130 free(buffer);
01131 free(outname);
01132 H5Sclose(fspace);
01133 H5Dclose(fdata);
01134 H5Gclose(fgroup);
01135 return 1;
01136 }
01137 return 0;
01138 }
01139
01140 int H5PartGetNumStashFiles(H5PartFile *f){
01141 hsize_t retval;
01142 if(H5PartFileHasName(f,"/","UserData") &&
01143 H5PartFileHasName(f,"/UserData","Files")){
01144 hid_t fgroup;
01145
01146 fgroup = H5Gopen(f->file,"/UserData/Files");
01147 H5Gget_num_objs(fgroup,&retval);
01148 return retval;
01149 }
01150 else return 0;
01151 }
01152
01153 int H5PartFileGetStashFileName(H5PartFile *f,int nameindex,char *filename,int maxnamelen){
01154 return 1;
01155 }