Actual source code: petscmem.h

  1: #pragma once

  3: /* SUBMANSEC = Sys */

  5: #include <petscsystypes.h>
  6: #include <petscmacros.h>

  8: #include <stdio.h> // FILE used by PetscMallocDump()/PetscMallocView()

 10: /*MC
 11:    PetscMalloc - Allocates memory for use with PETSc. One should use `PetscNew()`, `PetscMalloc1()` or `PetscCalloc1()` usually instead of `PetscMalloc()`

 13:    Synopsis:
 14: #include <petscsys.h>
 15:    PetscErrorCode PetscMalloc(size_t m, void **result)

 17:    Not Collective

 19:    Input Parameter:
 20: .  m - number of bytes to allocate

 22:    Output Parameter:
 23: .  result - memory allocated

 25:    Level: beginner

 27:    Notes:
 28:    Memory is always allocated at least double aligned

 30:    It is safe to allocate with an m of 0 and pass the resulting pointer to `PetscFree()`.
 31:    However, the pointer should never be dereferenced or the program will crash.

 33:    Developer Note:
 34:    All the `PetscMallocN()` routines actually call `PetscMalloc()` behind the scenes.

 36:    Except for data structures that store information about the PETSc options database all memory allocated by PETSc is
 37:    obtained with `PetscMalloc()` or `PetscCalloc()`

 39: .seealso: `PetscFree()`, `PetscNew()`, `PetscCalloc()`
 40: M*/
 41: #define PetscMalloc(a, b) ((*PetscTrMalloc)((a), PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void **)(b)))

 43: /*MC
 44:    PetscRealloc - Reallocates memory

 46:    Synopsis:
 47: #include <petscsys.h>
 48:    PetscErrorCode PetscRealloc(size_t m, void **result)

 50:    Not Collective

 52:    Input Parameters:
 53: +  m      - number of bytes to allocate
 54: -  result - previous memory

 56:    Output Parameter:
 57: .  result - new memory allocated

 59:    Level: developer

 61:    Notes:
 62:    `results` must have already been obtained with `PetscMalloc()`

 64:    Memory is always allocated at least double aligned

 66: .seealso: `PetscMalloc()`, `PetscFree()`, `PetscNew()`
 67: M*/
 68: #define PetscRealloc(a, b) ((*PetscTrRealloc)((a), __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void **)(b)))

 70: /*MC
 71:    PetscAddrAlign - Rounds up an address to `PETSC_MEMALIGN` alignment

 73:    Synopsis:
 74: #include <petscsys.h>
 75:    void *PetscAddrAlign(void *addr)

 77:    Not Collective

 79:    Input Parameter:
 80: .  addr - address to align (any pointer type)

 82:    Level: developer

 84: .seealso: `PetscMallocAlign()`
 85: M*/
 86: #define PetscAddrAlign(a) ((void *)((((PETSC_UINTPTR_T)(a)) + (PETSC_MEMALIGN - 1)) & ~(PETSC_MEMALIGN - 1)))

 88: /*MC
 89:    PetscCalloc - Allocates a cleared (zeroed) memory region aligned to `PETSC_MEMALIGN`, similar to `PetscMalloc()`

 91:    Synopsis:
 92: #include <petscsys.h>
 93:    PetscErrorCode PetscCalloc(size_t m, void **result)

 95:    Not Collective

 97:    Input Parameter:
 98: .  m - number of bytes to allocate

100:    Output Parameter:
101: .  result - memory allocated

103:    Level: beginner

105:    Notes:
106:    Memory is always allocated at least double aligned. This macro is useful in allocating memory pointed by void pointers

108:    It is safe to allocate with an m of 0 and pass the resulting pointer to `PetscFree()`.

110:    However, the pointer should never be dereferenced or the program will crash.

112:    Developer Note:
113:    All `PetscCallocN()` routines call `PetscCalloc()` behind the scenes.

115: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`
116: M*/
117: #define PetscCalloc(m, result) PetscMallocA(1, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)m), (void *)(result))

