Actual source code: petscbt.h

  1: #pragma once

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

  6: /* SUBMANSEC = Sys */

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

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

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

 23:   Not Collective; No Fortran Support

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

 28:   Level: developer

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

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

 40:   Not Collective; No Fortran Support

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

 46:   Level: developer

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

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

 58:   Not Collective; No Fortran Support

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

 63:   Level: developer

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

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

 75:   Not Collective; No Fortran Support

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

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

 83:   Level: developer

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

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

 95:   Not Collective; No Fortran Support

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

102:   Level: developer

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

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

114:   Not Collective; No Fortran Support

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

120:   Level: developer

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

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

132:   Not Collective; No Fortran Support

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

138:   Level: developer

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

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

152:   Not Collective; No Fortran Support

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

158:   Level: developer

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

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

172:   Not Collective; No Fortran Support

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

178:   Level: developer

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

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

192:   Not Collective; No Fortran Support

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

198:   Level: developer

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

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

212:   Not Collective; No Fortran Support

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

218:   Level: developer

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

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

232:   Not Collective; No Fortran Support

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

238:   Level: developer

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

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

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