Commits

Jed Brown  committed 47452e7

PetscSegBuffer: add extraction to existing buffer and in-place

* PetscSegBufferExtractAlloc: allocates new memory (old behavior)

* PetscSegBufferExtractTo: use provided buffer

* PetscSegBufferExtractInPlace: pack into space that will be used by
next call to PetscSegBufferGet().

  • Participants
  • Parent commits 0f453b9

Comments (0)

Files changed (3)

File include/petscsys.h

 PETSC_EXTERN PetscErrorCode PetscSegBufferCreate(PetscInt,PetscInt,PetscSegBuffer*);
 PETSC_EXTERN PetscErrorCode PetscSegBufferDestroy(PetscSegBuffer*);
 PETSC_EXTERN PetscErrorCode PetscSegBufferGet(PetscSegBuffer*,PetscInt,void*);
-PETSC_EXTERN PetscErrorCode PetscSegBufferExtract(PetscSegBuffer*,void*);
+PETSC_EXTERN PetscErrorCode PetscSegBufferExtractAlloc(PetscSegBuffer*,void*);
+PETSC_EXTERN PetscErrorCode PetscSegBufferExtractTo(PetscSegBuffer*,void*);
+PETSC_EXTERN PetscErrorCode PetscSegBufferExtractInPlace(PetscSegBuffer*,void*);
 
 /* Reset __FUNCT__ in case the user does not define it themselves */
 #undef __FUNCT__

File src/sys/utils/mpits.c

     }
   }
   *nfrom = nrecvs;
-  ierr   = PetscSegBufferExtract(&segrank,fromranks);CHKERRQ(ierr);
+  ierr   = PetscSegBufferExtractAlloc(&segrank,fromranks);CHKERRQ(ierr);
   ierr   = PetscSegBufferDestroy(&segrank);CHKERRQ(ierr);
-  ierr   = PetscSegBufferExtract(&segdata,fromdata);CHKERRQ(ierr);
+  ierr   = PetscSegBufferExtractAlloc(&segdata,fromdata);CHKERRQ(ierr);
   ierr   = PetscSegBufferDestroy(&segdata);CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }

File src/sys/utils/segbuffer.c

 
    Level: developer
 