119: /*MC
120:    PetscMalloc1 - Allocates an array of memory aligned to `PETSC_MEMALIGN`

122:    Synopsis:
123: #include <petscsys.h>
124:    PetscErrorCode PetscMalloc1(size_t m1, type **r1)

126:    Not Collective

128:    Input Parameter:
129: .  m1 - number of elements to allocate  (may be zero)

131:    Output Parameter:
132: .  r1 - memory allocated

134:    Level: beginner

136:    Note:
137:    This uses `sizeof()` of the memory type requested to determine the total memory to be allocated; therefore, you should not
138:    multiply the number of elements requested by the `sizeof()` the type. For example, use
139: .vb
140:   PetscInt *id;
141:   PetscMalloc1(10,&id);
142: .ve
143:        not
144: .vb
145:   PetscInt *id;
146:   PetscMalloc1(10*sizeof(PetscInt),&id);
147: .ve

149:   Does not zero the memory allocated, use `PetscCalloc1()` to obtain memory that has been zeroed.

151:   The `PetscMalloc[N]()` and `PetscCalloc[N]()` take an argument of type `size_t`! However, most codes use `value`, computed via `int` or `PetscInt` variables. This can overflow in
152:   32bit `int` computation - while computation in 64bit `size_t` would not overflow!
153:   It's best if any arithmetic that is done for size computations is done with `size_t` type - avoiding arithmetic overflow!

155:   `PetscMalloc[N]()` and `PetscCalloc[N]()` attempt to work-around this by casting the first variable to `size_t`.
156:   This works for most expressions, but not all, such as
157: .vb
158:   PetscInt *id, a, b;
159:   PetscMalloc1(use_a_squared ? a * a * b : a * b, &id); // use_a_squared is cast to size_t, but a and b are still PetscInt
160:   PetscMalloc1(a + b * b, &id); // a is cast to size_t, but b * b is performed at PetscInt precision first due to order-of-operations
161: .ve

163:   These expressions should either be avoided, or appropriately cast variables to `size_t`:
164: .vb
165:   PetscInt *id, a, b;
166:   PetscMalloc1(use_a_squared ? (size_t)a * a * b : (size_t)a * b, &id); // Cast a to size_t before multiplication
167:   PetscMalloc1(b * b + a, &id); // b is automatically cast to size_t and order-of-operations ensures size_t precision is maintained
168: .ve

170: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscCalloc1()`, `PetscMalloc2()`
171: M*/
172: #define PetscMalloc1(m1, r1) PetscMallocA(1, PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1))

174: /*MC
175:    PetscCalloc1 - Allocates a cleared (zeroed) array of memory aligned to `PETSC_MEMALIGN`

177:    Synopsis:
178: #include <petscsys.h>
179:    PetscErrorCode PetscCalloc1(size_t m1, type **r1)

181:    Not Collective

183:    Input Parameter:
184: .  m1 - number of elements to allocate in 1st chunk  (may be zero)

186:    Output Parameter:
187: .  r1 - memory allocated

189:    Level: beginner

191:    Note:
192:    See `PetscMalloc1()` for more details on usage.

194: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc1()`, `PetscCalloc2()`
195: M*/
196: #define PetscCalloc1(m1, r1) PetscMallocA(1, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1))

198: /*MC
199:    PetscMalloc2 - Allocates 2 arrays of memory both aligned to `PETSC_MEMALIGN`

201:    Synopsis:
202: #include <petscsys.h>
203:    PetscErrorCode PetscMalloc2(size_t m1, type **r1, size_t m2, type **r2)

205:    Not Collective

207:    Input Parameters:
208: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
209: -  m2 - number of elements to allocate in 2nd chunk  (may be zero)

211:    Output Parameters:
212: +  r1 - memory allocated in first chunk
213: -  r2 - memory allocated in second chunk

215:    Level: developer

217: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc1()`, `PetscCalloc2()`
218: M*/
219: #define PetscMalloc2(m1, r1, m2, r2) PetscMallocA(2, PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2))

