1*d5731834SJed Brown #include <../src/mat/utils/petscheap.h> 2*d5731834SJed Brown 3*d5731834SJed Brown typedef struct { 4*d5731834SJed Brown PetscInt id; 5*d5731834SJed Brown PetscInt value; 6*d5731834SJed Brown } HeapNode; 7*d5731834SJed Brown 8*d5731834SJed Brown struct _PetscHeap { 9*d5731834SJed Brown PetscInt end; /* one past the last item */ 10*d5731834SJed Brown PetscInt alloc; /* length of array */ 11*d5731834SJed Brown PetscInt stash; /* stash grows down, this points to last item */ 12*d5731834SJed Brown HeapNode *base; 13*d5731834SJed Brown }; 14*d5731834SJed Brown 15*d5731834SJed Brown #define Parent(loc) ((loc) >> 1) 16*d5731834SJed Brown #define Left(loc) ((loc) << 1) 17*d5731834SJed Brown #define Right(loc) (Left((loc))+1) 18*d5731834SJed Brown #define Value(h,loc) ((h)->base[loc].value) 19*d5731834SJed Brown #define Id(h,loc) ((h)->base[loc].id) 20*d5731834SJed Brown 21*d5731834SJed Brown PETSC_STATIC_INLINE void Swap(PetscHeap h,PetscInt loc,PetscInt loc2) { 22*d5731834SJed Brown PetscInt id,val; 23*d5731834SJed Brown id = Id(h,loc); 24*d5731834SJed Brown val = Value(h,loc); 25*d5731834SJed Brown h->base[loc].id = Id(h,loc2); 26*d5731834SJed Brown h->base[loc].value = Value(h,loc2); 27*d5731834SJed Brown h->base[loc2].id = id; 28*d5731834SJed Brown h->base[loc2].value = val; 29*d5731834SJed Brown } 30*d5731834SJed Brown PETSC_STATIC_INLINE PetscInt MinChild(PetscHeap h,PetscInt loc) { 31*d5731834SJed Brown if (Left(loc) >= h->end) return 0; 32*d5731834SJed Brown if (Right(loc) >= h->end) return Left(loc); 33*d5731834SJed Brown return Value(h,Left(loc)) <= Value(h,Right(loc)) ? Left(loc) : Right(loc); 34*d5731834SJed Brown } 35*d5731834SJed Brown 36*d5731834SJed Brown #undef __FUNCT__ 37*d5731834SJed Brown #define __FUNCT__ "PetscHeapCreate" 38*d5731834SJed Brown PetscErrorCode PetscHeapCreate(PetscInt maxsize,PetscHeap *heap) 39*d5731834SJed Brown { 40*d5731834SJed Brown PetscErrorCode ierr; 41*d5731834SJed Brown PetscHeap h; 42*d5731834SJed Brown 43*d5731834SJed Brown PetscFunctionBegin; 44*d5731834SJed Brown *heap = PETSC_NULL; 45*d5731834SJed Brown ierr = PetscMalloc(sizeof *h,&h);CHKERRQ(ierr); 46*d5731834SJed Brown h->end = 1; 47*d5731834SJed Brown h->alloc = maxsize+1; 48*d5731834SJed Brown h->stash = h->alloc; 49*d5731834SJed Brown ierr = PetscMalloc((maxsize+1)*sizeof(HeapNode),&h->base);CHKERRQ(ierr); 50*d5731834SJed Brown h->base[0].id = -1; 51*d5731834SJed Brown h->base[0].value = PETSC_MIN_INT; 52*d5731834SJed Brown *heap = h; 53*d5731834SJed Brown PetscFunctionReturn(0); 54*d5731834SJed Brown } 55*d5731834SJed Brown 56*d5731834SJed Brown #undef __FUNCT__ 57*d5731834SJed Brown #define __FUNCT__ "PetscHeapAdd" 58*d5731834SJed Brown PetscErrorCode PetscHeapAdd(PetscHeap h,PetscInt id,PetscInt val) 59*d5731834SJed Brown { 60*d5731834SJed Brown PetscInt loc; 61*d5731834SJed Brown 62*d5731834SJed Brown PetscFunctionBegin; 63*d5731834SJed Brown loc = h->end++; 64*d5731834SJed Brown if (h->end > h->stash) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Addition would exceed allocation %D (%D stashed)",h->alloc,(h->alloc-h->stash)); 65*d5731834SJed Brown h->base[loc].id = id; 66*d5731834SJed Brown h->base[loc].value = val; 67*d5731834SJed Brown 68*d5731834SJed Brown /* move up until heap condition is satisfied */ 69*d5731834SJed Brown while (Value(h,Parent(loc)) > val) { 70*d5731834SJed Brown Swap(h,loc,Parent(loc)); 71*d5731834SJed Brown loc = Parent(loc); 72*d5731834SJed Brown } 73*d5731834SJed Brown PetscFunctionReturn(0); 74*d5731834SJed Brown } 75*d5731834SJed Brown 76*d5731834SJed Brown #undef __FUNCT__ 77*d5731834SJed Brown #define __FUNCT__ "PetscHeapPop" 78*d5731834SJed Brown PetscErrorCode PetscHeapPop(PetscHeap h,PetscInt *id,PetscInt *val) 79*d5731834SJed Brown { 80*d5731834SJed Brown PetscInt loc,chld; 81*d5731834SJed Brown 82*d5731834SJed Brown PetscFunctionBegin; 83*d5731834SJed Brown if (h->end == 1) { 84*d5731834SJed Brown *id = h->base[0].id; 85*d5731834SJed Brown *val = h->base[0].value; 86*d5731834SJed Brown PetscFunctionReturn(0); 87*d5731834SJed Brown } 88*d5731834SJed Brown 89*d5731834SJed Brown *id = h->base[1].id; 90*d5731834SJed Brown *val = h->base[1].value; 91*d5731834SJed Brown 92*d5731834SJed Brown /* rotate last entry into first position */ 93*d5731834SJed Brown loc = --h->end; 94*d5731834SJed Brown h->base[1].id = Id(h,loc); 95*d5731834SJed Brown h->base[1].value = Value(h,loc); 96*d5731834SJed Brown 97*d5731834SJed Brown /* move down until min heap condition is satisfied */ 98*d5731834SJed Brown loc = 1; 99*d5731834SJed Brown while ((chld = MinChild(h,loc)) && Value(h,loc) > Value(h,chld)) { 100*d5731834SJed Brown Swap(h,loc,chld); 101*d5731834SJed Brown loc = chld; 102*d5731834SJed Brown } 103*d5731834SJed Brown PetscFunctionReturn(0); 104*d5731834SJed Brown } 105*d5731834SJed Brown 106*d5731834SJed Brown #undef __FUNCT__ 107*d5731834SJed Brown #define __FUNCT__ "PetscHeapPeek" 108*d5731834SJed Brown PetscErrorCode PetscHeapPeek(PetscHeap h,PetscInt *id,PetscInt *val) 109*d5731834SJed Brown { 110*d5731834SJed Brown PetscFunctionBegin; 111*d5731834SJed Brown if (h->end == 1) { 112*d5731834SJed Brown *id = h->base[0].id; 113*d5731834SJed Brown *val = h->base[0].value; 114*d5731834SJed Brown PetscFunctionReturn(0); 115*d5731834SJed Brown } 116*d5731834SJed Brown 117*d5731834SJed Brown *id = h->base[1].id; 118*d5731834SJed Brown *val = h->base[1].value; 119*d5731834SJed Brown PetscFunctionReturn(0); 120*d5731834SJed Brown } 121*d5731834SJed Brown 122*d5731834SJed Brown #undef __FUNCT__ 123*d5731834SJed Brown #define __FUNCT__ "PetscHeapStash" 124*d5731834SJed Brown PetscErrorCode PetscHeapStash(PetscHeap h,PetscInt id,PetscInt val) 125*d5731834SJed Brown { 126*d5731834SJed Brown PetscInt loc; 127*d5731834SJed Brown 128*d5731834SJed Brown PetscFunctionBegin; 129*d5731834SJed Brown loc = --h->stash; 130*d5731834SJed Brown h->base[loc].id = id; 131*d5731834SJed Brown h->base[loc].value = val; 132*d5731834SJed Brown PetscFunctionReturn(0); 133*d5731834SJed Brown } 134*d5731834SJed Brown 135*d5731834SJed Brown #undef __FUNCT__ 136*d5731834SJed Brown #define __FUNCT__ "PetscHeapUnstash" 137*d5731834SJed Brown PetscErrorCode PetscHeapUnstash(PetscHeap h) 138*d5731834SJed Brown { 139*d5731834SJed Brown PetscErrorCode ierr; 140*d5731834SJed Brown 141*d5731834SJed Brown PetscFunctionBegin; 142*d5731834SJed Brown while (h->stash < h->alloc) { 143*d5731834SJed Brown PetscInt id = Id(h,h->stash),value = Value(h,h->stash); 144*d5731834SJed Brown h->stash++; 145*d5731834SJed Brown ierr = PetscHeapAdd(h,id,value);CHKERRQ(ierr); 146*d5731834SJed Brown } 147*d5731834SJed Brown PetscFunctionReturn(0); 148*d5731834SJed Brown } 149*d5731834SJed Brown 150*d5731834SJed Brown #undef __FUNCT__ 151*d5731834SJed Brown #define __FUNCT__ "PetscHeapDestroy" 152*d5731834SJed Brown PetscErrorCode PetscHeapDestroy(PetscHeap *heap) 153*d5731834SJed Brown { 154*d5731834SJed Brown PetscErrorCode ierr; 155*d5731834SJed Brown 156*d5731834SJed Brown PetscFunctionBegin; 157*d5731834SJed Brown ierr = PetscFree((*heap)->base);CHKERRQ(ierr); 158*d5731834SJed Brown ierr = PetscFree(*heap);CHKERRQ(ierr); 159*d5731834SJed Brown PetscFunctionReturn(0); 160*d5731834SJed Brown } 161*d5731834SJed Brown 162*d5731834SJed Brown #undef __FUNCT__ 163*d5731834SJed Brown #define __FUNCT__ "PetscHeapView" 164*d5731834SJed Brown PetscErrorCode PetscHeapView(PetscHeap h,PetscViewer viewer) 165*d5731834SJed Brown { 166*d5731834SJed Brown PetscErrorCode ierr; 167*d5731834SJed Brown PetscBool iascii; 168*d5731834SJed Brown 169*d5731834SJed Brown PetscFunctionBegin; 170*d5731834SJed Brown if (!viewer) { 171*d5731834SJed Brown ierr = PetscViewerASCIIGetStdout(PETSC_COMM_SELF,&viewer);CHKERRQ(ierr); 172*d5731834SJed Brown } 173*d5731834SJed Brown PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 174*d5731834SJed Brown ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 175*d5731834SJed Brown if (iascii) { 176*d5731834SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Heap size %D with %D stashed\n",h->end-1,h->alloc-h->stash);CHKERRQ(ierr); 177*d5731834SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Heap in (id,value) pairs\n");CHKERRQ(ierr); 178*d5731834SJed Brown ierr = PetscIntView(2*(h->end-1),(const PetscInt*)(h->base+1),viewer);CHKERRQ(ierr); 179*d5731834SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Stash in (id,value) pairs\n");CHKERRQ(ierr); 180*d5731834SJed Brown ierr = PetscIntView(2*(h->alloc-h->stash),(const PetscInt*)(h->base+h->stash),viewer);CHKERRQ(ierr); 181*d5731834SJed Brown } 182*d5731834SJed Brown PetscFunctionReturn(0); 183*d5731834SJed Brown } 184