Formalize Debugging Structures
Currently debugging vs optimized is fairly static, consisting mostly of
./configure --with-debugging[=true/false]
While this structure provides pretty robust error checking if turned on, it can come at potentially significant performance cost (as noted rather emphatically by -log_view
), which makes debugging for problems occurring happening at extremely large scales cumbersome to track down. Other debugging tools/tips are also a lot harder to find/esoteric (for example PetscMallocDump()
or CHKMEMQ
or -check_pointer_intensity
), meaning they aren't usually used. To summarize:
The Problem
Debugging should be more easily discoverable and flexible. Additionally user defined debugging hooks are practically non-existent, in order to implement it requires changes to source and manually recompiling petsc.
Existing Solution
A very elegant way of handling this with proven performance capabilities is how the Vulkan graphics API handles debugging via so-called validation layers. Out of the box Vulkan does essentially zero error checking (not even for proper input data to functions), but validation layers provide a simple way to implement selective error checking. Examples include:
- the descriptor set state and pipeline state at each draw call are consistent
- pipelines are created correctly, known when used and bound at draw time
- descriptor sets are known and consist of valid types, formats, and layout
- descriptor set regions are valid, bound, and updated appropriately
- command buffers referenced are known and valid
- command sequencing for specific state dependencies and renderpass use is correct
- memory is available
- dynamic state is correctly set.
And those are just the most basic core validation layers. You can optionally create your own validation layers which you can hook in. The idea here is you can enable any combination of validation layers to specifically target suspected buggy areas (or turn them all on if you aren't sure), but waste cycles on unnecessary checks.