troubleshooting/PREPROCESSOR_DEBUGGING.md
The libnd4j.preprocess flag is a specialized debugging tool that runs only the C++ preprocessor, outputting the preprocessed source files before actual compilation. This is invaluable for:
mvn clean install -Dlibnd4j.preprocess=ON
Preprocessed files are created in the preprocessed directory with the following naming convention:
.iinclude/ops/declarable/generic/transforms/reverse.cpp becomes preprocessed/ops_declarable_generic_transforms_reverse.iThe preprocessor performs several transformations:
From the CMakeLists.txt configuration:
set(PREPROCESSED_DIR "${CMAKE_SOURCE_DIR}/preprocessed")
file(MAKE_DIRECTORY ${PREPROCESSED_DIR})
# Command format used internally
${compiler} -E ${include_dirs} "${src}" -o "${preprocessed_file}"
if(src MATCHES "\\.c$")
set(language "C")
elseif(src MATCHES "\\.cpp$|\\.cxx$|\\.cc$")
set(language "CXX")
else()
set(language "CXX")
endif()
When dealing with complex macro definitions like BUILD_DOUBLE_TEMPLATE:
#if defined(SD_COMMON_TYPES_GEN) && defined(SD_COMMON_TYPES_@FL_TYPE_INDEX@)
BUILD_DOUBLE_TEMPLATE(template void someFunc, (arg_list,..),
SD_COMMON_TYPES_@FL_TYPE_INDEX@, SD_INDEXING_TYPES);
#endif
Using preprocessor output helps verify:
When headers aren't found or wrong versions are included:
# Check full include path resolution
grep "#include" preprocessed/your_file.i
For code with multiple #ifdef paths:
#ifdef SD_CUDA
// CUDA-specific code
#else
// CPU code
#endif
The preprocessed output shows exactly which path was taken.
Organized Investigation:
# Create a directory for the specific issue
mkdir debug_issue_123
cd debug_issue_123
# Run preprocessor and copy relevant files
mvn clean install -Dlibnd4j.preprocess=ON
cp ../preprocessed/relevant_file.i .
Diff Comparison:
# Compare different configurations
mv preprocessed/file.i file_config1.i
# Change configuration
mvn clean install -Dlibnd4j.preprocess=ON
diff file_config1.i preprocessed/file.i
Macro Tracing:
Missing Definitions
grep -n "undefined" preprocessed/*.i
Include Order Issues
grep -n "#include" preprocessed/your_file.i
Template Instantiation Problems
grep -n "template" preprocessed/your_file.i
Filtering Output:
# Remove empty lines and comments
grep -v '^$' preprocessed/file.i | grep -v '^//'
# Focus on specific sections
sed -n '/START_SECTION/,/END_SECTION/p' preprocessed/file.i
Finding Macro Expansions:
# Search for specific macro expansions
grep -A 5 -B 5 "MACRO_NAME" preprocessed/file.i
Managing Output Size:
# Split large files for easier analysis
split -l 1000 preprocessed/large_file.i split_
# Create focused preprocessor outputs
mv preprocessed better_name_preprocessed_$(date +%Y%m%d)