221: /*MC
222:    PetscCalloc2 - Allocates 2 cleared (zeroed) arrays of memory both aligned to `PETSC_MEMALIGN`

224:    Synopsis:
225: #include <petscsys.h>
226:    PetscErrorCode PetscCalloc2(size_t m1, type **r1, size_t m2, type **r2)

228:    Not Collective

230:    Input Parameters:
231: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
232: -  m2 - number of elements to allocate in 2nd chunk  (may be zero)

234:    Output Parameters:
235: +  r1 - memory allocated in first chunk
236: -  r2 - memory allocated in second chunk

238:    Level: developer

240: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscCalloc1()`, `PetscMalloc2()`
241: M*/
242: #define PetscCalloc2(m1, r1, m2, r2) PetscMallocA(2, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2))

244: /*MC
245:    PetscMalloc3 - Allocates 3 arrays of memory, all aligned to `PETSC_MEMALIGN`

247:    Synopsis:
248: #include <petscsys.h>
249:    PetscErrorCode PetscMalloc3(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3)

251:    Not Collective

253:    Input Parameters:
254: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
255: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
256: -  m3 - number of elements to allocate in 3rd chunk  (may be zero)

258:    Output Parameters:
259: +  r1 - memory allocated in first chunk
260: .  r2 - memory allocated in second chunk
261: -  r3 - memory allocated in third chunk

263:    Level: developer

265: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscCalloc3()`, `PetscFree3()`
266: M*/
267: #define PetscMalloc3(m1, r1, m2, r2, m3, r3) \
268:   PetscMallocA(3, PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3))

270: /*MC
271:    PetscCalloc3 - Allocates 3 cleared (zeroed) arrays of memory, all aligned to `PETSC_MEMALIGN`

273:    Synopsis:
274: #include <petscsys.h>
275:    PetscErrorCode PetscCalloc3(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3)

277:    Not Collective

279:    Input Parameters:
280: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
281: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
282: -  m3 - number of elements to allocate in 3rd chunk  (may be zero)

284:    Output Parameters:
285: +  r1 - memory allocated in first chunk
286: .  r2 - memory allocated in second chunk
287: -  r3 - memory allocated in third chunk

289:    Level: developer

291: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscCalloc2()`, `PetscMalloc3()`, `PetscFree3()`
292: M*/
293: #define PetscCalloc3(m1, r1, m2, r2, m3, r3) \
294:   PetscMallocA(3, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3))

296: /*MC
297:    PetscMalloc4 - Allocates 4 arrays of memory, all aligned to `PETSC_MEMALIGN`

299:    Synopsis:
300: #include <petscsys.h>
301:    PetscErrorCode PetscMalloc4(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4)

303:    Not Collective

305:    Input Parameters:
306: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
307: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
308: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
309: -  m4 - number of elements to allocate in 4th chunk  (may be zero)

311:    Output Parameters:
312: +  r1 - memory allocated in first chunk
313: .  r2 - memory allocated in second chunk
314: .  r3 - memory allocated in third chunk
315: -  r4 - memory allocated in fourth chunk

317:    Level: developer

319: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscCalloc4()`, `PetscFree4()`
320: M*/
321: #define PetscMalloc4(m1, r1, m2, r2, m3, r3, m4, r4) \
322:   PetscMallocA(4, PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4))

324: /*MC
325:    PetscCalloc4 - Allocates 4 cleared (zeroed) arrays of memory, all aligned to `PETSC_MEMALIGN`

327:    Synopsis:
328: #include <petscsys.h>
329:    PetscErrorCode PetscCalloc4(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4)

331:    Not Collective

333:    Input Parameters:
334: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
335: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
336: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
337: -  m4 - number of elements to allocate in 4th chunk  (may be zero)

339:    Output Parameters:
340: +  r1 - memory allocated in first chunk
341: .  r2 - memory allocated in second chunk
342: .  r3 - memory allocated in third chunk
343: -  r4 - memory allocated in fourth chunk

345:    Level: developer

347: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscCalloc4()`, `PetscFree4()`
348: M*/
349: #define PetscCalloc4(m1, r1, m2, r2, m3, r3, m4, r4) \
350:   PetscMallocA(4, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4))

