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