-.seealso: PetscSegBufferGet(), PetscSegBufferExtract(), PetscSegBufferDestroy()
+.seealso: PetscSegBufferGet(), PetscSegBufferExtractAlloc(), PetscSegBufferExtractTo(), PetscSegBufferExtractInPlace(), PetscSegBufferDestroy()
 @*/
 PetscErrorCode PetscSegBufferCreate(PetscInt unitbytes,PetscInt expected,PetscSegBuffer *seg)
 {
 
    Level: developer
 
-.seealso: PetscSegBufferCreate(), PetscSegBufferExtract(), PetscSegBufferDestroy()
+.seealso: PetscSegBufferCreate(), PetscSegBufferExtractAlloc(), PetscSegBufferExtractTo(), PetscSegBufferExtractInPlace(), PetscSegBufferDestroy()
 @*/
 PetscErrorCode PetscSegBufferGet(PetscSegBuffer *seg,PetscInt count,void *buf)
 {
 }
 
 #undef __FUNCT__
-#define __FUNCT__ "PetscSegBufferExtract"
+#define __FUNCT__ "PetscSegBufferExtractTo"
 /*@C
-   PetscSegBufferExtract - extract contiguous data and reset segmented buffer
+   PetscSegBufferExtractTo - extract contiguous data to provided buffer and reset segmented buffer
 
    Not Collective
 
    Input Argument:
-.  seg - segmented buffer
-
-   Output Argument:
-.  contiguous - address of new array containing contiguous data, caller frees with PetscFree()
++  seg - segmented buffer
+-  contig - allocated buffer to hold contiguous data
 
    Level: developer
 
-.seealso: PetscSegBufferCreate(), PetscSegBufferGet(), PetscSegBufferDestroy()
+.seealso: PetscSegBufferCreate(), PetscSegBufferGet(), PetscSegBufferDestroy(), PetscSegBufferExtractAlloc(), PetscSegBufferExtractInPlace()
 @*/
-PetscErrorCode PetscSegBufferExtract(PetscSegBuffer *seg,void *contiguous)
+PetscErrorCode PetscSegBufferExtractTo(PetscSegBuffer *seg,void *contig)
 {
   PetscErrorCode ierr;
   PetscInt       unitbytes;
   PetscSegBuffer s,t;
-  char           *contig,*ptr;
+  char           *ptr;
 
   PetscFunctionBegin;
   s = *seg;
 
   unitbytes = s->unitbytes;
 
-  ierr = PetscMalloc((s->used+s->tailused)*unitbytes,&contig);CHKERRQ(ierr);
-  ptr  = contig + s->tailused*unitbytes;
+  ptr  = ((char*)contig) + s->tailused*unitbytes;
   ierr = PetscMemcpy(ptr,s->u.array,s->used*unitbytes);CHKERRQ(ierr);
   for (t=s->tail; t;) {
     PetscSegBuffer tail = t->tail;
     t    = tail;
   }
   if (ptr != contig) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Tail count does not match");
+  s->used             = 0;
   s->tailused         = 0;
   s->tail             = NULL;
-  *(char**)contiguous = contig;
+  PetscFunctionReturn(0);
+}
+
+#undef __FUNCT__
+#define __FUNCT__ "PetscSegBufferExtractAlloc"
+/*@C
+   PetscSegBufferExtractAlloc - extract contiguous data to new allocation and reset segmented buffer
+
+   Not Collective
+
+   Input Argument:
+.  seg - segmented buffer
+
+   Output Argument:
+.  contiguous - address of new array containing contiguous data, caller frees with PetscFree()
+
+   Level: developer
+
+   Developer Notes: 'seg' argument is a pointer so that implementation could reallocate, though this is not currently done
+
+.seealso: PetscSegBufferCreate(), PetscSegBufferGet(), PetscSegBufferDestroy(), PetscSegBufferExtractTo(), PetscSegBufferExtractInPlace()
+@*/
+PetscErrorCode PetscSegBufferExtractAlloc(PetscSegBuffer *seg,void *contiguous)
+{
+  PetscErrorCode ierr;
+  PetscSegBuffer s;
+  void           *contig;
+
+  PetscFunctionBegin;
+  s = *seg;
+
+  ierr = PetscMalloc((s->used+s->tailused)*s->unitbytes,&contig);CHKERRQ(ierr);
+  ierr = PetscSegBufferExtractTo(seg,contig);CHKERRQ(ierr);
+  *(void**)contiguous = contig;
+  PetscFunctionReturn(0);
+}
+
+#undef __FUNCT__
+#define __FUNCT__ "PetscSegBufferExtractInPlace"
+/*@C
+   PetscSegBufferExtractInPlace - extract in-place contiguous representation of data and reset segmented buffer for reuse
+
+   Collective
+
+   Input Arguments:
+.  seg - segmented buffer object
+
+   Output Arguments:
+.  contig - address of pointer to contiguous memory
+
+   Level: developer
+
+.seealso: PetscSegBufferExtractAlloc(), PetscSegBufferExtractTo()
+@*/
+PetscErrorCode PetscSegBufferExtractInPlace(PetscSegBuffer *seg,void *contig)
+{
+  PetscErrorCode ierr;
+
+  PetscFunctionBegin;
+  if (!(*seg)->tail) {
+    *(char**)contig = (*seg)->u.array;
+  } else {
+    PetscSegBuffer s = *seg,newseg;
+
+    ierr = PetscSegBufferCreate(s->unitbytes,s->used+s->tailused,&newseg);CHKERRQ(ierr);
+    ierr = PetscSegBufferExtractTo(seg,newseg->u.array);CHKERRQ(ierr);
+    ierr = PetscSegBufferDestroy(seg);CHKERRQ(ierr);
+    *seg = newseg;
+    *(void**)contig = newseg->u.array;
+  }
   PetscFunctionReturn(0);
 }