152849c42SDave May 252849c42SDave May #include "data_bucket.h" 352849c42SDave May 452849c42SDave May /* string helpers */ 52eac95f8SDave May PetscErrorCode StringInList( const char name[], const PetscInt N, const DataField gfield[], PetscBool *val ) 652849c42SDave May { 75c18a9d6SDave May PetscInt i; 852849c42SDave May 952849c42SDave May *val = PETSC_FALSE; 1052849c42SDave May for( i=0; i<N; i++ ) { 1152849c42SDave May if( strcmp( name, gfield[i]->name ) == 0 ) { 1252849c42SDave May *val = PETSC_TRUE; 132eac95f8SDave May PetscFunctionReturn(0); 1452849c42SDave May } 1552849c42SDave May } 162eac95f8SDave May PetscFunctionReturn(0); 1752849c42SDave May } 1852849c42SDave May 192eac95f8SDave May PetscErrorCode StringFindInList( const char name[], const PetscInt N, const DataField gfield[], PetscInt *index ) 2052849c42SDave May { 215c18a9d6SDave May PetscInt i; 2252849c42SDave May 2352849c42SDave May *index = -1; 2452849c42SDave May for( i=0; i<N; i++ ) { 2552849c42SDave May if( strcmp( name, gfield[i]->name ) == 0 ) { 2652849c42SDave May *index = i; 272eac95f8SDave May PetscFunctionReturn(0); 2852849c42SDave May } 2952849c42SDave May } 302eac95f8SDave May PetscFunctionReturn(0); 3152849c42SDave May } 3252849c42SDave May 332eac95f8SDave May #undef __FUNCT__ 342eac95f8SDave May #define __FUNCT__ "DataFieldCreate" 352eac95f8SDave May PetscErrorCode DataFieldCreate( const char registeration_function[], const char name[], const size_t size, const PetscInt L, DataField *DF ) 3652849c42SDave May { 3752849c42SDave May DataField df; 3852849c42SDave May 3952849c42SDave May df = malloc( sizeof(struct _p_DataField) ); 4052849c42SDave May memset( df, 0, sizeof(struct _p_DataField) ); 4152849c42SDave May 4252849c42SDave May 4352849c42SDave May asprintf( &df->registeration_function, "%s", registeration_function ); 4452849c42SDave May asprintf( &df->name, "%s", name ); 4552849c42SDave May df->atomic_size = size; 4652849c42SDave May df->L = L; 4752849c42SDave May 4852849c42SDave May df->data = malloc( size * L ); /* allocate something so we don't have to reallocate */ 4952849c42SDave May memset( df->data, 0, size * L ); 5052849c42SDave May 5152849c42SDave May *DF = df; 522eac95f8SDave May PetscFunctionReturn(0); 5352849c42SDave May } 5452849c42SDave May 552eac95f8SDave May #undef __FUNCT__ 562eac95f8SDave May #define __FUNCT__ "DataFieldDestroy" 572eac95f8SDave May PetscErrorCode DataFieldDestroy( DataField *DF ) 5852849c42SDave May { 5952849c42SDave May DataField df = *DF; 6052849c42SDave May 6152849c42SDave May free( df->registeration_function ); 6252849c42SDave May free( df->name ); 6352849c42SDave May free( df->data ); 6452849c42SDave May free(df); 6552849c42SDave May 6652849c42SDave May *DF = NULL; 672eac95f8SDave May PetscFunctionReturn(0); 6852849c42SDave May } 6952849c42SDave May 7052849c42SDave May /* data bucket */ 712eac95f8SDave May #undef __FUNCT__ 722eac95f8SDave May #define __FUNCT__ "DataBucketCreate" 732eac95f8SDave May PetscErrorCode DataBucketCreate( DataBucket *DB ) 7452849c42SDave May { 7552849c42SDave May DataBucket db; 7652849c42SDave May 7752849c42SDave May 7852849c42SDave May db = malloc( sizeof(struct _p_DataBucket) ); 7952849c42SDave May memset( db, 0, sizeof(struct _p_DataBucket) ); 8052849c42SDave May 8152849c42SDave May db->finalised = PETSC_FALSE; 8252849c42SDave May 8352849c42SDave May /* create empty spaces for fields */ 8452849c42SDave May db->L = 0; 8552849c42SDave May db->buffer = 1; 8652849c42SDave May db->allocated = 1; 8752849c42SDave May 8852849c42SDave May db->nfields = 0; 8952849c42SDave May db->field = malloc(sizeof(DataField)); 9052849c42SDave May 9152849c42SDave May *DB = db; 922eac95f8SDave May PetscFunctionReturn(0); 9352849c42SDave May } 9452849c42SDave May 952eac95f8SDave May #undef __FUNCT__ 962eac95f8SDave May #define __FUNCT__ "DataBucketDestroy" 972eac95f8SDave May PetscErrorCode DataBucketDestroy( DataBucket *DB ) 9852849c42SDave May { 9952849c42SDave May DataBucket db = *DB; 1005c18a9d6SDave May PetscInt f; 10152849c42SDave May 10252849c42SDave May /* release fields */ 10352849c42SDave May for( f=0; f<db->nfields; f++ ) { 10452849c42SDave May DataFieldDestroy(&db->field[f]); 10552849c42SDave May } 10652849c42SDave May 10752849c42SDave May /* this will catch the initially allocated objects in the event that no fields are registered */ 10852849c42SDave May if(db->field!=NULL) { 10952849c42SDave May free(db->field); 11052849c42SDave May } 11152849c42SDave May 11252849c42SDave May free(db); 11352849c42SDave May 11452849c42SDave May *DB = NULL; 1152eac95f8SDave May PetscFunctionReturn(0); 11652849c42SDave May } 11752849c42SDave May 1182eac95f8SDave May #undef __FUNCT__ 1192eac95f8SDave May #define __FUNCT__ "DataBucketRegisterField" 1202eac95f8SDave May PetscErrorCode DataBucketRegisterField( 12152849c42SDave May DataBucket db, 12252849c42SDave May const char registeration_function[], 12352849c42SDave May const char field_name[], 12452849c42SDave May size_t atomic_size, DataField *_gfield ) 12552849c42SDave May { 12652849c42SDave May PetscBool val; 12752849c42SDave May DataField *field,fp; 12852849c42SDave May 12952849c42SDave May /* check we haven't finalised the registration of fields */ 13052849c42SDave May /* 13152849c42SDave May if(db->finalised==PETSC_TRUE) { 13252849c42SDave May printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n"); 13352849c42SDave May ERROR(); 13452849c42SDave May } 13552849c42SDave May */ 13652849c42SDave May 13752849c42SDave May /* check for repeated name */ 13852849c42SDave May StringInList( field_name, db->nfields, (const DataField*)db->field, &val ); 1392eac95f8SDave May if(val == PETSC_TRUE ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field %s already exists. Cannot add same field twice",field_name); 14052849c42SDave May 14152849c42SDave May /* create new space for data */ 14252849c42SDave May field = realloc( db->field, sizeof(DataField)*(db->nfields+1)); 14352849c42SDave May db->field = field; 14452849c42SDave May 14552849c42SDave May /* add field */ 14652849c42SDave May DataFieldCreate( registeration_function, field_name, atomic_size, db->allocated, &fp ); 14752849c42SDave May db->field[ db->nfields ] = fp; 14852849c42SDave May 14952849c42SDave May db->nfields++; 15052849c42SDave May 15152849c42SDave May if(_gfield!=NULL){ 15252849c42SDave May *_gfield = fp; 15352849c42SDave May } 1542eac95f8SDave May PetscFunctionReturn(0); 15552849c42SDave May } 15652849c42SDave May 15752849c42SDave May /* 15852849c42SDave May #define DataBucketRegisterField(db,name,size,k) {\ 15952849c42SDave May char *location;\ 16052849c42SDave May asprintf(&location,"Registered by %s() at line %d within file %s", __FUNCTION__, __LINE__, __FILE__);\ 16152849c42SDave May _DataBucketRegisterField( (db), location, (name), (size), (k) );\ 16252849c42SDave May free(location);\ 16352849c42SDave May } 16452849c42SDave May */ 16552849c42SDave May 1662eac95f8SDave May #undef __FUNCT__ 1672eac95f8SDave May #define __FUNCT__ "DataBucketGetDataFieldByName" 1682eac95f8SDave May PetscErrorCode DataBucketGetDataFieldByName(DataBucket db,const char name[],DataField *gfield) 16952849c42SDave May { 1705c18a9d6SDave May PetscInt idx; 17152849c42SDave May PetscBool found; 17252849c42SDave May 17352849c42SDave May StringInList(name,db->nfields,(const DataField*)db->field,&found); 1742eac95f8SDave May if (!found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot find DataField with name %s",name); 1752eac95f8SDave May 17652849c42SDave May StringFindInList(name,db->nfields,(const DataField*)db->field,&idx); 17752849c42SDave May 17852849c42SDave May *gfield = db->field[idx]; 1792eac95f8SDave May PetscFunctionReturn(0); 18052849c42SDave May } 18152849c42SDave May 1827fbf63aeSDave May #undef __FUNCT__ 1837fbf63aeSDave May #define __FUNCT__ "DataBucketQueryDataFieldByName" 1847fbf63aeSDave May PetscErrorCode DataBucketQueryDataFieldByName(DataBucket db,const char name[],PetscBool *found) 18552849c42SDave May { 18652849c42SDave May *found = PETSC_FALSE; 18752849c42SDave May StringInList(name,db->nfields,(const DataField*)db->field,found); 1887fbf63aeSDave May PetscFunctionReturn(0); 18952849c42SDave May } 19052849c42SDave May 1917fbf63aeSDave May #undef __FUNCT__ 1927fbf63aeSDave May #define __FUNCT__ "DataBucketFinalize" 1937fbf63aeSDave May PetscErrorCode DataBucketFinalize(DataBucket db) 19452849c42SDave May { 19552849c42SDave May db->finalised = PETSC_TRUE; 1967fbf63aeSDave May PetscFunctionReturn(0); 19752849c42SDave May } 19852849c42SDave May 1997fbf63aeSDave May #undef __FUNCT__ 2007fbf63aeSDave May #define __FUNCT__ "DataFieldGetNumEntries" 2017fbf63aeSDave May PetscErrorCode DataFieldGetNumEntries(DataField df, PetscInt *sum) 20252849c42SDave May { 20352849c42SDave May *sum = df->L; 2047fbf63aeSDave May PetscFunctionReturn(0); 20552849c42SDave May } 20652849c42SDave May 2077fbf63aeSDave May #undef __FUNCT__ 2087fbf63aeSDave May #define __FUNCT__ "DataFieldSetSize" 2097fbf63aeSDave May PetscErrorCode DataFieldSetSize( DataField df, const PetscInt new_L ) 21052849c42SDave May { 21152849c42SDave May void *tmp_data; 21252849c42SDave May 213*a233d522SDave May if (new_L <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot set size of DataField to be <= 0"); 2147fbf63aeSDave May 2157fbf63aeSDave May if (new_L == df->L) PetscFunctionReturn(0); 21652849c42SDave May 21752849c42SDave May if (new_L > df->L) { 21852849c42SDave May 21952849c42SDave May tmp_data = realloc( df->data, df->atomic_size * (new_L) ); 22052849c42SDave May df->data = tmp_data; 22152849c42SDave May 22252849c42SDave May /* init new contents */ 22352849c42SDave May memset( ( ((char*)df->data)+df->L*df->atomic_size), 0, (new_L-df->L)*df->atomic_size ); 22452849c42SDave May 2257fbf63aeSDave May } else { 22652849c42SDave May /* reallocate pointer list, add +1 in case new_L = 0 */ 22752849c42SDave May tmp_data = realloc( df->data, df->atomic_size * (new_L+1) ); 22852849c42SDave May df->data = tmp_data; 22952849c42SDave May } 23052849c42SDave May 23152849c42SDave May df->L = new_L; 2327fbf63aeSDave May PetscFunctionReturn(0); 23352849c42SDave May } 23452849c42SDave May 2357fbf63aeSDave May #undef __FUNCT__ 2367fbf63aeSDave May #define __FUNCT__ "DataFieldZeroBlock" 2377fbf63aeSDave May PetscErrorCode DataFieldZeroBlock( DataField df, const PetscInt start, const PetscInt end ) 23852849c42SDave May { 2397fbf63aeSDave May if (start > end) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) > end(%D)",start,end); 2407fbf63aeSDave May 2417fbf63aeSDave May if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if start(%D) < 0",start); 2427fbf63aeSDave May 243*a233d522SDave May if (end > df->L) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot zero a block of entries if end(%D) >= array size(%D)",end,df->L); 24452849c42SDave May 24552849c42SDave May memset( ( ((char*)df->data)+start*df->atomic_size), 0, (end-start)*df->atomic_size ); 2467fbf63aeSDave May PetscFunctionReturn(0); 24752849c42SDave May } 24852849c42SDave May 24952849c42SDave May /* 25052849c42SDave May A negative buffer value will simply be ignored and the old buffer value will be used. 25152849c42SDave May */ 2527fbf63aeSDave May #undef __FUNCT__ 2537fbf63aeSDave May #define __FUNCT__ "DataBucketSetSizes" 2547fbf63aeSDave May PetscErrorCode DataBucketSetSizes( DataBucket db, const PetscInt L, const PetscInt buffer ) 25552849c42SDave May { 2565c18a9d6SDave May PetscInt current_allocated,new_used,new_unused,new_buffer,new_allocated,f; 25752849c42SDave May 2587fbf63aeSDave May if (db->finalised == PETSC_FALSE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"You must call DataBucketFinalize() before DataBucketSetSizes()"); 25952849c42SDave May 26052849c42SDave May current_allocated = db->allocated; 26152849c42SDave May 26252849c42SDave May new_used = L; 26352849c42SDave May new_unused = current_allocated - new_used; 26452849c42SDave May new_buffer = db->buffer; 26552849c42SDave May if( buffer >= 0 ) { /* update the buffer value */ 26652849c42SDave May new_buffer = buffer; 26752849c42SDave May } 26852849c42SDave May new_allocated = new_used + new_buffer; 26952849c42SDave May 27052849c42SDave May /* action */ 27152849c42SDave May if ( new_allocated > current_allocated ) { 27252849c42SDave May /* increase size to new_used + new_buffer */ 27352849c42SDave May for( f=0; f<db->nfields; f++ ) { 27452849c42SDave May DataFieldSetSize( db->field[f], new_allocated ); 27552849c42SDave May } 27652849c42SDave May 27752849c42SDave May db->L = new_used; 27852849c42SDave May db->buffer = new_buffer; 27952849c42SDave May db->allocated = new_used + new_buffer; 28052849c42SDave May } 28152849c42SDave May else { 28252849c42SDave May if( new_unused > 2 * new_buffer ) { 28352849c42SDave May 28452849c42SDave May /* shrink array to new_used + new_buffer */ 28552849c42SDave May for( f=0; f<db->nfields; f++ ) { 28652849c42SDave May DataFieldSetSize( db->field[f], new_allocated ); 28752849c42SDave May } 28852849c42SDave May 28952849c42SDave May db->L = new_used; 29052849c42SDave May db->buffer = new_buffer; 29152849c42SDave May db->allocated = new_used + new_buffer; 29252849c42SDave May } 29352849c42SDave May else { 29452849c42SDave May db->L = new_used; 29552849c42SDave May db->buffer = new_buffer; 29652849c42SDave May } 29752849c42SDave May } 29852849c42SDave May 29952849c42SDave May /* zero all entries from db->L to db->allocated */ 30052849c42SDave May for( f=0; f<db->nfields; f++ ) { 30152849c42SDave May DataField field = db->field[f]; 30252849c42SDave May DataFieldZeroBlock(field, db->L,db->allocated); 30352849c42SDave May } 3047fbf63aeSDave May PetscFunctionReturn(0); 30552849c42SDave May } 30652849c42SDave May 3077fbf63aeSDave May #undef __FUNCT__ 3087fbf63aeSDave May #define __FUNCT__ "DataBucketSetInitialSizes" 3097fbf63aeSDave May PetscErrorCode DataBucketSetInitialSizes( DataBucket db, const PetscInt L, const PetscInt buffer ) 31052849c42SDave May { 3115c18a9d6SDave May PetscInt f; 31252849c42SDave May DataBucketSetSizes(db,L,buffer); 31352849c42SDave May 31452849c42SDave May for( f=0; f<db->nfields; f++ ) { 31552849c42SDave May DataField field = db->field[f]; 31652849c42SDave May DataFieldZeroBlock(field,0,db->allocated); 31752849c42SDave May } 3187fbf63aeSDave May PetscFunctionReturn(0); 31952849c42SDave May } 32052849c42SDave May 3217fbf63aeSDave May #undef __FUNCT__ 3227fbf63aeSDave May #define __FUNCT__ "DataBucketGetSizes" 3237fbf63aeSDave May PetscErrorCode DataBucketGetSizes( DataBucket db, PetscInt *L, PetscInt *buffer, PetscInt *allocated ) 32452849c42SDave May { 32552849c42SDave May if (L) { *L = db->L; } 32652849c42SDave May if (buffer) { *buffer = db->buffer; } 32752849c42SDave May if (allocated) { *allocated = db->allocated; } 3287fbf63aeSDave May PetscFunctionReturn(0); 32952849c42SDave May } 33052849c42SDave May 3317fbf63aeSDave May #undef __FUNCT__ 3327fbf63aeSDave May #define __FUNCT__ "DataBucketGetGlobalSizes" 3337fbf63aeSDave May PetscErrorCode DataBucketGetGlobalSizes(MPI_Comm comm, DataBucket db, PetscInt *L, PetscInt *buffer, PetscInt *allocated ) 33452849c42SDave May { 3355c18a9d6SDave May PetscInt _L,_buffer,_allocated; 3365c18a9d6SDave May PetscInt ierr; 33752849c42SDave May 3385c18a9d6SDave May _L = db->L; 3395c18a9d6SDave May _buffer = db->buffer; 3405c18a9d6SDave May _allocated = db->allocated; 34152849c42SDave May 3425c18a9d6SDave May if (L) { ierr = MPI_Allreduce(&_L,L,1,MPIU_INT,MPI_SUM,comm); } 3435c18a9d6SDave May if (buffer) { ierr = MPI_Allreduce(&_buffer,buffer,1,MPIU_INT,MPI_SUM,comm); } 3445c18a9d6SDave May if (allocated) { ierr = MPI_Allreduce(&_allocated,allocated,1,MPIU_INT,MPI_SUM,comm); } 3457fbf63aeSDave May PetscFunctionReturn(0); 34652849c42SDave May } 34752849c42SDave May 3487fbf63aeSDave May #undef __FUNCT__ 3497fbf63aeSDave May #define __FUNCT__ "DataBucketGetGlobalSizes" 3507fbf63aeSDave May PetscErrorCode DataBucketGetDataFields( DataBucket db, PetscInt *L, DataField *fields[] ) 35152849c42SDave May { 35252849c42SDave May if (L) { *L = db->nfields; } 35352849c42SDave May if (fields) { *fields = db->field; } 3547fbf63aeSDave May PetscFunctionReturn(0); 35552849c42SDave May } 35652849c42SDave May 3577fbf63aeSDave May #undef __FUNCT__ 3587fbf63aeSDave May #define __FUNCT__ "DataFieldGetAccess" 3597fbf63aeSDave May PetscErrorCode DataFieldGetAccess( const DataField gfield ) 36052849c42SDave May { 3617fbf63aeSDave May if (gfield->active) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is already active. You must call DataFieldRestoreAccess()",gfield->name); 3627fbf63aeSDave May 36352849c42SDave May gfield->active = PETSC_TRUE; 3647fbf63aeSDave May PetscFunctionReturn(0); 36552849c42SDave May } 36652849c42SDave May 3677fbf63aeSDave May #undef __FUNCT__ 3687fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPoint" 3697fbf63aeSDave May PetscErrorCode DataFieldAccessPoint( const DataField gfield, const PetscInt pid, void **ctx_p ) 37052849c42SDave May { 37152849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD 37252849c42SDave May /* debug mode */ 3735c18a9d6SDave May /* check poPetscInt is valid */ 3747fbf63aeSDave May if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0"); 3757fbf63aeSDave May if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L); 37652849c42SDave May 3777fbf63aeSDave May if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess() before poPetscInt data can be retrivied",gfield->name); 37852849c42SDave May #endif 37952849c42SDave May 38052849c42SDave May //*ctx_p = (void*)( ((char*)gfield->data) + pid * gfield->atomic_size); 38152849c42SDave May *ctx_p = __DATATFIELD_point_access(gfield->data,pid,gfield->atomic_size); 3827fbf63aeSDave May PetscFunctionReturn(0); 38352849c42SDave May } 38452849c42SDave May 3857fbf63aeSDave May #undef __FUNCT__ 3867fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPointOffset" 3877fbf63aeSDave May PetscErrorCode DataFieldAccessPointOffset( const DataField gfield, const size_t offset, const PetscInt pid, void **ctx_p ) 38852849c42SDave May { 38952849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD 39052849c42SDave May /* debug mode */ 39152849c42SDave May 3925c18a9d6SDave May /* check poPetscInt is valid */ 3937fbf63aeSDave May /* if( offset < 0 ) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be >= 0");*//* Note compiler realizes this can never happen with an unsigned PetscInt */ 3947fbf63aeSDave May if (offset >= gfield->atomic_size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"offset must be < %zu",gfield->atomic_size); 39552849c42SDave May 3965c18a9d6SDave May /* check poPetscInt is valid */ 3977fbf63aeSDave May if (pid < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0"); 398*a233d522SDave May if (pid >= gfield->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",gfield->L); 39952849c42SDave May 400*a233d522SDave May if (gfield->active==PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess() before point data can be retrivied",gfield->name); 40152849c42SDave May #endif 40252849c42SDave May 40352849c42SDave May *ctx_p = __DATATFIELD_point_access_offset(gfield->data,pid,gfield->atomic_size,offset); 4047fbf63aeSDave May PetscFunctionReturn(0); 40552849c42SDave May } 40652849c42SDave May 4077fbf63aeSDave May #undef __FUNCT__ 4087fbf63aeSDave May #define __FUNCT__ "DataFieldAccessPointOffset" 4097fbf63aeSDave May PetscErrorCode DataFieldRestoreAccess( DataField gfield ) 41052849c42SDave May { 4117fbf63aeSDave May if (gfield->active == PETSC_FALSE) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" is not active. You must call DataFieldGetAccess()", gfield->name ); 4127fbf63aeSDave May 41352849c42SDave May gfield->active = PETSC_FALSE; 4147fbf63aeSDave May PetscFunctionReturn(0); 41552849c42SDave May } 41652849c42SDave May 4177fbf63aeSDave May #undef __FUNCT__ 4187fbf63aeSDave May #define __FUNCT__ "DataFieldVerifyAccess" 4197fbf63aeSDave May PetscErrorCode DataFieldVerifyAccess( const DataField gfield, const size_t size) 42052849c42SDave May { 42152849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD 4227fbf63aeSDave May if (gfield->atomic_size != size) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Field \"%s\" must be mapped to %zu bytes, your intended structure is %zu bytes in length.", 42352849c42SDave May gfield->name, gfield->atomic_size, size ); 42452849c42SDave May #endif 4257fbf63aeSDave May PetscFunctionReturn(0); 42652849c42SDave May } 42752849c42SDave May 4287fbf63aeSDave May #undef __FUNCT__ 4297fbf63aeSDave May #define __FUNCT__ "DataFieldGetAtomicSize" 4307fbf63aeSDave May PetscErrorCode DataFieldGetAtomicSize(const DataField gfield,size_t *size) 43152849c42SDave May { 43252849c42SDave May if (size) { *size = gfield->atomic_size; } 4337fbf63aeSDave May PetscFunctionReturn(0); 43452849c42SDave May } 43552849c42SDave May 4367fbf63aeSDave May #undef __FUNCT__ 4377fbf63aeSDave May #define __FUNCT__ "DataFieldGetEntries" 4387fbf63aeSDave May PetscErrorCode DataFieldGetEntries(const DataField gfield,void **data) 43952849c42SDave May { 44052849c42SDave May if (data) { 44152849c42SDave May *data = gfield->data; 44252849c42SDave May } 4437fbf63aeSDave May PetscFunctionReturn(0); 44452849c42SDave May } 44552849c42SDave May 4467fbf63aeSDave May #undef __FUNCT__ 4477fbf63aeSDave May #define __FUNCT__ "DataFieldRestoreEntries" 4487fbf63aeSDave May PetscErrorCode DataFieldRestoreEntries(const DataField gfield,void **data) 44952849c42SDave May { 45052849c42SDave May if (data) { 45152849c42SDave May *data = NULL; 45252849c42SDave May } 4537fbf63aeSDave May PetscFunctionReturn(0); 45452849c42SDave May } 45552849c42SDave May 45652849c42SDave May /* y = x */ 4577fbf63aeSDave May #undef __FUNCT__ 4587fbf63aeSDave May #define __FUNCT__ "DataBucketCopyPoint" 4597fbf63aeSDave May PetscErrorCode DataBucketCopyPoint( const DataBucket xb, const PetscInt pid_x, 4605c18a9d6SDave May const DataBucket yb, const PetscInt pid_y ) 46152849c42SDave May { 4625c18a9d6SDave May PetscInt f; 46352849c42SDave May for( f=0; f<xb->nfields; f++ ) { 46452849c42SDave May void *dest; 46552849c42SDave May void *src; 46652849c42SDave May 46752849c42SDave May DataFieldGetAccess( xb->field[f] ); 46852849c42SDave May if (xb!=yb) { DataFieldGetAccess( yb->field[f] ); } 46952849c42SDave May 47052849c42SDave May DataFieldAccessPoint( xb->field[f],pid_x, &src ); 47152849c42SDave May DataFieldAccessPoint( yb->field[f],pid_y, &dest ); 47252849c42SDave May 47352849c42SDave May memcpy( dest, src, xb->field[f]->atomic_size ); 47452849c42SDave May 47552849c42SDave May DataFieldRestoreAccess( xb->field[f] ); 47652849c42SDave May if (xb!=yb) { DataFieldRestoreAccess( yb->field[f] ); } 47752849c42SDave May } 4787fbf63aeSDave May PetscFunctionReturn(0); 47952849c42SDave May } 48052849c42SDave May 4817fbf63aeSDave May #undef __FUNCT__ 4827fbf63aeSDave May #define __FUNCT__ "DataBucketCreateFromSubset" 4837fbf63aeSDave May PetscErrorCode DataBucketCreateFromSubset( DataBucket DBIn, const PetscInt N, const PetscInt list[], DataBucket *DB ) 48452849c42SDave May { 4855c18a9d6SDave May PetscInt nfields; 48652849c42SDave May DataField *fields; 48752849c42SDave May DataBucketCreate(DB); 4885c18a9d6SDave May PetscInt f,L,buffer,allocated,p; 48952849c42SDave May 49052849c42SDave May /* copy contents of DBIn */ 49152849c42SDave May DataBucketGetDataFields(DBIn,&nfields,&fields); 49252849c42SDave May DataBucketGetSizes(DBIn,&L,&buffer,&allocated); 49352849c42SDave May 49452849c42SDave May for(f=0;f<nfields;f++) { 4952eac95f8SDave May DataBucketRegisterField(*DB,"DataBucketCreateFromSubset",fields[f]->name,fields[f]->atomic_size,NULL); 49652849c42SDave May } 49752849c42SDave May DataBucketFinalize(*DB); 49852849c42SDave May 49952849c42SDave May DataBucketSetSizes(*DB,L,buffer); 50052849c42SDave May 50152849c42SDave May /* now copy the desired guys from DBIn => DB */ 50252849c42SDave May for( p=0; p<N; p++ ) { 50352849c42SDave May DataBucketCopyPoint(DBIn,list[p], *DB,p); 50452849c42SDave May } 5057fbf63aeSDave May PetscFunctionReturn(0); 50652849c42SDave May } 50752849c42SDave May 50852849c42SDave May // insert into an exisitng location 5097fbf63aeSDave May #undef __FUNCT__ 5107fbf63aeSDave May #define __FUNCT__ "DataFieldInsertPoint" 5117fbf63aeSDave May PetscErrorCode DataFieldInsertPoint( const DataField field, const PetscInt index, const void *ctx ) 51252849c42SDave May { 51352849c42SDave May 51452849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD 5155c18a9d6SDave May /* check poPetscInt is valid */ 516*a233d522SDave May if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0"); 517*a233d522SDave May if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L); 51852849c42SDave May #endif 51952849c42SDave May 52052849c42SDave May // memcpy( (void*)((char*)field->data + index*field->atomic_size), ctx, field->atomic_size ); 52152849c42SDave May memcpy( __DATATFIELD_point_access(field->data,index,field->atomic_size), ctx, field->atomic_size ); 5227fbf63aeSDave May PetscFunctionReturn(0); 52352849c42SDave May } 52452849c42SDave May 52552849c42SDave May // remove data at index - replace with last point 526*a233d522SDave May #undef __FUNCT__ 527*a233d522SDave May #define __FUNCT__ "DataBucketRemovePointAtIndex" 5287fbf63aeSDave May PetscErrorCode DataBucketRemovePointAtIndex( const DataBucket db, const PetscInt index ) 52952849c42SDave May { 5305c18a9d6SDave May PetscInt f; 53152849c42SDave May 53252849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD 5335c18a9d6SDave May /* check poPetscInt is valid */ 534*a233d522SDave May if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0"); 535*a233d522SDave May if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->L+db->buffer); 53652849c42SDave May #endif 53752849c42SDave May 538*a233d522SDave May if (index >= db->L) { /* this point is not in the list - no need to error, but I will anyway */ 539*a233d522SDave May SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"You should not be trying to remove point at index=%D since it's < db->L = %D", index, db->L ); 54052849c42SDave May } 54152849c42SDave May 542*a233d522SDave May if (index != db->L-1) { /* not last point in list */ 54352849c42SDave May for( f=0; f<db->nfields; f++ ) { 54452849c42SDave May DataField field = db->field[f]; 54552849c42SDave May 54652849c42SDave May /* copy then remove */ 54752849c42SDave May DataFieldCopyPoint( db->L-1,field, index,field ); 54852849c42SDave May 54952849c42SDave May //DataFieldZeroPoint(field,index); 55052849c42SDave May } 55152849c42SDave May } 55252849c42SDave May 55352849c42SDave May /* decrement size */ 55452849c42SDave May /* this will zero out an crap at the end of the list */ 55552849c42SDave May DataBucketRemovePoint(db); 5567fbf63aeSDave May PetscFunctionReturn(0); 55752849c42SDave May } 55852849c42SDave May 55952849c42SDave May /* copy x into y */ 5607fbf63aeSDave May #undef __FUNCT__ 5617fbf63aeSDave May #define __FUNCT__ "DataFieldCopyPoint" 5627fbf63aeSDave May PetscErrorCode DataFieldCopyPoint( const PetscInt pid_x, const DataField field_x, 5635c18a9d6SDave May const PetscInt pid_y, const DataField field_y ) 56452849c42SDave May { 56552849c42SDave May 56652849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD 5675c18a9d6SDave May /* check poPetscInt is valid */ 568*a233d522SDave May if (pid_x < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be >= 0"); 569*a233d522SDave May if (pid_x >= field_x->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(IN) index must be < %D",field_x->L); 57052849c42SDave May 571*a233d522SDave May if (pid_y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be >= 0"); 572*a233d522SDave May if (pid_y >= field_y->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"(OUT) index must be < %D",field_y->L); 57352849c42SDave May 57452849c42SDave May if( field_y->atomic_size != field_x->atomic_size ) { 575*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"atomic size must match"); 57652849c42SDave May } 57752849c42SDave May #endif 57852849c42SDave May /* 57952849c42SDave May memcpy( (void*)((char*)field_y->data + pid_y*field_y->atomic_size), 58052849c42SDave May (void*)((char*)field_x->data + pid_x*field_x->atomic_size), 58152849c42SDave May field_x->atomic_size ); 58252849c42SDave May */ 58352849c42SDave May memcpy( __DATATFIELD_point_access(field_y->data,pid_y,field_y->atomic_size), 58452849c42SDave May __DATATFIELD_point_access(field_x->data,pid_x,field_x->atomic_size), 58552849c42SDave May field_y->atomic_size ); 5867fbf63aeSDave May PetscFunctionReturn(0); 58752849c42SDave May } 58852849c42SDave May 58952849c42SDave May 59052849c42SDave May // zero only the datafield at this point 5917fbf63aeSDave May #undef __FUNCT__ 5927fbf63aeSDave May #define __FUNCT__ "DataFieldZeroPoint" 5937fbf63aeSDave May PetscErrorCode DataFieldZeroPoint( const DataField field, const PetscInt index ) 59452849c42SDave May { 59552849c42SDave May #ifdef DATAFIELD_POINT_ACCESS_GUARD 5965c18a9d6SDave May /* check poPetscInt is valid */ 597*a233d522SDave May if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0"); 598*a233d522SDave May if (index >= field->L) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",field->L); 59952849c42SDave May #endif 60052849c42SDave May 60152849c42SDave May // memset( (void*)((char*)field->data + index*field->atomic_size), 0, field->atomic_size ); 60252849c42SDave May memset( __DATATFIELD_point_access(field->data,index,field->atomic_size), 0, field->atomic_size ); 6037fbf63aeSDave May PetscFunctionReturn(0); 60452849c42SDave May } 60552849c42SDave May 60652849c42SDave May // zero ALL data for this point 6077fbf63aeSDave May #undef __FUNCT__ 6087fbf63aeSDave May #define __FUNCT__ "DataBucketZeroPoint" 6097fbf63aeSDave May PetscErrorCode DataBucketZeroPoint( const DataBucket db, const PetscInt index ) 61052849c42SDave May { 6115c18a9d6SDave May PetscInt f; 61252849c42SDave May 6135c18a9d6SDave May /* check poPetscInt is valid */ 614*a233d522SDave May if (index < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be >= 0"); 615*a233d522SDave May if (index >= db->allocated) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index must be < %D",db->allocated); 61652849c42SDave May 61752849c42SDave May for(f=0;f<db->nfields;f++){ 61852849c42SDave May DataField field = db->field[f]; 61952849c42SDave May 62052849c42SDave May DataFieldZeroPoint(field,index); 62152849c42SDave May } 6227fbf63aeSDave May PetscFunctionReturn(0); 62352849c42SDave May } 62452849c42SDave May 62552849c42SDave May /* increment */ 6267fbf63aeSDave May #undef __FUNCT__ 6277fbf63aeSDave May #define __FUNCT__ "DataBucketAddPoint" 6287fbf63aeSDave May PetscErrorCode DataBucketAddPoint( DataBucket db ) 62952849c42SDave May { 63052849c42SDave May DataBucketSetSizes( db, db->L+1, -1 ); 6317fbf63aeSDave May PetscFunctionReturn(0); 63252849c42SDave May } 63352849c42SDave May 6347fbf63aeSDave May /* decrement */ 6357fbf63aeSDave May #undef __FUNCT__ 6367fbf63aeSDave May #define __FUNCT__ "DataBucketRemovePoint" 6377fbf63aeSDave May PetscErrorCode DataBucketRemovePoint( DataBucket db ) 6387fbf63aeSDave May { 6397fbf63aeSDave May DataBucketSetSizes( db, db->L-1, -1 ); 6407fbf63aeSDave May PetscFunctionReturn(0); 6417fbf63aeSDave May } 6427fbf63aeSDave May 6437fbf63aeSDave May #undef __FUNCT__ 6447fbf63aeSDave May #define __FUNCT__ "_DataFieldViewBinary" 6457fbf63aeSDave May PetscErrorCode _DataFieldViewBinary(DataField field, FILE *fp ) 64652849c42SDave May { 64752849c42SDave May fprintf(fp,"<DataField>\n"); 64852849c42SDave May fprintf(fp,"%d\n", field->L); 64952849c42SDave May fprintf(fp,"%zu\n",field->atomic_size); 65052849c42SDave May fprintf(fp,"%s\n", field->registeration_function); 65152849c42SDave May fprintf(fp,"%s\n", field->name); 65252849c42SDave May 65352849c42SDave May fwrite(field->data, field->atomic_size, field->L, fp); 65452849c42SDave May /* 65552849c42SDave May printf(" ** wrote %zu bytes for DataField \"%s\" \n", field->atomic_size * field->L, field->name ); 65652849c42SDave May */ 65752849c42SDave May fprintf(fp,"\n</DataField>\n"); 6587fbf63aeSDave May PetscFunctionReturn(0); 65952849c42SDave May } 66052849c42SDave May 6617fbf63aeSDave May #undef __FUNCT__ 6627fbf63aeSDave May #define __FUNCT__ "_DataBucketRegisterFieldFromFile" 6637fbf63aeSDave May PetscErrorCode _DataBucketRegisterFieldFromFile( FILE *fp, DataBucket db ) 66452849c42SDave May { 66552849c42SDave May PetscBool val; 66652849c42SDave May DataField *field; 66752849c42SDave May 66852849c42SDave May DataField gfield; 66952849c42SDave May char dummy[100]; 67052849c42SDave May char registeration_function[5000]; 67152849c42SDave May char field_name[5000]; 6725c18a9d6SDave May PetscInt L; 67352849c42SDave May size_t atomic_size,strL; 67452849c42SDave May 67552849c42SDave May 67652849c42SDave May /* check we haven't finalised the registration of fields */ 67752849c42SDave May /* 67852849c42SDave May if(db->finalised==PETSC_TRUE) { 67952849c42SDave May printf("ERROR: DataBucketFinalize() has been called. Cannot register more fields\n"); 68052849c42SDave May ERROR(); 68152849c42SDave May } 68252849c42SDave May */ 68352849c42SDave May 68452849c42SDave May 68552849c42SDave May /* read file contents */ 68652849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 68752849c42SDave May 68852849c42SDave May fscanf( fp, "%d\n",&L); //printf("read(L): %d\n", L); 68952849c42SDave May 69052849c42SDave May fscanf( fp, "%zu\n",&atomic_size); //printf("read(size): %zu\n",atomic_size); 69152849c42SDave May 69252849c42SDave May fgets(registeration_function,4999,fp); //printf("read(reg func): %s", registeration_function ); 69352849c42SDave May strL = strlen(registeration_function); 69452849c42SDave May if(strL>1){ 69552849c42SDave May registeration_function[strL-1] = 0; 69652849c42SDave May } 69752849c42SDave May 69852849c42SDave May fgets(field_name,4999,fp); //printf("read(name): %s", field_name ); 69952849c42SDave May strL = strlen(field_name); 70052849c42SDave May if(strL>1){ 70152849c42SDave May field_name[strL-1] = 0; 70252849c42SDave May } 70352849c42SDave May 7044b46c5e1SDave May #ifdef DATA_BUCKET_LOG 70552849c42SDave May printf(" ** read L=%d; atomic_size=%zu; reg_func=\"%s\"; name=\"%s\" \n", L,atomic_size,registeration_function,field_name); 70652849c42SDave May #endif 70752849c42SDave May 70852849c42SDave May 70952849c42SDave May /* check for repeated name */ 71052849c42SDave May StringInList( field_name, db->nfields, (const DataField*)db->field, &val ); 711*a233d522SDave May if (val == PETSC_TRUE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot add same field twice"); 71252849c42SDave May 71352849c42SDave May /* create new space for data */ 71452849c42SDave May field = realloc( db->field, sizeof(DataField)*(db->nfields+1)); 71552849c42SDave May db->field = field; 71652849c42SDave May 71752849c42SDave May /* add field */ 71852849c42SDave May DataFieldCreate( registeration_function, field_name, atomic_size, L, &gfield ); 71952849c42SDave May 72052849c42SDave May /* copy contents of file */ 72152849c42SDave May fread(gfield->data, gfield->atomic_size, gfield->L, fp); 7224b46c5e1SDave May #ifdef DATA_BUCKET_LOG 72352849c42SDave May printf(" ** read %zu bytes for DataField \"%s\" \n", gfield->atomic_size * gfield->L, field_name ); 72452849c42SDave May #endif 72552849c42SDave May /* finish reading meta data */ 72652849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 72752849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 72852849c42SDave May 72952849c42SDave May db->field[ db->nfields ] = gfield; 73052849c42SDave May 73152849c42SDave May db->nfields++; 7327fbf63aeSDave May PetscFunctionReturn(0); 73352849c42SDave May } 73452849c42SDave May 7357fbf63aeSDave May #undef __FUNCT__ 7367fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderWrite_v00" 7377fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderWrite_v00(FILE *fp) 73852849c42SDave May { 73952849c42SDave May fprintf(fp,"<DataBucketHeader>\n"); 74052849c42SDave May fprintf(fp,"type=DataBucket\n"); 74152849c42SDave May fprintf(fp,"format=ascii\n"); 74252849c42SDave May fprintf(fp,"version=0.0\n"); 74352849c42SDave May fprintf(fp,"options=\n"); 74452849c42SDave May fprintf(fp,"</DataBucketHeader>\n"); 7457fbf63aeSDave May PetscFunctionReturn(0); 74652849c42SDave May } 7477fbf63aeSDave May 7487fbf63aeSDave May #undef __FUNCT__ 7497fbf63aeSDave May #define __FUNCT__ "_DataBucketViewAscii_HeaderRead_v00" 7507fbf63aeSDave May PetscErrorCode _DataBucketViewAscii_HeaderRead_v00(FILE *fp) 75152849c42SDave May { 75252849c42SDave May char dummy[100]; 75352849c42SDave May size_t strL; 75452849c42SDave May 75552849c42SDave May // header open 75652849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 75752849c42SDave May 75852849c42SDave May // type 75952849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 76052849c42SDave May strL = strlen(dummy); 76152849c42SDave May if(strL>1) { dummy[strL-1] = 0; } 76252849c42SDave May if(strcmp(dummy,"type=DataBucket")!=0) { 763*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Data file doesn't contain a DataBucket type"); 76452849c42SDave May } 76552849c42SDave May 76652849c42SDave May // format 76752849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 76852849c42SDave May 76952849c42SDave May // version 77052849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 77152849c42SDave May strL = strlen(dummy); 77252849c42SDave May if(strL>1) { dummy[strL-1] = 0; } 77352849c42SDave May if (strcmp(dummy,"version=0.0") != 0) { 774*a233d522SDave May SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"DataBucket file must be parsed with version=0.0 : You tried %s", dummy); 77552849c42SDave May } 77652849c42SDave May 77752849c42SDave May // options 77852849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 77952849c42SDave May // header close 78052849c42SDave May fgets(dummy,99,fp); //printf("read(header): %s", dummy ); 7817fbf63aeSDave May PetscFunctionReturn(0); 78252849c42SDave May } 78352849c42SDave May 7847fbf63aeSDave May #undef __FUNCT__ 7857fbf63aeSDave May #define __FUNCT__ "_DataBucketLoadFromFileBinary_SEQ" 7867fbf63aeSDave May PetscErrorCode _DataBucketLoadFromFileBinary_SEQ(const char filename[], DataBucket *_db) 78752849c42SDave May { 78852849c42SDave May DataBucket db; 78952849c42SDave May FILE *fp; 7905c18a9d6SDave May PetscInt L,buffer,f,nfields; 79152849c42SDave May 79252849c42SDave May 7934b46c5e1SDave May #ifdef DATA_BUCKET_LOG 79452849c42SDave May printf("** DataBucketLoadFromFile **\n"); 79552849c42SDave May #endif 79652849c42SDave May 79752849c42SDave May /* open file */ 79852849c42SDave May fp = fopen(filename,"rb"); 79952849c42SDave May if (fp==NULL){ 800*a233d522SDave May SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file with name %s", filename); 80152849c42SDave May } 80252849c42SDave May 80352849c42SDave May /* read header */ 80452849c42SDave May _DataBucketViewAscii_HeaderRead_v00(fp); 80552849c42SDave May 80652849c42SDave May fscanf(fp,"%d\n%d\n%d\n",&L,&buffer,&nfields); 80752849c42SDave May 80852849c42SDave May DataBucketCreate(&db); 80952849c42SDave May 81052849c42SDave May for( f=0; f<nfields; f++ ) { 81152849c42SDave May _DataBucketRegisterFieldFromFile(fp,db); 81252849c42SDave May } 81352849c42SDave May fclose(fp); 81452849c42SDave May 81552849c42SDave May DataBucketFinalize(db); 81652849c42SDave May 81752849c42SDave May 81852849c42SDave May /* 81952849c42SDave May DataBucketSetSizes(db,L,buffer); 82052849c42SDave May */ 82152849c42SDave May db->L = L; 82252849c42SDave May db->buffer = buffer; 82352849c42SDave May db->allocated = L + buffer; 82452849c42SDave May 82552849c42SDave May *_db = db; 8267fbf63aeSDave May PetscFunctionReturn(0); 82752849c42SDave May } 82852849c42SDave May 8297fbf63aeSDave May #undef __FUNCT__ 8307fbf63aeSDave May #define __FUNCT__ "DataBucketLoadFromFile" 8317fbf63aeSDave May PetscErrorCode DataBucketLoadFromFile(MPI_Comm comm,const char filename[], DataBucketViewType type, DataBucket *db) 83252849c42SDave May { 8335c18a9d6SDave May PetscMPIInt nproc,rank; 83452849c42SDave May 83552849c42SDave May MPI_Comm_size(comm,&nproc); 83652849c42SDave May MPI_Comm_rank(comm,&rank); 83752849c42SDave May 8384b46c5e1SDave May #ifdef DATA_BUCKET_LOG 83952849c42SDave May printf("** DataBucketLoadFromFile **\n"); 84052849c42SDave May #endif 84152849c42SDave May if (type == DATABUCKET_VIEW_STDOUT) { 84252849c42SDave May 84352849c42SDave May } else if (type == DATABUCKET_VIEW_ASCII) { 844*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure"); 84552849c42SDave May } else if (type == DATABUCKET_VIEW_BINARY) { 84652849c42SDave May if (nproc == 1) { 84752849c42SDave May _DataBucketLoadFromFileBinary_SEQ(filename,db); 84852849c42SDave May } else { 84952849c42SDave May char *name; 85052849c42SDave May 85152849c42SDave May asprintf(&name,"%s_p%1.5d",filename, rank ); 85252849c42SDave May _DataBucketLoadFromFileBinary_SEQ(name,db); 85352849c42SDave May free(name); 85452849c42SDave May } 85552849c42SDave May } else { 856*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer requested"); 85752849c42SDave May } 8587fbf63aeSDave May PetscFunctionReturn(0); 85952849c42SDave May } 86052849c42SDave May 8617fbf63aeSDave May #undef __FUNCT__ 8627fbf63aeSDave May #define __FUNCT__ "_DataBucketViewBinary" 8637fbf63aeSDave May PetscErrorCode _DataBucketViewBinary(DataBucket db,const char filename[]) 86452849c42SDave May { 86552849c42SDave May FILE *fp = NULL; 8665c18a9d6SDave May PetscInt f; 86752849c42SDave May 86852849c42SDave May fp = fopen(filename,"wb"); 869*a233d522SDave May if (fp == NULL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot open file with name %s", filename); 87052849c42SDave May 87152849c42SDave May /* db header */ 87252849c42SDave May _DataBucketViewAscii_HeaderWrite_v00(fp); 87352849c42SDave May 87452849c42SDave May /* meta-data */ 87552849c42SDave May fprintf(fp,"%d\n%d\n%d\n", db->L,db->buffer,db->nfields); 87652849c42SDave May 87752849c42SDave May for( f=0; f<db->nfields; f++ ) { 87852849c42SDave May /* load datafields */ 87952849c42SDave May _DataFieldViewBinary(db->field[f],fp); 88052849c42SDave May } 88152849c42SDave May 88252849c42SDave May fclose(fp); 8837fbf63aeSDave May PetscFunctionReturn(0); 88452849c42SDave May } 88552849c42SDave May 8867fbf63aeSDave May #undef __FUNCT__ 8877fbf63aeSDave May #define __FUNCT__ "DataBucketView_SEQ" 8887fbf63aeSDave May PetscErrorCode DataBucketView_SEQ(DataBucket db,const char filename[],DataBucketViewType type) 88952849c42SDave May { 89052849c42SDave May switch (type) { 89152849c42SDave May case DATABUCKET_VIEW_STDOUT: 89252849c42SDave May { 8935c18a9d6SDave May PetscInt f; 89452849c42SDave May double memory_usage_total = 0.0; 89552849c42SDave May 89652849c42SDave May printf("DataBucketView(SEQ): (\"%s\")\n",filename); 89752849c42SDave May printf(" L = %d \n", db->L ); 89852849c42SDave May printf(" buffer = %d \n", db->buffer ); 89952849c42SDave May printf(" allocated = %d \n", db->allocated ); 90052849c42SDave May 90152849c42SDave May printf(" nfields registered = %d \n", db->nfields ); 90252849c42SDave May for( f=0; f<db->nfields; f++ ) { 90352849c42SDave May double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6; 90452849c42SDave May 90552849c42SDave May printf(" [%3d]: field name ==>> %30s : Mem. usage = %1.2e (MB) \n", f, db->field[f]->name, memory_usage_f ); 90652849c42SDave May memory_usage_total += memory_usage_f; 90752849c42SDave May } 90852849c42SDave May printf(" Total mem. usage = %1.2e (MB) \n", memory_usage_total ); 90952849c42SDave May } 91052849c42SDave May break; 91152849c42SDave May 91252849c42SDave May case DATABUCKET_VIEW_ASCII: 91352849c42SDave May { 914*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying particle data structure"); 91552849c42SDave May } 91652849c42SDave May break; 91752849c42SDave May 91852849c42SDave May case DATABUCKET_VIEW_BINARY: 91952849c42SDave May { 92052849c42SDave May _DataBucketViewBinary(db,filename); 92152849c42SDave May } 92252849c42SDave May break; 92352849c42SDave May 92452849c42SDave May case DATABUCKET_VIEW_HDF5: 92552849c42SDave May { 926*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No HDF5 support"); 92752849c42SDave May } 92852849c42SDave May break; 92952849c42SDave May 93052849c42SDave May default: 931*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested"); 93252849c42SDave May break; 93352849c42SDave May } 9347fbf63aeSDave May PetscFunctionReturn(0); 93552849c42SDave May } 93652849c42SDave May 9377fbf63aeSDave May #undef __FUNCT__ 9387fbf63aeSDave May #define __FUNCT__ "DataBucketView_MPI" 9397fbf63aeSDave May PetscErrorCode DataBucketView_MPI(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type) 94052849c42SDave May { 94152849c42SDave May switch (type) { 94252849c42SDave May case DATABUCKET_VIEW_STDOUT: 94352849c42SDave May { 9445c18a9d6SDave May PetscInt f; 9455c18a9d6SDave May PetscInt L,buffer,allocated; 94652849c42SDave May double memory_usage_total,memory_usage_total_local = 0.0; 9475c18a9d6SDave May PetscMPIInt rank; 9485c18a9d6SDave May PetscInt ierr; 94952849c42SDave May 95052849c42SDave May ierr = MPI_Comm_rank(comm,&rank); 95152849c42SDave May 95252849c42SDave May DataBucketGetGlobalSizes(comm,db,&L,&buffer,&allocated); 95352849c42SDave May 95452849c42SDave May for( f=0; f<db->nfields; f++ ) { 95552849c42SDave May double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6; 95652849c42SDave May 95752849c42SDave May memory_usage_total_local += memory_usage_f; 95852849c42SDave May } 95952849c42SDave May MPI_Allreduce(&memory_usage_total_local,&memory_usage_total,1,MPI_DOUBLE,MPI_SUM,comm); 96052849c42SDave May 96152849c42SDave May if (rank==0) { 9625c18a9d6SDave May PetscPrintf(comm,"DataBucketView(MPI): (\"%s\")\n",filename); 9635c18a9d6SDave May PetscPrintf(comm," L = %D \n", L ); 9645c18a9d6SDave May PetscPrintf(comm," buffer (max) = %D \n", buffer ); 9655c18a9d6SDave May PetscPrintf(comm," allocated = %D \n", allocated ); 96652849c42SDave May 9675c18a9d6SDave May PetscPrintf(comm," nfields registered = %D \n", db->nfields ); 96852849c42SDave May for( f=0; f<db->nfields; f++ ) { 96952849c42SDave May double memory_usage_f = (double)(db->field[f]->atomic_size * db->allocated) * 1.0e-6; 97052849c42SDave May 97152849c42SDave May printf(" [%3d]: field name ==>> %30s : Mem. usage = %1.2e (MB) : rank0\n", f, db->field[f]->name, memory_usage_f ); 97252849c42SDave May } 97352849c42SDave May 97452849c42SDave May printf(" Total mem. usage = %1.2e (MB) : collective\n", memory_usage_total ); 97552849c42SDave May } 97652849c42SDave May 97752849c42SDave May } 97852849c42SDave May break; 97952849c42SDave May 98052849c42SDave May case DATABUCKET_VIEW_ASCII: 98152849c42SDave May { 982*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot be implemented as we don't know the underlying data structure"); 98352849c42SDave May } 98452849c42SDave May break; 98552849c42SDave May 98652849c42SDave May case DATABUCKET_VIEW_BINARY: 98752849c42SDave May { 98852849c42SDave May char *name; 9895c18a9d6SDave May PetscMPIInt rank; 99052849c42SDave May 99152849c42SDave May /* create correct extension */ 99252849c42SDave May MPI_Comm_rank(comm,&rank); 99352849c42SDave May asprintf(&name,"%s_p%1.5d",filename, rank ); 99452849c42SDave May 99552849c42SDave May _DataBucketViewBinary(db,name); 99652849c42SDave May 99752849c42SDave May free(name); 99852849c42SDave May } 99952849c42SDave May break; 100052849c42SDave May 100152849c42SDave May case DATABUCKET_VIEW_HDF5: 100252849c42SDave May { 1003*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for HDF5"); 100452849c42SDave May } 100552849c42SDave May break; 100652849c42SDave May 100752849c42SDave May default: 1008*a233d522SDave May SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer method requested"); 100952849c42SDave May break; 101052849c42SDave May } 10117fbf63aeSDave May PetscFunctionReturn(0); 101252849c42SDave May } 101352849c42SDave May 10147fbf63aeSDave May #undef __FUNCT__ 10157fbf63aeSDave May #define __FUNCT__ "DataBucketView" 10167fbf63aeSDave May PetscErrorCode DataBucketView(MPI_Comm comm,DataBucket db,const char filename[],DataBucketViewType type) 101752849c42SDave May { 10185c18a9d6SDave May PetscMPIInt nproc; 101952849c42SDave May 102052849c42SDave May MPI_Comm_size(comm,&nproc); 102152849c42SDave May if (nproc==1) { 102252849c42SDave May DataBucketView_SEQ(db,filename,type); 102352849c42SDave May } else { 102452849c42SDave May DataBucketView_MPI(comm,db,filename,type); 102552849c42SDave May } 10267fbf63aeSDave May PetscFunctionReturn(0); 102752849c42SDave May } 102852849c42SDave May 10297fbf63aeSDave May #undef __FUNCT__ 10307fbf63aeSDave May #define __FUNCT__ "DataBucketDuplicateFields" 10317fbf63aeSDave May PetscErrorCode DataBucketDuplicateFields(DataBucket dbA,DataBucket *dbB) 103252849c42SDave May { 103352849c42SDave May DataBucket db2; 10345c18a9d6SDave May PetscInt f; 103552849c42SDave May 103652849c42SDave May DataBucketCreate(&db2); 103752849c42SDave May 103852849c42SDave May /* copy contents from dbA into db2 */ 103952849c42SDave May for (f=0; f<dbA->nfields; f++) { 104052849c42SDave May DataField field; 104152849c42SDave May size_t atomic_size; 104252849c42SDave May char *name; 104352849c42SDave May 104452849c42SDave May field = dbA->field[f]; 104552849c42SDave May 104652849c42SDave May atomic_size = field->atomic_size; 104752849c42SDave May name = field->name; 104852849c42SDave May 10492eac95f8SDave May DataBucketRegisterField(db2,"DataBucketDuplicateFields",name,atomic_size,NULL); 105052849c42SDave May } 105152849c42SDave May DataBucketFinalize(db2); 105252849c42SDave May DataBucketSetInitialSizes(db2,0,1000); 105352849c42SDave May 105452849c42SDave May /* set pointer */ 105552849c42SDave May *dbB = db2; 10567fbf63aeSDave May PetscFunctionReturn(0); 105752849c42SDave May } 105852849c42SDave May 105952849c42SDave May /* 106052849c42SDave May Insert points from db2 into db1 106152849c42SDave May db1 <<== db2 106252849c42SDave May */ 10637fbf63aeSDave May #undef __FUNCT__ 10647fbf63aeSDave May #define __FUNCT__ "DataBucketInsertValues" 10657fbf63aeSDave May PetscErrorCode DataBucketInsertValues(DataBucket db1,DataBucket db2) 106652849c42SDave May { 10675c18a9d6SDave May PetscInt n_mp_points1,n_mp_points2; 10685c18a9d6SDave May PetscInt n_mp_points1_new,p; 106952849c42SDave May 107052849c42SDave May DataBucketGetSizes(db1,&n_mp_points1,0,0); 107152849c42SDave May DataBucketGetSizes(db2,&n_mp_points2,0,0); 107252849c42SDave May 107352849c42SDave May n_mp_points1_new = n_mp_points1 + n_mp_points2; 107452849c42SDave May DataBucketSetSizes(db1,n_mp_points1_new,-1); 107552849c42SDave May 107652849c42SDave May for (p=0; p<n_mp_points2; p++) { 107752849c42SDave May // db1 <<== db2 // 107852849c42SDave May DataBucketCopyPoint( db2,p, db1,(n_mp_points1 + p) ); 107952849c42SDave May } 10807fbf63aeSDave May PetscFunctionReturn(0); 108152849c42SDave May } 108252849c42SDave May 108352849c42SDave May /* helpers for parallel send/recv */ 10847fbf63aeSDave May #undef __FUNCT__ 10857fbf63aeSDave May #define __FUNCT__ "DataBucketCreatePackedArray" 10867fbf63aeSDave May PetscErrorCode DataBucketCreatePackedArray(DataBucket db,size_t *bytes,void **buf) 108752849c42SDave May { 10885c18a9d6SDave May PetscInt f; 108952849c42SDave May size_t sizeof_marker_contents; 109052849c42SDave May void *buffer; 109152849c42SDave May 109252849c42SDave May sizeof_marker_contents = 0; 109352849c42SDave May for (f=0; f<db->nfields; f++) { 109452849c42SDave May DataField df = db->field[f]; 109552849c42SDave May 109652849c42SDave May sizeof_marker_contents += df->atomic_size; 109752849c42SDave May } 109852849c42SDave May 109952849c42SDave May buffer = malloc(sizeof_marker_contents); 110052849c42SDave May memset(buffer,0,sizeof_marker_contents); 110152849c42SDave May 110252849c42SDave May if (bytes) { *bytes = sizeof_marker_contents; } 110352849c42SDave May if (buf) { *buf = buffer; } 11047fbf63aeSDave May PetscFunctionReturn(0); 110552849c42SDave May } 110652849c42SDave May 11077fbf63aeSDave May #undef __FUNCT__ 11087fbf63aeSDave May #define __FUNCT__ "DataBucketDestroyPackedArray" 11097fbf63aeSDave May PetscErrorCode DataBucketDestroyPackedArray(DataBucket db,void **buf) 111052849c42SDave May { 111152849c42SDave May if (buf) { 111252849c42SDave May free(*buf); 111352849c42SDave May *buf = NULL; 111452849c42SDave May } 11157fbf63aeSDave May PetscFunctionReturn(0); 111652849c42SDave May } 111752849c42SDave May 11187fbf63aeSDave May #undef __FUNCT__ 11197fbf63aeSDave May #define __FUNCT__ "DataBucketFillPackedArray" 11207fbf63aeSDave May PetscErrorCode DataBucketFillPackedArray(DataBucket db,const PetscInt index,void *buf) 112152849c42SDave May { 11225c18a9d6SDave May PetscInt f; 112352849c42SDave May void *data,*data_p; 112452849c42SDave May size_t asize,offset; 112552849c42SDave May 112652849c42SDave May offset = 0; 112752849c42SDave May for (f=0; f<db->nfields; f++) { 112852849c42SDave May DataField df = db->field[f]; 112952849c42SDave May 113052849c42SDave May asize = df->atomic_size; 113152849c42SDave May 113252849c42SDave May data = (void*)( df->data ); 113352849c42SDave May data_p = (void*)( (char*)data + index*asize ); 113452849c42SDave May 113552849c42SDave May memcpy( (void*)((char*)buf + offset), data_p, asize); 113652849c42SDave May offset = offset + asize; 113752849c42SDave May } 11387fbf63aeSDave May PetscFunctionReturn(0); 113952849c42SDave May } 114052849c42SDave May 11417fbf63aeSDave May #undef __FUNCT__ 11427fbf63aeSDave May #define __FUNCT__ "DataBucketInsertPackedArray" 11437fbf63aeSDave May PetscErrorCode DataBucketInsertPackedArray(DataBucket db,const PetscInt idx,void *data) 114452849c42SDave May { 11455c18a9d6SDave May PetscInt f; 114652849c42SDave May void *data_p; 114752849c42SDave May size_t offset; 114852849c42SDave May 114952849c42SDave May offset = 0; 115052849c42SDave May for (f=0; f<db->nfields; f++) { 115152849c42SDave May DataField df = db->field[f]; 115252849c42SDave May 115352849c42SDave May data_p = (void*)( (char*)data + offset ); 115452849c42SDave May 115552849c42SDave May DataFieldInsertPoint(df, idx, (void*)data_p ); 115652849c42SDave May offset = offset + df->atomic_size; 115752849c42SDave May } 11587fbf63aeSDave May PetscFunctionReturn(0); 115952849c42SDave May } 1160