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);