352: /*MC
353:    PetscMalloc5 - Allocates 5 arrays of memory, all aligned to `PETSC_MEMALIGN`

355:    Synopsis:
356: #include <petscsys.h>
357:    PetscErrorCode PetscMalloc5(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4, size_t m5, type **r5)

359:    Not Collective

361:    Input Parameters:
362: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
363: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
364: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
365: .  m4 - number of elements to allocate in 4th chunk  (may be zero)
366: -  m5 - number of elements to allocate in 5th chunk  (may be zero)

368:    Output Parameters:
369: +  r1 - memory allocated in first chunk
370: .  r2 - memory allocated in second chunk
371: .  r3 - memory allocated in third chunk
372: .  r4 - memory allocated in fourth chunk
373: -  r5 - memory allocated in fifth chunk

375:    Level: developer

377: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscCalloc5()`, `PetscFree5()`
378: M*/
379: #define PetscMalloc5(m1, r1, m2, r2, m3, r3, m4, r4, m5, r5) \
380:   PetscMallocA(5, PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4), ((size_t)((size_t)m5) * sizeof(**(r5))), (r5))

382: /*MC
383:    PetscCalloc5 - Allocates 5 cleared (zeroed) arrays of memory, all aligned to `PETSC_MEMALIGN`

385:    Synopsis:
386: #include <petscsys.h>
387:    PetscErrorCode PetscCalloc5(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4, size_t m5, type **r5)

389:    Not Collective

391:    Input Parameters:
392: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
393: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
394: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
395: .  m4 - number of elements to allocate in 4th chunk  (may be zero)
396: -  m5 - number of elements to allocate in 5th chunk  (may be zero)

398:    Output Parameters:
399: +  r1 - memory allocated in first chunk
400: .  r2 - memory allocated in second chunk
401: .  r3 - memory allocated in third chunk
402: .  r4 - memory allocated in fourth chunk
403: -  r5 - memory allocated in fifth chunk

405:    Level: developer

407: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc5()`, `PetscFree5()`
408: M*/
409: #define PetscCalloc5(m1, r1, m2, r2, m3, r3, m4, r4, m5, r5) \
410:   PetscMallocA(5, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4), ((size_t)((size_t)m5) * sizeof(**(r5))), (r5))

412: /*MC
413:    PetscMalloc6 - Allocates 6 arrays of memory, all aligned to `PETSC_MEMALIGN`

415:    Synopsis:
416: #include <petscsys.h>
417:    PetscErrorCode PetscMalloc6(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4, size_t m5, type **r5, size_t m6, type **r6)

419:    Not Collective

421:    Input Parameters:
422: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
423: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
424: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
425: .  m4 - number of elements to allocate in 4th chunk  (may be zero)
426: .  m5 - number of elements to allocate in 5th chunk  (may be zero)
427: -  m6 - number of elements to allocate in 6th chunk  (may be zero)

429:    Output Parameteasr:
430: +  r1 - memory allocated in first chunk
431: .  r2 - memory allocated in second chunk
432: .  r3 - memory allocated in third chunk
433: .  r4 - memory allocated in fourth chunk
434: .  r5 - memory allocated in fifth chunk
435: -  r6 - memory allocated in sixth chunk

437:    Level: developer

439: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscCalloc6()`, `PetscFree3()`, `PetscFree4()`, `PetscFree5()`, `PetscFree6()`
440: M*/
441: #define PetscMalloc6(m1, r1, m2, r2, m3, r3, m4, r4, m5, r5, m6, r6) \
442:   PetscMallocA(6, PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4), ((size_t)((size_t)m5) * sizeof(**(r5))), (r5), ((size_t)((size_t)m6) * sizeof(**(r6))), (r6))

444: /*MC
445:    PetscCalloc6 - Allocates 6 cleared (zeroed) arrays of memory, all aligned to `PETSC_MEMALIGN`

447:    Synopsis:
448: #include <petscsys.h>
449:    PetscErrorCode PetscCalloc6(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4, size_t m5, type **r5, size_t m6, type **r6)

451:    Not Collective

453:    Input Parameters:
454: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
455: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
456: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
457: .  m4 - number of elements to allocate in 4th chunk  (may be zero)
458: .  m5 - number of elements to allocate in 5th chunk  (may be zero)
459: -  m6 - number of elements to allocate in 6th chunk  (may be zero)

461:    Output Parameters:
462: +  r1 - memory allocated in first chunk
463: .  r2 - memory allocated in second chunk
464: .  r3 - memory allocated in third chunk
465: .  r4 - memory allocated in fourth chunk
466: .  r5 - memory allocated in fifth chunk
467: -  r6 - memory allocated in sixth chunk

469:    Level: developer

471: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscMalloc6()`, `PetscFree6()`
472: M*/
473: #define PetscCalloc6(m1, r1, m2, r2, m3, r3, m4, r4, m5, r5, m6, r6) \
474:   PetscMallocA(6, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4), ((size_t)((size_t)m5) * sizeof(**(r5))), (r5), ((size_t)((size_t)m6) * sizeof(**(r6))), (r6))

