Actual source code: petscbt.h

  1: #pragma once

  3: #include <petscsystypes.h>
  4: #include <petscviewertypes.h>
  5: #include <petscstring.h>

  7: /* SUBMANSEC = Sys */

  9: /* convert an index i to an index suitable for indexing a PetscBT, such that
 10:  * bt[PetscBTIndex(i)] returns the i'th value of the bt */
 11: static inline size_t PetscBTIndex_Internal(PetscCount index)
 12: {
 13:   return (size_t)index / PETSC_BITS_PER_BYTE;
 14: }

 16: static inline PetscByte PetscBTMask_Internal(PetscCount index)
 17: {
 18:   return (PetscByte)(1 << index % PETSC_BITS_PER_BYTE);
 19: }

 21: /*@C
 22:   PetscBTLength - Returns the number of bytes needed to store a `PetscBT`

 24:   Not Collective; No Fortran Support

 26:   Input Parameter:
 27: . m  - the number of bits in `array`

 29:   Level: developer

 31: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTMemzero()`, `PetscBTLookup()`, `PetscBTLookupSet()`
 32: @*/
 33: static inline size_t PetscBTLength(PetscCount m)
 34: {
 35:   return (size_t)m / PETSC_BITS_PER_BYTE + 1;
 36: }

 38: /*@C
 39:   PetscBTMemzero - Zero the contents of a `PetscBT` (bit array), setting every bit to `0`

 41:   Not Collective; No Fortran Support

 43:   Input Parameters:
 44: + m     - the number of bits the array can hold
 45: - array - the `PetscBT` whose bits should be cleared

 47:   Level: developer

 49: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTDestroy()`, `PetscBTCopy()`
 50: @*/
 51: static inline PetscErrorCode PetscBTMemzero(PetscCount m, PetscBT array)
 52: {
 53:   return PetscArrayzero(array, PetscBTLength(m));
 54: }

 56: /*@C
 57:   PetscBTDestroy - Destroy a `PetscBT` (bit array) created with `PetscBTCreate()`, freeing its storage and setting the pointer to `NULL`

 59:   Not Collective; No Fortran Support

 61:   Input Parameter:
 62: . array - pointer to the `PetscBT` to destroy; `*array` is set to `NULL` on return

 64:   Level: developer

 66: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTMemzero()`
 67: @*/
 68: static inline PetscErrorCode PetscBTDestroy(PetscBT *array)
 69: {
 70:   return (*array) ? PetscFree(*array) : PETSC_SUCCESS;
 71: }

 73: /*@C
 74:   PetscBTCreate - Create a `PetscBT` (bit array) capable of storing `m` bits, with all bits initialized to `0`

 76:   Not Collective; No Fortran Support

 78:   Input Parameter:
 79: . m - the number of bits the array can hold

 81:   Output Parameter:
 82: . array - the newly created `PetscBT`

 84:   Level: developer

 86: .seealso: `PetscBT`, `PetscBTDestroy()`, `PetscBTMemzero()`, `PetscBTSet()`, `PetscBTLookup()`
 87: @*/
 88: static inline PetscErrorCode PetscBTCreate(PetscCount m, PetscBT *array)
 89: {
 90:   return PetscCalloc1(PetscBTLength(m), array);
 91: }

 93: /*@C
 94:   PetscBTCopy - Copy the contents of one `PetscBT` (bit array) into another

 96:   Not Collective; No Fortran Support

 98:   Input Parameters:
 99: + dest   - the destination `PetscBT`, which must already be allocated to hold at least `m` bits
100: . m      - the number of bits to copy
101: - source - the source `PetscBT` providing the bits

103:   Level: developer

105: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTMemzero()`
106: @*/
107: static inline PetscErrorCode PetscBTCopy(PetscBT dest, PetscCount m, PetscBT source)
108: {
109:   return PetscArraycpy(dest, source, PetscBTLength(m));
110: }

112: /*@C
113:   PetscBTLookup - Check if a particular bit in a `PetscBT` is set

115:   Not Collective; No Fortran Support

117:   Input Parameters:
118: + array - the `PetscBT`
119: - index - the bit index to check

121:   Level: developer

123: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTMemzero()`, `PetscBTLookupSet()`
124: @*/
125: static inline PetscByte PetscBTLookup(PetscBT array, PetscCount index)
126: {
127:   return array[PetscBTIndex_Internal(index)] & PetscBTMask_Internal(index);
128: }

