ADRs/0032- CPP Debugging.md
Implemented
Proposed by: Adam Gibson (20-11-2024) Discussed with: Paul Dubs
We need a way to provide debugging utilities for C++ code in the nd4j library. These utilities help in identifying issues such as out-of-bounds crashes and unexpected behavior in mathematical operations. The goal is to have a set of tools that can be easily enabled or disabled via configuration flags.
We implement three distinct debugging utilities that can be controlled through configuration flags:
Each utility serves a specific debugging purpose and can be independently enabled or disabled through both Maven and CMake configuration.
<!-- Print Indices Configuration -->
<libnd4j.printindices>OFF</libnd4j.printindices>
<!-- Print Math Configuration -->
<libnd4j.printmath>OFF</libnd4j.printmath>
<!-- Preprocessor Configuration -->
<libnd4j.preprocess>OFF</libnd4j.preprocess>
The utilities are integrated into the build system through a shell script that configures CMake. The script:
echo PRINT_INDICES = "$PRINT_INDICES"
echo PRINT_MATH = "$PRINT_MATH"
echo PREPROCESS = "$PREPROCESS"
eval "$CMAKE_COMMAND" \
-DPRINT_MATH="$PRINT_MATH" \
-DPRINT_INDICES="$PRINT_INDICES" \
# ... other CMake configurations
if [ "$PREPROCESS" == "ON" ]; then
# Re-run CMake with preprocessing enabled
eval "$CMAKE_COMMAND" \
-DPRINT_MATH="$PRINT_MATH" \
-DPRINT_INDICES="$PRINT_INDICES" \
-DSD_PREPROCESS="$PREPROCESS" \
# ... other configurations
echo "Running preprocessing step..."
exit 0
fi
Tracks loop iterations and array access patterns to help identify out-of-bounds issues and iteration-related bugs.
libnd4j.printindicesPRINT_INDICESPRINT_INDICES macro in C++ code#if defined(PRINT_INDICES)
printf("i: %lld xEws %lld ReduceBoolFunction<X, Z>::execScalar\n", i, xEws);
#endif
else {
for (auto i = start; i < stop; i++) {
#if defined(PRINT_INDICES)
printf("i: %lld xEws %lld ReduceBoolFunction<X, Z>::execScalar\n", i, xEws);
#endif
intermediate[thread_id] = OpType::update(
intermediate[thread_id],
OpType::op(x[i * xEws], extraParams),
extraParams
);
}
}
Provides detailed tracking of mathematical operations, including input values, outputs, and execution flow.
libnd4j.printmathPRINT_MATHSD_GCC_FUNCTRACE macro in C++ code when enabledtemplate <>
SD_INLINE SD_HOST void sd_print_math2<uint16_t>(char* func_name, uint16_t input1, uint16_t input2, uint16_t output) {
#if defined(SD_GCC_FUNCTRACE)
PRINT_IF_NECESSARY(func_name);
#endif
printf("%s: input1 = %d, input2 = %d, output = %d\n", func_name, input1, input2, output);
fflush(stdout);
}
Generates preprocessed source files to help debug macro-related issues and understand macro expansion.
libnd4j.preprocessSD_PREPROCESSWhen preprocessing is enabled:
libnd4j.preprocess=ONPREPROCESS=ON-DSD_PREPROCESS=ONif("${SD_PREPROCESS}" STREQUAL "ON")
message("Preprocessing enabled ${CMAKE_BINARY_DIR}")
include_directories(${CMAKE_BINARY_DIR}/../../include)
list(REMOVE_DUPLICATES ALL_SOURCES)
# Generate preprocessed files