476: /*MC
477:    PetscMalloc7 - Allocates 7 arrays of memory, all aligned to `PETSC_MEMALIGN`

479:    Synopsis:
480: #include <petscsys.h>
481:    PetscErrorCode PetscMalloc7(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4, size_t m5, type **r5, size_t m6, type **r6, size_t m7, type **r7)

483:    Not Collective

485:    Input Parameters:
486: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
487: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
488: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
489: .  m4 - number of elements to allocate in 4th chunk  (may be zero)
490: .  m5 - number of elements to allocate in 5th chunk  (may be zero)
491: .  m6 - number of elements to allocate in 6th chunk  (may be zero)
492: -  m7 - number of elements to allocate in 7th chunk  (may be zero)

494:    Output Parameters:
495: +  r1 - memory allocated in first chunk
496: .  r2 - memory allocated in second chunk
497: .  r3 - memory allocated in third chunk
498: .  r4 - memory allocated in fourth chunk
499: .  r5 - memory allocated in fifth chunk
500: .  r6 - memory allocated in sixth chunk
501: -  r7 - memory allocated in seventh chunk

503:    Level: developer

505: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscCalloc7()`, `PetscFree7()`
506: M*/
507: #define PetscMalloc7(m1, r1, m2, r2, m3, r3, m4, r4, m5, r5, m6, r6, m7, r7) \
508:   PetscMallocA(7, PETSC_FALSE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4), ((size_t)((size_t)m5) * sizeof(**(r5))), (r5), ((size_t)((size_t)m6) * sizeof(**(r6))), (r6), ((size_t)((size_t)m7) * sizeof(**(r7))), (r7))

510: /*MC
511:    PetscCalloc7 - Allocates 7 cleared (zeroed) arrays of memory, all aligned to `PETSC_MEMALIGN`

513:    Synopsis:
514: #include <petscsys.h>
515:    PetscErrorCode PetscCalloc7(size_t m1, type **r1, size_t m2, type **r2, size_t m3, type **r3, size_t m4, type **r4, size_t m5, type **r5, size_t m6, type **r6, size_t m7, type **r7)

517:    Not Collective

519:    Input Parameters:
520: +  m1 - number of elements to allocate in 1st chunk  (may be zero)
521: .  m2 - number of elements to allocate in 2nd chunk  (may be zero)
522: .  m3 - number of elements to allocate in 3rd chunk  (may be zero)
523: .  m4 - number of elements to allocate in 4th chunk  (may be zero)
524: .  m5 - number of elements to allocate in 5th chunk  (may be zero)
525: .  m6 - number of elements to allocate in 6th chunk  (may be zero)
526: -  m7 - number of elements to allocate in 7th chunk  (may be zero)

528:    Output Parameters:
529: +  r1 - memory allocated in first chunk
530: .  r2 - memory allocated in second chunk
531: .  r3 - memory allocated in third chunk
532: .  r4 - memory allocated in fourth chunk
533: .  r5 - memory allocated in fifth chunk
534: .  r6 - memory allocated in sixth chunk
535: -  r7 - memory allocated in seventh chunk

537:    Level: developer

539: .seealso: `PetscFree()`, `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscMalloc7()`, `PetscFree7()`
540: M*/
541: #define PetscCalloc7(m1, r1, m2, r2, m3, r3, m4, r4, m5, r5, m6, r6, m7, r7) \
542:   PetscMallocA(7, PETSC_TRUE, __LINE__, PETSC_FUNCTION_NAME, __FILE__, ((size_t)((size_t)m1) * sizeof(**(r1))), (void *)(r1), ((size_t)((size_t)m2) * sizeof(**(r2))), (r2), ((size_t)((size_t)m3) * sizeof(**(r3))), (r3), ((size_t)((size_t)m4) * sizeof(**(r4))), (r4), ((size_t)((size_t)m5) * sizeof(**(r5))), (r5), ((size_t)((size_t)m6) * sizeof(**(r6))), (r6), ((size_t)((size_t)m7) * sizeof(**(r7))), (r7))