130: /*@C
131:   PetscBTSet - Set the bit at a given index in a `PetscBT` (bit array) to `1`

133:   Not Collective; No Fortran Support

135:   Input Parameters:
136: + array - the `PetscBT`
137: - index - the bit index to set

139:   Level: developer

141: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTLookup()`, `PetscBTClear()`, `PetscBTNegate()`, `PetscBTLookupSet()`
142: @*/
143: static inline PetscErrorCode PetscBTSet(PetscBT array, PetscCount index)
144: {
145:   PetscFunctionBegin;
146:   array[PetscBTIndex_Internal(index)] |= PetscBTMask_Internal(index);
147:   PetscFunctionReturn(PETSC_SUCCESS);
148: }

150: /*@C
151:   PetscBTNegate - Flip (xor) the bit at a given index in a `PetscBT` (bit array)

153:   Not Collective; No Fortran Support

155:   Input Parameters:
156: + array - the `PetscBT`
157: - index - the bit index to flip

159:   Level: developer

161: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTSet()`, `PetscBTClear()`, `PetscBTLookup()`
162: @*/
163: static inline PetscErrorCode PetscBTNegate(PetscBT array, PetscCount index)
164: {
165:   PetscFunctionBegin;
166:   array[PetscBTIndex_Internal(index)] ^= PetscBTMask_Internal(index);
167:   PetscFunctionReturn(PETSC_SUCCESS);
168: }

170: /*@C
171:   PetscBTClear - Clear the bit at a given index in a `PetscBT` (bit array), setting it to `0`

173:   Not Collective; No Fortran Support

175:   Input Parameters:
176: + array - the `PetscBT`
177: - index - the bit index to clear

179:   Level: developer

181: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTSet()`, `PetscBTNegate()`, `PetscBTLookup()`
182: @*/
183: static inline PetscErrorCode PetscBTClear(PetscBT array, PetscCount index)
184: {
185:   PetscFunctionBegin;
186:   array[PetscBTIndex_Internal(index)] &= (PetscByte)~PetscBTMask_Internal(index);
187:   PetscFunctionReturn(PETSC_SUCCESS);
188: }

190: /*@C
191:   PetscBTLookupSet - Check if a particular bit in a `PetscBT` is set and then set it

193:   Not Collective; No Fortran Support

195:   Input Parameters:
196: + array - the `PetscBT`
197: - index - the bit index to check and set

199:   Level: developer

201: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTMemzero()`, `PetscBTLookup()`, `PetscBTLookupClear()`
202: @*/
203: static inline PetscByte PetscBTLookupSet(PetscBT array, PetscCount index)
204: {
205:   const PetscByte ret = PetscBTLookup(array, index);
206:   PetscCallContinue(PetscBTSet(array, index));
207:   return ret;
208: }

210: /*@C
211:   PetscBTLookupClear - Check if a particular bit in a `PetscBT` is set and then clear it

213:   Not Collective; No Fortran Support

215:   Input Parameters:
216: + array - the `PetscBT`
217: - index - the bit index to check and clear

219:   Level: developer

221: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTMemzero()`, `PetscBTLookup()`, `PetscBTLookupSet()`
222: @*/
223: static inline PetscByte PetscBTLookupClear(PetscBT array, PetscCount index)
224: {
225:   const PetscByte ret = PetscBTLookup(array, index);
226:   PetscCallContinue(PetscBTClear(array, index));
227:   return ret;
228: }

230: /*@C
231:   PetscBTCountSet - Count the number of bits that are set in a `PetscBT`

233:   Not Collective; No Fortran Support

235:   Input Parameters:
236: + array - the `PetscBT`
237: - m     - the number of bits in `array`

239:   Level: developer

241: .seealso: `PetscBT`, `PetscBTCreate()`, `PetscBTMemzero()`, `PetscBTLookup()`, `PetscBTLookupSet()`
242: @*/
243: static inline PetscCount PetscBTCountSet(PetscBT array, PetscCount m)
244: {
245:   PetscCount cnt = 0;
246:   for (size_t j = 0; j < PetscBTLength(m); j++) {
247:     PetscByte       byte = array[j];
248:     const PetscByte c1   = 0x55;
249:     const PetscByte c2   = 0x33;
250:     const PetscByte c4   = 0x0F;

252:     byte -= (byte >> 1) & c1;
253:     byte = ((byte >> 2) & c2) + (byte & c2);
254:     cnt += (byte + (byte >> 4)) & c4;
255:   }
256:   return cnt;
257: }

259: PETSC_EXTERN PetscErrorCode PetscBTView(PetscCount, const PetscBT, PetscViewer);