xref: /petsc/src/dm/impls/swarm/data_bucket.c (revision a233d522e592b4382d56b3cd92d8e4af76a8fe5f)
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