544: /*MC
545:    PetscNew - Allocates memory of a particular type, zeros the memory! Aligned to `PETSC_MEMALIGN`

547:    Synopsis:
548: #include <petscsys.h>
549:    PetscErrorCode PetscNew(type **result)

551:    Not Collective

553:    Output Parameter:
554: .  result - memory allocated, sized to match pointer `type`

556:    Level: beginner

558:    Developer Note:
559:    Calls `PetscCalloc()` with the appropriate memory size obtained from `type`

561: .seealso: `PetscFree()`, `PetscMalloc()`, `PetscCall()`, `PetscCalloc1()`, `PetscMalloc1()`
562: M*/
563: #define PetscNew(b) PetscCalloc1(1, (b))

565: /*MC
566:    PetscNewLog - Deprecated alias for `PetscNew()`; previously logged the allocation against a `PetscObject`

568:    Synopsis:
569: #include <petscsys.h>
570:    PetscErrorCode PetscNewLog(PetscObject obj, type **result)

572:    Not Collective

574:    Input Parameter:
575: .  obj - the `PetscObject` to which the allocation used to be charged (now ignored)

577:    Output Parameter:
578: .  result - the newly allocated memory, sized to match `type`

580:    Level: deprecated

582:    Note:
583:    This macro is retained only for source compatibility. Use `PetscNew()` instead; PETSc no longer associates allocations with a specific `PetscObject`.

585: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscCalloc1()`, `PetscFree()`
586: M*/
587: #define PetscNewLog(o, b) PETSC_DEPRECATED_MACRO(3, 18, 0, "PetscNew()", ) PetscNew(b)

589: /*MC
590:    PetscFree - Frees memory

592:    Synopsis:
593: #include <petscsys.h>
594:    PetscErrorCode PetscFree(void *memory)

596:    Not Collective

598:    Input Parameter:
599: .   memory - memory to free (the pointer is ALWAYS set to `NULL` upon success)

601:    Level: beginner

603:    Notes:
604:    Do not free memory obtained with `PetscMalloc2()`, `PetscCalloc2()` etc, they must be freed with `PetscFree2()` etc.

606:    It is safe to call `PetscFree()` on a `NULL` pointer.

608: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscMalloc1()`, `PetscCalloc1()`
609: M*/
610: #define PetscFree(a) ((PetscErrorCode)((*PetscTrFree)((void *)(a), __LINE__, PETSC_FUNCTION_NAME, __FILE__) || ((a) = PETSC_NULLPTR, PETSC_SUCCESS)))

612: /*MC
613:    PetscFree2 - Frees 2 chunks of memory obtained with `PetscMalloc2()`

615:    Synopsis:
616: #include <petscsys.h>
617:    PetscErrorCode PetscFree2(void *memory1, void *memory2)

619:    Not Collective

621:    Input Parameters:
622: +   memory1 - memory to free
623: -   memory2 - 2nd memory to free

625:    Level: developer

627:    Notes:
628:     Memory must have been obtained with `PetscMalloc2()`

630:     The arguments need to be in the same order as they were in the call to `PetscMalloc2()`

632: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscFree()`
633: M*/
634: #define PetscFree2(m1, m2) PetscFreeA(2, __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void *)&(m1), &(m2))

636: /*MC
637:    PetscFree3 - Frees 3 chunks of memory obtained with `PetscMalloc3()`

639:    Synopsis:
640: #include <petscsys.h>
641:    PetscErrorCode PetscFree3(void *memory1, void *memory2, void *memory3)

643:    Not Collective

645:    Input Parameters:
646: +   memory1 - memory to free
647: .   memory2 - 2nd memory to free
648: -   memory3 - 3rd memory to free

650:    Level: developer

652:    Notes:
653:     Memory must have been obtained with `PetscMalloc3()`

655:     The arguments need to be in the same order as they were in the call to `PetscMalloc3()`

657: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscFree()`, `PetscMalloc3()`
658: M*/
659: #define PetscFree3(m1, m2, m3) PetscFreeA(3, __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void *)&(m1), &(m2), &(m3))

661: /*MC
662:    PetscFree4 - Frees 4 chunks of memory obtained with `PetscMalloc4()`

664:    Synopsis:
665: #include <petscsys.h>
666:    PetscErrorCode PetscFree4(void *m1, void *m2, void *m3, void *m4)

668:    Not Collective

670:    Input Parameters:
671: +   m1 - memory to free
672: .   m2 - 2nd memory to free
673: .   m3 - 3rd memory to free
674: -   m4 - 4th memory to free

676:    Level: developer

678:    Notes:
679:     Memory must have been obtained with `PetscMalloc4()`

681:     The arguments need to be in the same order as they were in the call to `PetscMalloc4()`

683: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscFree()`, `PetscMalloc3()`, `PetscMalloc4()`
684: M*/
685: #define PetscFree4(m1, m2, m3, m4) PetscFreeA(4, __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void *)&(m1), &(m2), &(m3), &(m4))

687: /*MC
688:    PetscFree5 - Frees 5 chunks of memory obtained with `PetscMalloc5()`

690:    Synopsis:
691: #include <petscsys.h>
692:    PetscErrorCode PetscFree5(void *m1, void *m2, void *m3, void *m4, void *m5)

694:    Not Collective

696:    Input Parameters:
697: +   m1 - memory to free
698: .   m2 - 2nd memory to free
699: .   m3 - 3rd memory to free
700: .   m4 - 4th memory to free
701: -   m5 - 5th memory to free

703:    Level: developer

705:    Notes:
706:     Memory must have been obtained with `PetscMalloc5()`

708:     The arguments need to be in the same order as they were in the call to `PetscMalloc5()`

710: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscFree()`, `PetscMalloc3()`, `PetscMalloc4()`, `PetscMalloc5()`
711: M*/
712: #define PetscFree5(m1, m2, m3, m4, m5) PetscFreeA(5, __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void *)&(m1), &(m2), &(m3), &(m4), &(m5))

714: /*MC
715:    PetscFree6 - Frees 6 chunks of memory obtained with `PetscMalloc6()`

717:    Synopsis:
718: #include <petscsys.h>
719:    PetscErrorCode PetscFree6(void *m1, void *m2, void *m3, void *m4, void *m5, void *m6)

721:    Not Collective

723:    Input Parameters:
724: +   m1 - memory to free
725: .   m2 - 2nd memory to free
726: .   m3 - 3rd memory to free
727: .   m4 - 4th memory to free
728: .   m5 - 5th memory to free
729: -   m6 - 6th memory to free

731:    Level: developer

733:    Notes:
734:     Memory must have been obtained with `PetscMalloc6()`

736:     The arguments need to be in the same order as they were in the call to `PetscMalloc6()`

738: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscFree()`, `PetscMalloc3()`, `PetscMalloc4()`, `PetscMalloc5()`, `PetscMalloc6()`
739: M*/
740: #define PetscFree6(m1, m2, m3, m4, m5, m6) PetscFreeA(6, __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void *)&(m1), &(m2), &(m3), &(m4), &(m5), &(m6))

742: /*MC
743:    PetscFree7 - Frees 7 chunks of memory obtained with `PetscMalloc7()`

745:    Synopsis:
746: #include <petscsys.h>
747:    PetscErrorCode PetscFree7(void *m1, void *m2, void *m3, void *m4, void *m5, void *m6, void *m7)

749:    Not Collective

751:    Input Parameters:
752: +   m1 - memory to free
753: .   m2 - 2nd memory to free
754: .   m3 - 3rd memory to free
755: .   m4 - 4th memory to free
756: .   m5 - 5th memory to free
757: .   m6 - 6th memory to free
758: -   m7 - 7th memory to free

760:    Level: developer

762:    Notes:
763:     Memory must have been obtained with `PetscMalloc7()`

765:     The arguments need to be in the same order as they were in the call to `PetscMalloc7()`

767: .seealso: `PetscNew()`, `PetscMalloc()`, `PetscMalloc2()`, `PetscFree()`, `PetscMalloc3()`, `PetscMalloc4()`, `PetscMalloc5()`, `PetscMalloc6()`,
768:           `PetscMalloc7()`
769: M*/
770: #define PetscFree7(m1, m2, m3, m4, m5, m6, m7) PetscFreeA(7, __LINE__, PETSC_FUNCTION_NAME, __FILE__, (void *)&(m1), &(m2), &(m3), &(m4), &(m5), &(m6), &(m7))

772: PETSC_EXTERN PetscErrorCode PetscMallocA(int, PetscBool, int, const char *, const char *, size_t, void *, ...);
773: PETSC_EXTERN PetscErrorCode PetscFreeA(int, int, const char *, const char *, void *, ...);
774: PETSC_EXTERN PetscErrorCode (*PetscTrMalloc)(size_t, PetscBool, int, const char[], const char[], void **);
775: PETSC_EXTERN PetscErrorCode (*PetscTrFree)(void *, int, const char[], const char[]);
776: PETSC_EXTERN PetscErrorCode (*PetscTrRealloc)(size_t, int, const char[], const char[], void **);
777: PETSC_EXTERN PetscErrorCode PetscMallocSetCoalesce(PetscBool);
778: PETSC_EXTERN PetscErrorCode PetscMallocSet(PetscErrorCode (*)(size_t, PetscBool, int, const char[], const char[], void **), PetscErrorCode (*)(void *, int, const char[], const char[]), PetscErrorCode (*)(size_t, int, const char[], const char[], void **));
779: PETSC_EXTERN PetscErrorCode PetscMallocClear(void);

781: /*
782:   Unlike PetscMallocSet and PetscMallocClear which overwrite the existing settings, these two functions save the previous choice of allocator, and should be used in pair.
783: */
784: PETSC_EXTERN PetscErrorCode PetscMallocSetDRAM(void);
785: PETSC_EXTERN PetscErrorCode PetscMallocResetDRAM(void);
786: #if PetscDefined(HAVE_CUDA)
787: PETSC_EXTERN PetscErrorCode PetscMallocSetCUDAHost(void);
788: PETSC_EXTERN PetscErrorCode PetscMallocResetCUDAHost(void);
789: #endif
790: #if PetscDefined(HAVE_HIP)
791: PETSC_EXTERN PetscErrorCode PetscMallocSetHIPHost(void);
792: PETSC_EXTERN PetscErrorCode PetscMallocResetHIPHost(void);
793: #endif

795: /*
796:    Routines for tracing memory corruption/bleeding with default PETSc memory allocation
797: */
798: PETSC_EXTERN PetscErrorCode PetscMallocDump(FILE *);
799: PETSC_EXTERN PetscErrorCode PetscMallocView(FILE *);
800: PETSC_EXTERN PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble *);
801: PETSC_EXTERN PetscErrorCode PetscMallocGetMaximumUsage(PetscLogDouble *);
802: PETSC_EXTERN PetscErrorCode PetscMallocPushMaximumUsage(int);
803: PETSC_EXTERN PetscErrorCode PetscMallocPopMaximumUsage(int, PetscLogDouble *);
804: PETSC_EXTERN PetscErrorCode PetscMallocSetDebug(PetscBool, PetscBool);
805: PETSC_EXTERN PetscErrorCode PetscMallocGetDebug(PetscBool *, PetscBool *, PetscBool *);
806: PETSC_EXTERN PetscErrorCode PetscMallocValidate(int, const char[], const char[]);
807: PETSC_EXTERN PetscErrorCode PetscMallocViewSet(PetscLogDouble);
808: PETSC_EXTERN PetscErrorCode PetscMallocViewGet(PetscBool *);
809: PETSC_EXTERN PetscErrorCode PetscMallocLogRequestedSizeSet(PetscBool);
810: PETSC_EXTERN PetscErrorCode PetscMallocLogRequestedSizeGet(PetscBool *);