chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:47:05 +08:00
commit 4f3b7da785
7394 changed files with 2005594 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
# cmake/BuildCPU.cmake
# Contains all logic for building the CPU library.
add_definitions(-D__CPUBLAS__=true)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
# --- Source File Collection ---
file(GLOB_RECURSE BLAS_SOURCES ./include/blas/*.h )
file(GLOB_RECURSE PERF_SOURCES ./include/performance/*.cpp ./include/performance/*.h)
file(GLOB_RECURSE EXCEPTIONS_SOURCES ./include/exceptions/*.cpp ./include/exceptions/*.h)
file(GLOB_RECURSE EXEC_SOURCES ./include/execution/*.cpp ./include/execution/*.h)
file(GLOB_RECURSE TYPES_SOURCES ./include/types/*.cpp ./include/types/*.h)
file(GLOB_RECURSE ARRAY_SOURCES ./include/array/*.cpp ./include/array/*.h)
file(GLOB_RECURSE MEMORY_SOURCES ./include/memory/*.cpp ./include/memory/*.h)
file(GLOB_RECURSE GRAPH_SOURCES ./include/graph/*.cpp ./include/graph/*.h)
file(GLOB_RECURSE CUSTOMOPS_SOURCES ./include/ops/declarable/generic/*.cpp)
file(GLOB_RECURSE CUSTOMOPS_HELPERS_IMPL_SOURCES ./include/ops/declarable/helpers/impl/*.cpp)
file(GLOB_RECURSE CUSTOMOPS_HELPERS_CPU_SOURCES ./include/ops/declarable/helpers/cpu/*.cpp)
file(GLOB_RECURSE OPS_SOURCES ./include/ops/impl/*.cpp ./include/ops/declarable/impl/*.cpp ./include/ops/*.h)
file(GLOB_RECURSE INDEXING_SOURCES ./include/indexing/*.cpp ./include/indexing/*.h)
file(GLOB_RECURSE HELPERS_SOURCES ./include/build_info.cpp ./include/ConstMessages.cpp ./include/helpers/*.cpp ./include/helpers/cpu/*.cpp ./include/helpers/*.h)
file(GLOB_RECURSE LEGACY_SOURCES ./include/legacy/impl/*.cpp ./include/legacy/cpu/*.cpp ./include/legacy/*.h)
file(GLOB_RECURSE LOOPS_SOURCES ./include/loops/*.cpp ./include/loops/*.h)
set(ALL_SOURCES "")
set(STATIC_SOURCES_TO_CHECK ${BLAS_SOURCES} ${PERF_SOURCES} ${EXCEPTIONS_SOURCES} ${EXEC_SOURCES} ${TYPES_SOURCES} ${ARRAY_SOURCES} ${MEMORY_SOURCES} ${GRAPH_SOURCES} ${CUSTOMOPS_SOURCES} ${CUSTOMOPS_HELPERS_IMPL_SOURCES} ${CUSTOMOPS_HELPERS_CPU_SOURCES} ${OPS_SOURCES} ${INDEXING_SOURCES} ${HELPERS_SOURCES} ${LEGACY_SOURCES} ${LOOPS_SOURCES})
# Add PLT wrapper functions for functrace builds (GCC and Clang)
# Required for --wrap=atexit and --wrap=at_quick_exit linker flags
# These wrappers avoid PLT relocations in >2GB binaries
if(SD_GCC_FUNCTRACE)
list(APPEND STATIC_SOURCES_TO_CHECK ./include/platform/noplt_libc_stubs.c)
message(STATUS "✅ Added noplt_libc_stubs.c for functrace build (provides __wrap_atexit and __wrap_at_quick_exit)")
endif()
if(HAVE_ONEDNN)
file(GLOB_RECURSE CUSTOMOPS_ONEDNN_SOURCES ./include/ops/declarable/platform/mkldnn/*.cpp ./include/ops/declarable/platform/mkldnn/mkldnnUtils.h)
list(APPEND STATIC_SOURCES_TO_CHECK ${CUSTOMOPS_ONEDNN_SOURCES})
endif()
if(HAVE_ARMCOMPUTE)
file(GLOB_RECURSE CUSTOMOPS_ARMCOMPUTE_SOURCES ./include/ops/declarable/platform/armcompute/*.cpp ./include/ops/declarable/platform/armcompute/*.h)
list(APPEND STATIC_SOURCES_TO_CHECK ${CUSTOMOPS_ARMCOMPUTE_SOURCES})
endif()
list(APPEND ALL_SOURCES ${STATIC_SOURCES_TO_CHECK})
list(REMOVE_DUPLICATES ALL_SOURCES)
# --- Generate CPU Template Instantiations ---
file(GLOB_RECURSE COMPILATION_UNITS
./include/ops/impl/compilation_units/*.cpp.in
./include/ops/declarable/helpers/cpu/compilation_units/*.cpp.in
./include/loops/cpu/compilation_units/*.cpp.in
./include/helpers/cpu/loops/*.cpp.in)
foreach(FL_ITEM ${COMPILATION_UNITS})
genCompilation(${FL_ITEM})
endforeach()
# --- Build Library ---
set(OBJECT_LIB_NAME "${SD_LIBRARY_NAME}_object")
add_library(${OBJECT_LIB_NAME} OBJECT ${ALL_SOURCES})
add_dependencies(${OBJECT_LIB_NAME} flatbuffers_interface)
target_include_directories(${OBJECT_LIB_NAME} PUBLIC ${EXTERNAL_INCLUDE_DIRS})
set_property(TARGET ${OBJECT_LIB_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "${MSVC_RT_LIB}$<$<CONFIG:Debug>:Debug>")
add_library(${SD_LIBRARY_NAME} SHARED $<TARGET_OBJECTS:${OBJECT_LIB_NAME}>)
set_target_properties(${SD_LIBRARY_NAME} PROPERTIES OUTPUT_NAME ${SD_LIBRARY_NAME})
set_property(TARGET ${SD_LIBRARY_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "${MSVC_RT_LIB}$<$<CONFIG:Debug>:Debug>")
# --- Link Dependencies ---
target_link_libraries(${SD_LIBRARY_NAME} PUBLIC
${ONEDNN}
${ARMCOMPUTE_LIBRARIES}
${OPENBLAS_LIBRARIES}
${BLAS_LIBRARIES}
${JVM_LIBRARY}
flatbuffers_interface
)
# --- OpenMP Configuration ---
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
message(STATUS "OpenMP found, linking OpenMP::OpenMP_CXX")
target_link_libraries(${SD_LIBRARY_NAME} PUBLIC OpenMP::OpenMP_CXX)
else()
message(WARNING "OpenMP not found, falling back to manual configuration")
target_compile_options(${SD_LIBRARY_NAME} INTERFACE "-fopenmp")
target_link_libraries(${SD_LIBRARY_NAME} PUBLIC "-fopenmp")
endif()
endif()
+179
View File
@@ -0,0 +1,179 @@
# CombinationCaching.cmake
# Smart type combination reuse and caching system
# Main function to handle combination reuse
function(use_cached_type_combinations)
# Check if combinations already exist in memory
if(DEFINED COMBINATIONS_2 AND DEFINED COMBINATIONS_3)
list(LENGTH COMBINATIONS_2 combo2_count)
list(LENGTH COMBINATIONS_3 combo3_count)
if(combo2_count GREATER 0 AND combo3_count GREATER 0)
message(STATUS "♻️ Reusing existing combinations: 2-type=${combo2_count}, 3-type=${combo3_count}")
return()
endif()
endif()
# Check for cached combinations file
set(COMBO_CACHE_FILE "${CMAKE_BINARY_DIR}/type_combinations.cache")
if(EXISTS "${COMBO_CACHE_FILE}")
message(STATUS "📁 Loading combinations from cache file...")
include("${COMBO_CACHE_FILE}")
# Verify cache loaded successfully
if(DEFINED COMBINATIONS_2 AND DEFINED COMBINATIONS_3)
list(LENGTH COMBINATIONS_2 combo2_count)
list(LENGTH COMBINATIONS_3 combo3_count)
message(STATUS "✅ Loaded from cache: 2-type=${combo2_count}, 3-type=${combo3_count}")
return()
else()
message(STATUS "⚠️ Cache file corrupted, regenerating...")
endif()
endif()
# Only generate if we absolutely have to
message(STATUS "🔄 Generating type combinations (first time only)...")
# Ensure type system is initialized
if(NOT DEFINED SD_COMMON_TYPES_COUNT OR SD_COMMON_TYPES_COUNT EQUAL 0)
validate_and_process_types_failfast()
build_indexed_type_lists()
endif()
initialize_dynamic_combinations()
# Verify combinations were created
if(DEFINED COMBINATIONS_2 AND DEFINED COMBINATIONS_3)
list(LENGTH COMBINATIONS_2 combo2_count)
list(LENGTH COMBINATIONS_3 combo3_count)
message(STATUS "✅ Generated combinations: 2-type=${combo2_count}, 3-type=${combo3_count}")
# Cache for future use
save_combinations_to_cache("${COMBO_CACHE_FILE}")
else()
message(FATAL_ERROR "❌ Failed to generate type combinations!")
endif()
endfunction()
# Save combinations to cache file
function(save_combinations_to_cache cache_file)
message(STATUS "💾 Saving combinations to cache...")
set(cache_content "# Generated type combinations cache\n")
string(APPEND cache_content "# Generated on: ${CMAKE_CURRENT_TIMESTAMP}\n\n")
# Save 2-type combinations
string(APPEND cache_content "set(COMBINATIONS_2 \"")
foreach(combo ${COMBINATIONS_2})
string(APPEND cache_content "${combo};")
endforeach()
string(APPEND cache_content "\" CACHE INTERNAL \"2-type combinations\")\n\n")
# Save 3-type combinations
string(APPEND cache_content "set(COMBINATIONS_3 \"")
foreach(combo ${COMBINATIONS_3})
string(APPEND cache_content "${combo};")
endforeach()
string(APPEND cache_content "\" CACHE INTERNAL \"3-type combinations\")\n\n")
# Save metadata
string(APPEND cache_content "set(COMBINATIONS_CACHE_TIMESTAMP \"${CMAKE_CURRENT_TIMESTAMP}\" CACHE INTERNAL \"Cache timestamp\")\n")
string(APPEND cache_content "set(COMBINATIONS_CACHE_VALID TRUE CACHE INTERNAL \"Cache validity flag\")\n")
file(WRITE "${cache_file}" "${cache_content}")
message(STATUS "💾 Combinations cached to: ${cache_file}")
endfunction()
# Generate reusable combination strings once
function(generate_combination_strings_once)
if(DEFINED GLOBAL_COMB2_STRING AND DEFINED GLOBAL_COMB3_STRING)
message(STATUS "♻️ Reusing existing combination strings")
return()
endif()
message(STATUS "🔧 Generating combination strings...")
# Generate 2-type combination string
set(COMB2_STRING "")
foreach(combination ${COMBINATIONS_2})
string(REPLACE "," ";" combo_parts "${combination}")
list(GET combo_parts 0 t1)
list(GET combo_parts 1 t2)
string(APPEND COMB2_STRING "INSTANTIATE_2(${t1}, ${t2})")
endforeach()
# Generate 3-type combination string
set(COMB3_STRING "")
foreach(combination ${COMBINATIONS_3})
string(REPLACE "," ";" combo_parts "${combination}")
list(GET combo_parts 0 t1)
list(GET combo_parts 1 t2)
list(GET combo_parts 2 t3)
string(APPEND COMB3_STRING "INSTANTIATE_3(${t1}, ${t2}, ${t3}); ")
endforeach()
# Cache globally for reuse
set(GLOBAL_COMB2_STRING "${COMB2_STRING}" CACHE INTERNAL "Global 2-type combination string")
set(GLOBAL_COMB3_STRING "${COMB3_STRING}" CACHE INTERNAL "Global 3-type combination string")
list(LENGTH COMBINATIONS_2 combo2_count)
list(LENGTH COMBINATIONS_3 combo3_count)
message(STATUS "✅ Generated strings: 2-type=${combo2_count} instantiations, 3-type=${combo3_count} instantiations")
endfunction()
# Clear cache if needed (for development)
function(clear_combination_cache)
set(COMBO_CACHE_FILE "${CMAKE_BINARY_DIR}/type_combinations.cache")
if(EXISTS "${COMBO_CACHE_FILE}")
file(REMOVE "${COMBO_CACHE_FILE}")
message(STATUS "🗑️ Cleared combination cache")
endif()
# Clear memory cache
unset(COMBINATIONS_2 CACHE)
unset(COMBINATIONS_3 CACHE)
unset(GLOBAL_COMB2_STRING CACHE)
unset(GLOBAL_COMB3_STRING CACHE)
unset(COMBINATIONS_CACHE_VALID CACHE)
endfunction()
# Validate cache integrity
function(validate_combination_cache)
if(NOT DEFINED COMBINATIONS_CACHE_VALID OR NOT COMBINATIONS_CACHE_VALID)
message(STATUS "⚠️ Combination cache is invalid, will regenerate")
clear_combination_cache()
return()
endif()
# Check if combinations are reasonable
if(DEFINED COMBINATIONS_2 AND DEFINED COMBINATIONS_3)
list(LENGTH COMBINATIONS_2 combo2_count)
list(LENGTH COMBINATIONS_3 combo3_count)
if(combo2_count LESS 10 OR combo3_count LESS 10)
message(STATUS "⚠️ Combination counts seem too low, will regenerate")
clear_combination_cache()
return()
endif()
message(STATUS "✅ Cache validation passed")
else()
message(STATUS "⚠️ Combinations not found in cache, will regenerate")
clear_combination_cache()
endif()
endfunction()
# Main setup function
function(setup_smart_combination_reuse)
message(STATUS "=== SETTING UP SMART COMBINATION REUSE ===")
# Validate existing cache
validate_combination_cache()
# Use cached combinations without regeneration
use_cached_type_combinations()
# Create combination strings once, reuse everywhere
generate_combination_strings_once()
message(STATUS "✅ Smart combination reuse setup complete")
endfunction()
+689
View File
@@ -0,0 +1,689 @@
# cmake/CompilerFlags.cmake
# Configures compiler and linker flags for optimization and correctness.
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# When sanitizers or lifecycle tracking are enabled, we use large code model which can cause PLT overflow
# Skip -fno-plt for these builds to avoid "PC-relative offset overflow" linker errors
if(NOT ((DEFINED SD_SANITIZERS AND NOT SD_SANITIZERS STREQUAL "") OR SD_GCC_FUNCTRACE))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-plt")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-plt")
else()
if(DEFINED SD_SANITIZERS AND NOT SD_SANITIZERS STREQUAL "")
message(STATUS "Skipping -fno-plt for sanitizer build (incompatible with large code model)")
elseif(SD_GCC_FUNCTRACE)
message(STATUS "Skipping -fno-plt for lifecycle tracking build (incompatible with large code model)")
endif()
endif()
#This is to avoid jemalloc crashes where c++ uses sized deallocations
add_compile_options(-fno-sized-deallocation)
# JavaCPP loads our library via dlopen() at runtime, not at program startup
# Libraries loaded via dlopen() with static TLS (initial-exec model) can exhaust the static TLS block
# Solution: Force global-dynamic TLS model for ALL thread-local storage
# - global-dynamic: Uses __tls_get_addr() for dynamic TLS allocation at runtime
# - Works with dlopen() because TLS is allocated dynamically, not from static block
# - Slightly slower than initial-exec, but required for dlopen() compatibility
# Also disable thread-safe static initialization guards which use TLS internally
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftls-model=global-dynamic -fno-threadsafe-statics")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftls-model=global-dynamic")
# ADDITIONAL FIX: Use GNU2 TLS dialect (TLSDESC) for better dlopen() support
# Traditional TLS implementation (gnu dialect) has limitations with libraries loaded via dlopen()
# GNU2 dialect uses TLS descriptors which are specifically designed for dynamic loading
# - Reduces TLS block fragmentation
# - More efficient for libraries loaded at runtime
# - Better handles libraries with many TLS variables
# This is a DIFFERENT approach from session #310's global-dynamic alone
# Supported on x86-64 by both GCC and Clang (requires glibc 2.10+, widely available)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtls-dialect=gnu2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mtls-dialect=gnu2")
message(STATUS "Applied GNU2 TLS dialect (TLSDESC) for improved dlopen() compatibility")
endif()
message(STATUS "Applied global-dynamic TLS model for dlopen() compatibility (JavaCPP requirement)")
endif()
# Template depth limits - standardized based on build type
# Release builds: 512 (sufficient for production, faster compilation)
# Debug builds: 1024 (deeper nesting for development)
# GCC-specific error limiting
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-fmax-errors=3) # Stop on first few errors
endif()
# Clang-specific workarounds for source location limits
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Work around Clang's source location limit with heavily templated code
add_compile_options(-Wno-error)
add_compile_options(-ferror-limit=0)
# Reduce macro expansion tracking overhead
add_compile_options(-fmacro-backtrace-limit=0)
# Reduce template error backtrace noise
add_compile_options(-ftemplate-backtrace-limit=10)
# Aggressive Clang 20 memory optimizations for functrace ONLY
if(SD_GCC_FUNCTRACE)
message(STATUS "⚡ Applying Clang 20 memory optimizations for functrace build ONLY")
# Disable PCH validation (saves memory)
add_compile_options(-Xclang -fno-validate-pch)
# Reduce template instantiation depth
add_compile_options(-ftemplate-depth=512)
# Clang 20 specific: Reduce memory during code generation
add_compile_options(-Xclang -mllvm -Xclang -inline-threshold=50)
# Reduce DWARF debug info overhead (keep line tables only)
add_compile_options(-fdebug-info-for-profiling)
# These flags don't exist: -hot-cold-split, -reduce-array-computations, -enable-loop-distribute
# Disable expensive optimizations during compilation to save memory
add_compile_options(-fno-slp-vectorize)
add_compile_options(-fno-vectorize)
message(STATUS " - Disabled PCH validation")
message(STATUS " - Template depth: 512")
message(STATUS " - Reduced inline threshold for memory")
message(STATUS " - Debug info optimized for profiling")
message(STATUS " - Vectorization disabled (saves memory)")
endif()
# Use newer source manager if available (Clang 15+)
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "15.0")
message(STATUS "Clang 15+ detected, using optimizations for large translation units")
endif()
endif()
# --- Link Time Optimization (LTO) ---
if(SD_USE_LTO)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
message(STATUS "Using Link Time Optimization")
add_compile_options(-flto)
add_link_options(-flto)
endif()
endif()
# --- Memory Model for large binaries ---
# CRITICAL: -mcmodel=large is INCOMPATIBLE with system CRT libraries (crtbeginS.o, crti.o)
# System libraries are compiled with -mcmodel=small and cannot be linked into -mcmodel=large binaries
# This causes "relocation truncated to fit: R_X86_64_PC32" errors (see session #959, #1008)
# SOLUTION: Use -mcmodel=medium for both sanitizers AND functrace builds
# Medium model: Code can be anywhere, data/GOT in lowest 2GB (compatible with system libraries)
if(SD_X86_BUILD AND NOT WIN32)
if(SD_SANITIZE OR SD_GCC_FUNCTRACE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=medium -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcmodel=medium")
if(SD_SANITIZE)
message(STATUS "Applied medium memory model for x86-64 architecture (sanitizers enabled)")
elseif(SD_GCC_FUNCTRACE)
message(STATUS "Applied medium memory model for x86-64 architecture (lifecycle tracking enabled)")
endif()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=medium -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcmodel=medium")
message(STATUS "Applied medium memory model for x86-64 architecture")
endif()
else()
if(SD_ARM_BUILD OR SD_ANDROID_BUILD)
message(STATUS "Skipping large memory model for ARM/Android architecture (not supported)")
elseif(WIN32)
message(STATUS "Skipping large memory model for Windows (using alternative approach)")
endif()
endif()
# --- Section splitting for better linker handling ---
# Note: Memory optimization params (ggc-min-*) are set below in GCC-specific section to avoid duplicates
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
# MEMORY OPTIMIZATION: Additional flags for functrace ONLY to reduce memory
if(SD_GCC_FUNCTRACE)
# Merge identical constants to reduce object file size
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmerge-all-constants")
# Use non-unique section names (reduces ELF section overhead) - Clang only
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unique-section-names")
# Don't keep full AST in memory during code generation
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -discard-value-names")
endif()
message(STATUS "⚡ Applied memory-reduction compiler flags for functrace ONLY:")
message(STATUS " - fmerge-all-constants (reduce duplication)")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS " - fno-unique-section-names (reduce ELF overhead, Clang only)")
message(STATUS " - discard-value-names (reduce AST retention)")
endif()
endif()
endif()
# --- Allow duplicate instantiations for template folding ---
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# GCC: Use -fpermissive to allow duplicate instantiations
add_compile_options(-fpermissive)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Clang: Suppress all warnings and errors for template instantiation issues
add_compile_options(-w)
add_compile_options(-Wno-error)
add_compile_options(-Wno-everything)
message(STATUS "✅ Clang: Enabled template folding with all warnings suppressed and dead strip")
endif()
# --- MSVC-specific optimizations ---
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/Gy) # Function-level linking
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /OPT:REF /OPT:ICF")
add_compile_options(/bigobj /EHsc /Zc:preprocessor)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
# --- Windows Specific Configurations ---
if(WIN32 AND NOT ANDROID)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
endif()
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS ON)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS ON)
set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@")
set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@")
set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON CACHE INTERNAL "")
endif()
# --- GCC/Clang Specific Flags ---
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT SD_CUDA)
message(STATUS "Adding GCC memory optimization flags: --param ggc-min-expand=100 --param ggc-min-heapsize=131072")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ${INFORMATIVE_FLAGS} -std=c++17 -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --param ggc-min-expand=100 --param ggc-min-heapsize=131072 -fPIC")
if(UNIX)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,$ORIGIN/,--no-undefined,--verbose")
else()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,$ORIGIN/,--no-undefined,--verbose")
endif()
endif()
# --- Build Type Specific Flags ---
if(SD_ANDROID_BUILD)
# ... flags for android ...
elseif(APPLE)
# ... flags for apple ...
elseif(WIN32)
# ... flags for windows ...
else() # Generic Linux/Unix
if("${SD_GCC_FUNCTRACE}" STREQUAL "ON")
set(CMAKE_CXX_FLAGS_RELEASE "-O${SD_OPTIMIZATION_LEVEL} -fPIC -g")
else()
set(CMAKE_CXX_FLAGS_RELEASE "-O${SD_OPTIMIZATION_LEVEL} -fPIC -D_RELEASE=true")
endif()
set(CMAKE_CXX_FLAGS_DEBUG " -g -O${SD_OPTIMIZATION_LEVEL} -fPIC")
endif()
# --- Sanitizer Configuration ---
# In CompilerFlags.cmake, change the sanitizer section:
# --- Sanitizer Configuration ---
if(SD_SANITIZE)
# For large binaries with MSan: must use large code model
# Use LLD linker for better memory handling (gold OOMs on 23GB+ builds)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# MEMORY OPTIMIZATION: Use -gline-tables-only instead of full debug info (Clang-specific)
# This reduces memory by 40-60% for template-heavy code while maintaining stack traces
set(SANITIZE_FLAGS " -fPIC -fsanitize=${SD_SANITIZERS} -fno-sanitize-recover=all -fuse-ld=gold -gline-tables-only")
# MemorySanitizer-specific: Use ignorelist to skip instrumentation of external libraries
if(SD_SANITIZERS MATCHES "memory")
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fsanitize-ignorelist=${CMAKE_CURRENT_SOURCE_DIR}/msan_ignorelist.txt")
# Disable origin tracking to reduce MSan's static TLS usage
# - Origin tracking uses significant TLS to track uninitialized memory sources
# - With dlopen() (JavaCPP's loading method), static TLS space is limited
# - Disabling origin tracking keeps MSan functional but reduces TLS footprint
# - MSan will still detect uninitialized memory, just without origin traces
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fsanitize-memory-track-origins=0")
# - Dynamic linking: libnd4jcpu.so depends on libclang_rt.msan.so (separate .so with static TLS)
# - Static linking: MSan runtime code embedded in libnd4jcpu.so (TLS becomes part of our library)
# - Combined with global-dynamic TLS model, this eliminates static TLS block exhaustion
# - Static linking is safe here because we only have ONE library using MSan (no multi-library conflicts)
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -static-libsan")
message(STATUS "Applied MemorySanitizer ignorelist for external libraries")
message(STATUS "Disabled MSan origin tracking to reduce TLS usage for dlopen() compatibility")
message(STATUS "Enabled static MSan runtime linking to eliminate separate TLS allocation")
endif()
# Explicitly force global-dynamic TLS model for dlopen() compatibility
# - global-dynamic: Uses __tls_get_addr() for dynamic TLS allocation
# - Works with libraries loaded via dlopen() (JavaCPP's method)
# - Avoids static TLS block exhaustion
# ALSO disable thread-safe statics to prevent __tls_guard from using initial-exec TLS
# Thread-safe static initialization uses internal TLS that doesn't respect -ftls-model flag
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -ftls-model=global-dynamic -fno-threadsafe-statics")
# Additional memory optimizations for template-heavy instantiation files
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fmerge-all-constants")
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-unique-section-names") # Clang-specific
message(STATUS "Applied memory-optimized sanitizer flags (-gline-tables-only, Clang-specific)")
else()
set(SANITIZE_FLAGS " -Wall -Wextra -fPIC -fsanitize=${SD_SANITIZERS} -fno-sanitize-recover=all")
endif()
# Gold linker + sanitizers: Must explicitly pass -fsanitize to linker
# The -fsanitize flag tells clang driver to link the sanitizer runtime
# Gold linker handles MSan's TLS correctly for shared libraries (LLD has issues)
set(SANITIZE_LINK_FLAGS "-fsanitize=${SD_SANITIZERS} -fuse-ld=gold")
# Without this, linker uses wrong relocation types → "relocation truncated to fit" errors
if(SD_X86_BUILD AND NOT WIN32)
if(DEFINED SD_SANITIZERS AND NOT SD_SANITIZERS STREQUAL "")
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -mcmodel=large")
message(STATUS "Applied large code model to linker flags (matches compiler -mcmodel=large)")
else()
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -mcmodel=medium")
endif()
endif()
# Linker memory optimizations for large template-heavy builds
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Detect which linker is being used
set(DETECTED_LINKER "unknown")
if(SANITIZE_LINK_FLAGS MATCHES "-fuse-ld=gold")
set(DETECTED_LINKER "gold")
elseif(SANITIZE_LINK_FLAGS MATCHES "-fuse-ld=lld")
set(DETECTED_LINKER "lld")
elseif(SANITIZE_LINK_FLAGS MATCHES "-fuse-ld=bfd")
set(DETECTED_LINKER "bfd")
else()
# Try to detect from compiler default
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -Wl,--version
OUTPUT_VARIABLE LINKER_VERSION_OUTPUT
ERROR_VARIABLE LINKER_VERSION_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(LINKER_VERSION_OUTPUT MATCHES "GNU gold")
set(DETECTED_LINKER "gold")
elseif(LINKER_VERSION_OUTPUT MATCHES "LLD")
set(DETECTED_LINKER "lld")
elseif(LINKER_VERSION_OUTPUT MATCHES "GNU ld")
set(DETECTED_LINKER "bfd")
endif()
endif()
message(STATUS "Detected linker: ${DETECTED_LINKER}")
# Apply linker-specific memory optimizations
if(DETECTED_LINKER STREQUAL "gold")
# GNU gold linker flags
# Memory sanitizer needs reduced caching to avoid OOM, but leak sanitizer benefits from caching
if(SD_SANITIZERS MATCHES "memory")
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--no-keep-memory")
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--no-map-whole-files")
endif()
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--icf=safe")
# Gold uses its own internal hash table optimization that cannot be configured
# Gold by default is single-threaded. Multi-threading speeds up linking 2-4x
# and can reduce peak memory by spreading work across time
cmake_host_system_information(RESULT NUM_CORES QUERY NUMBER_OF_PHYSICAL_CORES)
math(EXPR LINKER_THREADS "${NUM_CORES} / 2") # Use half of cores for linking
if(LINKER_THREADS LESS 2)
set(LINKER_THREADS 2)
endif()
if(LINKER_THREADS GREATER 8)
set(LINKER_THREADS 8) # Cap at 8 threads (gold's sweet spot)
endif()
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--threads")
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--thread-count,${LINKER_THREADS}")
message(STATUS "Applied GNU gold linker optimizations:")
if(SD_SANITIZERS MATCHES "memory")
message(STATUS " - --no-keep-memory: Don't cache file contents (MemorySanitizer only)")
message(STATUS " - --no-map-whole-files: Map only needed file parts (MemorySanitizer only)")
else()
message(STATUS " - Using default caching (better for leak/address sanitizers)")
endif()
message(STATUS " - --icf=safe: Fold identical code sections")
message(STATUS " - --threads: Enable parallel linking with ${LINKER_THREADS} threads")
message(STATUS " Note: Gold linker manages hash table size internally (not configurable)")
elseif(DETECTED_LINKER STREQUAL "lld")
# LLVM lld linker flags (different syntax than gold)
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--icf=all")
# For very large builds (23GB+ object files), reduce memory usage
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--gc-sections")
# LLD has built-in threading, configure job count
cmake_host_system_information(RESULT NUM_CORES QUERY NUMBER_OF_PHYSICAL_CORES)
math(EXPR LINKER_THREADS "${NUM_CORES} / 2")
if(LINKER_THREADS LESS 2)
set(LINKER_THREADS 2)
endif()
if(LINKER_THREADS GREATER 16)
set(LINKER_THREADS 16) # LLD scales better than gold
endif()
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--threads=${LINKER_THREADS}")
message(STATUS "Applied LLVM lld linker memory optimizations:")
message(STATUS " - --icf=all: Aggressive identical code folding")
message(STATUS " - --gc-sections: Remove unused code sections")
message(STATUS " - --threads=${LINKER_THREADS}: Enable parallel linking")
message(STATUS " Note: LLD handles large builds (23GB+) better than gold")
elseif(DETECTED_LINKER STREQUAL "bfd")
# GNU ld (bfd) - older linker with limited optimization support
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -Wl,--no-keep-memory")
# BFD doesn't support threading or advanced ICF
message(STATUS "Applied GNU ld (bfd) linker memory optimizations:")
message(STATUS " - --no-keep-memory: Don't cache file contents in memory")
message(WARNING "GNU ld (bfd) is single-threaded and slower than gold/lld. Consider using gold or lld for faster builds.")
else()
message(WARNING "Unknown linker detected. Skipping linker-specific optimizations.")
message(STATUS "To specify linker explicitly, use: -DCMAKE_CXX_FLAGS=\"-fuse-ld=gold\" (or lld/bfd)")
endif()
endif()
# For Homebrew clang or custom LLVM, also add explicit runtime library path
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-resource-dir
OUTPUT_VARIABLE CLANG_RESOURCE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Determine OS-specific lib subdirectory
if(APPLE)
set(SANITIZER_LIB_SUBDIR "darwin")
elseif(WIN32)
set(SANITIZER_LIB_SUBDIR "windows")
else()
set(SANITIZER_LIB_SUBDIR "linux")
endif()
# Determine architecture for sanitizer library names
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
set(SANITIZER_ARCH "x86_64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64")
set(SANITIZER_ARCH "aarch64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le")
set(SANITIZER_ARCH "powerpc64le")
else()
set(SANITIZER_ARCH ${CMAKE_SYSTEM_PROCESSOR})
endif()
set(SANITIZER_LIB_PATH "${CLANG_RESOURCE_DIR}/lib/${SANITIZER_LIB_SUBDIR}")
if(EXISTS "${SANITIZER_LIB_PATH}")
# Add library search path and RPATH for sanitizer runtime
if(APPLE)
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -L${SANITIZER_LIB_PATH} -Wl,-rpath,${SANITIZER_LIB_PATH}")
elseif(WIN32)
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -L${SANITIZER_LIB_PATH}")
else()
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -L${SANITIZER_LIB_PATH} -Wl,-rpath,${SANITIZER_LIB_PATH}")
endif()
# When using gold linker with -static-libsan, we don't need explicit runtime linking
# The -static-libsan flag tells Clang to link the static runtime archives automatically
# REMOVED: Explicit -lclang_rt.msan-* (for shared runtime) - now using static linking
if(SD_SANITIZERS MATCHES "memory")
# Note: With -static-libsan flag above, Clang handles static runtime linking
message(STATUS "Using static MSan runtime (via -static-libsan) for gold linker (${SANITIZER_ARCH})")
endif()
# -fsanitize=leak uses the ASAN runtime (there's no separate LSAN .so)
# For shared libraries loaded by JVM/JNI, the sanitizer runtime MUST be
# dynamically linked, not statically linked. Without this, the sanitizer
# runtime is not initialized and leaks are not detected.
#
# With gold linker, Clang defaults to static linking of sanitizer runtime.
# We must explicitly link the shared .so file to make it a NEEDED dependency.
if(SD_SANITIZERS MATCHES "leak" OR SD_SANITIZERS MATCHES "address")
set(SANITIZE_LINK_FLAGS "${SANITIZE_LINK_FLAGS} -lclang_rt.asan-${SANITIZER_ARCH}")
message(STATUS "Added explicit ASAN shared runtime library for leak/address sanitizer (${SANITIZER_ARCH}, JNI compatibility)")
endif()
message(STATUS "Added clang sanitizer runtime library path and RPATH: ${SANITIZER_LIB_PATH}")
endif()
endif()
message("Using sanitizers: ${SD_SANITIZERS}...")
if(SD_CPU)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}" CACHE STRING "C++ flags" FORCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}" CACHE STRING "C flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZE_LINK_FLAGS}" CACHE STRING "Exe linker flags" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SANITIZE_LINK_FLAGS}" CACHE STRING "Shared linker flags" FORCE)
endif()
if(SD_CUDA)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS} --relocatable-device-code=true" CACHE STRING "C++ flags" FORCE)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${SANITIZE_FLAGS}" CACHE STRING "CUDA flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZE_LINK_FLAGS}" CACHE STRING "Exe linker flags" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SANITIZE_LINK_FLAGS}" CACHE STRING "Shared linker flags" FORCE)
endif()
# MEMORY OPTIMIZATION: Limit parallel compilation jobs for sanitizer builds
# Template instantiation files with sanitizers can use 8-12GB per compiler process
# Limiting parallel jobs prevents memory exhaustion
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Use CMake 3.0+ job pools to limit parallelism
# Each instantiation file with MSan can peak at ~10GB
# Safe limit: max(6, available_RAM_GB / 12)
set(SANITIZER_MAX_JOBS 8)
set_property(GLOBAL PROPERTY JOB_POOLS compile_pool=${SANITIZER_MAX_JOBS})
set(CMAKE_JOB_POOL_COMPILE compile_pool)
message(STATUS "⚠️ Limited parallel compilation to ${SANITIZER_MAX_JOBS} jobs for memory-intensive sanitizer build")
message(STATUS " Estimated peak memory: ~${SANITIZER_MAX_JOBS}0 GB")
endif()
endif()
# --- Strict Linker Flags to Catch Undefined Symbols Early ---
# This helps catch missing template specializations at link time instead of runtime
# EXCEPTION: Do NOT use --no-undefined with sanitizers, as they require runtime symbol resolution
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT SD_SANITIZE AND NOT SD_GCC_FUNCTRACE)
message(STATUS "⚠️ ENFORCING strict linker flags - build will FAIL on ANY undefined symbols")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
# Without this, linker uses wrong relocation types → "relocation truncated to fit" errors
if(SD_X86_BUILD AND NOT WIN32)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mcmodel=medium")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mcmodel=medium")
message(STATUS "Applied medium code model to linker flags (matches compiler -mcmodel=medium)")
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND SD_GCC_FUNCTRACE AND NOT SD_SANITIZE)
#
#
# THIS IS A PLATFORM LIMITATION, NOT A CODE BUG
#
message(STATUS "⚠️ SD_GCC_FUNCTRACE enabled - binary will be ~3GB")
message(STATUS "⚠️ WARNING: High risk of relocation errors with precompiled system libraries")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
# Aggressive size reduction for functrace builds
add_compile_options(-ffunction-sections -fdata-sections)
add_compile_options(-fvisibility=hidden -fvisibility-inlines-hidden)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections,--as-needed")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections,--as-needed")
# Memory optimizations for linking large binaries
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-keep-memory")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--reduce-memory-overheads")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--hash-size=31")
# NOTE: We use compiler-rt for runtime builtins but NOT libunwind for exception handling
# (Session #1045 fix: libunwind conflicts with JVM's libgcc_s, causing _Unwind_SetGR crashes)
# The system's libgcc_s handles exception unwinding, which is compatible with JVM
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# CRITICAL FIX: Do NOT use --unwindlib=libunwind for JNI libraries!
#
# Problem (discovered in session #1045):
# - When --unwindlib=libunwind is used, Clang generates code assuming LLVM's libunwind ABI
# - We also statically link libunwind.a
# - BUT: At runtime, the JVM has libgcc_s.so loaded (for its own exception handling)
# - Due to dynamic symbol interposition, _Unwind* symbols from libgcc_s.so override
# our statically linked libunwind symbols
# - Result: ABI mismatch between exception context format → CRASH in _Unwind_SetGR
#
# The crash manifests as: SIGSEGV in _Unwind_SetGR+0x3e trying to write to read-only
# memory in libnd4jcpu.so during exception handling
#
# Solution: Use the system's default exception handling (libgcc_s), which is
# compatible with the JVM environment. Keep compiler-rt only for builtins.
#
# Use compiler-rt for runtime builtins (math, etc.) but NOT for exception handling
add_compile_options(--rtlib=compiler-rt)
# REMOVED: add_compile_options(--unwindlib=libunwind)
# Let the system use libgcc_s for exception unwinding - compatible with JVM
message(STATUS "✅ Using Clang compiler-rt for runtime builtins")
message(STATUS "✅ Using system libgcc_s for exception handling (JNI/JVM compatible)")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# With GCC, -finstrument-functions may pull in gprof startup code (__gmon_start__)
# but this symbol is weakly defined and doesn't cause actual linker errors.
# No special linker flags needed - GCC runtime handles this correctly.
message(STATUS "✅ Using GCC with functrace (no special profiling symbols needed)")
endif()
# Apply medium code model to match compiler (CRITICAL: large model incompatible with system CRT)
if(SD_X86_BUILD AND NOT WIN32)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mcmodel=medium")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mcmodel=medium")
# Allow text relocations as escape hatch if binary is still too large
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,notext")
# Disable linker relaxation to prevent GOTPCREL relocation failures (required for medium code model)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-relax")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-relax")
message(STATUS "Applied medium code model for functrace ONLY (binary size: ~3GB)")
message(STATUS "Applied linker memory optimizations for functrace ONLY (--no-keep-memory, --reduce-memory-overheads)")
message(STATUS "Added -Wl,-z,notext to allow text relocations if needed")
message(STATUS "Added -Wl,--no-relax to prevent GOT relocation issues with medium code model")
endif()
elseif(SD_SANITIZE)
message(STATUS "️ Skipping --no-undefined for sanitizer build (sanitizer runtime symbols resolved at runtime)")
endif()
# Make build more verbose to see template instantiation issues
set(CMAKE_VERBOSE_MAKEFILE ON)
if(SD_GCC_FUNCTRACE)
message(STATUS "✅ Applying SD_GCC_FUNCTRACE debug flags for line number information")
# MEMORY OPTIMIZATION: Use minimal debug info instead of full debug info
# This reduces compilation memory usage by 40-60% while maintaining stack traces
# Clang: -gline-tables-only provides file names, line numbers, function names
# GCC: -g1 provides minimal debug info (line numbers and functions only)
# Full debug info (-ggdb3) causes memory explosion with templates
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS_RELEASE "-O0 -gline-tables-only -fPIC -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -gline-tables-only -fPIC")
set(CMAKE_C_FLAGS_RELEASE "-O0 -gline-tables-only -fPIC -DNDEBUG")
set(CMAKE_C_FLAGS_DEBUG "-O0 -gline-tables-only -fPIC")
else()
set(CMAKE_CXX_FLAGS_RELEASE "-O0 -g1 -fPIC -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g1 -fPIC")
set(CMAKE_C_FLAGS_RELEASE "-O0 -g1 -fPIC -DNDEBUG")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g1 -fPIC")
endif()
# Add comprehensive debug flags
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Debug flags with function instrumentation
# MEMORY OPTIMIZATION: Use -g1 (minimal debug info) instead of -ggdb3
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g1 -finstrument-functions -fno-omit-frame-pointer -fno-optimize-sibling-calls -rdynamic -fno-threadsafe-statics -ftls-model=global-dynamic")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g1 -fno-omit-frame-pointer -ftls-model=global-dynamic")
message(STATUS "Applied memory-optimized debug flags for GCC (instrumentation enabled):")
message(STATUS " - g1 (minimal debug info) for 40-60% memory reduction vs ggdb3")
message(STATUS " - disabled thread-safe static guards")
message(STATUS " - enabled function instrumentation")
# Override any conflicting optimization
string(REGEX REPLACE "-O[0-9s]" "-O0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-O[0-9s]" "-O0" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Debug flags with function instrumentation
# MEMORY OPTIMIZATION: Use -gline-tables-only instead of -ggdb3 (Clang-specific flag)
# AGGRESSIVE MEMORY: Disable inline tracking and macro debug info
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gline-tables-only -finstrument-functions -fno-omit-frame-pointer -fno-optimize-sibling-calls -rdynamic -fno-threadsafe-statics -ftls-model=global-dynamic -fno-standalone-debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gline-tables-only -fno-omit-frame-pointer -ftls-model=global-dynamic -fno-standalone-debug")
message(STATUS "Applied memory-optimized debug flags for Clang (instrumentation enabled):")
message(STATUS " - gline-tables-only (Clang-specific) for 40-60% memory reduction vs ggdb3")
message(STATUS " - disabled thread-safe static guards")
message(STATUS " - enabled function instrumentation")
# Override any conflicting optimization
string(REGEX REPLACE "-O[0-9s]" "-O0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-O[0-9s]" "-O0" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
endif()
# Ensure debug info is preserved in linker
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -rdynamic")
# Prevent stripping
set(CMAKE_STRIP "/bin/true")
# Add the compiler definition
add_compile_definitions(SD_GCC_FUNCTRACE=ON)
# Enable function instrumentation
message(STATUS "️ Function instrumentation enabled. This will significantly increase binary size.")
endif()
# --- Flag Deduplication ---
# Remove duplicate flags that may have accumulated through multiple conditional blocks
# This ensures cleaner build logs and prevents potential flag conflicts
# Helper function to deduplicate flags in a space-separated string
function(deduplicate_flags FLAG_VAR)
# Get the original flags
set(original_flags "${${FLAG_VAR}}")
# Special handling: protect --param flags by temporarily replacing spaces
string(REGEX REPLACE "--param ([^ ]+)" "--param=\\1" temp_flags "${original_flags}")
# Convert space-separated string to list
string(REPLACE " " ";" FLAG_LIST "${temp_flags}")
# Remove duplicates while preserving order
list(REMOVE_DUPLICATES FLAG_LIST)
# Convert back to space-separated string
string(REPLACE ";" " " FLAG_STRING "${FLAG_LIST}")
# Restore --param format (space instead of =)
string(REGEX REPLACE "--param=([^ ]+)" "--param \\1" FLAG_STRING "${FLAG_STRING}")
# Set the parent scope variable
set(${FLAG_VAR} "${FLAG_STRING}" PARENT_SCOPE)
endfunction()
# Deduplicate compiler flags
deduplicate_flags(CMAKE_CXX_FLAGS)
deduplicate_flags(CMAKE_C_FLAGS)
deduplicate_flags(CMAKE_CXX_FLAGS_RELEASE)
deduplicate_flags(CMAKE_CXX_FLAGS_DEBUG)
deduplicate_flags(CMAKE_C_FLAGS_RELEASE)
deduplicate_flags(CMAKE_C_FLAGS_DEBUG)
# Deduplicate linker flags
deduplicate_flags(CMAKE_SHARED_LINKER_FLAGS)
deduplicate_flags(CMAKE_EXE_LINKER_FLAGS)
deduplicate_flags(CMAKE_MODULE_LINKER_FLAGS)
message(STATUS "✅ Compiler and linker flags deduplicated")
+107
View File
@@ -0,0 +1,107 @@
# CompilerOptimizations.cmake - Compiler flags and optimization settings
# Link Time Optimization
if(SD_USE_LTO)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
message(STATUS "Using Link Time Optimization")
add_compile_options(-flto)
add_link_options(-flto)
endif()
endif()
# Architecture Tuning
if(SD_ARCH MATCHES "armv8")
set(ARCH_TUNE "-march=${SD_ARCH}")
elseif(SD_ARCH MATCHES "armv7")
set(ARCH_TUNE "-march=${SD_ARCH} -mfpu=neon")
elseif(SD_EXTENSION MATCHES "avx2")
message("Building AVX2 binary...")
set(ARCH_TUNE "-mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mprefetchwt1 -DSD_F16C=true -DF_AVX2=true")
if(NO_AVX256_SPLIT)
set(ARCH_TUNE "${ARCH_TUNE} -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store")
endif()
else()
if("${SD_ARCH}" STREQUAL "x86-64")
message("Building x86_64 binary...")
set(ARCH_TYPE "generic")
add_compile_definitions(F_X64=true)
else()
set(ARCH_TYPE "${SD_ARCH}")
endif()
if(SD_EXTENSION MATCHES "avx512")
message("Building AVX512 binary...")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mavx512f -mavx512vl -mavx512bw -mavx512dq -mavx512cd -mbmi -mbmi2 -mprefetchwt1 -mclflushopt -mxsavec -mxsaves -DSD_F16C=true -DF_AVX512=true")
endif()
# FIXED: Only set architecture flags if we have valid values
if(NOT WIN32 AND NOT SD_CUDA)
if(DEFINED SD_ARCH AND NOT SD_ARCH STREQUAL "" AND DEFINED ARCH_TYPE AND NOT ARCH_TYPE STREQUAL "")
set(ARCH_TUNE "-march=${SD_ARCH} -mtune=${ARCH_TYPE}")
elseif(DEFINED SD_ARCH AND NOT SD_ARCH STREQUAL "")
# Fallback if ARCH_TYPE is not set
set(ARCH_TUNE "-march=${SD_ARCH}")
endif()
endif()
endif()
# Comprehensive linker fix for PLT overflow
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND SD_X86_BUILD)
message(STATUS "Configuring linker for large template library with PLT overflow prevention")
# Clear any existing conflicting linker flags
string(REGEX REPLACE "-fuse-ld=[a-zA-Z]+" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
string(REGEX REPLACE "-fuse-ld=[a-zA-Z]+" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
# Test if linker supports --plt-align before using it
execute_process(
COMMAND ${CMAKE_LINKER} --help
OUTPUT_VARIABLE LD_HELP_OUTPUT
ERROR_QUIET
)
endif()
# Use large memory model (required for your template scale) - FIXED: Only for x86-64, not ARM
if(SD_X86_BUILD AND NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=medium -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcmodel=medium")
message(STATUS "Applied large memory model for x86-64 architecture")
else()
if(SD_ARM_BUILD OR SD_ANDROID_BUILD)
message(STATUS "Skipping large memory model for ARM/Android architecture (not supported)")
elseif(WIN32)
message(STATUS "Skipping large memory model for Windows (using alternative approach)")
endif()
endif()
# Memory optimization during compilation - FIXED: Only apply to GCC
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --param ggc-min-expand=100 --param ggc-min-heapsize=131072")
endif()
# Section splitting for better linker handling - FIXED: Only apply to GCC/Clang
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
endif()
# MSVC-specific optimizations
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# MSVC equivalent optimizations
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Gy") # Function-level linking
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gy") # Function-level linking
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /OPT:REF /OPT:ICF") # Remove unreferenced code
endif()
message(STATUS "Applied PLT overflow prevention for large template library")
if(SD_NATIVE)
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64*" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64*")
set(SD_X86_BUILD false)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
endif()
+850
View File
@@ -0,0 +1,850 @@
################################################################################
# CUDA Configuration Functions
# Functions for CUDA-specific build configuration and optimization
################################################################################
# Enhanced CUDA toolkit detection with proper include path setup
function(setup_cuda_toolkit_paths)
message(STATUS "🔍 Setting up CUDA toolkit paths...")
# Find CUDA toolkit first
find_package(CUDAToolkit REQUIRED)
if(NOT CUDAToolkit_FOUND)
message(FATAL_ERROR "CUDA toolkit not found. Please install CUDA toolkit or set CUDA_PATH environment variable.")
endif()
# Get CUDA include directories
get_target_property(CUDA_INCLUDE_DIRS CUDA::toolkit INTERFACE_INCLUDE_DIRECTORIES)
# If the above doesn't work, try alternative methods
if(NOT CUDA_INCLUDE_DIRS)
set(CUDA_INCLUDE_DIRS "${CUDAToolkit_INCLUDE_DIRS}")
endif()
# Still not found? Try environment variables and common paths
if(NOT CUDA_INCLUDE_DIRS)
set(CUDA_SEARCH_PATHS
$ENV{CUDA_PATH}
$ENV{CUDA_HOME}
$ENV{CUDA_ROOT}
${CUDAToolkit_ROOT}
)
if(WIN32)
list(APPEND CUDA_SEARCH_PATHS
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.6"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.5"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.4"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.3"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.2"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.1"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.0"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.8"
"C:/tools/cuda"
)
else()
list(APPEND CUDA_SEARCH_PATHS
/usr/local/cuda
/opt/cuda
/usr/cuda
)
endif()
foreach(search_path ${CUDA_SEARCH_PATHS})
if(EXISTS "${search_path}/include/cuda.h")
set(CUDA_INCLUDE_DIRS "${search_path}/include")
message(STATUS "✅ Found CUDA include directory: ${CUDA_INCLUDE_DIRS}")
break()
endif()
endforeach()
endif()
# Verify we found CUDA headers
if(NOT CUDA_INCLUDE_DIRS)
message(FATAL_ERROR "❌ CUDA include directories not found. Please ensure CUDA toolkit is properly installed.")
endif()
# Verify cuda.h exists
set(CUDA_H_FOUND FALSE)
foreach(include_dir ${CUDA_INCLUDE_DIRS})
if(EXISTS "${include_dir}/cuda.h")
set(CUDA_H_FOUND TRUE)
message(STATUS "✅ Found cuda.h in: ${include_dir}")
break()
endif()
endforeach()
if(NOT CUDA_H_FOUND)
message(FATAL_ERROR "❌ cuda.h not found in CUDA include directories: ${CUDA_INCLUDE_DIRS}")
endif()
# Set variables for parent scope
set(CUDA_INCLUDE_DIRS "${CUDA_INCLUDE_DIRS}" PARENT_SCOPE)
set(CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_ROOT}" PARENT_SCOPE)
message(STATUS "✅ CUDA toolkit paths configured:")
message(STATUS " Root: ${CUDAToolkit_ROOT}")
message(STATUS " Include: ${CUDA_INCLUDE_DIRS}")
message(STATUS " Version: ${CUDAToolkit_VERSION}")
endfunction()
# Modern cuDNN detection using updated FindCUDNN.cmake practices
function(setup_modern_cudnn)
set(HAVE_CUDNN FALSE PARENT_SCOPE)
if(NOT (HELPERS_cudnn AND SD_CUDA))
message(STATUS "🔍 cuDNN: Skipped (HELPERS_cudnn=${HELPERS_cudnn}, SD_CUDA=${SD_CUDA})")
return()
endif()
message(STATUS "🔍 Searching for cuDNN...")
# Find the CUDA toolkit first to get the proper paths
find_package(CUDAToolkit REQUIRED)
# Enhanced search paths for CI environments and common installations
set(CUDNN_SEARCH_PATHS
# Environment variables
$ENV{CUDNN_ROOT_DIR}
$ENV{CUDNN_ROOT}
$ENV{CUDA_PATH}
$ENV{CUDA_HOME}
# CMake variables
${CUDNN_ROOT_DIR}
${CUDAToolkit_ROOT}
)
# Add platform-specific paths
if(WIN32)
# Windows-specific paths
list(APPEND CUDNN_SEARCH_PATHS
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.6"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.5"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.4"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.3"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.2"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.1"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.0"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.8"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.7"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.6"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.5"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.4"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.3"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.2"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.1"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.0"
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA"
"C:/tools/cuda" # Common CI path on Windows
)
else()
# Linux/Unix-specific paths
list(APPEND CUDNN_SEARCH_PATHS
# CI-specific paths (GitHub Actions, etc.)
/usr/local/cuda-12.6
/usr/local/cuda-12.5
/usr/local/cuda-12.4
/usr/local/cuda-12.3
/usr/local/cuda-12.2
/usr/local/cuda-12.1
/usr/local/cuda-12.0
/usr/local/cuda-11.8
/usr/local/cuda-11.7
/usr/local/cuda-11.6
/usr/local/cuda-11.5
/usr/local/cuda-11.4
/usr/local/cuda-11.3
/usr/local/cuda-11.2
/usr/local/cuda-11.1
/usr/local/cuda-11.0
/usr/local/cuda
# Package manager paths
/usr/include/cudnn
/usr/local/include/cudnn
/opt/cuda
/opt/cudnn
# System paths
/usr
/usr/local
)
endif()
message(STATUS "🔍 Searching for cuDNN headers...")
# Search for cuDNN headers with comprehensive path coverage
find_path(CUDNN_INCLUDE_DIR
NAMES cudnn.h
HINTS ${CUDNN_SEARCH_PATHS}
PATHS ${CUDNN_SEARCH_PATHS}
PATH_SUFFIXES
include
targets/x86_64-linux/include
targets/aarch64-linux/include
include/cudnn
cudnn/include
x86_64-linux/include
aarch64-linux/include
NO_DEFAULT_PATH
)
# If not found, try system paths
if(NOT CUDNN_INCLUDE_DIR)
find_path(CUDNN_INCLUDE_DIR
NAMES cudnn.h
PATHS /usr/include /usr/local/include /opt/include
PATH_SUFFIXES cudnn
)
endif()
message(STATUS "🔍 Searching for cuDNN libraries...")
# Search for cuDNN libraries
find_library(CUDNN_LIBRARY
NAMES cudnn libcudnn cudnn8 libcudnn8
HINTS ${CUDNN_SEARCH_PATHS}
PATHS ${CUDNN_SEARCH_PATHS}
PATH_SUFFIXES
lib64
lib
lib/x64
targets/x86_64-linux/lib
targets/aarch64-linux/lib
lib64/cudnn
lib/cudnn
cudnn/lib64
cudnn/lib
x86_64-linux/lib
aarch64-linux/lib
NO_DEFAULT_PATH
)
# If not found, try system paths
if(NOT CUDNN_LIBRARY)
find_library(CUDNN_LIBRARY
NAMES cudnn libcudnn cudnn8 libcudnn8
PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib
PATH_SUFFIXES cudnn
)
endif()
message(STATUS "🔍 cuDNN search results:")
message(STATUS " CUDNN_INCLUDE_DIR: ${CUDNN_INCLUDE_DIR}")
message(STATUS " CUDNN_LIBRARY: ${CUDNN_LIBRARY}")
# Check if we found both header and library
if(CUDNN_INCLUDE_DIR AND CUDNN_LIBRARY)
message(STATUS "✅ cuDNN found!")
# Extract version information from cudnn.h
if(EXISTS "${CUDNN_INCLUDE_DIR}/cudnn.h")
file(READ "${CUDNN_INCLUDE_DIR}/cudnn.h" CUDNN_HEADER_CONTENTS)
# Try different version detection methods
string(REGEX MATCH "define CUDNN_MAJOR[ \t]+([0-9]+)" CUDNN_VERSION_MAJOR_MATCH "${CUDNN_HEADER_CONTENTS}")
string(REGEX MATCH "define CUDNN_MINOR[ \t]+([0-9]+)" CUDNN_VERSION_MINOR_MATCH "${CUDNN_HEADER_CONTENTS}")
string(REGEX MATCH "define CUDNN_PATCHLEVEL[ \t]+([0-9]+)" CUDNN_VERSION_PATCH_MATCH "${CUDNN_HEADER_CONTENTS}")
if(CUDNN_VERSION_MAJOR_MATCH)
string(REGEX REPLACE "define CUDNN_MAJOR[ \t]+([0-9]+)" "\\1" CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR_MATCH}")
string(REGEX REPLACE "define CUDNN_MINOR[ \t]+([0-9]+)" "\\1" CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR_MATCH}")
string(REGEX REPLACE "define CUDNN_PATCHLEVEL[ \t]+([0-9]+)" "\\1" CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH_MATCH}")
set(CUDNN_VERSION_STRING "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}")
else()
# Try alternative version detection
string(REGEX MATCH "#define CUDNN_MAJOR ([0-9]+)" CUDNN_VERSION_MAJOR_MATCH2 "${CUDNN_HEADER_CONTENTS}")
if(CUDNN_VERSION_MAJOR_MATCH2)
string(REGEX REPLACE "#define CUDNN_MAJOR ([0-9]+)" "\\1" CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR_MATCH2}")
string(REGEX MATCH "#define CUDNN_MINOR ([0-9]+)" CUDNN_VERSION_MINOR_MATCH2 "${CUDNN_HEADER_CONTENTS}")
string(REGEX MATCH "#define CUDNN_PATCHLEVEL ([0-9]+)" CUDNN_VERSION_PATCH_MATCH2 "${CUDNN_HEADER_CONTENTS}")
string(REGEX REPLACE "#define CUDNN_MINOR ([0-9]+)" "\\1" CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR_MATCH2}")
string(REGEX REPLACE "#define CUDNN_PATCHLEVEL ([0-9]+)" "\\1" CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH_MATCH2}")
set(CUDNN_VERSION_STRING "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}")
else()
set(CUDNN_VERSION_STRING "Unknown")
endif()
endif()
else()
message(WARNING "⚠️ cuDNN header found but cannot read version")
set(CUDNN_VERSION_STRING "Unknown")
endif()
# Create imported target if it doesn't exist
if(NOT TARGET CUDNN::cudnn)
add_library(CUDNN::cudnn UNKNOWN IMPORTED)
set_target_properties(CUDNN::cudnn PROPERTIES
IMPORTED_LOCATION "${CUDNN_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${CUDNN_INCLUDE_DIR}"
)
endif()
message(STATUS "✅ cuDNN configuration:")
message(STATUS " Include: ${CUDNN_INCLUDE_DIR}")
message(STATUS " Library: ${CUDNN_LIBRARY}")
message(STATUS " Version: ${CUDNN_VERSION_STRING}")
# Set all the variables that might be needed
set(HAVE_CUDNN TRUE PARENT_SCOPE)
set(CUDNN_FOUND TRUE PARENT_SCOPE)
set(CUDNN_INCLUDE_DIR "${CUDNN_INCLUDE_DIR}" PARENT_SCOPE)
set(CUDNN_LIBRARIES "${CUDNN_LIBRARY}" PARENT_SCOPE)
set(CUDNN_LIBRARY "${CUDNN_LIBRARY}" PARENT_SCOPE)
set(CUDNN_VERSION_STRING "${CUDNN_VERSION_STRING}" PARENT_SCOPE)
return()
endif()
# Try package manager detection as fallback
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(PC_CUDNN QUIET cudnn)
if(PC_CUDNN_FOUND)
message(STATUS "✅ Found cuDNN via pkg-config")
set(HAVE_CUDNN TRUE PARENT_SCOPE)
set(CUDNN_INCLUDE_DIR "${PC_CUDNN_INCLUDE_DIRS}" PARENT_SCOPE)
set(CUDNN_LIBRARIES "${PC_CUDNN_LIBRARIES}" PARENT_SCOPE)
set(CUDNN_VERSION_STRING "${PC_CUDNN_VERSION}" PARENT_SCOPE)
return()
endif()
endif()
# Final attempt: check if cuDNN is embedded in CUDA installation
if(CUDAToolkit_FOUND AND CUDAToolkit_INCLUDE_DIRS)
foreach(cuda_include_dir ${CUDAToolkit_INCLUDE_DIRS})
if(EXISTS "${cuda_include_dir}/cudnn.h")
message(STATUS "✅ Found cuDNN embedded in CUDA installation")
set(HAVE_CUDNN TRUE PARENT_SCOPE)
set(CUDNN_INCLUDE_DIR "${cuda_include_dir}" PARENT_SCOPE)
set(CUDNN_LIBRARIES "" PARENT_SCOPE) # May be linked with CUDA
set(CUDNN_VERSION_STRING "Embedded" PARENT_SCOPE)
return()
endif()
endforeach()
endif()
message(STATUS "❌ cuDNN not found. Searched extensively in:")
message(STATUS " Environment variables: CUDNN_ROOT_DIR, CUDNN_ROOT, CUDA_PATH, CUDA_HOME")
message(STATUS " CUDA installation: ${CUDAToolkit_ROOT}")
if(WIN32)
message(STATUS " System paths: $ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit")
else()
message(STATUS " System paths: /usr, /usr/local, /opt")
endif()
message(STATUS " Package manager: pkg-config")
message(STATUS "")
message(STATUS "💡 To fix this issue:")
message(STATUS " 1. Install cuDNN development libraries")
message(STATUS " 2. Set CUDNN_ROOT_DIR to your cuDNN installation")
message(STATUS " 3. Ensure cuDNN headers are in CUDA_PATH/include")
message(STATUS " 4. Or disable cuDNN with -DHELPERS_cudnn=OFF")
# Debug information
message(STATUS "")
message(STATUS "🔍 Debug information:")
message(STATUS " CUDAToolkit_ROOT: ${CUDAToolkit_ROOT}")
message(STATUS " CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}")
message(STATUS " ENV CUDNN_ROOT_DIR: $ENV{CUDNN_ROOT_DIR}")
message(STATUS " ENV CUDA_PATH: $ENV{CUDA_PATH}")
message(STATUS " ENV CUDA_HOME: $ENV{CUDA_HOME}")
endfunction()
function(configure_cuda_linking main_target_name)
# Setup CUDA toolkit paths first
setup_cuda_toolkit_paths()
# Find the CUDAToolkit to define the CUDA::toolkit target
find_package(CUDAToolkit REQUIRED)
# Setup modern cuDNN detection
setup_modern_cudnn()
# This ensures cuda.h and other CUDA headers are found
if(CUDA_INCLUDE_DIRS)
target_include_directories(${main_target_name} PUBLIC ${CUDA_INCLUDE_DIRS})
message(STATUS "✅ Added CUDA include directories to ${main_target_name}: ${CUDA_INCLUDE_DIRS}")
endif()
# Apply GNU-specific CUDA compiler flags for duplicate instantiation handling
# ONLY for non-Windows builds
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT WIN32)
message(STATUS "🔧 Applying GNU-specific CUDA flags for duplicate instantiation handling")
target_compile_options(${main_target_name} PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-fno-implicit-templates>
)
endif()
# Modern CMake uses imported targets which handle all necessary dependencies.
# Linking against CUDA::toolkit automatically adds include directories,
# runtime libraries, and all other required flags.
target_link_libraries(${main_target_name} PUBLIC CUDA::toolkit)
# If cuDNN was found, link against its imported target
if(HAVE_CUDNN AND TARGET CUDNN::cudnn)
message(STATUS "✅ Linking with modern CUDNN::cudnn target")
target_link_libraries(${main_target_name} PUBLIC CUDNN::cudnn)
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
elseif(HAVE_CUDNN AND CUDNN_LIBRARIES)
message(STATUS "✅ Linking with cuDNN libraries: ${CUDNN_LIBRARIES}")
target_link_libraries(${main_target_name} PUBLIC ${CUDNN_LIBRARIES})
target_include_directories(${main_target_name} PUBLIC ${CUDNN_INCLUDE_DIR})
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
elseif(HAVE_CUDNN AND CUDNN_INCLUDE_DIR)
message(STATUS "✅ Linking with cuDNN include-only (embedded in CUDA)")
target_include_directories(${main_target_name} PUBLIC ${CUDNN_INCLUDE_DIR})
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
else()
message(STATUS "️ Building without cuDNN support")
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=0)
endif()
target_link_libraries(${main_target_name} PUBLIC flatbuffers_interface)
install(TARGETS ${main_target_name} DESTINATION .)
endfunction()
function(setup_cuda_architectures_early)
if(NOT SD_CUDA)
return()
endif()
# Fix missing _CMAKE_CUDA_WHOLE_FLAG (note the underscore prefix)
if(NOT DEFINED _CMAKE_CUDA_WHOLE_FLAG)
message(STATUS "Setting _CMAKE_CUDA_WHOLE_FLAG (was missing)")
if(WIN32)
set(_CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE INTERNAL "CUDA whole archive flag")
else()
set(_CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE INTERNAL "CUDA whole archive flag")
endif()
endif()
if(NOT DEFINED CMAKE_CUDA_WHOLE_FLAG)
if(WIN32)
set(CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE STRING "CUDA whole archive flag")
else()
set(CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE STRING "CUDA whole archive flag")
endif()
endif()
message(STATUS "🔧 Early CUDA: Configuring architectures before project() call")
if(DEFINED COMPUTE)
string(TOLOWER "${COMPUTE}" COMPUTE_CMP)
if(COMPUTE_CMP STREQUAL "all")
set(CUDA_ARCHITECTURES "75;80;86;89" PARENT_SCOPE)
message(STATUS " CUDA architectures (all): 75;80;86;89")
elseif(COMPUTE_CMP STREQUAL "auto")
set(CMAKE_CUDA_ARCHITECTURES "86" PARENT_SCOPE)
message(STATUS " CUDA architectures (auto): 86")
else()
string(REPLACE "," ";" ARCH_LIST "${COMPUTE}")
set(PARSED_ARCHS "")
foreach(ARCH ${ARCH_LIST})
string(REPLACE "." "" ARCH_CLEAN "${ARCH}")
if(ARCH_CLEAN MATCHES "^[0-9][0-9]$")
list(APPEND PARSED_ARCHS "${ARCH_CLEAN}")
endif()
endforeach()
if(PARSED_ARCHS)
set(CUDA_ARCHITECTURES "${PARSED_ARCHS}" PARENT_SCOPE)
message(STATUS " CUDA architectures (custom): ${PARSED_ARCHS}")
else()
set(CUDA_ARCHITECTURES "86" PARENT_SCOPE)
message(STATUS " CUDA architectures (default): 86")
endif()
endif()
else()
set(CUDA_ARCHITECTURES "86" PARENT_SCOPE)
message(STATUS " CUDA architectures (no COMPUTE): 86")
endif()
endfunction()
function(setup_cuda_language)
if(NOT DEFINED _CMAKE_CUDA_WHOLE_FLAG)
message(STATUS "Setting _CMAKE_CUDA_WHOLE_FLAG (was missing)")
if(WIN32)
set(_CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE INTERNAL "CUDA whole archive flag")
else()
set(_CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE INTERNAL "CUDA whole archive flag")
endif()
endif()
include(CheckLanguage)
check_language(CUDA)
if(NOT CMAKE_CUDA_COMPILER)
find_program(NVCC_EXECUTABLE nvcc)
if(NVCC_EXECUTABLE)
set(CMAKE_CUDA_COMPILER ${NVCC_EXECUTABLE} PARENT_SCOPE)
message(STATUS "CUDA compiler found: ${CMAKE_CUDA_COMPILER}")
else()
message(FATAL_ERROR "CUDA compiler not found. Please ensure CUDA toolkit is installed and nvcc is in PATH.")
endif()
endif()
message(STATUS "CUDA language enabled successfully with compiler: ${CMAKE_CUDA_COMPILER}")
endfunction()
function(configure_windows_cuda_build)
if(NOT WIN32)
return()
endif()
message(STATUS "Configuring Windows CUDA build with verbose mode...")
# Enable verbose output for the build system
set(CMAKE_VERBOSE_MAKEFILE ON PARENT_SCOPE)
set(CMAKE_CUDA_VERBOSE_FLAG ON PARENT_SCOPE)
# Completely disable response files to prevent command line issues
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS OFF PARENT_SCOPE)
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES OFF PARENT_SCOPE)
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES OFF PARENT_SCOPE)
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LINK_OBJECTS OFF PARENT_SCOPE)
# Remove problematic dependency generation that causes NVCC failures
set(CMAKE_CUDA_DEPFILE_FORMAT "" PARENT_SCOPE)
set(CMAKE_CUDA_DEPENDS_USE_COMPILER OFF PARENT_SCOPE)
# Clean MSVC runtime library settings
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "" PARENT_SCOPE)
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "" PARENT_SCOPE)
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "" PARENT_SCOPE)
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "" PARENT_SCOPE)
# Force clean CXX flags to prevent contamination
set(CMAKE_CXX_FLAGS "" PARENT_SCOPE)
# Enable verbose rule and target messages
set_property(GLOBAL PROPERTY RULE_MESSAGES ON)
set_property(GLOBAL PROPERTY TARGET_MESSAGES ON)
message(STATUS "Windows CUDA: Verbose mode enabled with clean flags")
endfunction()
function(configure_cuda_architecture_flags COMPUTE)
string(TOLOWER "${COMPUTE}" COMPUTE_CMP)
if(COMPUTE_CMP STREQUAL "all")
set(CUDA_ARCH_FLAGS "-gencode arch=compute_75,code=sm_75 -gencode arch=compute_80,code=sm_80 -gencode arch=compute_86,code=sm_86 -gencode arch=compute_89,code=sm_89" PARENT_SCOPE)
message(STATUS "Building for all CUDA architectures (gencode flags)")
elseif(COMPUTE_CMP STREQUAL "auto")
set(CUDA_ARCH_FLAGS "-gencode arch=compute_86,code=sm_86" PARENT_SCOPE)
message(STATUS "Auto-detecting CUDA architectures (gencode flags)")
else()
string(REPLACE "," ";" ARCH_LIST "${COMPUTE}")
set(ARCH_FLAGS "")
foreach(ARCH ${ARCH_LIST})
string(REPLACE "." "" ARCH_CLEAN "${ARCH}")
if(ARCH_CLEAN MATCHES "^[0-9][0-9]$")
set(ARCH_FLAGS "${ARCH_FLAGS} -gencode arch=compute_${ARCH_CLEAN},code=sm_${ARCH_CLEAN}")
endif()
endforeach()
string(STRIP "${ARCH_FLAGS}" ARCH_FLAGS)
if(ARCH_FLAGS)
set(CUDA_ARCH_FLAGS "${ARCH_FLAGS}" PARENT_SCOPE)
message(STATUS "Using custom CUDA architectures (gencode flags): ${ARCH_FLAGS}")
else()
set(CUDA_ARCH_FLAGS "-gencode arch=compute_86,code=sm_86" PARENT_SCOPE)
message(STATUS "Using default CUDA architecture (gencode flags)")
endif()
endif()
endfunction()
function(build_cuda_compiler_flags CUDA_ARCH_FLAGS)
set(LOCAL_CUDA_FLAGS "")
if(WIN32 AND MSVC)
message(STATUS "Configuring CUDA for Windows MSVC with verbose mode...")
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} PARENT_SCOPE)
set(LOCAL_CUDA_FLAGS "-maxrregcount=128")
# Enable verbose mode for Windows CUDA compilation
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --verbose")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --ptxas-options=-v")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --resource-usage")
# Host compiler verbose flags
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/showIncludes")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/verbose")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/diagnostics:caret")
# Linker verbose flags
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=/VERBOSE")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=/TIME")
# Explicitly enable C++17 for the host compiler
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/std:c++17")
if(WIN32 AND NOT CMAKE_CUDA_HOST_COMPILER)
find_program(CL_IN_PATH cl.exe)
if(CL_IN_PATH)
# Check if this cl.exe is 64-bit by examining its path
get_filename_component(CL_DIR ${CL_IN_PATH} DIRECTORY)
if(CL_DIR MATCHES "x64")
set(CMAKE_CUDA_HOST_COMPILER ${CL_IN_PATH})
message(STATUS "Found x64 cl.exe in PATH: ${CMAKE_CUDA_HOST_COMPILER}")
else()
# Try to find x64 version relative to this cl.exe
get_filename_component(CL_PARENT ${CL_DIR} DIRECTORY)
if(EXISTS "${CL_PARENT}/x64/cl.exe")
set(CMAKE_CUDA_HOST_COMPILER "${CL_PARENT}/x64/cl.exe")
message(STATUS "Found x64 cl.exe relative to PATH cl.exe: ${CMAKE_CUDA_HOST_COMPILER}")
endif()
endif()
endif()
endif()
if(WIN32 AND NOT CMAKE_CUDA_HOST_COMPILER)
# Only check the most common paths that exist in barebones installs
set(COMMON_PATHS
"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC"
"C:/Program Files/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC"
)
foreach(BASE_PATH ${COMMON_PATHS})
if(EXISTS ${BASE_PATH})
file(GLOB MSVC_VERSIONS "${BASE_PATH}/*")
if(MSVC_VERSIONS)
# Get the lexicographically last version (should be newest)
list(SORT MSVC_VERSIONS)
list(REVERSE MSVC_VERSIONS)
list(GET MSVC_VERSIONS 0 LATEST_MSVC)
set(CANDIDATE_COMPILER "${LATEST_MSVC}/bin/Hostx64/x64/cl.exe")
if(EXISTS ${CANDIDATE_COMPILER})
set(CMAKE_CUDA_HOST_COMPILER ${CANDIDATE_COMPILER})
message(STATUS "Found CUDA host compiler in standard path: ${CMAKE_CUDA_HOST_COMPILER}")
break()
endif()
endif()
endif()
endforeach()
endif()
# Validation and warning
if(WIN32)
if(CMAKE_CUDA_HOST_COMPILER)
if(NOT EXISTS ${CMAKE_CUDA_HOST_COMPILER})
message(WARNING "CUDA host compiler path does not exist: ${CMAKE_CUDA_HOST_COMPILER}")
unset(CMAKE_CUDA_HOST_COMPILER)
else()
message(STATUS "Final CUDA host compiler: ${CMAKE_CUDA_HOST_COMPILER}")
endif()
else()
message(WARNING "Could not auto-detect x64 CUDA host compiler.")
message(STATUS "Manual options:")
message(STATUS " 1. Use x64 Native Tools Command Prompt")
message(STATUS " 2. Set manually: -DCMAKE_CUDA_HOST_COMPILER=\"path/to/x64/cl.exe\"")
message(STATUS " 3. Ensure x64 cl.exe is in your PATH")
endif()
endif()
# Windows/MSVC flags: bigobj, EHsc, *and* disable the new preprocessor
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}
-Xcompiler=/std:c++17
-Xcompiler=/bigobj
-Xcompiler=/EHsc
-Xcompiler=/Zc:preprocessor-")
# Force clean host compiler flags
set(CMAKE_CXX_FLAGS "" PARENT_SCOPE)
message(STATUS "CUDA Windows verbose flags configured")
else()
message(STATUS "Configuring CUDA for Unix/Linux with verbose mode...")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -maxrregcount=128")
# Enable verbose mode for Unix/Linux CUDA compilation
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --verbose")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --ptxas-options=-v")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --resource-usage")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Host compiler verbose flags for GCC
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-v")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-H")
# Linker verbose flags
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=-v")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=--verbose")
if(SD_GCC_FUNCTRACE)
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-fPIC --device-debug -lineinfo -G")
else()
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-fPIC -Xcompiler=-fpermissive")
# Add flags to handle duplicate instantiations for GNU compiler
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-fno-implicit-templates")
endif()
endif()
message(STATUS "CUDA Unix/Linux verbose flags configured")
endif()
if("${SD_PTXAS}" STREQUAL "ON")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --ptxas-options=-v")
endif()
if(SD_KEEP_NVCC_OUTPUT)
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --keep")
endif()
if(DEFINED CUDA_ARCH_FLAGS)
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} ${CUDA_ARCH_FLAGS}")
endif()
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -w --cudart=shared --expt-extended-lambda -Xfatbin -compress-all")
if(CMAKE_CUDA_COMPILER_VERSION)
string(REGEX MATCH "^([0-9]+)" CUDA_VERSION_MAJOR "${CMAKE_CUDA_COMPILER_VERSION}")
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -DCUDA_VERSION_MAJOR=${CUDA_VERSION_MAJOR}")
endif()
# Clean up any problematic flags for Windows
if(WIN32)
# Remove any GCC-style flags that might have been added
string(REGEX REPLACE "-MD[^a-zA-Z]" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-MT[^a-zA-Z]" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-MF[^a-zA-Z]" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-x cu" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-fpermissive" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-Wno-error" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "/FS[ ]*" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-Xcompiler=-Fd[^,]*,?" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-Xcompiler=," "-Xcompiler=" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(REGEX REPLACE "-Xcompiler=$" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
endif()
string(REGEX REPLACE " +" " " LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
string(STRIP "${LOCAL_CUDA_FLAGS}" LOCAL_CUDA_FLAGS)
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON PARENT_SCOPE)
set(CMAKE_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}" PARENT_SCOPE)
message(STATUS "Final CMAKE_CUDA_FLAGS (with verbose): ${LOCAL_CUDA_FLAGS}")
endfunction()
# Debug configuration function
function(debug_cuda_configuration)
message(STATUS "=== CUDA Configuration Debug Info ===")
message(STATUS "CMAKE_CUDA_COMPILER: ${CMAKE_CUDA_COMPILER}")
message(STATUS "CMAKE_CUDA_COMPILER_VERSION: ${CMAKE_CUDA_COMPILER_VERSION}")
message(STATUS "CMAKE_CUDA_ARCHITECTURES: ${CMAKE_CUDA_ARCHITECTURES}")
message(STATUS "CMAKE_CUDA_FLAGS: ${CMAKE_CUDA_FLAGS}")
message(STATUS "CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES: ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}")
message(STATUS "CMAKE_CUDA_COMPILE_OBJECT: ${CMAKE_CUDA_COMPILE_OBJECT}")
message(STATUS "CUDA_INCLUDE_DIRS: ${CUDA_INCLUDE_DIRS}")
message(STATUS "CUDAToolkit_ROOT: ${CUDAToolkit_ROOT}")
message(STATUS "CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}")
if(HAVE_CUDNN)
message(STATUS "CUDNN_INCLUDE_DIR: ${CUDNN_INCLUDE_DIR}")
message(STATUS "CUDNN_LIBRARIES: ${CUDNN_LIBRARIES}")
message(STATUS "CUDNN_VERSION: ${CUDNN_VERSION_STRING}")
endif()
message(STATUS "=== End CUDA Debug Info ===")
endfunction()
# Enhanced CUDA include directory setup for global configuration
function(setup_cuda_include_directories)
setup_cuda_toolkit_paths()
# Set global include directories that will be inherited by all targets
if(CUDA_INCLUDE_DIRS)
include_directories(${CUDA_INCLUDE_DIRS})
message(STATUS "✅ Added global CUDA include directories: ${CUDA_INCLUDE_DIRS}")
endif()
# Also set the CMAKE variable for compatibility
if(CUDAToolkit_INCLUDE_DIRS)
set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES ${CUDAToolkit_INCLUDE_DIRS} PARENT_SCOPE)
endif()
endfunction()
function(setup_cuda_build)
message(STATUS "=== CUDA BUILD CONFIGURATION (VERBOSE MODE) ===")
# Enable verbose output for the build system
set(CMAKE_VERBOSE_MAKEFILE ON PARENT_SCOPE)
set(CMAKE_CUDA_VERBOSE_FLAG ON PARENT_SCOPE)
if(NOT DEFINED _CMAKE_CUDA_WHOLE_FLAG)
message(STATUS "Setting _CMAKE_CUDA_WHOLE_FLAG (was missing)")
if(WIN32)
set(_CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE INTERNAL "CUDA whole archive flag")
else()
set(_CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE INTERNAL "CUDA whole archive flag")
endif()
endif()
# Setup CUDA toolkit paths and include directories early
setup_cuda_include_directories()
if(NOT DEFINED COMPUTE)
set(COMPUTE "auto")
endif()
configure_cuda_architecture_flags("${COMPUTE}")
set_property(GLOBAL PROPERTY CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES}")
setup_cuda_language()
if(NOT CMAKE_CUDA_COMPILER)
message(FATAL_ERROR "CUDA compiler not found after enabling CUDA language")
endif()
message(STATUS "CUDA Compiler: ${CMAKE_CUDA_COMPILER}")
message(STATUS "CUDA Include Dirs: ${CUDA_INCLUDE_DIRS}")
message(STATUS "CUDAToolkit Include Dirs: ${CUDAToolkit_INCLUDE_DIRS}")
message(STATUS "Host CXX Compiler: ${CMAKE_CXX_COMPILER_ID}")
configure_windows_cuda_build()
build_cuda_compiler_flags("${CUDA_ARCH_FLAGS}")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS}" PARENT_SCOPE)
# Also set the toolkit include directories for global access
set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${CUDA_INCLUDE_DIRS}" PARENT_SCOPE)
# Enable verbose rule and target messages
set_property(GLOBAL PROPERTY RULE_MESSAGES ON)
set_property(GLOBAL PROPERTY TARGET_MESSAGES ON)
debug_cuda_configuration()
add_compile_definitions(SD_CUDA=true)
set(DEFAULT_ENGINE "samediff::ENGINE_CUDA" PARENT_SCOPE)
message(STATUS "=== CUDA BUILD CONFIGURATION (VERBOSE MODE) COMPLETE ===")
endfunction()
# Enhanced function to ensure CUDA paths are available at configure time
function(ensure_cuda_paths_available)
if(NOT SD_CUDA)
return()
endif()
message(STATUS "🔍 Ensuring CUDA paths are available...")
# Find CUDA early
find_package(CUDAToolkit REQUIRED)
# Set up paths immediately
setup_cuda_toolkit_paths()
# Export to parent scope for immediate use
set(CUDA_INCLUDE_DIRS "${CUDA_INCLUDE_DIRS}" PARENT_SCOPE)
set(CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_ROOT}" PARENT_SCOPE)
message(STATUS "✅ CUDA paths configured and available")
endfunction()
# Legacy function for backward compatibility - now calls modern version
function(setup_cudnn)
setup_modern_cudnn()
# Set legacy variables for backward compatibility
set(HAVE_CUDNN ${HAVE_CUDNN} PARENT_SCOPE)
if(HAVE_CUDNN)
set(CUDNN_INCLUDE_DIR ${CUDNN_INCLUDE_DIR} PARENT_SCOPE)
set(CUDNN ${CUDNN_LIBRARIES} PARENT_SCOPE)
endif()
endfunction()
+510
View File
@@ -0,0 +1,510 @@
# cmake/Dependencies.cmake
# Manages all third-party dependencies. Logic is encapsulated in functions.
include(ExternalProject)
function(setup_android_arm_openblas)
set(is_android_or_arm FALSE)
if(ANDROID OR SD_ANDROID_BUILD OR SD_ARM_BUILD OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm64|ARM64")
set(is_android_or_arm TRUE)
endif()
if(NOT is_android_or_arm)
return()
endif()
message(STATUS "🔧 Setting up OpenBLAS for Android/ARM platform")
# Handle path normalization for Android/ARM
if(OPENBLAS_PATH MATCHES "lib/[^/]+$")
get_filename_component(OPENBLAS_PATH "${OPENBLAS_PATH}/../.." ABSOLUTE)
message(STATUS "🔧 Normalized OPENBLAS_PATH: ${OPENBLAS_PATH}")
endif()
# Platform-specific OpenBLAS library name handling
if(EXISTS "${OPENBLAS_PATH}/lib")
# Define search patterns based on platform
set(LIB_SEARCH_PATTERNS
"${OPENBLAS_PATH}/lib/libopenblas.so"
"${OPENBLAS_PATH}/lib/libopenblas.a"
)
# Add platform-specific patterns
if(ANDROID OR SD_ANDROID_BUILD)
if(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")
list(APPEND LIB_SEARCH_PATTERNS
"${OPENBLAS_PATH}/lib/android-x86_64/libopenblas.so"
"${OPENBLAS_PATH}/lib/android-x86_64/libopenblas.a"
)
elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
list(APPEND LIB_SEARCH_PATTERNS
"${OPENBLAS_PATH}/lib/android-arm64/libopenblas.so"
"${OPENBLAS_PATH}/lib/android-arm64/libopenblas.a"
"${OPENBLAS_PATH}/lib/android-aarch64/libopenblas.so"
"${OPENBLAS_PATH}/lib/android-aarch64/libopenblas.a"
)
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm64|ARM64")
list(APPEND LIB_SEARCH_PATTERNS
"${OPENBLAS_PATH}/lib/linux-arm64/libopenblas.so"
"${OPENBLAS_PATH}/lib/linux-arm64/libopenblas.a"
"${OPENBLAS_PATH}/lib/linux-aarch64/libopenblas.so"
"${OPENBLAS_PATH}/lib/linux-aarch64/libopenblas.a"
)
endif()
# Search for libraries
set(FOUND_OPENBLAS_LIBS "")
foreach(pattern ${LIB_SEARCH_PATTERNS})
file(GLOB matched_libs ${pattern})
if(matched_libs)
list(APPEND FOUND_OPENBLAS_LIBS ${matched_libs})
endif()
endforeach()
if(FOUND_OPENBLAS_LIBS)
message(STATUS "✅ Found OpenBLAS libraries: ${FOUND_OPENBLAS_LIBS}")
else()
message(WARNING "⚠️ No OpenBLAS libraries found in ${OPENBLAS_PATH}/lib")
endif()
endif()
# Set platform-specific compiler flags for OpenBLAS
if(ANDROID OR SD_ANDROID_BUILD)
if(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=x86-64" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=x86-64" PARENT_SCOPE)
elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a" PARENT_SCOPE)
endif()
elseif(SD_ARM_BUILD OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm64|ARM64")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a -mtune=cortex-a72" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a -mtune=cortex-a72" PARENT_SCOPE)
endif()
# Set additional ARM-specific optimizations
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm64|ARM64" OR CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfix-cortex-a53-835769 -mfix-cortex-a53-843419" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfix-cortex-a53-835769 -mfix-cortex-a53-843419" PARENT_SCOPE)
endif()
endfunction()
function(setup_blas)
if(SD_CUDA)
return()
endif()
if(NOT OPENBLAS_PATH)
message(STATUS "❌ OPENBLAS_PATH not set")
return()
endif()
# Handle Android path normalization at CMake level (in case shell script normalization didn't work)
setup_android_arm_openblas()
# Verify the path exists and has the required headers
if(NOT EXISTS "${OPENBLAS_PATH}/include")
message(STATUS "❌ OpenBLAS include directory not found: ${OPENBLAS_PATH}/include")
return()
endif()
if(NOT EXISTS "${OPENBLAS_PATH}/include/cblas.h")
message(STATUS "❌ OpenBLAS cblas.h not found: ${OPENBLAS_PATH}/include/cblas.h")
return()
endif()
# Set up OpenBLAS
message(STATUS "✅ Setting up OpenBLAS:")
message(STATUS " Path: ${OPENBLAS_PATH}")
message(STATUS " Include: ${OPENBLAS_PATH}/include")
message(STATUS " Library: ${OPENBLAS_PATH}/")
# Use global include_directories for compatibility
include_directories(${OPENBLAS_PATH}/include/)
# Set up library directories
if(EXISTS "${OPENBLAS_PATH}/lib")
link_directories(${OPENBLAS_PATH}/)
endif()
add_compile_definitions(HAVE_OPENBLAS=1)
# Set parent scope variables
set(HAVE_OPENBLAS 1 PARENT_SCOPE)
set(OPENBLAS_LIBRARIES openblas PARENT_SCOPE)
set(OPENBLAS_PATH "${OPENBLAS_PATH}" PARENT_SCOPE)
message(STATUS "✅ OpenBLAS setup complete")
endfunction()
function(setup_cudnn)
set(HAVE_CUDNN false PARENT_SCOPE)
set(CUDNN "" PARENT_SCOPE)
if(NOT (HELPERS_cudnn STREQUAL "ON" AND SD_CUDA))
message(STATUS "cuDNN helper is disabled (HELPERS_cudnn=${HELPERS_cudnn}, SD_CUDA=${SD_CUDA})")
return()
endif()
endfunction()
# =============================================================================
# FLATBUFFERS (Required) - Cross-compilation compatible version
# =============================================================================
function(setup_flatbuffers)
set(FLATBUFFERS_VERSION "25.2.10")
set(FLATBUFFERS_URL "https://github.com/google/flatbuffers/archive/v${FLATBUFFERS_VERSION}.tar.gz")
# Determine if we should build flatc
set(SHOULD_BUILD_FLATC FALSE)
if(DEFINED ENV{GENERATE_FLATC} OR DEFINED GENERATE_FLATC)
set(SHOULD_BUILD_FLATC TRUE)
endif()
if(CMAKE_CROSSCOMPILING AND SHOULD_BUILD_FLATC)
# Cross-compilation scenario: build flatc for host, library for target
message(STATUS "Cross-compiling FlatBuffers: building flatc for host, library for target")
# Stage 1: Build flatc for host system
set(FLATC_HOST_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-host")
set(FLATC_HOST_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-host-build")
set(FLATC_EXECUTABLE "${FLATC_HOST_BUILD_DIR}/flatc")
# Determine host system compilers
find_program(HOST_C_COMPILER NAMES gcc clang cc)
find_program(HOST_CXX_COMPILER NAMES g++ clang++ c++)
if(NOT HOST_C_COMPILER OR NOT HOST_CXX_COMPILER)
message(FATAL_ERROR "Could not find host system compilers for flatc build")
endif()
# Build CMAKE_ARGS without toolchain file for host build
set(HOST_CMAKE_ARGS
-DCMAKE_BUILD_TYPE=Release
-DFLATBUFFERS_BUILD_FLATC=ON
-DFLATBUFFERS_BUILD_FLATLIB=OFF
-DFLATBUFFERS_BUILD_TESTS=OFF
-DFLATBUFFERS_BUILD_SAMPLES=OFF
-DCMAKE_C_COMPILER=${HOST_C_COMPILER}
-DCMAKE_CXX_COMPILER=${HOST_CXX_COMPILER}
)
ExternalProject_Add(flatbuffers_host
URL ${FLATBUFFERS_URL}
SOURCE_DIR "${FLATC_HOST_DIR}"
BINARY_DIR "${FLATC_HOST_BUILD_DIR}"
CMAKE_ARGS ${HOST_CMAKE_ARGS}
BUILD_COMMAND ${CMAKE_COMMAND} --build . --target flatc --config Release
INSTALL_COMMAND ""
BUILD_BYPRODUCTS "${FLATC_EXECUTABLE}"
)
# Stage 2: Build FlatBuffers library for target
# Build CMAKE_ARGS for target build, only include variables that are set
set(TARGET_CMAKE_ARGS
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_BUILD_TYPE=Release
-DFLATBUFFERS_BUILD_FLATC=OFF
-DFLATBUFFERS_BUILD_FLATLIB=ON
-DFLATBUFFERS_BUILD_TESTS=OFF
-DFLATBUFFERS_BUILD_SAMPLES=OFF
)
# Only add cross-compilation arguments if they are defined
if(CMAKE_TOOLCHAIN_FILE)
list(APPEND TARGET_CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
endif()
if(CMAKE_SYSTEM_NAME)
list(APPEND TARGET_CMAKE_ARGS -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
endif()
if(CMAKE_SYSTEM_VERSION)
list(APPEND TARGET_CMAKE_ARGS -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION})
endif()
if(CMAKE_ANDROID_ARCH_ABI)
list(APPEND TARGET_CMAKE_ARGS -DCMAKE_ANDROID_ARCH_ABI=${CMAKE_ANDROID_ARCH_ABI})
endif()
if(CMAKE_ANDROID_NDK)
list(APPEND TARGET_CMAKE_ARGS -DCMAKE_ANDROID_NDK=${CMAKE_ANDROID_NDK})
endif()
if(CMAKE_ANDROID_STL_TYPE)
list(APPEND TARGET_CMAKE_ARGS -DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE})
endif()
if(ANDROID_ABI)
list(APPEND TARGET_CMAKE_ARGS -DANDROID_ABI=${ANDROID_ABI})
endif()
if(ANDROID_PLATFORM)
list(APPEND TARGET_CMAKE_ARGS -DANDROID_PLATFORM=${ANDROID_PLATFORM})
endif()
if(ANDROID_STL)
list(APPEND TARGET_CMAKE_ARGS -DANDROID_STL=${ANDROID_STL})
endif()
ExternalProject_Add(flatbuffers_target
URL ${FLATBUFFERS_URL}
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-target-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-target-build"
CMAKE_ARGS ${TARGET_CMAKE_ARGS}
INSTALL_COMMAND ""
BUILD_BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-target-build/libflatbuffers.a"
DEPENDS flatbuffers_host
)
# DO NOT use include_directories() - use target_include_directories on flatbuffers_interface instead
# Set up include directories and library
# include_directories("${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-target-src/include")
set(FLATBUFFERS_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-target-build/libflatbuffers.a")
set(FLATBUFFERS_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-target-src")
# Create interface library for target
add_library(flatbuffers_interface INTERFACE)
target_link_libraries(flatbuffers_interface INTERFACE ${FLATBUFFERS_LIBRARY})
target_include_directories(flatbuffers_interface INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-target-src/include")
add_dependencies(flatbuffers_interface flatbuffers_target)
# Check if flatbuffers.h already exists
set(FLATBUFFERS_HEADER_DEST "${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers/flatbuffers.h")
if(EXISTS ${FLATBUFFERS_HEADER_DEST})
message(STATUS "Found existing flatbuffers.h at ${FLATBUFFERS_HEADER_DEST}")
endif()
# Generate headers and copy Java files inline after ExternalProject builds
ExternalProject_Add_Step(flatbuffers_host generate_headers_and_copy_java
COMMAND ${CMAKE_COMMAND} -E env "FLATC_PATH=${FLATC_EXECUTABLE}"
bash ${CMAKE_CURRENT_SOURCE_DIR}/flatc-generate.sh
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/copy-flatc-java.sh
COMMAND ${CMAKE_COMMAND} -E make_directory
"${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-host/include/flatbuffers/flatbuffers.h"
"${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers/flatbuffers.h"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating FlatBuffers headers, copying Java files, and copying flatbuffers.h using host flatc"
DEPENDEES build
BYPRODUCTS
${CMAKE_CURRENT_SOURCE_DIR}/include/graph/generated.h
${CMAKE_CURRENT_SOURCE_DIR}/.java_files_copied
${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers/flatbuffers.h
)
else()
# Native build or cross-compilation without flatc generation
message(STATUS "Native FlatBuffers build")
if(SHOULD_BUILD_FLATC)
set(FLATBUFFERS_BUILD_FLATC "ON")
else()
set(FLATBUFFERS_BUILD_FLATC "OFF")
endif()
ExternalProject_Add(flatbuffers_external
URL ${FLATBUFFERS_URL}
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build"
CMAKE_ARGS
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_BUILD_TYPE=Release
-DFLATBUFFERS_BUILD_FLATC=${FLATBUFFERS_BUILD_FLATC}
-DFLATBUFFERS_BUILD_FLATLIB=ON
-DFLATBUFFERS_BUILD_TESTS=OFF
-DFLATBUFFERS_BUILD_SAMPLES=OFF
INSTALL_COMMAND ""
BUILD_BYPRODUCTS
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build/flatc"
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build/libflatbuffers.a"
)
# DO NOT use include_directories() - use target_include_directories on flatbuffers_interface instead
# include_directories("${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src/include")
set(FLATBUFFERS_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build/libflatbuffers.a")
set(FLATBUFFERS_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src")
# Check if flatbuffers.h already exists
set(FLATBUFFERS_HEADER_DEST "${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers/flatbuffers.h")
if(EXISTS ${FLATBUFFERS_HEADER_DEST})
message(STATUS "Found existing flatbuffers.h at ${FLATBUFFERS_HEADER_DEST}")
endif()
if(SHOULD_BUILD_FLATC)
set(FLATC_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build/flatc")
# Generate headers and copy Java files inline after ExternalProject builds
ExternalProject_Add_Step(flatbuffers_external generate_headers_and_copy_java
COMMAND ${CMAKE_COMMAND} -E env "FLATC_PATH=${FLATC_EXECUTABLE}"
bash ${CMAKE_CURRENT_SOURCE_DIR}/flatc-generate.sh
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/copy-flatc-java.sh
COMMAND ${CMAKE_COMMAND} -E make_directory
"${CMAKE_SOURCE_DIR}/include/flatbuffers"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src/include/flatbuffers/flatbuffers.h"
"${CMAKE_SOURCE_DIR}/include/flatbuffers/flatbuffers.h"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating FlatBuffers headers, copying Java files, and copying flatbuffers.h"
DEPENDEES build
BYPRODUCTS
${CMAKE_CURRENT_SOURCE_DIR}/include/graph/generated.h
${CMAKE_CURRENT_SOURCE_DIR}/.java_files_copied
${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers/flatbuffers.h
)
else()
# Even without flatc generation, copy the flatbuffers.h header
ExternalProject_Add_Step(flatbuffers_external copy_flatbuffers_header
COMMAND ${CMAKE_COMMAND} -E make_directory
"${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src/include/flatbuffers/flatbuffers.h"
"${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers/flatbuffers.h"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Copying flatbuffers.h header"
DEPENDEES build
BYPRODUCTS
${CMAKE_SOURCE_DIR}/libnd4j/include/flatbuffers/flatbuffers.h
)
endif()
# Create interface library
add_library(flatbuffers_interface INTERFACE)
target_link_libraries(flatbuffers_interface INTERFACE ${FLATBUFFERS_LIBRARY})
target_include_directories(flatbuffers_interface INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src/include")
add_dependencies(flatbuffers_interface flatbuffers_external)
endif()
# Set global variables for parent scope
set(FLATBUFFERS_LIBRARY ${FLATBUFFERS_LIBRARY} PARENT_SCOPE)
set(FLATBUFFERS_SOURCE_DIR ${FLATBUFFERS_SOURCE_DIR} PARENT_SCOPE)
if(SHOULD_BUILD_FLATC)
set(FLATC_EXECUTABLE ${FLATC_EXECUTABLE} PARENT_SCOPE)
endif()
message(STATUS "✅ FlatBuffers setup complete")
if(CMAKE_CROSSCOMPILING AND SHOULD_BUILD_FLATC)
message(STATUS " Host flatc: ${FLATC_EXECUTABLE}")
message(STATUS " Target library: ${FLATBUFFERS_LIBRARY}")
else()
message(STATUS " Library: ${FLATBUFFERS_LIBRARY}")
if(SHOULD_BUILD_FLATC)
message(STATUS " flatc: ${FLATC_EXECUTABLE}")
endif()
endif()
endfunction()
# =============================================================================
# ONEDNN (Optional)
# =============================================================================
function(setup_onednn)
if(NOT HELPERS_onednn STREQUAL "ON")
message(STATUS "OneDNN helper is disabled (HELPERS_onednn=${HELPERS_onednn})")
set(HAVE_ONEDNN FALSE PARENT_SCOPE)
set(ONEDNN "" PARENT_SCOPE)
return()
endif()
if(TARGET onednn_external)
message(STATUS "OneDNN helper is enabled (target already exists)")
set(HAVE_ONEDNN TRUE PARENT_SCOPE)
set(ONEDNN onednn_interface PARENT_SCOPE)
return()
endif()
message(STATUS "OneDNN helper is enabled")
set(HAVE_ONEDNN TRUE PARENT_SCOPE)
set(ONEDNN_INSTALL_DIR "${CMAKE_BINARY_DIR}/onednn_install")
ExternalProject_Add(onednn_external
PREFIX "${CMAKE_BINARY_DIR}/onednn_external"
GIT_REPOSITORY "https://github.com/uxlfoundation/oneDNN.git"
GIT_TAG "v3.8.1"
SOURCE_DIR "${CMAKE_BINARY_DIR}/onednn_external/src"
BINARY_DIR "${CMAKE_BINARY_DIR}/onednn_external/build"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${ONEDNN_INSTALL_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DDNNL_LIBRARY_TYPE=STATIC -DDNNL_BUILD_TESTS=OFF -DDNNL_BUILD_EXAMPLES=OFF -DDNNL_VERBOSE=OFF -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config ${CMAKE_BUILD_TYPE} --parallel
INSTALL_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target install --config ${CMAKE_BUILD_TYPE}
BUILD_BYPRODUCTS "${ONEDNN_INSTALL_DIR}/include/dnnl.h" "${ONEDNN_INSTALL_DIR}/lib/libdnnl.a" "${ONEDNN_INSTALL_DIR}/lib/dnnl.lib"
TIMEOUT 600
)
add_library(onednn_interface INTERFACE)
target_include_directories(onednn_interface INTERFACE "${ONEDNN_INSTALL_DIR}/include")
if(WIN32)
target_link_libraries(onednn_interface INTERFACE "${ONEDNN_INSTALL_DIR}/lib/dnnl.lib")
else()
target_link_libraries(onednn_interface INTERFACE "${ONEDNN_INSTALL_DIR}/lib/libdnnl.a")
endif()
add_dependencies(onednn_interface onednn_external)
set(ONEDNN onednn_interface PARENT_SCOPE)
endfunction()
# =============================================================================
# ARM COMPUTE LIBRARY (Optional)
# =============================================================================
function(setup_armcompute)
set(HAVE_ARMCOMPUTE 0 PARENT_SCOPE)
if(NOT HELPERS_armcompute STREQUAL "ON")
message(STATUS "ARM Compute helper is disabled (HELPERS_armcompute=${HELPERS_armcompute})")
return()
endif()
if(TARGET armcompute_external)
set(HAVE_ARMCOMPUTE 1 PARENT_SCOPE)
set(ARMCOMPUTE_LIBRARIES armcompute_interface PARENT_SCOPE)
return()
endif()
if(LIBND4J_BUILD_WITH_ARMCOMPUTE AND (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm64|ARM64"))
set(ARMCOMPUTE_INSTALL_DIR "${CMAKE_BINARY_DIR}/armcompute_install")
set(ARMCOMPUTE_VERSION "v25.04")
set(ARMCOMPUTE_ARCH "aarch64")
set(ARMCOMPUTE_PLATFORM "linux")
set(ARMCOMPUTE_FLAVOR "cpu")
set(ARMCOMPUTE_PKG_NAME "arm_compute-${ARMCOMPUTE_VERSION}-${ARMCOMPUTE_PLATFORM}-${ARMCOMPUTE_ARCH}-${ARMCOMPUTE_FLAVOR}-bin")
set(ARMCOMPUTE_URL "https://github.com/ARM-software/ComputeLibrary/releases/download/${ARMCOMPUTE_VERSION}/${ARMCOMPUTE_PKG_NAME}.tar.gz")
ExternalProject_Add(armcompute_external
PREFIX "${CMAKE_BINARY_DIR}/armcompute_external"
URL "${ARMCOMPUTE_URL}"
DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/downloads"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/${ARMCOMPUTE_PKG_NAME} ${ARMCOMPUTE_INSTALL_DIR}
BUILD_BYPRODUCTS "${ARMCOMPUTE_INSTALL_DIR}/include/arm_compute/core/CL/CLKernelLibrary.h"
)
add_library(armcompute_interface INTERFACE)
target_include_directories(armcompute_interface INTERFACE "${ARMCOMPUTE_INSTALL_DIR}/include")
target_link_directories(armcompute_interface INTERFACE "${ARMCOMPUTE_INSTALL_DIR}/lib")
target_link_libraries(armcompute_interface INTERFACE arm_compute arm_compute_graph)
add_dependencies(armcompute_interface armcompute_external)
set(ARMCOMPUTE_LIBRARIES armcompute_interface PARENT_SCOPE)
set(HAVE_ARMCOMPUTE 1 PARENT_SCOPE)
endif()
endfunction()
# =============================================================================
# CUDNN (Optional, for CUDA builds)
# =============================================================================
function(setup_cudnn)
set(HAVE_CUDNN false PARENT_SCOPE)
set(CUDNN "" PARENT_SCOPE)
if(NOT (HELPERS_cudnn AND SD_CUDA))
return()
endif()
find_package(CUDNN)
if(CUDNN_FOUND)
message(STATUS "✓ Found cuDNN: ${CUDNN_LIBRARY}")
include_directories(${CUDNN_INCLUDE_DIR})
set(HAVE_CUDNN true PARENT_SCOPE)
set(CUDNN ${CUDNN_LIBRARIES} PARENT_SCOPE)
add_definitions(-DHAVE_CUDNN=1)
else()
message(WARNING "✗ cuDNN not found. Continuing without cuDNN support.")
endif()
endfunction()
@@ -0,0 +1,64 @@
# GCC and Clang flags for C++ template duplicate instantiation issues
cmake_minimum_required(VERSION 3.15)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# For C++ template duplicate instantiation errors
if(NOT SD_CUDA)
add_compile_options(-fpermissive)
add_compile_options(-ftemplate-depth=1024)
add_compile_options(-fno-gnu-unique)
message(STATUS "Added -fpermissive: Allows duplicate template instantiations")
message(STATUS "Added template-related flags for C++ duplicate handling")
else()
# Also set CXX flags for host compilation
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -Wno-error")
message(STATUS "Added CUDA-specific compiler flags for duplicate template instantiations")
message(STATUS "Added --disable-warnings to suppress NVCC errors")
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# For Clang template duplicate instantiation handling
if(NOT SD_CUDA)
# Template instantiation depth
add_compile_options(-ftemplate-depth=1024)
# Check if this is an Android build
if(ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Android")
# Android NDK specific handling - be more permissive like GCC
add_compile_options(-Wno-error)
add_compile_options(-Wno-duplicate-decl-specifier)
add_compile_options(-Wno-unused-command-line-argument)
add_compile_options(-ffunction-sections)
add_compile_options(-fdata-sections)
# Android linker doesn't support ICF well, use basic folding
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
message(STATUS "Added Android-specific Clang flags for duplicate template handling")
else()
# Desktop Clang with full template folding support
add_compile_options(-ffunction-sections)
add_compile_options(-fdata-sections)
add_compile_options(-fmerge-all-constants)
add_compile_options(-fno-unique-section-names)
# Use LLD linker for better template folding support
add_compile_options(-fuse-ld=lld)
# Linker flags for identical code folding (ICF)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--icf=all -Wl,--gc-sections")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--icf=all -Wl,--gc-sections")
message(STATUS "Added desktop Clang template folding with LLD linker")
endif()
else()
# CUDA with Clang
if(ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Android")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024 -Wno-error -Wno-duplicate-decl-specifier")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
message(STATUS "Added Android CUDA-specific Clang flags")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024 -ffunction-sections -fdata-sections")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=-ffunction-sections -Xcompiler=-fdata-sections")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld -Wl,--icf=all")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=lld -Wl,--icf=all")
message(STATUS "Added desktop CUDA-specific Clang template folding")
endif()
endif()
endif()
+590
View File
@@ -0,0 +1,590 @@
# cmake/ExtractInstantiations.cmake
# COMPLETE CONSOLIDATED PARALLEL TEMPLATE INSTANTIATION EXTRACTION
# All functionality in ONE file - no separate helper files needed
message(STATUS "")
message(STATUS "=====================================================")
message(STATUS "=== TEMPLATE INSTANTIATION ANALYSIS MODE ACTIVE ===")
message(STATUS "=====================================================")
message(STATUS "SD_EXTRACT_INSTANTIATIONS = ${SD_EXTRACT_INSTANTIATIONS}")
message(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}")
message(STATUS "CMAKE_BINARY_DIR = ${CMAKE_BINARY_DIR}")
# ============================================================================
# HELPER FUNCTIONS - ALL INLINE, NO SEPARATE FILES
# ============================================================================
# Function to normalize template signatures for comparison
function(normalize_template_signature TEMPLATE OUT_VAR)
set(normalized "${TEMPLATE}")
# Remove all extra whitespace
string(REGEX REPLACE "[ \t\r\n]+" " " normalized "${normalized}")
string(STRIP "${normalized}" normalized)
# Normalize spacing around template brackets
string(REPLACE "< " "<" normalized "${normalized}")
string(REPLACE " >" ">" normalized "${normalized}")
string(REPLACE " <" "<" normalized "${normalized}")
string(REPLACE "> " ">" normalized "${normalized}")
# Normalize pointer and reference notation
string(REPLACE " *" "*" normalized "${normalized}")
string(REPLACE " &" "&" normalized "${normalized}")
string(REPLACE "* " "*" normalized "${normalized}")
string(REPLACE "& " "&" normalized "${normalized}")
# Normalize const placement
string(REGEX REPLACE "const[ ]+([^ ]+)" "\\1 const" normalized "${normalized}")
# Normalize namespace separators
string(REPLACE " ::" "::" normalized "${normalized}")
string(REPLACE ":: " "::" normalized "${normalized}")
# Remove trailing const
string(REGEX REPLACE "[ ]+const$" "" normalized "${normalized}")
set(${OUT_VAR} "${normalized}" PARENT_SCOPE)
endfunction()
# Function to check if a template should be filtered out
function(should_filter_template TEMPLATE OUT_VAR)
set(should_filter FALSE)
# Filter out all std:: templates
if(TEMPLATE MATCHES "^std::")
set(should_filter TRUE)
endif()
# Filter out compiler intrinsics and internal templates
if(TEMPLATE MATCHES "^__" OR
TEMPLATE MATCHES "^operator" OR
TEMPLATE MATCHES "^decltype" OR
TEMPLATE MATCHES "^typename" OR
TEMPLATE MATCHES "^template")
set(should_filter TRUE)
endif()
# Filter out basic types that aren't really templates
if(TEMPLATE MATCHES "^(bool|char|short|int|long|float|double|void|unsigned|signed)")
set(should_filter TRUE)
endif()
set(${OUT_VAR} ${should_filter} PARENT_SCOPE)
endfunction()
# Setup compilation flags function
function(setup_instantiation_flags)
# Setup FlatBuffers
set(PREPROCESS_FLATBUFFERS_VERSION "25.2.10")
set(PREPROCESS_FLATBUFFERS_URL "https://github.com/google/flatbuffers/archive/v${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz")
set(PREPROCESS_FB_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/preprocess-flatbuffers-src")
set(PREPROCESS_FB_HEADER "${PREPROCESS_FB_SOURCE_DIR}/include/flatbuffers/flatbuffers.h")
if(NOT EXISTS ${PREPROCESS_FB_HEADER})
message("Downloading and extracting FlatBuffers for instantiation analysis...")
file(DOWNLOAD ${PREPROCESS_FLATBUFFERS_URL}
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz"
SHOW_PROGRESS
STATUS download_status)
list(GET download_status 0 download_result)
if(NOT download_result EQUAL 0)
message(FATAL_ERROR "Failed to download FlatBuffers for instantiation analysis")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
RESULT_VARIABLE extract_result
)
if(NOT extract_result EQUAL 0)
message(FATAL_ERROR "Failed to extract FlatBuffers for instantiation analysis")
endif()
file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}"
"${PREPROCESS_FB_SOURCE_DIR}")
endif()
# Build include paths
set(all_includes "${CMAKE_CURRENT_SOURCE_DIR}/include")
file(GLOB_RECURSE all_dirs LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/include/*")
foreach(item ${all_dirs})
if(IS_DIRECTORY ${item})
list(APPEND all_includes ${item})
endif()
endforeach()
list(APPEND all_includes
"${CMAKE_CURRENT_BINARY_DIR}/include"
"${CMAKE_SOURCE_DIR}/include/"
"${CMAKE_SOURCE_DIR}/include/system"
"${CMAKE_BINARY_DIR}/compilation_units"
"${CMAKE_BINARY_DIR}/cpu_instantiations"
"${CMAKE_BINARY_DIR}/cuda_instantiations"
"${CMAKE_BINARY_DIR}/include"
"${PREPROCESS_FB_SOURCE_DIR}/include"
)
# Build include flags string
set(include_flags "")
foreach(dir IN LISTS all_includes)
if(EXISTS ${dir})
string(APPEND include_flags " -I${dir}")
endif()
endforeach()
# Build definition flags
set(defs_flags "")
string(APPEND defs_flags " -D__CPUBLAS__=true")
if(SD_CUDA)
string(APPEND defs_flags " -D__CUDABLAS__=true -DHAVE_CUDA=1")
endif()
if(HAVE_OPENBLAS)
string(APPEND defs_flags " -DHAVE_OPENBLAS=1")
endif()
if(SD_ALL_OPS OR "${SD_OPS_LIST}" STREQUAL "")
string(APPEND defs_flags " -DSD_ALL_OPS=1")
string(APPEND defs_flags " -DNOT_EXCLUDED(x)=1")
else()
foreach(OP ${SD_OPS_LIST})
string(APPEND defs_flags " -DOP_${OP}=1")
endforeach()
string(APPEND defs_flags " -DNOT_EXCLUDED(x)=\\(defined\\(x\\)\\)")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
string(APPEND defs_flags " -DDEBUG=1 -D_DEBUG=1")
else()
string(APPEND defs_flags " -DNDEBUG=1")
endif()
if(SD_TYPES_LIST)
string(REPLACE ";" "," types_comma_list "${SD_TYPES_LIST}")
string(APPEND defs_flags " -DSD_TYPES_LIST=\"${types_comma_list}\"")
endif()
# Export to parent scope
set(INST_INCLUDE_FLAGS ${include_flags} PARENT_SCOPE)
set(INST_DEFS_FLAGS ${defs_flags} PARENT_SCOPE)
set(INST_LANG_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" PARENT_SCOPE)
# Find required tools
find_program(NM_TOOL NAMES nm gcc-nm llvm-nm)
find_program(CPPFILT_TOOL NAMES c++filt llvm-cxxfilt)
set(NM_TOOL ${NM_TOOL} PARENT_SCOPE)
set(CPPFILT_TOOL ${CPPFILT_TOOL} PARENT_SCOPE)
endfunction()
# Get source list function
function(get_source_list OUT_VAR)
if(DEFINED ALL_SOURCES AND ALL_SOURCES)
set(${OUT_VAR} ${ALL_SOURCES} PARENT_SCOPE)
elseif(DEFINED ALL_SOURCES_LIST AND ALL_SOURCES_LIST)
set(${OUT_VAR} ${ALL_SOURCES_LIST} PARENT_SCOPE)
else()
set(${OUT_VAR} "" PARENT_SCOPE)
endif()
endfunction()
# MAIN EXTRACTION FUNCTION - CONSOLIDATED WITH ACCURATE FILTERING
function(extract_templates_consolidated SOURCE_FILE USED_OUTPUT_FILE PROVIDED_OUTPUT_FILE SAFE_NAME)
# Initialize empty results
set(used_templates "")
set(provided_templates "")
# Check if source file exists
if(NOT EXISTS "${SOURCE_FILE}")
file(WRITE ${USED_OUTPUT_FILE} "")
file(WRITE ${PROVIDED_OUTPUT_FILE} "")
return()
endif()
# Determine compiler and flags
if(SOURCE_FILE MATCHES "\\.cu$")
set(compiler "${CMAKE_CUDA_COMPILER}")
set(lang_flags "${CMAKE_CUDA_FLAGS} ${CMAKE_CUDA_FLAGS_${CMAKE_BUILD_TYPE}}")
else()
set(compiler "${CMAKE_CXX_COMPILER}")
set(lang_flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
endif()
if(NOT compiler)
file(WRITE ${USED_OUTPUT_FILE} "")
file(WRITE ${PROVIDED_OUTPUT_FILE} "")
return()
endif()
# SINGLE PREPROCESSING PASS
separate_arguments(lang_flags_list UNIX_COMMAND "${lang_flags}")
separate_arguments(defs_flags_list UNIX_COMMAND "${INST_DEFS_FLAGS}")
separate_arguments(include_flags_list UNIX_COMMAND "${INST_INCLUDE_FLAGS}")
execute_process(
COMMAND ${compiler}
-E -P -C -dD
${lang_flags_list}
${defs_flags_list}
${include_flags_list}
"${SOURCE_FILE}"
OUTPUT_VARIABLE preprocessed_content
ERROR_VARIABLE preprocess_errors
RESULT_VARIABLE preprocess_result
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT preprocess_result EQUAL 0)
file(WRITE ${USED_OUTPUT_FILE} "")
file(WRITE ${PROVIDED_OUTPUT_FILE} "")
return()
endif()
string(LENGTH "${preprocessed_content}" content_length)
if(content_length GREATER 52428800)
file(WRITE ${USED_OUTPUT_FILE} "")
file(WRITE ${PROVIDED_OUTPUT_FILE} "")
return()
endif()
# EXTRACT PROVIDED TEMPLATES
string(REGEX MATCHALL "template[ \t]+(?!extern)(class|struct)[ \t]+[a-zA-Z_][a-zA-Z0-9_:]*[ \t]*<[^;>]+>[ \t]*;"
explicit_instantiations "${preprocessed_content}")
foreach(inst ${explicit_instantiations})
string(REGEX MATCH "[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>" tmpl "${inst}")
if(tmpl)
should_filter_template("${tmpl}" should_filter)
if(NOT should_filter)
normalize_template_signature("${tmpl}" normalized)
list(APPEND provided_templates "${normalized}")
endif()
endif()
endforeach()
# EXTRACT USED TEMPLATES
string(REGEX MATCHALL "extern[ \t]+template[ \t]+(class|struct)[ \t]+[a-zA-Z_][a-zA-Z0-9_:]*[ \t]*<[^;>]+>[ \t]*;"
extern_templates "${preprocessed_content}")
foreach(ext ${extern_templates})
string(REGEX MATCH "[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>" tmpl "${ext}")
if(tmpl)
should_filter_template("${tmpl}" should_filter)
if(NOT should_filter)
normalize_template_signature("${tmpl}" normalized)
list(APPEND used_templates "${normalized}")
endif()
endif()
endforeach()
# Project-specific patterns
set(project_template_patterns
"NDArray<[^>]+>"
"DataBuffer<[^>]+>"
"ResultSet<[^>]+>"
"ShapeList<[^>]+>"
"LaunchContext<[^>]+>"
"BroadcastHelper<[^>]+>"
"BroadcastInt<[^>]+>"
"BroadcastBool<[^>]+>"
"Broadcast<[^>]+>"
"PairWiseTransform<[^>]+>"
"ScalarTransform<[^>]+>"
"RandomFunction<[^>]+>"
"ReduceSameFunction<[^>]+>"
"ReduceFloatFunction<[^>]+>"
"ReduceBoolFunction<[^>]+>"
"ReduceLongFunction<[^>]+>"
"Reduce3<[^>]+>"
"IndexReduce<[^>]+>"
"ReductionLoops<[^>]+>"
"IndexReductionLoops<[^>]+>"
"LoopKind::Kind<[^>]+>"
"SpecialMethods<[^>]+>"
"TypeCast::convertGeneric<[^>]+>"
"DeclarableOp<[^>]+>"
"DeclarableCustomOp<[^>]+>"
"DeclarableReductionOp<[^>]+>"
"GEMM<[^>]+>"
"GEMV<[^>]+>"
"AXPY<[^>]+>"
)
foreach(pattern ${project_template_patterns})
string(REGEX MATCHALL "${pattern}" matches "${preprocessed_content}")
foreach(match ${matches})
should_filter_template("${match}" should_filter)
if(NOT should_filter)
normalize_template_signature("${match}" normalized)
list(APPEND used_templates "${normalized}")
endif()
endforeach()
endforeach()
# Remove duplicates and write
if(used_templates)
list(REMOVE_DUPLICATES used_templates)
list(SORT used_templates)
string(REPLACE ";" "\n" used_content "${used_templates}")
file(WRITE ${USED_OUTPUT_FILE} "${used_content}")
else()
file(WRITE ${USED_OUTPUT_FILE} "")
endif()
if(provided_templates)
list(REMOVE_DUPLICATES provided_templates)
list(SORT provided_templates)
string(REPLACE ";" "\n" provided_content "${provided_templates}")
file(WRITE ${PROVIDED_OUTPUT_FILE} "${provided_content}")
else()
file(WRITE ${PROVIDED_OUTPUT_FILE} "")
endif()
endfunction()
# Process batch function for parallel execution
function(process_batch BATCH_ID BATCH_FILE)
if(NOT EXISTS ${BATCH_FILE})
file(WRITE "${INST_BATCH_DIR}/batch_${BATCH_ID}.done" "")
return()
endif()
file(STRINGS ${BATCH_FILE} FILES_TO_PROCESS)
list(LENGTH FILES_TO_PROCESS batch_size)
message("[Batch ${BATCH_ID}] Processing ${batch_size} files")
set(batch_results "")
set(processed_count 0)
foreach(src IN LISTS FILES_TO_PROCESS)
if(NOT EXISTS ${src})
continue()
endif()
get_filename_component(src_name ${src} NAME_WE)
get_filename_component(src_path ${src} PATH)
get_filename_component(src_full_name ${src} NAME)
file(RELATIVE_PATH rel_path ${CMAKE_SOURCE_DIR} ${src_path})
string(REPLACE "/" "_" safe_name "${rel_path}_${src_name}")
set(IS_GENERATED FALSE)
if(src MATCHES "${CMAKE_BINARY_DIR}")
set(IS_GENERATED TRUE)
endif()
set(used_file "${INST_USED_DIR}/${safe_name}.used")
set(provided_file "${INST_PROVIDED_DIR}/${safe_name}.provided")
extract_templates_consolidated("${src}" "${used_file}" "${provided_file}" "${safe_name}")
if(EXISTS ${used_file})
file(STRINGS ${used_file} used_list)
else()
set(used_list "")
endif()
if(EXISTS ${provided_file})
file(STRINGS ${provided_file} provided_list)
else()
set(provided_list "")
endif()
set(missing_templates "")
foreach(used_tmpl ${used_list})
set(found FALSE)
foreach(provided_tmpl ${provided_list})
if(used_tmpl STREQUAL provided_tmpl)
set(found TRUE)
break()
endif()
endforeach()
if(NOT found)
list(APPEND missing_templates "${used_tmpl}")
endif()
endforeach()
set(missing_file "${INST_MISSING_DIR}/${safe_name}.missing")
if(missing_templates)
list(REMOVE_DUPLICATES missing_templates)
string(REPLACE ";" "\n" missing_content "${missing_templates}")
file(WRITE ${missing_file} "${missing_content}")
list(LENGTH missing_templates missing_count)
else()
file(WRITE ${missing_file} "")
set(missing_count 0)
endif()
list(LENGTH used_list used_count)
list(LENGTH provided_list provided_count)
string(APPEND batch_results "${src}|${safe_name}|${used_count}|${provided_count}|${missing_count}|${IS_GENERATED}\n")
math(EXPR processed_count "${processed_count} + 1")
endforeach()
file(WRITE "${INST_BATCH_DIR}/batch_${BATCH_ID}.done" "${batch_results}")
message("[Batch ${BATCH_ID}] Completed: ${processed_count} files")
endfunction()
# ============================================================================
# MAIN EXECUTION
# ============================================================================
# Determine parallelism
if(NOT DEFINED INST_PARALLEL_JOBS)
include(ProcessorCount)
ProcessorCount(PROCESSOR_COUNT)
# PERFORMANCE OPTIMIZATION: Use all available cores for functrace builds
# Old logic: Reserved 2 cores (PROCESSOR_COUNT - 2)
# New logic: Use all cores (template processing is CPU-bound, not I/O-bound)
if(PROCESSOR_COUNT GREATER 0)
set(INST_PARALLEL_JOBS ${PROCESSOR_COUNT})
else()
set(INST_PARALLEL_JOBS 4)
endif()
endif()
message(STATUS "Parallel jobs: ${INST_PARALLEL_JOBS}")
# Setup directories
set(INST_DIR "${CMAKE_SOURCE_DIR}/instantiation_analysis")
set(INST_USED_DIR "${INST_DIR}/used")
set(INST_PROVIDED_DIR "${INST_DIR}/provided")
set(INST_MISSING_DIR "${INST_DIR}/missing")
set(INST_REPORTS_DIR "${INST_DIR}/reports")
set(INST_TEMP_DIR "${INST_DIR}/temp")
set(INST_BY_FILE_DIR "${INST_DIR}/by_file")
set(INST_BATCH_DIR "${INST_DIR}/batches")
foreach(dir IN ITEMS ${INST_DIR} ${INST_USED_DIR} ${INST_PROVIDED_DIR}
${INST_MISSING_DIR} ${INST_REPORTS_DIR} ${INST_TEMP_DIR}
${INST_BY_FILE_DIR} ${INST_BATCH_DIR})
if(NOT EXISTS ${dir})
file(MAKE_DIRECTORY ${dir})
endif()
endforeach()
# Setup flags
setup_instantiation_flags()
# Get sources
message(STATUS "Collecting source files...")
get_source_list(SOURCE_LIST)
if(NOT SOURCE_LIST)
file(GLOB_RECURSE SOURCE_LIST
"${CMAKE_SOURCE_DIR}/include/**/*.cpp"
"${CMAKE_SOURCE_DIR}/include/**/*.cu"
)
endif()
# Add generated sources
if(SD_CUDA)
file(GLOB_RECURSE GEN_SOURCES
"${CMAKE_BINARY_DIR}/cuda_instantiations/*.cu"
"${CMAKE_BINARY_DIR}/compilation_units/*.cu")
else()
file(GLOB_RECURSE GEN_SOURCES
"${CMAKE_BINARY_DIR}/cpu_instantiations/*.cpp"
"${CMAKE_BINARY_DIR}/compilation_units/*.cpp")
endif()
list(APPEND SOURCE_LIST ${GEN_SOURCES})
# Filter and deduplicate
set(FILTERED_SOURCE_LIST "")
foreach(src IN LISTS SOURCE_LIST)
if(src MATCHES "\\.(cpp|cxx|cc|cu)$" AND EXISTS ${src})
list(APPEND FILTERED_SOURCE_LIST ${src})
endif()
endforeach()
list(REMOVE_DUPLICATES FILTERED_SOURCE_LIST)
set(SOURCE_LIST ${FILTERED_SOURCE_LIST})
list(LENGTH SOURCE_LIST source_count)
message(STATUS "Total files to analyze: ${source_count}")
# Create batches
math(EXPR FILES_PER_BATCH "${source_count} / ${INST_PARALLEL_JOBS}")
if(FILES_PER_BATCH EQUAL 0)
set(FILES_PER_BATCH 1)
endif()
set(current_batch 0)
set(files_in_batch 0)
foreach(src IN LISTS SOURCE_LIST)
file(APPEND "${INST_BATCH_DIR}/batch_${current_batch}.txt" "${src}\n")
math(EXPR files_in_batch "${files_in_batch} + 1")
if(files_in_batch GREATER_EQUAL FILES_PER_BATCH AND current_batch LESS ${INST_PARALLEL_JOBS})
math(EXPR current_batch "${current_batch} + 1")
set(files_in_batch 0)
endif()
endforeach()
# Process batches
message(STATUS "Processing ${INST_PARALLEL_JOBS} batches...")
foreach(batch_id RANGE 0 ${INST_PARALLEL_JOBS})
set(batch_file "${INST_BATCH_DIR}/batch_${batch_id}.txt")
if(EXISTS ${batch_file})
process_batch(${batch_id} ${batch_file})
endif()
endforeach()
# Aggregate results
message(STATUS "Aggregating results...")
set(TOTAL_USED 0)
set(TOTAL_PROVIDED 0)
set(TOTAL_MISSING 0)
file(WRITE ${INST_REPORTS_DIR}/summary.csv "File,Path,Used,Provided,Missing,Type\n")
foreach(batch_id RANGE 0 ${INST_PARALLEL_JOBS})
set(done_file "${INST_BATCH_DIR}/batch_${batch_id}.done")
if(EXISTS ${done_file})
file(STRINGS ${done_file} batch_results)
foreach(result_line ${batch_results})
if(result_line)
string(REPLACE "|" ";" result_parts "${result_line}")
list(LENGTH result_parts parts_count)
if(parts_count EQUAL 6)
list(GET result_parts 0 src)
list(GET result_parts 2 used_count)
list(GET result_parts 3 provided_count)
list(GET result_parts 4 missing_count)
list(GET result_parts 5 is_generated)
math(EXPR TOTAL_USED "${TOTAL_USED} + ${used_count}")
math(EXPR TOTAL_PROVIDED "${TOTAL_PROVIDED} + ${provided_count}")
math(EXPR TOTAL_MISSING "${TOTAL_MISSING} + ${missing_count}")
get_filename_component(src_name ${src} NAME)
get_filename_component(src_path ${src} PATH)
file(RELATIVE_PATH rel_path ${CMAKE_SOURCE_DIR} ${src_path})
set(file_type "original")
if(is_generated)
set(file_type "generated")
endif()
file(APPEND ${INST_REPORTS_DIR}/summary.csv
"${src_name},${rel_path},${used_count},${provided_count},${missing_count},${file_type}\n")
endif()
endif()
endforeach()
endif()
endforeach()
# Final summary
message(STATUS "")
message(STATUS "=====================================================")
message(STATUS "=== ANALYSIS COMPLETE ===")
message(STATUS "=====================================================")
message(STATUS "Templates Used: ${TOTAL_USED}")
message(STATUS "Templates Provided: ${TOTAL_PROVIDED}")
message(STATUS "Templates Missing: ${TOTAL_MISSING}")
message(STATUS "")
message(STATUS "Reports generated in: ${INST_REPORTS_DIR}")
# Exit without continuing build
message(STATUS "Exiting after instantiation extraction (SD_EXTRACT_INSTANTIATIONS=ON)")
return()
+533
View File
@@ -0,0 +1,533 @@
# FileConcatenation.cmake
# Clean template concatenation with duplicate import elimination
# Global variables to track includes and content
set(GLOBAL_INCLUDES_SET "" CACHE INTERNAL "Set of unique includes")
set(GLOBAL_INCLUDES_LIST "" CACHE INTERNAL "Ordered list of unique includes")
# Function to extract and deduplicate includes from content
function(extract_and_deduplicate_includes content includes_var content_without_includes_var)
# Handle empty content
if(content STREQUAL "")
set(${includes_var} "" PARENT_SCOPE)
set(${content_without_includes_var} "" PARENT_SCOPE)
return()
endif()
# Split content into lines
string(REPLACE "\n" ";" content_lines "${content}")
set(extracted_includes "")
set(content_without_includes "")
set(in_multiline_comment FALSE)
foreach(line ${content_lines})
# Handle empty lines
if(NOT DEFINED line OR line STREQUAL "")
string(APPEND content_without_includes "\n")
continue()
endif()
# Handle multi-line comments
if(line MATCHES "/\\*")
set(in_multiline_comment TRUE)
endif()
if(line MATCHES "\\*/")
set(in_multiline_comment FALSE)
string(APPEND content_without_includes "${line}\n")
continue()
endif()
if(in_multiline_comment)
string(APPEND content_without_includes "${line}\n")
continue()
endif()
# Skip single-line comments unless they contain includes
if(line MATCHES "^[ \t]*//.*#include")
# This is a commented include, treat as regular content
string(APPEND content_without_includes "${line}\n")
elseif(line MATCHES "^[ \t]*//")
# Regular comment, keep as content
string(APPEND content_without_includes "${line}\n")
elseif(line MATCHES "^[ \t]*#include")
# Extract include statement - use STRIP instead of REGEX REPLACE to avoid empty match issues
string(STRIP "${line}" cleaned_include)
if(NOT cleaned_include STREQUAL "")
list(APPEND extracted_includes "${cleaned_include}")
endif()
else()
# Regular content line
string(APPEND content_without_includes "${line}\n")
endif()
endforeach()
set(${includes_var} "${extracted_includes}" PARENT_SCOPE)
set(${content_without_includes_var} "${content_without_includes}" PARENT_SCOPE)
endfunction()
# Function to add includes to global set maintaining order
function(add_includes_to_global_set new_includes)
foreach(include_stmt ${new_includes})
# Normalize the include statement
string(STRIP "${include_stmt}" include_stmt)
# Check if this include is already in our global set
list(FIND GLOBAL_INCLUDES_SET "${include_stmt}" found_index)
if(found_index EQUAL -1)
# New include, add to both set and ordered list
list(APPEND GLOBAL_INCLUDES_SET "${include_stmt}")
list(APPEND GLOBAL_INCLUDES_LIST "${include_stmt}")
# Update cache
set(GLOBAL_INCLUDES_SET "${GLOBAL_INCLUDES_SET}" CACHE INTERNAL "Set of unique includes")
set(GLOBAL_INCLUDES_LIST "${GLOBAL_INCLUDES_LIST}" CACHE INTERNAL "Ordered list of unique includes")
endif()
endforeach()
endfunction()
# Function to generate the final includes section
function(generate_includes_section result_var)
set(includes_section "")
if(GLOBAL_INCLUDES_LIST)
string(APPEND includes_section "/*\n * Consolidated Include Section\n * All unique includes from processed templates\n */\n")
# Group includes by type for better organization
set(system_includes "")
set(local_includes "")
set(other_includes "")
foreach(include_stmt ${GLOBAL_INCLUDES_LIST})
if(include_stmt MATCHES "#include[ \t]*<.*>")
list(APPEND system_includes "${include_stmt}")
elseif(include_stmt MATCHES "#include[ \t]*\".*\"")
list(APPEND local_includes "${include_stmt}")
else()
list(APPEND other_includes "${include_stmt}")
endif()
endforeach()
# Output system includes first
if(system_includes)
string(APPEND includes_section "\n// System includes\n")
foreach(include_stmt ${system_includes})
string(APPEND includes_section "${include_stmt}\n")
endforeach()
endif()
# Then local includes
if(local_includes)
string(APPEND includes_section "\n// Local includes\n")
foreach(include_stmt ${local_includes})
string(APPEND includes_section "${include_stmt}\n")
endforeach()
endif()
# Finally other includes
if(other_includes)
string(APPEND includes_section "\n// Other includes\n")
foreach(include_stmt ${other_includes})
string(APPEND includes_section "${include_stmt}\n")
endforeach()
endif()
string(APPEND includes_section "\n")
endif()
set(${result_var} "${includes_section}" PARENT_SCOPE)
endfunction()
# Process a single template instance with specific type indices
function(process_single_template_instance template_file comb1 comb2 comb3 result_var)
file(READ "${template_file}" original_content)
# Set template variables
set(FL_TYPE_INDEX ${comb1})
set(TYPE_INDEX_1 ${comb1})
set(TYPE_INDEX_2 ${comb2})
set(TYPE_INDEX_3 ${comb3})
# Determine what #cmakedefine flags to enable based on template content
set(SD_COMMON_TYPES_GEN 0)
set(SD_FLOAT_TYPES_GEN 0)
set(SD_INTEGER_TYPES_GEN 0)
set(SD_PAIRWISE_TYPES_GEN 0)
set(SD_SEMANTIC_TYPES_GEN 0)
if(original_content MATCHES "#cmakedefine[ \t]+SD_COMMON_TYPES_GEN")
set(SD_COMMON_TYPES_GEN 1)
endif()
if(original_content MATCHES "#cmakedefine[ \t]+SD_FLOAT_TYPES_GEN")
set(SD_FLOAT_TYPES_GEN 1)
endif()
if(original_content MATCHES "#cmakedefine[ \t]+SD_INTEGER_TYPES_GEN")
set(SD_INTEGER_TYPES_GEN 1)
endif()
if(original_content MATCHES "#cmakedefine[ \t]+SD_PAIRWISE_TYPES_GEN")
set(SD_PAIRWISE_TYPES_GEN 1)
endif()
if(original_content MATCHES "#cmakedefine[ \t]+SD_SEMANTIC_TYPES_GEN")
set(SD_SEMANTIC_TYPES_GEN 1)
endif()
# Manual string replacement instead of configure_file
set(processed_content "${original_content}")
# Replace @variable@ patterns
string(REPLACE "@FL_TYPE_INDEX@" "${FL_TYPE_INDEX}" processed_content "${processed_content}")
string(REPLACE "@TYPE_INDEX_1@" "${TYPE_INDEX_1}" processed_content "${processed_content}")
string(REPLACE "@TYPE_INDEX_2@" "${TYPE_INDEX_2}" processed_content "${processed_content}")
string(REPLACE "@TYPE_INDEX_3@" "${TYPE_INDEX_3}" processed_content "${processed_content}")
# Process #cmakedefine directives
if(SD_COMMON_TYPES_GEN)
string(REPLACE "#cmakedefine SD_COMMON_TYPES_GEN" "#define SD_COMMON_TYPES_GEN" processed_content "${processed_content}")
else()
string(REPLACE "#cmakedefine SD_COMMON_TYPES_GEN" "/* #undef SD_COMMON_TYPES_GEN */" processed_content "${processed_content}")
endif()
if(SD_FLOAT_TYPES_GEN)
string(REPLACE "#cmakedefine SD_FLOAT_TYPES_GEN" "#define SD_FLOAT_TYPES_GEN" processed_content "${processed_content}")
else()
string(REPLACE "#cmakedefine SD_FLOAT_TYPES_GEN" "/* #undef SD_FLOAT_TYPES_GEN */" processed_content "${processed_content}")
endif()
if(SD_INTEGER_TYPES_GEN)
string(REPLACE "#cmakedefine SD_INTEGER_TYPES_GEN" "#define SD_INTEGER_TYPES_GEN" processed_content "${processed_content}")
else()
string(REPLACE "#cmakedefine SD_INTEGER_TYPES_GEN" "/* #undef SD_INTEGER_TYPES_GEN */" processed_content "${processed_content}")
endif()
if(SD_PAIRWISE_TYPES_GEN)
string(REPLACE "#cmakedefine SD_PAIRWISE_TYPES_GEN" "#define SD_PAIRWISE_TYPES_GEN" processed_content "${processed_content}")
else()
string(REPLACE "#cmakedefine SD_PAIRWISE_TYPES_GEN" "/* #undef SD_PAIRWISE_TYPES_GEN */" processed_content "${processed_content}")
endif()
if(SD_SEMANTIC_TYPES_GEN)
string(REPLACE "#cmakedefine SD_SEMANTIC_TYPES_GEN" "#define SD_SEMANTIC_TYPES_GEN" processed_content "${processed_content}")
else()
string(REPLACE "#cmakedefine SD_SEMANTIC_TYPES_GEN" "/* #undef SD_SEMANTIC_TYPES_GEN */" processed_content "${processed_content}")
endif()
# Validation - check that processing worked
if(processed_content MATCHES "@[A-Za-z_]+@")
message(WARNING "Template processing failed for ${template_file} with indices ${comb1},${comb2},${comb3} - unresolved variables remain")
set(${result_var} "" PARENT_SCOPE)
return()
endif()
if(processed_content MATCHES "#cmakedefine[ \t]+[A-Za-z_]+")
message(WARNING "CMakeDefine processing failed for ${template_file} with indices ${comb1},${comb2},${comb3} - unresolved directives remain")
set(${result_var} "" PARENT_SCOPE)
return()
endif()
set(${result_var} "${processed_content}" PARENT_SCOPE)
endfunction()
# Process template with type combinations and include deduplication
function(process_template_with_combinations template_file combination_type combinations result_var)
if(NOT EXISTS "${template_file}")
set(${result_var} "" PARENT_SCOPE)
return()
endif()
set(all_content "")
get_filename_component(template_name ${template_file} NAME_WE)
# Detect if this is a single-type template
file(READ "${template_file}" template_content)
set(is_single_type_template FALSE)
if(template_content MATCHES "@FL_TYPE_INDEX@" AND
NOT template_content MATCHES "@TYPE_INDEX_[23]@|@COMB[23]@")
set(is_single_type_template TRUE)
message(STATUS "📋 Detected single-type template: ${template_name}")
endif()
if(is_single_type_template)
# Single-type processing: Extract all unique type indices and process each individually
set(unique_indices "")
foreach(combination ${combinations})
string(REPLACE "," ";" comb_list "${combination}")
foreach(index ${comb_list})
list(FIND unique_indices ${index} found_pos)
if(found_pos EQUAL -1)
list(APPEND unique_indices ${index})
endif()
endforeach()
endforeach()
list(SORT unique_indices COMPARE NATURAL)
message(STATUS "🔢 Processing ${template_name} with individual indices: ${unique_indices}")
# Process each unique index individually
foreach(index ${unique_indices})
# For single-type templates, use the index for all three parameters
process_single_template_instance("${template_file}" ${index} ${index} ${index} instance_content)
if(NOT instance_content STREQUAL "")
# Extract includes and content separately
extract_and_deduplicate_includes("${instance_content}" extracted_includes content_only)
# Add includes to global set
add_includes_to_global_set("${extracted_includes}")
# Only append the content without includes
string(APPEND all_content "// === ${template_name}_${index}.cpp ===\n")
string(APPEND all_content "${content_only}")
string(APPEND all_content "// === End ${template_name}_${index}.cpp ===\n\n")
# Verify float16 instantiation
if(index EQUAL 3)
if(instance_content MATCHES "SD_COMMON_TYPES_3")
message(STATUS "✅ Float16 ${template_name} instantiation generated (index ${index})")
else()
message(WARNING "⚠️ Float16 ${template_name} instantiation incomplete")
endif()
endif()
endif()
endforeach()
else()
# Multi-type processing: Original logic for templates that actually use multiple types
message(STATUS "📋 Processing multi-type template: ${template_name}")
foreach(combination ${combinations})
string(REPLACE "," ";" comb_list "${combination}")
list(LENGTH comb_list comb_count)
# Validate combination format
if(NOT ((combination_type EQUAL 3 AND comb_count EQUAL 3) OR
(combination_type EQUAL 2 AND comb_count EQUAL 2)))
continue()
endif()
# Extract combination indices
if(combination_type EQUAL 3)
list(GET comb_list 0 comb1)
list(GET comb_list 1 comb2)
list(GET comb_list 2 comb3)
set(file_suffix "${comb1}_${comb2}_${comb3}")
else()
list(GET comb_list 0 comb1)
list(GET comb_list 1 comb2)
set(comb3 ${comb1})
set(file_suffix "${comb1}_${comb2}")
endif()
# Validate indices
if(DEFINED SD_COMMON_TYPES_COUNT)
math(EXPR max_index "${SD_COMMON_TYPES_COUNT} - 1")
if(comb1 GREATER max_index OR comb2 GREATER max_index OR comb3 GREATER max_index)
continue()
endif()
endif()
# Process the multi-type template
process_single_template_instance("${template_file}" ${comb1} ${comb2} ${comb3} instance_content)
if(NOT instance_content STREQUAL "")
# Extract includes and content separately
extract_and_deduplicate_includes("${instance_content}" extracted_includes content_only)
# Add includes to global set
add_includes_to_global_set("${extracted_includes}")
# Only append the content without includes
string(APPEND all_content "// === ${template_name}_${file_suffix}.cpp ===\n")
string(APPEND all_content "${content_only}")
string(APPEND all_content "// === End ${template_name}_${file_suffix}.cpp ===\n\n")
endif()
endforeach()
endif()
set(${result_var} "${all_content}" PARENT_SCOPE)
endfunction()
# Detect template requirements
function(detect_template_requirements template_file needs_2_type_var needs_3_type_var)
file(READ "${template_file}" template_content)
set(needs_2_type FALSE)
set(needs_3_type FALSE)
if(template_content MATCHES "TYPE_INDEX_3|COMB3|_template_3")
set(needs_3_type TRUE)
endif()
if(template_content MATCHES "TYPE_INDEX_2|COMB2|_template_2")
set(needs_2_type TRUE)
endif()
if(NOT needs_2_type AND NOT needs_3_type)
get_filename_component(template_name "${template_file}" NAME)
if(template_name MATCHES "_3\\.")
set(needs_3_type TRUE)
elseif(template_name MATCHES "_2\\.")
set(needs_2_type TRUE)
else()
set(needs_2_type TRUE)
set(needs_3_type TRUE)
endif()
endif()
set(${needs_2_type_var} ${needs_2_type} PARENT_SCOPE)
set(${needs_3_type_var} ${needs_3_type} PARENT_SCOPE)
endfunction()
# Process a batch of templates into one concatenated unit
function(process_concatenated_unit unit_index template_files)
# Clear global includes for this unit
set(GLOBAL_INCLUDES_SET "" CACHE INTERNAL "Set of unique includes")
set(GLOBAL_INCLUDES_LIST "" CACHE INTERNAL "Ordered list of unique includes")
set(output_dir "${CMAKE_BINARY_DIR}")
set(final_unit_file "${output_dir}/concatenated_unit_${unit_index}.cpp")
string(TIMESTAMP current_time "%Y-%m-%d %H:%M:%S")
set(unit_content_body "")
foreach(template_file ${template_files})
get_filename_component(template_name ${template_file} NAME_WE)
message(STATUS " Processing template: ${template_name}")
# Detect template requirements
detect_template_requirements("${template_file}" needs_2_type needs_3_type)
# Process with 3-type combinations if needed
if(needs_3_type AND COMBINATIONS_3)
process_template_with_combinations("${template_file}" 3 "${COMBINATIONS_3}" template_content)
string(APPEND unit_content_body "${template_content}")
endif()
# Process with 2-type combinations if needed
if(needs_2_type AND COMBINATIONS_2)
process_template_with_combinations("${template_file}" 2 "${COMBINATIONS_2}" template_content)
string(APPEND unit_content_body "${template_content}")
endif()
endforeach()
# Generate the consolidated includes section
generate_includes_section(includes_section)
# Combine everything with proper structure
set(final_content "/*\n * Concatenated Compilation Unit ${unit_index}\n * Generated: ${current_time}\n */\n\n")
string(APPEND final_content "${includes_section}")
string(APPEND final_content "/*\n * Template Implementations\n */\n\n")
string(APPEND final_content "${unit_content_body}")
file(WRITE "${final_unit_file}" "${final_content}")
list(APPEND CONCATENATED_SOURCES "${final_unit_file}")
set(CONCATENATED_SOURCES ${CONCATENATED_SOURCES} PARENT_SCOPE)
# Report deduplication statistics
list(LENGTH GLOBAL_INCLUDES_LIST total_unique_includes)
message(STATUS "✅ Created concatenated_unit_${unit_index}.cpp with ${total_unique_includes} unique includes")
endfunction()
# Main function to concatenate and process compilation units
function(concatenate_and_process_compilation_units target_count)
message(STATUS "=== CONCATENATING AND PROCESSING COMPILATION UNITS ===")
# Find all template files
file(GLOB_RECURSE ALL_TEMPLATE_FILES
"${CMAKE_SOURCE_DIR}/include/ops/declarable/helpers/cpu/compilation_units/*.cpp.in"
"${CMAKE_SOURCE_DIR}/include/loops/cpu/compilation_units/*.cpp.in"
"${CMAKE_SOURCE_DIR}/include/loops/cpu/comb_compilation_units/*.cpp.in"
"${CMAKE_SOURCE_DIR}/include/helpers/cpu/loops/*.cpp.in"
)
list(LENGTH ALL_TEMPLATE_FILES total_files)
if(total_files EQUAL 0)
message(FATAL_ERROR "❌ No template files found to process!")
endif()
math(EXPR files_per_unit "(${total_files} + ${target_count} - 1) / ${target_count}")
message(STATUS "📊 Processing ${total_files} templates into ${target_count} units with include deduplication")
# Ensure we have combinations
if(NOT DEFINED COMBINATIONS_2 OR NOT DEFINED COMBINATIONS_3)
message(FATAL_ERROR "❌ Type combinations not initialized!")
endif()
list(LENGTH COMBINATIONS_2 combo2_count)
list(LENGTH COMBINATIONS_3 combo3_count)
message(STATUS "Using ${combo2_count} 2-type and ${combo3_count} 3-type combinations")
# Create concatenated units
set(unit_index 0)
set(files_in_current_unit 0)
set(current_unit_files "")
foreach(template_file ${ALL_TEMPLATE_FILES})
list(APPEND current_unit_files ${template_file})
math(EXPR files_in_current_unit "${files_in_current_unit} + 1")
if(files_in_current_unit GREATER_EQUAL files_per_unit)
process_concatenated_unit(${unit_index} "${current_unit_files}")
set(current_unit_files "")
set(files_in_current_unit 0)
math(EXPR unit_index "${unit_index} + 1")
endif()
endforeach()
# Handle remaining files
if(NOT current_unit_files STREQUAL "")
process_concatenated_unit(${unit_index} "${current_unit_files}")
endif()
message(STATUS "✅ Created concatenated compilation units with deduplicated includes")
set(CONCATENATED_SOURCES ${CONCATENATED_SOURCES} PARENT_SCOPE)
endfunction()
# Main entry point
function(create_4gb_safe_concatenated_units)
message(STATUS "🔧 Creating concatenated compilation units with include deduplication...")
set(TARGET_UNITS 4)
if(NOT DEFINED COMBINATIONS_2 OR NOT DEFINED COMBINATIONS_3)
message(STATUS "Initializing dynamic combinations...")
initialize_dynamic_combinations()
endif()
# Debug output
list(LENGTH COMBINATIONS_2 combo2_count)
list(LENGTH COMBINATIONS_3 combo3_count)
if(combo2_count GREATER 0)
list(GET COMBINATIONS_2 0 first_combo2)
message(STATUS "Debug: First 2-type combination: ${first_combo2}")
endif()
if(combo3_count GREATER 0)
list(GET COMBINATIONS_3 0 first_combo3)
message(STATUS "Debug: First 3-type combination: ${first_combo3}")
endif()
concatenate_and_process_compilation_units(${TARGET_UNITS})
if(DEFINED CONCATENATED_SOURCES)
list(LENGTH CONCATENATED_SOURCES unit_count)
message(STATUS "📊 Created ${unit_count} concatenated units with deduplicated includes")
endif()
endfunction()
# Clean up existing units
function(clean_concatenated_units)
file(GLOB existing_units "${CMAKE_BINARY_DIR}/concatenated_unit_*.cpp")
if(existing_units)
file(REMOVE ${existing_units})
list(LENGTH existing_units removed_count)
message(STATUS "🗑️ Cleaned up ${removed_count} existing concatenated units")
endif()
# Clean up any temp processing files
file(GLOB temp_files "${CMAKE_BINARY_DIR}/temp_*.cpp*")
if(temp_files)
file(REMOVE ${temp_files})
endif()
endfunction()
+69
View File
@@ -0,0 +1,69 @@
# FindARMCOMPUTE.cmake
# Find ARM Compute Library includes and libraries
#
# Sets the following variables:
# ARMCOMPUTE_FOUND - True if ARM Compute Library was found
# ARMCOMPUTE_INCLUDE - Path to ARM Compute Library include directory
# ARMCOMPUTE_LIBRARIES - ARM Compute Library libraries to link against
#
# This module will look for ARM Compute Library in standard locations and
# in the directory specified by the ARMCOMPUTE_ROOT variable.
# Find include directory
find_path(ARMCOMPUTE_INCLUDE
NAMES arm_compute/core/CL/CLKernelLibrary.h
PATHS
${ARMCOMPUTE_ROOT}
${ARMCOMPUTE_ROOT}/include
ENV ARMCOMPUTE_ROOT
ENV ARMCOMPUTE_PATH
/usr/include
/usr/local/include
REQUIRED
)
# Find library files
find_library(ARMCOMPUTE_CORE_LIBRARY
NAMES arm_compute_core-static arm_compute_core
PATHS
${ARMCOMPUTE_ROOT}
${ARMCOMPUTE_ROOT}/lib
${ARMCOMPUTE_ROOT}/build
ENV ARMCOMPUTE_ROOT
ENV ARMCOMPUTE_PATH
/usr/lib
/usr/local/lib
REQUIRED
)
find_library(ARMCOMPUTE_LIBRARY
NAMES arm_compute-static arm_compute
PATHS
${ARMCOMPUTE_ROOT}
${ARMCOMPUTE_ROOT}/lib
${ARMCOMPUTE_ROOT}/build
ENV ARMCOMPUTE_ROOT
ENV ARMCOMPUTE_PATH
/usr/lib
/usr/local/lib
REQUIRED
)
# Set libraries variable
set(ARMCOMPUTE_LIBRARIES ${ARMCOMPUTE_LIBRARY} ${ARMCOMPUTE_CORE_LIBRARY})
# Handle the QUIETLY and REQUIRED arguments
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ARMCOMPUTE
DEFAULT_MSG
ARMCOMPUTE_INCLUDE
ARMCOMPUTE_LIBRARIES
)
# Mark as advanced
mark_as_advanced(
ARMCOMPUTE_INCLUDE
ARMCOMPUTE_LIBRARY
ARMCOMPUTE_CORE_LIBRARY
ARMCOMPUTE_LIBRARIES
)
+100
View File
@@ -0,0 +1,100 @@
# - Find Dwarf
# Find the dwarf.h header from elf utils
#
# DWARF_INCLUDE_DIR - where to find dwarf.h, etc.
# DWARF_LIBRARIES - List of libraries when using elf utils.
# DWARF_FOUND - True if fdo found.
message(STATUS "Checking availability of DWARF and ELF development libraries")
INCLUDE(CheckLibraryExists)
if (DWARF_INCLUDE_DIR AND LIBDW_INCLUDE_DIR AND DWARF_LIBRARY AND ELF_LIBRARY)
# Already in cache, be silent
set(DWARF_FIND_QUIETLY TRUE)
endif (DWARF_INCLUDE_DIR AND LIBDW_INCLUDE_DIR AND DWARF_LIBRARY AND ELF_LIBRARY)
find_path(DWARF_INCLUDE_DIR dwarf.h
/usr/include
/usr/local/include
/usr/include/libdwarf
~/usr/local/include
)
find_path(LIBDW_INCLUDE_DIR elfutils/libdw.h
/usr/include
/usr/local/include
~/usr/local/include
)
find_library(DWARF_LIBRARY
NAMES dw dwarf
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64 ~/usr/local/lib ~/usr/local/lib64
)
find_library(ELF_LIBRARY
NAMES elf
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64 ~/usr/local/lib ~/usr/local/lib64
)
if (DWARF_INCLUDE_DIR AND LIBDW_INCLUDE_DIR AND DWARF_LIBRARY AND ELF_LIBRARY)
set(DWARF_FOUND TRUE)
set(DWARF_LIBRARIES ${DWARF_LIBRARY} ${ELF_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${DWARF_LIBRARIES})
# check if libdw have the dwfl_module_build_id routine, i.e. if it supports the buildid
# mechanism to match binaries to detached debug info sections (the -debuginfo packages
# in distributions such as fedora). We do it against libelf because, IIRC, some distros
# include libdw linked statically into libelf.
check_library_exists(elf dwfl_module_build_id "" HAVE_DWFL_MODULE_BUILD_ID)
else (DWARF_INCLUDE_DIR AND LIBDW_INCLUDE_DIR AND DWARF_LIBRARY AND ELF_LIBRARY)
set(DWARF_FOUND FALSE)
set(DWARF_LIBRARIES)
endif (DWARF_INCLUDE_DIR AND LIBDW_INCLUDE_DIR AND DWARF_LIBRARY AND ELF_LIBRARY)
if (DWARF_FOUND)
if (NOT DWARF_FIND_QUIETLY)
message(STATUS "Found dwarf.h header: ${DWARF_INCLUDE_DIR}")
message(STATUS "Found elfutils/libdw.h header: ${LIBDW_INCLUDE_DIR}")
message(STATUS "Found libdw library: ${DWARF_LIBRARY}")
message(STATUS "Found libelf library: ${ELF_LIBRARY}")
endif (NOT DWARF_FIND_QUIETLY)
else (DWARF_FOUND)
if (DWARF_FIND_REQUIRED)
# Check if we are in a Red Hat (RHEL) or Fedora system to tell
# exactly which packages should be installed. Please send
# patches for other distributions.
find_path(FEDORA fedora-release /etc)
find_path(REDHAT redhat-release /etc)
if (FEDORA OR REDHAT)
if (NOT DWARF_INCLUDE_DIR OR NOT LIBDW_INCLUDE_DIR)
message(STATUS "Please install the elfutils-devel package")
endif (NOT DWARF_INCLUDE_DIR OR NOT LIBDW_INCLUDE_DIR)
if (NOT DWARF_LIBRARY)
message(STATUS "Please install the elfutils-libs package")
endif (NOT DWARF_LIBRARY)
if (NOT ELF_LIBRARY)
message(STATUS "Please install the elfutils-libelf package")
endif (NOT ELF_LIBRARY)
else (FEDORA OR REDHAT)
if (NOT DWARF_INCLUDE_DIR)
message(STATUS "Could NOT find dwarf include dir")
endif (NOT DWARF_INCLUDE_DIR)
if (NOT LIBDW_INCLUDE_DIR)
message(STATUS "Could NOT find libdw include dir")
endif (NOT LIBDW_INCLUDE_DIR)
if (NOT DWARF_LIBRARY)
message(STATUS "Could NOT find libdw library")
endif (NOT DWARF_LIBRARY)
if (NOT ELF_LIBRARY)
message(STATUS "Could NOT find libelf library")
endif (NOT ELF_LIBRARY)
endif (FEDORA OR REDHAT)
message(FATAL_ERROR "Could NOT find some ELF and DWARF libraries, please install the missing packages")
endif (DWARF_FIND_REQUIRED)
endif (DWARF_FOUND)
mark_as_advanced(DWARF_INCLUDE_DIR LIBDW_INCLUDE_DIR DWARF_LIBRARY ELF_LIBRARY)
include_directories(${DWARF_INCLUDE_DIR} ${LIBDW_INCLUDE_DIR})
message(STATUS "Checking availability of DWARF and ELF development libraries - done")
+19
View File
@@ -0,0 +1,19 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
+70
View File
@@ -0,0 +1,70 @@
# cmake/InstantiationCache.cmake
# Smart caching for instantiation analysis
function(should_process_file SOURCE_FILE SAFE_NAME OUT_VAR)
# Get file modification time
file(TIMESTAMP ${SOURCE_FILE} source_mtime)
# Check if cached results exist
set(cache_file "${INST_TEMP_DIR}/${SAFE_NAME}.cache")
if(EXISTS ${cache_file})
# Read cache timestamp
file(READ ${cache_file} cache_content LIMIT 100)
string(REGEX MATCH "timestamp:([0-9]+)" _ ${cache_content})
set(cache_time ${CMAKE_MATCH_1})
# Compare timestamps
if(cache_time AND source_mtime EQUAL cache_time)
# Cache is valid, skip processing
set(${OUT_VAR} FALSE PARENT_SCOPE)
# Load cached results
if(EXISTS ${INST_USED_DIR}/${SAFE_NAME}.used.cached)
file(COPY ${INST_USED_DIR}/${SAFE_NAME}.used.cached
DESTINATION ${INST_USED_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(RENAME ${INST_USED_DIR}/${SAFE_NAME}.used.cached
${INST_USED_DIR}/${SAFE_NAME}.used)
endif()
if(EXISTS ${INST_PROVIDED_DIR}/${SAFE_NAME}.provided.cached)
file(COPY ${INST_PROVIDED_DIR}/${SAFE_NAME}.provided.cached
DESTINATION ${INST_PROVIDED_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(RENAME ${INST_PROVIDED_DIR}/${SAFE_NAME}.provided.cached
${INST_PROVIDED_DIR}/${SAFE_NAME}.provided)
endif()
return()
endif()
endif()
# Need to process this file
set(${OUT_VAR} TRUE PARENT_SCOPE)
endfunction()
function(cache_analysis_results SOURCE_FILE SAFE_NAME)
file(TIMESTAMP ${SOURCE_FILE} source_mtime)
# Write cache marker
set(cache_file "${INST_TEMP_DIR}/${SAFE_NAME}.cache")
file(WRITE ${cache_file} "timestamp:${source_mtime}\n")
# Cache the analysis results
if(EXISTS ${INST_USED_DIR}/${SAFE_NAME}.used)
file(COPY ${INST_USED_DIR}/${SAFE_NAME}.used
DESTINATION ${INST_USED_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(RENAME ${INST_USED_DIR}/${SAFE_NAME}.used
${INST_USED_DIR}/${SAFE_NAME}.used.cached)
endif()
if(EXISTS ${INST_PROVIDED_DIR}/${SAFE_NAME}.provided)
file(COPY ${INST_PROVIDED_DIR}/${SAFE_NAME}.provided
DESTINATION ${INST_PROVIDED_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(RENAME ${INST_PROVIDED_DIR}/${SAFE_NAME}.provided
${INST_PROVIDED_DIR}/${SAFE_NAME}.provided.cached)
endif()
endfunction()
+612
View File
@@ -0,0 +1,612 @@
# cmake/InstantiationHelpers.cmake
# Helper functions for template instantiation extraction
# Function to setup compilation flags for instantiation extraction
function(setup_instantiation_flags)
# FIRST: Setup FlatBuffers EXACTLY like PostBuild.cmake does
set(PREPROCESS_FLATBUFFERS_VERSION "25.2.10")
set(PREPROCESS_FLATBUFFERS_URL "https://github.com/google/flatbuffers/archive/v${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz")
set(PREPROCESS_FB_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/preprocess-flatbuffers-src")
# Check if we already have FlatBuffers headers
set(PREPROCESS_FB_HEADER "${PREPROCESS_FB_SOURCE_DIR}/include/flatbuffers/flatbuffers.h")
if(NOT EXISTS ${PREPROCESS_FB_HEADER})
message("Downloading and extracting FlatBuffers for instantiation analysis...")
# Download and extract FlatBuffers
file(DOWNLOAD ${PREPROCESS_FLATBUFFERS_URL}
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz"
SHOW_PROGRESS
STATUS download_status)
list(GET download_status 0 download_result)
if(NOT download_result EQUAL 0)
message(FATAL_ERROR "Failed to download FlatBuffers for instantiation analysis")
endif()
# Extract the archive
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
RESULT_VARIABLE extract_result
)
if(NOT extract_result EQUAL 0)
message(FATAL_ERROR "Failed to extract FlatBuffers for instantiation analysis")
endif()
# Move the extracted directory to our expected location
file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}"
"${PREPROCESS_FB_SOURCE_DIR}")
endif()
# NOW COPY THE EXACT INCLUDE SETUP FROM PostBuild.cmake
# Get ALL subdirectories under include/ and add the root include directory first
set(all_includes "${CMAKE_CURRENT_SOURCE_DIR}/include")
file(GLOB_RECURSE all_dirs LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/include/*")
foreach(item ${all_dirs})
if(IS_DIRECTORY ${item})
list(APPEND all_includes ${item})
endif()
endforeach()
# Add binary include directory
list(APPEND all_includes "${CMAKE_CURRENT_BINARY_DIR}/include")
# Also add build directories - EXACTLY AS IN PostBuild.cmake
list(APPEND all_includes
"${CMAKE_SOURCE_DIR}/include/"
"${CMAKE_SOURCE_DIR}/include/system"
"${CMAKE_BINARY_DIR}/compilation_units"
"${CMAKE_BINARY_DIR}/cpu_instantiations"
"${CMAKE_BINARY_DIR}/cuda_instantiations"
"${CMAKE_BINARY_DIR}/include"
)
# Add our self-contained FlatBuffers include directory - EXACTLY AS IN PostBuild.cmake
list(APPEND all_includes "${PREPROCESS_FB_SOURCE_DIR}/include")
# Build include flags string
set(include_flags "")
foreach(dir IN LISTS all_includes)
if(EXISTS ${dir})
string(APPEND include_flags " -I${dir}")
endif()
endforeach()
set(defs_flags "")
# Add basic platform definitions
string(APPEND defs_flags " -D__CPUBLAS__=true")
if(SD_CUDA)
string(APPEND defs_flags " -D__CUDABLAS__=true -DHAVE_CUDA=1")
endif()
if(HAVE_OPENBLAS)
string(APPEND defs_flags " -DHAVE_OPENBLAS=1")
endif()
if(SD_ALL_OPS OR "${SD_OPS_LIST}" STREQUAL "")
string(APPEND defs_flags " -DSD_ALL_OPS=1")
# When SD_ALL_OPS=1, NOT_EXCLUDED should evaluate to 1 for all ops
string(APPEND defs_flags " -DNOT_EXCLUDED(x)=1")
else()
# Add specific operation definitions
foreach(OP ${SD_OPS_LIST})
string(APPEND defs_flags " -DOP_${OP}=1")
endforeach()
# Define NOT_EXCLUDED macro for selective ops
string(APPEND defs_flags " -DNOT_EXCLUDED(x)=\\(defined\\(x\\)\\)")
endif()
# Add build type definitions
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
string(APPEND defs_flags " -DDEBUG=1 -D_DEBUG=1")
else()
string(APPEND defs_flags " -DNDEBUG=1")
endif()
# Add any additional compile definitions from the main build
if(compile_defs AND NOT compile_defs STREQUAL "compile_defs-NOTFOUND")
foreach(def IN LISTS compile_defs)
string(APPEND defs_flags " -D${def}")
endforeach()
endif()
# Datatype definitions
if(SD_TYPES_LIST)
string(REPLACE ";" "," types_comma_list "${SD_TYPES_LIST}")
string(APPEND defs_flags " -DSD_TYPES_LIST=\"${types_comma_list}\"")
endif()
# Export to parent scope
set(INST_INCLUDE_FLAGS ${include_flags} PARENT_SCOPE)
set(INST_DEFS_FLAGS ${defs_flags} PARENT_SCOPE)
set(INST_LANG_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" PARENT_SCOPE)
# Find required tools
find_program(NM_TOOL NAMES nm gcc-nm llvm-nm)
find_program(CPPFILT_TOOL NAMES c++filt llvm-cxxfilt)
set(NM_TOOL ${NM_TOOL} PARENT_SCOPE)
set(CPPFILT_TOOL ${CPPFILT_TOOL} PARENT_SCOPE)
endfunction()
# Function to get source list
function(get_source_list OUT_VAR)
if(DEFINED ALL_SOURCES AND ALL_SOURCES)
set(${OUT_VAR} ${ALL_SOURCES} PARENT_SCOPE)
elseif(DEFINED ALL_SOURCES_LIST AND ALL_SOURCES_LIST)
set(${OUT_VAR} ${ALL_SOURCES_LIST} PARENT_SCOPE)
else()
set(${OUT_VAR} "" PARENT_SCOPE)
endif()
endfunction()
# Function to extract used templates from a source file - KEEP THE ORIGINAL WORKING VERSION
function(extract_used_templates SOURCE_FILE OUTPUT_FILE SAFE_NAME)
# Initialize empty result
set(used_templates "")
# Check if source file exists
if(NOT EXISTS "${SOURCE_FILE}")
message(WARNING "Source file does not exist: ${SOURCE_FILE}")
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_USED_TEMPLATES "" PARENT_SCOPE)
return()
endif()
# Check if temp directory exists
if(NOT EXISTS "${INST_TEMP_DIR}")
file(MAKE_DIRECTORY "${INST_TEMP_DIR}")
endif()
# Always preprocess the file to expand all macros
set(preprocessed_file "${INST_TEMP_DIR}/${SAFE_NAME}_preprocessed.i")
# Determine compiler and flags based on file type
if(SOURCE_FILE MATCHES "\\.cu$")
set(compiler "${CMAKE_CUDA_COMPILER}")
set(lang_flags "${CMAKE_CUDA_FLAGS} ${CMAKE_CUDA_FLAGS_${CMAKE_BUILD_TYPE}}")
elseif(SOURCE_FILE MATCHES "\\.c$")
set(compiler "${CMAKE_C_COMPILER}")
set(lang_flags "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}")
else()
set(compiler "${CMAKE_CXX_COMPILER}")
set(lang_flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
endif()
# Check if compiler exists
if(NOT EXISTS "${compiler}" AND NOT compiler)
message(WARNING "Compiler not found for ${SOURCE_FILE}")
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_USED_TEMPLATES "" PARENT_SCOPE)
return()
endif()
# Preprocess the file to expand all macros - USING EXACT WORKING METHOD FROM PostBuild.cmake
# Split the flags properly for execute_process
separate_arguments(lang_flags_list UNIX_COMMAND "${lang_flags}")
separate_arguments(defs_flags_list UNIX_COMMAND "${INST_DEFS_FLAGS}")
separate_arguments(include_flags_list UNIX_COMMAND "${INST_INCLUDE_FLAGS}")
execute_process(
COMMAND ${compiler} -E -P -C ${lang_flags_list} ${defs_flags_list} ${include_flags_list} "${SOURCE_FILE}" -o "${preprocessed_file}"
RESULT_VARIABLE preprocess_result
ERROR_VARIABLE preprocess_errors
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
if(NOT preprocess_result EQUAL 0)
message(WARNING "Failed to preprocess ${SOURCE_FILE}: ${preprocess_errors}")
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_USED_TEMPLATES "" PARENT_SCOPE)
return()
endif()
if(NOT EXISTS ${preprocessed_file})
message(WARNING "Preprocessed file not created for ${SOURCE_FILE}")
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_USED_TEMPLATES "" PARENT_SCOPE)
return()
endif()
# Method 1: Compile the preprocessed file with -fno-implicit-templates to find required templates
execute_process(
COMMAND ${compiler}
-fsyntax-only
-fno-implicit-templates
-ftemplate-backtrace-limit=0
${lang_flags}
${INST_DEFS_FLAGS}
${INST_INCLUDE_FLAGS}
-x c++ # Force C++ mode since .i files might not be recognized
${preprocessed_file}
ERROR_VARIABLE compile_errors
OUTPUT_QUIET
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 30
)
if(compile_errors)
# Parse undefined references from the preprocessed compilation
string(REGEX MATCHALL "undefined reference to '[^']+'" undefined_refs "${compile_errors}")
foreach(ref ${undefined_refs})
string(REGEX REPLACE "undefined reference to '([^']+)'" "\\1" symbol "${ref}")
# Filter for template instantiations
if(symbol MATCHES ".*<.*>.*")
# Demangle if needed
if(symbol MATCHES "^_Z")
if(CPPFILT_TOOL)
execute_process(
COMMAND ${CPPFILT_TOOL} "${symbol}"
OUTPUT_VARIABLE demangled
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(demangled)
set(symbol "${demangled}")
endif()
endif()
endif()
list(APPEND used_templates "${symbol}")
endif()
endforeach()
# Parse instantiation requirements
string(REGEX MATCHALL "instantiation of '[^']+' required" inst_reqs "${compile_errors}")
foreach(req ${inst_reqs})
string(REGEX REPLACE "instantiation of '([^']+)' required" "\\1" tmpl "${req}")
if(tmpl MATCHES ".*<.*>.*")
list(APPEND used_templates "${tmpl}")
endif()
endforeach()
# Parse "error: explicit instantiation of '[^']+' but no definition available"
string(REGEX MATCHALL "explicit instantiation of '[^']+' but no definition" missing_defs "${compile_errors}")
foreach(def ${missing_defs})
string(REGEX REPLACE "explicit instantiation of '([^']+)' but no definition" "\\1" tmpl "${def}")
if(tmpl MATCHES ".*<.*>.*")
list(APPEND used_templates "${tmpl}")
endif()
endforeach()
endif()
# Method 2: Parse the preprocessed source for template usage patterns
file(READ ${preprocessed_file} source_content LIMIT 10485760) # Read up to 10MB
# Look for explicit template instantiation declarations (extern template)
string(REGEX MATCHALL "extern[ \t]+template[ \t]+[^;]+<[^>]+>[^;]*;" extern_templates "${source_content}")
foreach(ext_tmpl ${extern_templates})
string(REGEX MATCH "[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>" tmpl "${ext_tmpl}")
if(tmpl)
list(APPEND used_templates "${tmpl}")
endif()
endforeach()
# Look for template instantiation patterns in expanded macros
# These patterns commonly appear after macro expansion
set(expanded_patterns
"template[ \t]+class[ \t]+[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>"
"template[ \t]+struct[ \t]+[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>"
"template[ \t]+void[ \t]+[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>::[a-zA-Z_][a-zA-Z0-9_]*"
"template[ \t]+[a-zA-Z_][a-zA-Z0-9_:]*[ \t]+[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>::[a-zA-Z_][a-zA-Z0-9_]*"
)
foreach(pattern ${expanded_patterns})
string(REGEX MATCHALL "${pattern}" matches "${source_content}")
foreach(match ${matches})
# Extract the template class/function signature
string(REGEX MATCH "[a-zA-Z_][a-zA-Z0-9_:]*<[^>]+>" tmpl "${match}")
if(tmpl)
list(APPEND used_templates "${tmpl}")
endif()
endforeach()
endforeach()
# Method 3: Look for template function calls and instantiations
# Common template patterns that indicate usage
set(usage_patterns
"NDArray<[^>]+>"
"DataBuffer<[^>]+>"
"BroadcastHelper<[^>]+>"
"BroadcastInt<[^>]+>"
"BroadcastBool<[^>]+>"
"Broadcast<[^>]+>"
"LoopKind::Kind<[^>]+>"
"LaunchContext<[^>]+>"
"ResultSet<[^>]+>"
"ShapeList<[^>]+>"
"SpecialMethods<[^>]+>"
"TypeCast::convertGeneric<[^>]+>"
"PairWiseTransform<[^>]+>"
"ScalarTransform<[^>]+>"
"RandomFunction<[^>]+>"
"ReduceSameFunction<[^>]+>"
"ReduceFloatFunction<[^>]+>"
"ReduceBoolFunction<[^>]+>"
"ReduceLongFunction<[^>]+>"
"Reduce3<[^>]+>"
"IndexReduce<[^>]+>"
"ReductionLoops<[^>]+>"
"IndexReductionLoops<[^>]+>"
"std::vector<[^>]+>"
"std::unique_ptr<[^>]+>"
"std::shared_ptr<[^>]+>"
)
foreach(pattern ${usage_patterns})
string(REGEX MATCHALL "${pattern}" matches "${source_content}")
list(APPEND used_templates ${matches})
endforeach()
# Method 4: Try to compile to object and extract undefined symbols
set(temp_obj "${INST_TEMP_DIR}/${SAFE_NAME}_test.o")
execute_process(
COMMAND ${compiler}
-c
-o ${temp_obj}
${lang_flags}
${INST_DEFS_FLAGS}
${INST_INCLUDE_FLAGS}
-x c++
${preprocessed_file}
ERROR_VARIABLE obj_errors
OUTPUT_QUIET
RESULT_VARIABLE obj_result
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 30
)
# Extract undefined symbols from linker errors
if(obj_errors)
string(REGEX MATCHALL "undefined reference to `[^']+'" undef_symbols "${obj_errors}")
foreach(symbol ${undef_symbols})
string(REGEX REPLACE "undefined reference to `([^']+)'" "\\1" sym "${symbol}")
if(sym MATCHES ".*<.*>.*")
# Try to demangle if it's mangled
if(sym MATCHES "^_Z" AND CPPFILT_TOOL)
execute_process(
COMMAND ${CPPFILT_TOOL} "${sym}"
OUTPUT_VARIABLE demangled
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(demangled)
set(sym "${demangled}")
endif()
endif()
list(APPEND used_templates "${sym}")
endif()
endforeach()
endif()
# If object was created, also check with nm for undefined symbols
if(obj_result EQUAL 0 AND EXISTS ${temp_obj} AND NM_TOOL)
execute_process(
COMMAND ${NM_TOOL} -u ${temp_obj}
OUTPUT_VARIABLE nm_undefined
ERROR_QUIET
)
if(nm_undefined)
string(REGEX MATCHALL "_Z[A-Za-z0-9_]+" mangled_symbols "${nm_undefined}")
foreach(mangled ${mangled_symbols})
if(CPPFILT_TOOL)
execute_process(
COMMAND ${CPPFILT_TOOL} ${mangled}
OUTPUT_VARIABLE demangled
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(demangled AND demangled MATCHES ".*<.*>.*")
list(APPEND used_templates "${demangled}")
endif()
endif()
endforeach()
endif()
file(REMOVE ${temp_obj})
endif()
# Clean up preprocessed file
file(REMOVE ${preprocessed_file})
# Remove duplicates and filter out noise
if(used_templates)
list(REMOVE_DUPLICATES used_templates)
# Filter out standard library internals and compiler intrinsics
set(filtered_templates "")
foreach(tmpl ${used_templates})
if(NOT tmpl MATCHES "^__" AND
NOT tmpl MATCHES "^std::__" AND
NOT tmpl MATCHES "^__gnu" AND
NOT tmpl MATCHES "^__builtin" AND
NOT tmpl MATCHES "^operator")
list(APPEND filtered_templates "${tmpl}")
endif()
endforeach()
string(REPLACE ";" "\n" used_content "${filtered_templates}")
file(WRITE ${OUTPUT_FILE} "${used_content}")
set(EXTRACTED_USED_TEMPLATES ${filtered_templates} PARENT_SCOPE)
else()
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_USED_TEMPLATES "" PARENT_SCOPE)
endif()
endfunction()
function(extract_provided_templates SOURCE_FILE OUTPUT_FILE SAFE_NAME)
set(provided_templates "")
# Check if source file exists
if(NOT EXISTS "${SOURCE_FILE}")
message(WARNING "Source file does not exist: ${SOURCE_FILE}")
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_PROVIDED_TEMPLATES "" PARENT_SCOPE)
return()
endif()
# Check if temp directory exists
if(NOT EXISTS "${INST_TEMP_DIR}")
file(MAKE_DIRECTORY "${INST_TEMP_DIR}")
endif()
# Method 1: Check for explicit instantiations in source
file(READ ${SOURCE_FILE} source_content LIMIT 1048576)
string(REGEX MATCHALL "template[ \t]+class[ \t]+[^;]+<[^>]+>[^;]*;"
explicit_class "${source_content}")
string(REGEX MATCHALL "template[ \t]+struct[ \t]+[^;]+<[^>]+>[^;]*;"
explicit_struct "${source_content}")
foreach(inst ${explicit_class} ${explicit_struct})
string(REGEX MATCH "[a-zA-Z_][a-zA-Z0-9_]*<[^>]+>" tmpl "${inst}")
if(tmpl)
list(APPEND provided_templates "${tmpl}")
endif()
endforeach()
# Method 2: Compile to object and extract symbols
set(temp_obj "${INST_TEMP_DIR}/${SAFE_NAME}.o")
# Determine compiler based on file type
if(SOURCE_FILE MATCHES "\\.cu$")
set(compiler "${CMAKE_CUDA_COMPILER}")
elseif(SOURCE_FILE MATCHES "\\.c$")
set(compiler "${CMAKE_C_COMPILER}")
else()
set(compiler "${CMAKE_CXX_COMPILER}")
endif()
# Check if compiler exists
if(NOT EXISTS "${compiler}" AND NOT compiler)
message(WARNING "Compiler not found for ${SOURCE_FILE}")
# Still write what we found from method 1
if(provided_templates)
list(REMOVE_DUPLICATES provided_templates)
string(REPLACE ";" "\n" provided_content "${provided_templates}")
file(WRITE ${OUTPUT_FILE} "${provided_content}")
set(EXTRACTED_PROVIDED_TEMPLATES ${provided_templates} PARENT_SCOPE)
else()
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_PROVIDED_TEMPLATES "" PARENT_SCOPE)
endif()
return()
endif()
execute_process(
COMMAND ${compiler}
-c
-o ${temp_obj}
${INST_LANG_FLAGS}
${INST_DEFS_FLAGS}
${INST_INCLUDE_FLAGS}
${SOURCE_FILE}
ERROR_QUIET
OUTPUT_QUIET
RESULT_VARIABLE compile_result
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
if(compile_result EQUAL 0 AND EXISTS ${temp_obj})
if(NM_TOOL AND CPPFILT_TOOL)
# Extract defined symbols
execute_process(
COMMAND ${NM_TOOL} --defined-only ${temp_obj}
OUTPUT_VARIABLE nm_output
ERROR_QUIET
)
if(nm_output)
# Extract and demangle template symbols
string(REGEX MATCHALL "_Z[A-Za-z0-9_]+" mangled_symbols "${nm_output}")
foreach(mangled ${mangled_symbols})
execute_process(
COMMAND ${CPPFILT_TOOL} ${mangled}
OUTPUT_VARIABLE demangled
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(demangled MATCHES ".*<.*>.*")
# Filter out std:: and internal templates
if(NOT demangled MATCHES "^std::" AND
NOT demangled MATCHES "^__" AND
NOT demangled MATCHES "^operator")
list(APPEND provided_templates "${demangled}")
endif()
endif()
endforeach()
endif()
endif()
file(REMOVE ${temp_obj})
endif()
# Method 3: Parse assembly output for template instantiations
execute_process(
COMMAND ${compiler}
-S
-o -
-fverbose-asm
${INST_LANG_FLAGS}
${INST_DEFS_FLAGS}
${INST_INCLUDE_FLAGS}
${SOURCE_FILE}
OUTPUT_VARIABLE asm_output
ERROR_QUIET
RESULT_VARIABLE asm_result
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 10
)
if(asm_result EQUAL 0 AND asm_output)
# Extract template info from assembly comments
string(LENGTH "${asm_output}" asm_length)
if(asm_length LESS 10000000) # Only process if under 10MB
string(REGEX MATCHALL "#.*<[^>]+>.*" asm_templates "${asm_output}")
foreach(comment ${asm_templates})
string(REGEX MATCH "[a-zA-Z_][a-zA-Z0-9_]*<[^>]+>" tmpl "${comment}")
if(tmpl AND NOT tmpl MATCHES "^std::")
list(APPEND provided_templates "${tmpl}")
endif()
endforeach()
endif()
endif()
# Remove duplicates and write to file
if(provided_templates)
list(REMOVE_DUPLICATES provided_templates)
string(REPLACE ";" "\n" provided_content "${provided_templates}")
file(WRITE ${OUTPUT_FILE} "${provided_content}")
set(EXTRACTED_PROVIDED_TEMPLATES ${provided_templates} PARENT_SCOPE)
else()
file(WRITE ${OUTPUT_FILE} "")
set(EXTRACTED_PROVIDED_TEMPLATES "" PARENT_SCOPE)
endif()
endfunction()
# Function to normalize template names for comparison
function(normalize_template_name TEMPLATE OUT_VAR)
set(normalized "${TEMPLATE}")
# Remove extra spaces
string(REGEX REPLACE "[ \t]+" " " normalized "${normalized}")
string(STRIP "${normalized}" normalized)
# Normalize const placement
string(REPLACE "const " "" normalized "${normalized}")
string(REPLACE " const" "" normalized "${normalized}")
# Remove allocator specifications from std containers
string(REGEX REPLACE "std::allocator<[^>]+>" "" normalized "${normalized}")
# Normalize pointer/reference spacing
string(REPLACE " *" "*" normalized "${normalized}")
string(REPLACE " &" "&" normalized "${normalized}")
set(${OUT_VAR} "${normalized}" PARENT_SCOPE)
endfunction()
+853
View File
@@ -0,0 +1,853 @@
# =============================================================================
# UNIFIED BUILD ORCHESTRATION SCRIPT WITH CUDA TEMPLATE PARITY
#
# This enhanced version includes support for CUDA template processing
# to achieve complete parity between CPU and CUDA template systems.
# UPDATED with modern cuDNN integration
#
# CACHE INVALIDATION: Modified to force CMake reconfiguration after
# PCH disabling in session #1002. Resolves Makefile2 having stale
# progress count (99 steps) while build.make has correct count (1251 steps).
# This inconsistency caused build to stop at 98% missing files 48-64.
# =============================================================================
# =============================================================================
# SECTION 1: HELPER FUNCTION DEFINITIONS
# All functions are defined first to ensure they are available when called.
# =============================================================================
# --- Helper for colored status messages ---
function(print_status_colored type message)
if(type STREQUAL "ERROR")
message(FATAL_ERROR "❌ ${message}")
elseif(type STREQUAL "WARNING")
message(WARNING "⚠️ ${message}")
elseif(type STREQUAL "SUCCESS")
message(STATUS "✅ ${message}")
elseif(type STREQUAL "INFO")
message(STATUS "️ ${message}")
else()
message(STATUS "${message}")
endif()
endfunction()
function(libnd4j_setup_target_with_types target_name)
message(STATUS "🔧 Setting up libnd4j target with type definitions: ${target_name}")
# Ensure target exists
if(NOT TARGET ${target_name})
message(FATAL_ERROR "Target ${target_name} does not exist")
endif()
# Apply type definitions immediately after target creation
setup_type_definitions_for_target(${target_name})
# Apply any additional target configuration
set_target_properties(${target_name} PROPERTIES POSITION_INDEPENDENT_CODE ON)
message(STATUS "✅ Target ${target_name} configured with type definitions")
endfunction()
function(orchestrate_enhanced_build target_name)
message(STATUS "️ === ORCHESTRATING ENHANCED LIBND4J BUILD WITH TEMPLATE PARITY ===")
message(STATUS "️ === 1. INITIALIZING BUILD CONFIGURATION ===")
# Setup target with type definitions
libnd4j_setup_target_with_types(${target_name})
message(STATUS "️ === 2. INITIALIZING DEPENDENCIES & OPERATIONS ===")
message(STATUS "Dependencies initialization complete.")
message(STATUS "️ === 3. CONFIGURING ENHANCED SELECTIVE RENDERING ===")
message(STATUS "✅ Enhanced CPU selective rendering setup complete")
message(STATUS "️ === 4. FINALIZING BUILD WITH TYPE DEFINITIONS ===")
finalize_build_with_type_definitions(${target_name})
message(STATUS "✅ === ENHANCED BUILD ORCHESTRATION COMPLETE ===")
message(STATUS "🖥️ Enhanced CPU build orchestration complete - System ready for compilation")
endfunction()
# Simplified function for immediate use after target creation
function(apply_libnd4j_type_definitions target_name)
if(TARGET ${target_name})
setup_type_definitions_for_target(${target_name})
message(STATUS "✅ Applied type definitions to ${target_name}")
else()
message(FATAL_ERROR "❌ Target ${target_name} not found for type definitions")
endif()
endfunction()
function(apply_libnd4j_type_definitions_auto)
# Use the SD_LIBRARY_NAME variable set in CMakeLists.txt
if(DEFINED SD_LIBRARY_NAME AND TARGET ${SD_LIBRARY_NAME})
set(target_name ${SD_LIBRARY_NAME})
message(STATUS "Using SD_LIBRARY_NAME target: ${target_name}")
setup_type_definitions_for_target(${target_name})
return()
endif()
# Fallback to detecting the target based on build type
if(SD_CUDA AND TARGET nd4jcuda)
setup_type_definitions_for_target(nd4jcuda)
message(STATUS "Applied type definitions to nd4jcuda")
elseif(SD_CPU AND TARGET nd4jcpu)
setup_type_definitions_for_target(nd4jcpu)
message(STATUS "Applied type definitions to nd4jcpu")
elseif(TARGET nd4jcpu)
setup_type_definitions_for_target(nd4jcpu)
message(STATUS "Applied type definitions to nd4jcpu (fallback)")
elseif(TARGET nd4jcuda)
setup_type_definitions_for_target(nd4jcuda)
message(STATUS "Applied type definitions to nd4jcuda (fallback)")
else()
message(WARNING "❌ No nd4j targets found for type definitions")
get_property(all_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS)
message(STATUS "Available targets: ${all_targets}")
endif()
endfunction()
# Function to apply to specific target by name
function(apply_libnd4j_type_definitions target_name)
if(TARGET ${target_name})
setup_type_definitions_for_target(${target_name})
message(STATUS "✅ Applied type definitions to ${target_name}")
else()
message(FATAL_ERROR "❌ Target ${target_name} not found for type definitions")
endif()
endfunction()
# Function to apply to all libnd4j targets
function(apply_libnd4j_type_definitions_all)
set(possible_targets "nd4jcpu;nd4jcuda;nd4j;libnd4j")
set(applied_count 0)
foreach(target ${possible_targets})
if(TARGET ${target})
setup_type_definitions_for_target(${target})
message(STATUS "✅ Applied type definitions to ${target}")
math(EXPR applied_count "${applied_count} + 1")
endif()
endforeach()
if(applied_count EQUAL 0)
message(WARNING "❌ No libnd4j targets found")
get_property(all_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS)
message(STATUS "Available targets: ${all_targets}")
else()
message(STATUS "✅ Applied type definitions to ${applied_count} targets")
endif()
endfunction()
# --- Platform environment setup functions ---
function(setup_cpu_environment)
message(STATUS "🔧 Setting up CPU environment")
add_definitions(-D__CPUBLAS__=true)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
message(STATUS "✅ OpenMP found and will be linked")
else()
message(STATUS "⚠️ OpenMP not found, will use manual configuration")
endif()
endif()
if(SD_X86_BUILD)
message(STATUS "🎯 Enabling x86 optimizations")
endif()
message(STATUS "✅ CPU environment setup complete")
endfunction()
# --- Enhanced source collection with CUDA template support ---
function(collect_all_sources out_source_list)
set(ALL_SOURCES_LIST "")
file(GLOB_RECURSE PERF_SOURCES ./include/performance/*.cpp)
file(GLOB_RECURSE EXCEPTIONS_SOURCES ./include/exceptions/*.cpp)
file(GLOB_RECURSE TYPES_SOURCES ./include/types/*.cpp)
file(GLOB_RECURSE GRAPH_SOURCES ./include/graph/*.cpp)
file(GLOB_RECURSE CUSTOMOPS_SOURCES ./include/ops/declarable/generic/*.cpp)
file(GLOB_RECURSE OPS_SOURCES ./include/ops/impl/*.cpp ./include/ops/declarable/impl/*.cpp)
file(GLOB_RECURSE INDEXING_SOURCES ./include/indexing/*.cpp)
list(APPEND ALL_SOURCES_LIST
${PERF_SOURCES} ${EXCEPTIONS_SOURCES} ${TYPES_SOURCES} ${GRAPH_SOURCES}
${CUSTOMOPS_SOURCES} ${OPS_SOURCES} ${INDEXING_SOURCES}
)
# This call populates CUSTOMOPS_GENERIC_SOURCES with both CPU and CUDA generated files
setup_template_processing()
if(SD_CUDA)
file(GLOB_RECURSE EXEC_SOURCES ./include/execution/impl/*.cpp ./include/execution/cuda/*.cu ./include/execution/*.cu)
file(GLOB_RECURSE ARRAY_SOURCES ./include/array/cuda/*.cu ./include/array/impl/*.cpp ./include/array/*.cpp)
file(GLOB_RECURSE MEMORY_SOURCES ./include/memory/impl/*.cpp ./include/memory/cuda/*.cu)
file(GLOB_RECURSE CUSTOMOPS_HELPERS_SOURCES ./include/ops/declarable/helpers/cuda/*.cu ./include/ops/declarable/helpers/impl/*.cpp)
file(GLOB_RECURSE HELPERS_SOURCES ./include/build_info.cpp ./include/ConstMessages.cpp ./include/helpers/*.cpp ./include/helpers/cuda/*.cu)
file(GLOB_RECURSE LOOPS_SOURCES ./include/loops/impl/*.cpp)
file(GLOB_RECURSE LEGACY_SOURCES ./include/legacy/impl/*.cpp ./include/legacy/*.cu)
file(GLOB_RECURSE LOOPS_SOURCES_CUDA ./include/loops/*.cu ./include/loops/cuda/**/*.cu)
file(GLOB_RECURSE VALIDATION_SOURCES ./include/array/DataTypeValidation.cpp)
file(GLOB CPU_HELPERS_TO_EXCLUDE ./include/legacy/cpu/*.cpp ./include/helpers/cpu/*.cpp ./include/array/cpu/*.cpp)
list(APPEND ALL_SOURCES_LIST
${EXEC_SOURCES} ${ARRAY_SOURCES} ${MEMORY_SOURCES} ${CUSTOMOPS_HELPERS_SOURCES}
${HELPERS_SOURCES} ${LOOPS_SOURCES} ${LEGACY_SOURCES} ${LOOPS_SOURCES_CUDA}
${VALIDATION_SOURCES}
)
list(REMOVE_ITEM ALL_SOURCES_LIST ${CPU_HELPERS_TO_EXCLUDE})
if(HAVE_CUDNN)
file(GLOB_RECURSE CUSTOMOPS_CUDNN_SOURCES ./include/ops/declarable/platform/cudnn/*.cu)
list(APPEND ALL_SOURCES_LIST ${CUSTOMOPS_CUDNN_SOURCES})
endif()
message(STATUS "🚀 CUDA build: Enhanced template system will generate additional CUDA instantiations")
else()
file(GLOB_RECURSE EXEC_SOURCES ./include/execution/*.cpp)
file(GLOB_RECURSE ARRAY_SOURCES ./include/array/*.cpp)
file(GLOB_RECURSE MEMORY_SOURCES ./include/memory/*.cpp)
file(GLOB_RECURSE CUSTOMOPS_HELPERS_IMPL_SOURCES ./include/ops/declarable/helpers/impl/*.cpp)
file(GLOB_RECURSE CUSTOMOPS_HELPERS_CPU_SOURCES ./include/ops/declarable/helpers/cpu/*.cpp)
file(GLOB_RECURSE HELPERS_SOURCES ./include/build_info.cpp ./include/ConstMessages.cpp ./include/helpers/*.cpp ./include/helpers/cpu/*.cpp)
file(GLOB_RECURSE LEGACY_SOURCES ./include/legacy/impl/*.cpp ./include/legacy/cpu/*.cpp)
file(GLOB_RECURSE LOOPS_SOURCES ./include/loops/*.cpp)
list(APPEND ALL_SOURCES_LIST
${EXEC_SOURCES} ${ARRAY_SOURCES} ${MEMORY_SOURCES} ${CUSTOMOPS_HELPERS_IMPL_SOURCES}
${CUSTOMOPS_HELPERS_CPU_SOURCES} ${HELPERS_SOURCES} ${LEGACY_SOURCES}
${LOOPS_SOURCES}
)
if(HAVE_ONEDNN)
file(GLOB_RECURSE CUSTOMOPS_ONEDNN_SOURCES ./include/ops/declarable/platform/mkldnn/*.cpp)
list(APPEND ALL_SOURCES_LIST ${CUSTOMOPS_ONEDNN_SOURCES})
endif()
if(HAVE_ARMCOMPUTE)
file(GLOB_RECURSE CUSTOMOPS_ARMCOMPUTE_SOURCES ./include/ops/declarable/platform/armcompute/*.cpp)
list(APPEND ALL_SOURCES_LIST ${CUSTOMOPS_ARMCOMPUTE_SOURCES})
endif()
message(STATUS "🖥️ CPU build: Enhanced template system will generate optimized CPU instantiations")
endif()
# When SD_GCC_FUNCTRACE is ON, the binary exceeds 2GB and PLT relocations fail
# libc_nonshared.a contains precompiled functions (like atexit) that use PLT
# We provide our own implementations compiled with -fno-plt to override them
if(SD_GCC_FUNCTRACE)
list(APPEND ALL_SOURCES_LIST ${CMAKE_CURRENT_SOURCE_DIR}/include/platform/noplt_libc_stubs.c)
message(STATUS "✅ Added no-PLT libc stubs for >2GB functrace build compatibility")
endif()
# ✅ Add the generated template sources (now includes both CPU and CUDA)
list(APPEND ALL_SOURCES_LIST ${CUSTOMOPS_GENERIC_SOURCES})
list(REMOVE_DUPLICATES ALL_SOURCES_LIST)
set(${out_source_list} ${ALL_SOURCES_LIST} PARENT_SCOPE)
# Enhanced logging
list(LENGTH CUSTOMOPS_GENERIC_SOURCES template_source_count)
if(SD_CUDA)
message(STATUS "📊 Total CUDA template-generated sources: ${template_source_count}")
else()
message(STATUS "📊 Total CPU template-generated sources: ${template_source_count}")
endif()
endfunction()
function(configure_cpu_linking main_target_name)
target_link_libraries(${main_target_name} PUBLIC
${ONEDNN} ${ARMCOMPUTE_LIBRARIES} ${OPENBLAS_LIBRARIES}
${BLAS_LIBRARIES} ${JVM_LIBRARY} flatbuffers_interface)
# Add debug libraries when SD_GCC_FUNCTRACE is enabled
if(SD_GCC_FUNCTRACE)
# CRITICAL FIX (Session #1045): Do NOT link libunwind!
# - We removed --unwindlib=libunwind from compile flags in CompilerFlags.cmake
# - Using system libgcc_s for exception handling (JVM compatible)
# - libunwind would conflict with JVM's libgcc_s causing _Unwind_SetGR crashes
# Both Clang and GCC now use the same debug libraries (no libunwind)
target_link_libraries(${main_target_name} PUBLIC
bfd dw dl elf pthread)
message(STATUS "✅ Added debug libraries for SD_GCC_FUNCTRACE (using libgcc_s for unwinding, JVM compatible)")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
target_link_libraries(${main_target_name} PUBLIC OpenMP::OpenMP_CXX)
else()
target_link_libraries(${main_target_name} PUBLIC "-fopenmp")
endif()
endif()
endfunction()
# UPDATED: Modern CUDA linking with improved cuDNN detection
function(configure_cuda_linking main_target_name)
# Find the CUDAToolkit to define the CUDA::toolkit target
find_package(CUDAToolkit REQUIRED)
# Setup modern cuDNN detection
setup_modern_cudnn()
# Modern CMake uses imported targets which handle all necessary dependencies.
# Linking against CUDA::toolkit automatically adds include directories,
# runtime libraries, and all other required flags.
target_link_libraries(${main_target_name} PUBLIC CUDA::toolkit ${JVM_LIBRARY})
# If cuDNN was found, link against its imported target
if(HAVE_CUDNN AND TARGET CUDNN::cudnn)
message(STATUS "✅ Linking with modern CUDNN::cudnn target")
target_link_libraries(${main_target_name} PUBLIC CUDNN::cudnn)
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
elseif(HAVE_CUDNN AND CUDNN_LIBRARIES)
message(STATUS "✅ Linking with cuDNN libraries: ${CUDNN_LIBRARIES}")
target_link_libraries(${main_target_name} PUBLIC ${CUDNN_LIBRARIES})
target_include_directories(${main_target_name} PUBLIC ${CUDNN_INCLUDE_DIR})
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
elseif(HAVE_CUDNN AND CUDNN_INCLUDE_DIR)
message(STATUS "✅ Linking with cuDNN include-only (embedded in CUDA)")
target_include_directories(${main_target_name} PUBLIC ${CUDNN_INCLUDE_DIR})
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
else()
message(STATUS "️ Building without cuDNN support")
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=0)
endif()
target_include_directories("${main_target_name}" PUBLIC "${CUDA_INCLUDE_DIRS}")
target_link_libraries(${main_target_name} PUBLIC flatbuffers_interface)
endfunction()
# --- Enhanced library creation function ---
function(create_and_link_library)
set(OBJECT_LIB_NAME "${SD_LIBRARY_NAME}_object")
set(MAIN_LIB_NAME "${SD_LIBRARY_NAME}")
if(NOT TARGET ${OBJECT_LIB_NAME})
add_library(${OBJECT_LIB_NAME} OBJECT ${ALL_SOURCES})
add_dependencies(${OBJECT_LIB_NAME} flatbuffers_interface)
target_link_libraries(${OBJECT_LIB_NAME} PUBLIC flatbuffers_interface)
# picking up incomplete flatbuffers.h from libnd4j/include/flatbuffers/
# The ExternalProject downloads full headers to flatbuffers-src/include
get_target_property(FLATBUFFERS_INCLUDES flatbuffers_interface INTERFACE_INCLUDE_DIRECTORIES)
if(FLATBUFFERS_INCLUDES)
target_include_directories(${OBJECT_LIB_NAME} BEFORE PUBLIC ${FLATBUFFERS_INCLUDES})
endif()
if(SD_CUDA)
# Find the CUDA Toolkit to make the CUDA::toolkit target available.
find_package(CUDAToolkit REQUIRED)
# THE FIX: For OBJECT libraries, you must get the include directories from
# the modern CUDA::toolkit target and apply them DIRECTLY to the object library
# that is being compiled.
get_target_property(CUDA_INCLUDE_DIRS CUDA::toolkit INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(${OBJECT_LIB_NAME} PUBLIC ${CUDA_INCLUDE_DIRS})
# UPDATED: Add cuDNN include directories if available
if(HAVE_CUDNN AND CUDNN_INCLUDE_DIR)
target_include_directories(${OBJECT_LIB_NAME} PUBLIC ${CUDNN_INCLUDE_DIR})
target_compile_definitions(${OBJECT_LIB_NAME} PUBLIC HAVE_CUDNN=1)
message(STATUS "🔧 Added cuDNN includes to object library: ${CUDNN_INCLUDE_DIR}")
else()
target_compile_definitions(${OBJECT_LIB_NAME} PUBLIC HAVE_CUDNN=0)
endif()
message(STATUS "🚀 CUDA object library configured with enhanced template support")
endif()
target_include_directories(${OBJECT_LIB_NAME} PUBLIC
"${CMAKE_CURRENT_BINARY_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include/array"
"${CMAKE_CURRENT_SOURCE_DIR}/include/execution"
"${CMAKE_CURRENT_SOURCE_DIR}/include/exceptions"
"${CMAKE_CURRENT_SOURCE_DIR}/include/graph"
"${CMAKE_CURRENT_SOURCE_DIR}/include/helpers"
"${CMAKE_CURRENT_SOURCE_DIR}/include/loops"
"${CMAKE_CURRENT_SOURCE_DIR}/include/memory"
"${CMAKE_CURRENT_SOURCE_DIR}/include/ops"
"${CMAKE_CURRENT_SOURCE_DIR}/include/types"
"${CMAKE_CURRENT_SOURCE_DIR}/include/system"
"${CMAKE_CURRENT_SOURCE_DIR}/include/legacy"
"${CMAKE_CURRENT_SOURCE_DIR}/include/performance"
"${CMAKE_CURRENT_SOURCE_DIR}/include/indexing"
"${CMAKE_CURRENT_SOURCE_DIR}/include/generated"
"${CMAKE_BINARY_DIR}/compilation_units"
"${CMAKE_BINARY_DIR}/cpu_instantiations"
)
if(SD_CUDA)
target_include_directories(${OBJECT_LIB_NAME} PUBLIC
"${CMAKE_BINARY_DIR}/cuda_instantiations"
)
else()
target_include_directories(${OBJECT_LIB_NAME} PUBLIC
"${OPENBLAS_PATH}/include"
"${CMAKE_BINARY_DIR}/cpu_instantiations"
)
endif ()
if(SD_CUDA AND DEFINED CMAKE_CUDA_ARCHITECTURES AND CMAKE_CUDA_ARCHITECTURES)
set_target_properties(${OBJECT_LIB_NAME} PROPERTIES
CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES}")
endif()
message(STATUS "🔧 Applying type definitions to OBJECT library: ${OBJECT_LIB_NAME}")
setup_type_definitions_for_target(${OBJECT_LIB_NAME})
# Enable precompiled headers for large commonly-included headers
# This significantly speeds up incremental builds when these headers change
# PERMANENTLY DISABLED: Causes cache staleness issues when SD_GCC_FUNCTRACE changes
# The CMake cache can hold stale values causing build failures
if(FALSE) # Disabled to prevent cache staleness issues
message(STATUS "🚀 Enabling precompiled headers for ${OBJECT_LIB_NAME}")
target_precompile_headers(${OBJECT_LIB_NAME} PRIVATE
<system/op_boilerplate.h>
<system/type_boilerplate.h>
)
message(STATUS "✅ Precompiled headers enabled for op_boilerplate.h and type_boilerplate.h")
elseif(SD_GCC_FUNCTRACE)
message(STATUS "⚠️ Precompiled headers DISABLED (prevents CMake cache staleness issues)")
else()
message(STATUS "⚠️ Precompiled headers DISABLED (prevents CMake cache staleness issues)")
endif()
endif()
if(NOT TARGET ${MAIN_LIB_NAME})
add_library(${MAIN_LIB_NAME} SHARED $<TARGET_OBJECTS:${OBJECT_LIB_NAME}>)
set_target_properties(${MAIN_LIB_NAME} PROPERTIES OUTPUT_NAME ${MAIN_LIB_NAME})
# Code model configuration is now centralized in CompilerFlags.cmake to avoid conflicts
# (CMAKE_SHARED_LINKER_FLAGS is set there with -mcmodel=large for sanitizer builds)
# Removed: target_link_options setting to prevent duplicate -mcmodel flags in link command
# if(SD_X86_BUILD AND NOT WIN32 AND DEFINED SD_SANITIZERS AND NOT SD_SANITIZERS STREQUAL "")
# target_link_options(${MAIN_LIB_NAME} PRIVATE "-mcmodel=large")
# message(STATUS "Applied -mcmodel=large to linker for ${MAIN_LIB_NAME}")
# endif()
message(STATUS "Code model configuration deferred to CompilerFlags.cmake (via CMAKE_SHARED_LINKER_FLAGS)")
# No CUDA includes needed here, they are handled by the linking function
target_include_directories(${MAIN_LIB_NAME} PUBLIC
"${OPENBLAS_PATH}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include/blas"
"${CMAKE_CURRENT_BINARY_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include/array"
"${CMAKE_CURRENT_SOURCE_DIR}/include/execution"
"${CMAKE_CURRENT_SOURCE_DIR}/include/exceptions"
"${CMAKE_CURRENT_SOURCE_DIR}/include/graph"
"${CMAKE_CURRENT_SOURCE_DIR}/include/helpers"
"${CMAKE_CURRENT_SOURCE_DIR}/include/loops"
"${CMAKE_CURRENT_SOURCE_DIR}/include/memory"
"${CMAKE_CURRENT_SOURCE_DIR}/include/ops"
"${CMAKE_CURRENT_SOURCE_DIR}/include/types"
"${CMAKE_CURRENT_SOURCE_DIR}/include/system"
"${CMAKE_CURRENT_SOURCE_DIR}/include/legacy"
"${CMAKE_CURRENT_SOURCE_DIR}/include/performance"
"${CMAKE_CURRENT_SOURCE_DIR}/include/indexing"
"${CMAKE_CURRENT_SOURCE_DIR}/include/generated"
"${CMAKE_BINARY_DIR}/compilation_units"
"${CMAKE_BINARY_DIR}/cpu_instantiations"
"${CMAKE_BINARY_DIR}/cuda_instantiations")
if(SD_CUDA)
target_include_directories(${MAIN_LIB_NAME} PUBLIC
"${CMAKE_BINARY_DIR}/cuda_instantiations"
)
else()
target_include_directories(${MAIN_LIB_NAME} PUBLIC
"${OPENBLAS_PATH}/include"
"${CMAKE_BINARY_DIR}/cpu_instantiations"
)
endif ()
# 🔧 ALSO apply type definitions to the shared library (for completeness)
message(STATUS "🔧 Applying type definitions to SHARED library: ${MAIN_LIB_NAME}")
setup_type_definitions_for_target(${MAIN_LIB_NAME})
endif()
# Remove the old call since we're now applying to both targets explicitly
# apply_libnd4j_type_definitions_auto()
if(SD_CUDA)
configure_cuda_linking(${MAIN_LIB_NAME})
else()
configure_cpu_linking(${MAIN_LIB_NAME})
endif()
endfunction()
# =============================================================================
# SECTION 2: MAIN BUILD ORCHESTRATION WITH ENHANCED CUDA/CPU TEMPLATE SUPPORT
# The main, sequential build process starts here.
# =============================================================================
print_status_colored("INFO" "=== ORCHESTRATING ENHANCED LIBND4J BUILD WITH TEMPLATE PARITY ===")
# --- Phase 1: Initial Setup ---
print_status_colored("INFO" "=== 1. INITIALIZING BUILD CONFIGURATION ===")
function(setup_initial_configuration)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
message(FATAL_ERROR "❌ You need at least GCC 4.9")
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
endif()
message(STATUS "🔧 Configuring Position Independent Code (PIC)...")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
message(STATUS "✅ Position Independent Code configuration complete")
endfunction()
setup_initial_configuration()
include(Dependencies)
setup_flatbuffers()
# --- Set library name and default engine first ---
if(NOT DEFINED SD_LIBRARY_NAME)
if(SD_CUDA)
set(SD_LIBRARY_NAME nd4jcuda)
set(DEFAULT_ENGINE "samediff::ENGINE_CUDA")
add_compile_definitions(DEFAULT_ENGINE=samediff::ENGINE_CUDA)
print_status_colored("INFO" "🚀 CUDA build mode: Enhanced template system will provide full CPU/CUDA parity")
else()
set(SD_LIBRARY_NAME nd4jcpu)
set(DEFAULT_ENGINE "samediff::ENGINE_CPU")
add_compile_definitions(DEFAULT_ENGINE=samediff::ENGINE_CPU)
print_status_colored("INFO" "🖥️ CPU build mode: Enhanced template system active")
endif()
endif()
# =============================================================================
# MINIMAL TYPE VALIDATION INTEGRATION - ONLY WHAT'S NEEDED
# =============================================================================
print_status_colored("INFO" "=== INTEGRATING TYPE VALIDATION ===")
# Call the type validation setup
LIBND4J_SETUP_TYPE_VALIDATION()
print_status_colored("SUCCESS" "Type validation integration complete")
# =============================================================================
if(SD_CUDA)
print_status_colored("INFO" "=== CUDA EARLY INITIALIZATION WITH TEMPLATE SUPPORT ===")
include(CudaConfiguration)
setup_cuda_build()
print_status_colored("SUCCESS" "CUDA initialization complete with enhanced template support")
endif()
# --- Phase 2: Handle Dependencies & Operations ---
print_status_colored("INFO" "=== 2. INITIALIZING DEPENDENCIES & OPERATIONS ===")
include(DuplicateInstantiationDetection)
include(TemplateProcessing)
include(CompilerFlags)
setup_platform_optimizations()
setup_onednn()
setup_armcompute()
# UPDATED: Modern cuDNN setup
if(SD_CUDA)
include(CudaConfiguration)
setup_modern_cudnn() # Use the modern cuDNN detection
message(STATUS "🔧 Modern cuDNN configuration: HAVE_CUDNN=${HAVE_CUDNN}")
if(HAVE_CUDNN)
message(STATUS "✅ cuDNN found and configured")
if(DEFINED CUDNN_VERSION_STRING)
message(STATUS " cuDNN version: ${CUDNN_VERSION_STRING}")
endif()
else()
message(STATUS "️ Building without cuDNN support")
endif()
else()
# For CPU builds, set HAVE_CUDNN to false
set(HAVE_CUDNN FALSE)
endif()
setup_blas()
setup_blas()
message(STATUS "🔍 DEBUG: After setup_blas() - OPENBLAS_PATH='${OPENBLAS_PATH}', HAVE_OPENBLAS='${HAVE_OPENBLAS}'")
message(STATUS "Dependencies initialization complete.")
message(STATUS "Dependencies initialization complete.")
message(STATUS "🔧 Helper Configuration: ONEDNN=${HAVE_ONEDNN}, ARMCOMPUTE=${HAVE_ARMCOMPUTE}, CUDNN=${HAVE_CUDNN}")
# --- Build TYPE_DEFINES string before generating config.h ---
# This ensures config.h has all HAS_* macros defined from the start
set(TYPE_DEFINES "")
# Check if we're in selective types mode
if(DEFINED SD_TYPES_LIST AND NOT SD_TYPES_LIST STREQUAL "")
# Selective types mode - export only enabled types
# The HAS_* macros were already set by apply_type_definitions_to_target
# We need to capture them and add to TYPE_DEFINES
# Get all HAS_* definitions that were set
get_directory_property(COMPILE_DEFS COMPILE_DEFINITIONS)
# Sort definitions to ensure deterministic order
# This prevents config.h from changing during build-time CMake reconfiguration
set(HAS_DEFS_LIST "")
foreach(def IN LISTS COMPILE_DEFS)
if(def MATCHES "^HAS_")
list(APPEND HAS_DEFS_LIST "${def}")
endif()
endforeach()
# Sort alphabetically for consistent output
list(SORT HAS_DEFS_LIST)
# Build TYPE_DEFINES string with sorted definitions
foreach(def IN LISTS HAS_DEFS_LIST)
string(APPEND TYPE_DEFINES "#define ${def}\n")
endforeach()
else()
# All types mode - define all HAS_* macros
string(APPEND TYPE_DEFINES "#define HAS_BOOL 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_DOUBLE 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT64 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_HALF 1\n")
string(APPEND TYPE_DEFINES "#define HAS_BFLOAT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_BFLOAT 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_HALF2 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT8_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT16_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT32_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT64 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT64_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_LONG 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT8_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT16_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT32_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT64 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT64_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UNSIGNEDLONG 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UTF8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_STD_STRING 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UTF16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_STD_U16STRING 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UTF32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_STD_U32STRING 1\n")
endif()
# --- Generate config.h AFTER setting all variables including TYPE_DEFINES ---
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/include/config.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/include/config.h")
set(DEFINITIONS_CONTENT "")
if(SD_ALL_OPS OR "${SD_OPS_LIST}" STREQUAL "")
add_compile_definitions(SD_ALL_OPS=1)
string(APPEND DEFINITIONS_CONTENT "#define SD_ALL_OPS 1\n")
else()
foreach(OP ${SD_OPS_LIST})
add_compile_definitions(OP_${OP}=1)
string(APPEND DEFINITIONS_CONTENT "#define OP_${OP} 1\n")
endforeach()
endif()
file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/generated")
set(INCLUDE_OPS_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/generated/include_ops.h")
file(WRITE "${INCLUDE_OPS_FILE}" "#ifndef SD_DEFINITIONS_GEN_H_\n#define SD_DEFINITIONS_GEN_H_\n${DEFINITIONS_CONTENT}\n#endif\n")
# --- Phase 3: Enhanced Selective Rendering Setup ---
print_status_colored("INFO" "=== 3. CONFIGURING ENHANCED SELECTIVE RENDERING ===")
include(SelectiveRenderingCore)
setup_selective_rendering_unified_safe(
TYPE_PROFILE "${SD_TYPE_PROFILE}"
OUTPUT_DIR "${CMAKE_BINARY_DIR}/include")
if(NOT DEFINED UNIFIED_COMBINATIONS_3 OR NOT UNIFIED_COMBINATIONS_3)
message(FATAL_ERROR "❌ CRITICAL: Unified selective rendering setup failed!")
endif()
list(LENGTH UNIFIED_ACTIVE_TYPES type_count)
list(LENGTH UNIFIED_COMBINATIONS_3 combo_3_count)
if(SD_CUDA)
message(STATUS "✅ Enhanced CUDA selective rendering setup complete: ${type_count} types, ${combo_3_count} combinations.")
else()
message(STATUS "✅ Enhanced CPU selective rendering setup complete: ${type_count} types, ${combo_3_count} combinations.")
endif()
if(DEFINED HAS_FLOAT16 AND HAS_FLOAT16)
list(FIND UNIFIED_ACTIVE_TYPES "float16" float16_pos)
if(float16_pos LESS 0)
message(FATAL_ERROR "❌ CRITICAL: float16 missing despite HAS_FLOAT16=TRUE! This will cause build errors.")
else()
message(STATUS "✅ VERIFIED: float16 present at position ${float16_pos}")
endif()
endif()
# --- Phase 4: Create and Link Final Library with Enhanced Template System ---
print_status_colored("INFO" "=== 4. CREATING AND LINKING FINAL LIBRARY WITH ENHANCED TEMPLATES ===")
# ✅ DO NOT reset CUSTOMOPS_GENERIC_SOURCES - it's a CACHE variable populated by TemplateProcessing.cmake
# Resetting it here causes the cached template files to be lost, resulting in build errors
collect_all_sources(ALL_SOURCES)
create_and_link_library()
message(STATUS "Final library target created and linked with enhanced template support.")
# --- Phase 5: Enhanced Final Reports and Summaries ---
if(DEFINED SD_GENERATE_TYPE_REPORT AND SD_GENERATE_TYPE_REPORT)
print_status_colored("INFO" "=== GENERATING ENHANCED USAGE DOCUMENTATION ===")
set(usage_doc "${CMAKE_BINARY_DIR}/enhanced_selective_rendering_usage.md")
set(doc_content "# Enhanced Unified Selective Rendering Usage\n\nThis build was configured with the enhanced unified selective rendering system providing full CPU/CUDA parity.\n\n")
if(DEFINED SD_TYPE_PROFILE)
string(APPEND doc_content "**Type Profile**: ${SD_TYPE_PROFILE}\n\n")
endif()
if(SD_CUDA)
string(APPEND doc_content "**Build Mode**: CUDA with enhanced template system\n")
string(APPEND doc_content "**Template Parity**: Full parity achieved between CPU and CUDA template systems\n\n")
if(HAVE_CUDNN)
string(APPEND doc_content "**cuDNN Support**: Enabled\n")
if(DEFINED CUDNN_VERSION_STRING)
string(APPEND doc_content "**cuDNN Version**: ${CUDNN_VERSION_STRING}\n")
endif()
else()
string(APPEND doc_content "**cuDNN Support**: Disabled\n")
endif()
else()
string(APPEND doc_content "**Build Mode**: CPU with enhanced template system\n\n")
endif()
file(WRITE "${usage_doc}" "${doc_content}")
message(STATUS "📝 Enhanced usage documentation written to: ${usage_doc}")
endif()
print_status_colored("SUCCESS" "=== ENHANCED BUILD ORCHESTRATION COMPLETE ===")
message(STATUS "")
message(STATUS "🎯 ENHANCED BUILD SUMMARY:")
message(STATUS " Library: ${SD_LIBRARY_NAME}")
message(STATUS " Platform: ${CMAKE_SYSTEM_NAME}")
if(SD_CUDA)
message(STATUS " CUDA: Enabled with enhanced template parity")
message(STATUS " Template System: CUDA templates achieve full CPU parity")
message(STATUS " cuDNN: ${HAVE_CUDNN}")
if(HAVE_CUDNN AND DEFINED CUDNN_VERSION_STRING)
message(STATUS " cuDNN Version: ${CUDNN_VERSION_STRING}")
endif()
else()
message(STATUS " CUDA: Disabled")
message(STATUS " Template System: Enhanced CPU templates")
endif()
if(DEFINED SD_TYPE_PROFILE)
message(STATUS " Type Profile: ${SD_TYPE_PROFILE}")
endif()
if(DEFINED type_count)
message(STATUS " Active Types: ${type_count}")
endif()
if(DEFINED combo_3_count)
message(STATUS " Template Combinations: ${combo_3_count}")
endif()
include(TypeRegistryGenerator)
dump_type_macros_to_disk()
if(SD_CUDA)
message(STATUS "🚀 Enhanced CUDA build orchestration complete - CUDA/CPU template parity achieved")
else()
message(STATUS "🖥️ Enhanced CPU build orchestration complete - System ready for compilation")
endif()
message(STATUS "")
# === ENHANCED TEMPLATE SYSTEM VERIFICATION ===
print_status_colored("INFO" "=== VERIFYING ENHANCED TEMPLATE SYSTEM ===")
# Verify template generation worked
list(LENGTH CUSTOMOPS_GENERIC_SOURCES template_file_count)
if(template_file_count GREATER 0)
if(SD_CUDA)
message(STATUS "✅ CUDA template generation verified: ${template_file_count} files")
# Check for CUDA-specific template files
set(cuda_template_count 0)
foreach(source_file ${CUSTOMOPS_GENERIC_SOURCES})
if(source_file MATCHES "\\.cu$")
math(EXPR cuda_template_count "${cuda_template_count} + 1")
endif()
endforeach()
message(STATUS "🔍 CUDA template files: ${cuda_template_count}")
if(cuda_template_count GREATER 0)
print_status_colored("SUCCESS" "CUDA template parity system operational")
else()
print_status_colored("WARNING" "No CUDA template files detected - check template processing")
endif()
else()
message(STATUS "✅ CPU template generation verified: ${template_file_count} files")
print_status_colored("SUCCESS" "Enhanced CPU template system operational")
endif()
endif()
# Final verification of directory structure
if(SD_CUDA)
if(EXISTS "${CMAKE_BINARY_DIR}/cuda_instantiations")
message(STATUS "✅ CUDA instantiation directory verified")
else()
message(WARNING "⚠️ CUDA instantiation directory not found")
endif()
else()
if(EXISTS "${CMAKE_BINARY_DIR}/cpu_instantiations")
message(STATUS "✅ CPU instantiation directory verified")
else()
message(WARNING "⚠️ CPU instantiation directory not found")
endif()
endif()
# Set OBJECT_LIB_NAME for PostBuild.cmake (matches pattern from create_and_link_library function)
if(NOT DEFINED OBJECT_LIB_NAME AND DEFINED SD_LIBRARY_NAME)
set(OBJECT_LIB_NAME "${SD_LIBRARY_NAME}_object")
message(STATUS "Set OBJECT_LIB_NAME for PostBuild: ${OBJECT_LIB_NAME}")
endif()
# Check for instantiation extraction BEFORE PostBuild
if(SD_EXTRACT_INSTANTIATIONS)
print_status_colored("INFO" "=== TEMPLATE INSTANTIATION EXTRACTION MODE ===")
include(ExtractInstantiations)
# ExtractInstantiations.cmake will handle everything and exit
return()
endif()
# Precompiled headers PERMANENTLY DISABLED to prevent CMake cache staleness issues
# When SD_GCC_FUNCTRACE or other flags change, stale cache can cause build failures
if(FALSE) # Disabled to prevent cache staleness issues
target_precompile_headers(${SD_LIBRARY_NAME} PRIVATE
<vector>
<memory>
<algorithm>
<functional>
<cstring>
"${CMAKE_CURRENT_SOURCE_DIR}/include/system/op_boilerplate.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/system/type_boilerplate.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/system/type_boiler_plate_expansioons.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/array/DataType.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/array/NDArray.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/array/NDArray.hXX"
"${CMAKE_CURRENT_SOURCE_DIR}/include/types/types.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/math/platformmath.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/math/templatemath.h"
)
message(STATUS "✅ Precompiled headers enabled for main library")
else()
message(STATUS "⚠️ Precompiled headers DISABLED (prevents CMake cache staleness issues)")
endif()
include(PostBuild)
print_status_colored("SUCCESS" "=== ENHANCED TEMPLATE SYSTEM VERIFICATION COMPLETE ===")
+239
View File
@@ -0,0 +1,239 @@
# cmake/Options.cmake
# Defines all user-configurable build options and helper functions.
# --- Build Feature Options ---
option(SD_NATIVE "Optimize for build machine (might not work on others)" OFF)
option(SD_CHECK_VECTORIZATION "checks for vectorization" OFF)
option(SD_STATIC_LIB "Build static library (ignored, only shared lib is built)" OFF)
option(SD_SHARED_LIB "Build shared library (ignored, this is the default)" ON)
option(SD_USE_LTO "Use link time optimization" OFF)
option(SD_SANITIZE "Enable Address Sanitizer" OFF)
option(SD_EXTRACT_INSTANTIATIONS "Extract template instantiations and exit" OFF)
option(SD_GENERATE_FIX_FILES "Generate fix files for missing instantiations" OFF)
option(SD_INSTANTIATION_VERBOSE "Verbose instantiation extraction" OFF)
# --- COMPILATION OPTIMIZATION OPTIONS (NEW) ---
# These dramatically affect template compilation time
option(SD_FAST_BUILD "Enable fast build mode with minimal templates" OFF)
option(SD_UNITY_BUILD "Enable Unity build for faster compilation" OFF)
set(SD_PARALLEL_COMPILE_JOBS "0" CACHE STRING "Number of parallel compile jobs (0 = auto)")
# --- Helper Library Toggles ---
option(HELPERS_armcompute "Enable ARM Compute Library helper" OFF)
option(HELPERS_onednn "Enable OneDNN helper" OFF)
option(HELPERS_cudnn "Enable cuDNN helper" OFF)
# Force all helpers OFF by default to prevent compilation issues
set(HELPERS_armcompute OFF CACHE BOOL "Force disable ARM Compute Library helper" FORCE)
set(HELPERS_onednn OFF CACHE BOOL "Force disable OneDNN helper" FORCE)
set(HELPERS_cudnn OFF CACHE BOOL "Force disable cuDNN helper" FORCE)
# Set corresponding HAVE_* variables
set(HAVE_ARMCOMPUTE OFF CACHE BOOL "ARM Compute Library availability" FORCE)
set(HAVE_ONEDNN OFF CACHE BOOL "OneDNN availability" FORCE)
set(HAVE_CUDNN OFF CACHE BOOL "cuDNN availability" FORCE)
set(GENERATED_TYPE_COMBINATIONS "" CACHE INTERNAL "Generated type combinations")
set(PROCESSED_TEMPLATE_FILES "" CACHE INTERNAL "Processed template files")
# --- Debug and Trace Options ---
option(SD_GCC_FUNCTRACE "Use call traces" OFF)
# Enable compile_commands.json for functrace builds (helps with validation)
if(SD_GCC_FUNCTRACE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Export compile commands for validation" FORCE)
endif()
option(PRINT_INDICES "Print indices" OFF)
option(PRINT_MATH "Print math operations" OFF)
option(SD_PTXAS "Enable ptxas verbose output" OFF)
option(SD_KEEP_NVCC_OUTPUT "Keep NVCC output files" OFF)
option(SD_PREPROCESS "Enable preprocessing" OFF)
# --- Build Target Options ---
option(SD_BUILD_TESTS "Build tests" OFF)
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler" OFF)
# Hack to disable flatc build unless explicitly enabled
set(FLATBUFFERS_BUILD_FLATC "OFF" CACHE STRING "Hack to disable flatc build" FORCE)
# --- Type System and Template Options ---
option(SD_ENABLE_SEMANTIC_FILTERING "Enable semantic filtering to reduce template combinations" ON)
option(SD_ENABLE_SELECTIVE_RENDERING "Enable selective rendering system" ON)
option(SD_AGGRESSIVE_SEMANTIC_FILTERING "Use aggressive filtering rules" ON)
# CHANGED: Default to MINIMAL for faster builds
set(SD_TYPE_PROFILE "STANDARD_ALL_TYPES" CACHE STRING "Type profile for semantic filtering (MINIMAL, ESSENTIAL, QUANTIZATION, INFERENCE, TRAINING,STANDARD_ALL_TYPES)")
set_property(CACHE SD_TYPE_PROFILE PROPERTY STRINGS STANDARD_ALL_TYPES MINIMAL ESSENTIAL QUANTIZATION INFERENCE TRAINING)
# CHANGED: Lower default to prevent explosion
set(SD_MAX_TEMPLATE_COMBINATIONS "1000" CACHE STRING "Maximum template combinations to generate (safety limit)")
# --- NEW: Template Chunking Configuration ---
# These control how template instantiations are split across files
# TLS relocation overflow is caused by TOO MANY FILES, not large files
# Solution: Use larger chunks with call tracing to minimize file count
# Detect build configuration and set appropriate defaults
if(DEFINED SD_GCC_FUNCTRACE AND SD_GCC_FUNCTRACE)
# Call tracing enabled - need larger chunks to avoid TLS overflow
if((DEFINED SD_SANITIZE AND SD_SANITIZE) OR (DEFINED SD_SANITIZERS AND NOT SD_SANITIZERS STREQUAL ""))
# Call tracing + Sanitizers: Compromise between speed and RAM
# Larger than sanitizers-only (prevents TLS overflow) but not too large (prevents OOM)
set(CHUNK_TARGET_INSTANTIATIONS "30" CACHE STRING "Balanced chunks for call tracing + sanitizers" FORCE)
set(MULTI_PASS_CHUNK_SIZE "70" CACHE STRING "Balanced direct chunks for call tracing + sanitizers" FORCE)
message(STATUS "⚠️ Call tracing + Sanitizers: Using balanced chunks (30/70) - prevents TLS overflow and OOM")
else()
# Call tracing only: Very large chunks for maximum speed (no RAM constraints without sanitizers)
# Functrace adds minimal memory overhead, so we can use much larger chunks than normal builds
# Larger chunks = fewer files = faster linking + less TLS overhead
set(CHUNK_TARGET_INSTANTIATIONS "80" CACHE STRING "Very large chunks for call tracing only" FORCE)
set(MULTI_PASS_CHUNK_SIZE "200" CACHE STRING "Very large direct chunks for call tracing only" FORCE)
message(STATUS "🔍 Call tracing only: Using very large chunks (80/200) for maximum build speed")
endif()
elseif((DEFINED SD_SANITIZE AND SD_SANITIZE) OR (DEFINED SD_SANITIZERS AND NOT SD_SANITIZERS STREQUAL ""))
# Sanitizers only: Small chunks to prevent OOM (sanitizer builds use massive RAM per file)
set(CHUNK_TARGET_INSTANTIATIONS "6" CACHE STRING "Small chunks for sanitizers (prevents OOM)" FORCE)
set(MULTI_PASS_CHUNK_SIZE "8" CACHE STRING "Small direct chunks for sanitizers (prevents OOM)" FORCE)
message(STATUS "⚠️ Sanitizers: Using small chunks (6/8) to prevent out-of-memory during compilation")
else()
# Normal builds: Use memory-based defaults (no special instrumentation)
cmake_host_system_information(RESULT AVAILABLE_MEMORY QUERY AVAILABLE_PHYSICAL_MEMORY)
if(AVAILABLE_MEMORY LESS 4000)
set(CHUNK_TARGET_INSTANTIATIONS "3" CACHE STRING "Conservative chunks for low memory" FORCE)
set(MULTI_PASS_CHUNK_SIZE "25" CACHE STRING "Conservative direct chunks" FORCE)
message(STATUS "💾 Low memory detected: Using small chunks (3/25)")
elseif(AVAILABLE_MEMORY LESS 8000)
set(CHUNK_TARGET_INSTANTIATIONS "6" CACHE STRING "Moderate chunks for medium memory" FORCE)
set(MULTI_PASS_CHUNK_SIZE "35" CACHE STRING "Moderate direct chunks" FORCE)
message(STATUS "💾 Medium memory detected: Using moderate chunks (6/35)")
elseif(AVAILABLE_MEMORY LESS 16000)
set(CHUNK_TARGET_INSTANTIATIONS "10" CACHE STRING "Balanced chunks for high memory" FORCE)
set(MULTI_PASS_CHUNK_SIZE "50" CACHE STRING "Balanced direct chunks" FORCE)
message(STATUS "💾 High memory detected: Using balanced chunks (10/50)")
else()
set(CHUNK_TARGET_INSTANTIATIONS "12" CACHE STRING "Optimized chunks for very high memory" FORCE)
set(MULTI_PASS_CHUNK_SIZE "60" CACHE STRING "Optimized direct chunks" FORCE)
message(STATUS "💾 Very high memory detected: Using large chunks (12/60)")
endif()
endif()
set(CHUNK_MAX_INSTANTIATIONS "3" CACHE STRING "Maximum template instantiations per chunk file")
set(USE_MULTI_PASS_GENERATION "OFF" CACHE STRING "Use multi-pass generation (ON/OFF/AUTO)")
# --- NEW: Type Selection for Fast Builds ---
if(SD_FAST_BUILD)
message(STATUS "🚀 Fast build mode enabled - using minimal type set")
set(SD_TYPE_PROFILE "MINIMAL" CACHE STRING "Type profile for fast builds" FORCE)
set(SD_TYPES_LIST "float;double" CACHE STRING "Minimal type set for fast builds" FORCE)
set(SD_AGGRESSIVE_SEMANTIC_FILTERING ON CACHE BOOL "Use aggressive filtering" FORCE)
set(CHUNK_TARGET_INSTANTIATIONS "100" CACHE STRING "Larger chunks for fast builds" FORCE)
set(SD_MAX_TEMPLATE_COMBINATIONS "500" CACHE STRING "Strict limit for fast builds" FORCE)
endif()
# --- NEW: Configure Unity Build ---
if(SD_UNITY_BUILD)
message(STATUS "🔧 Unity build enabled for faster compilation")
set(CMAKE_UNITY_BUILD ON CACHE BOOL "Enable Unity builds" FORCE)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 20 CACHE STRING "Unity build batch size" FORCE)
endif()
# --- NEW: Configure Parallel Compilation ---
if(NOT SD_PARALLEL_COMPILE_JOBS STREQUAL "0")
set(CMAKE_BUILD_PARALLEL_LEVEL ${SD_PARALLEL_COMPILE_JOBS} CACHE STRING "Parallel build level" FORCE)
message(STATUS "🔧 Parallel compilation set to ${SD_PARALLEL_COMPILE_JOBS} jobs")
else()
# Auto-detect number of cores
include(ProcessorCount)
ProcessorCount(N)
if(NOT N EQUAL 0)
set(CMAKE_BUILD_PARALLEL_LEVEL ${N} CACHE STRING "Parallel build level" FORCE)
message(STATUS "🔧 Auto-detected ${N} cores for parallel compilation")
endif()
endif()
# --- NEW: Compiler-specific optimizations for template compilation ---
# Template depth: 512 for release (faster compilation), 1024 for debug (deeper nesting support)
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
add_compile_options(-ftemplate-depth=1024)
message(STATUS "Using template depth 1024 for ${CMAKE_BUILD_TYPE} build")
else()
add_compile_options(-ftemplate-depth=512)
message(STATUS "Using template depth 512 for ${CMAKE_BUILD_TYPE} build")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Enable faster template compilation in GCC 10+
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)
add_compile_options(-fconcepts-diagnostics-depth=2)
endif()
# For development builds, use faster but less optimized compilation
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR SD_FAST_BUILD)
add_compile_options(-O0 -fno-inline-functions)
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# For development builds, use faster but less optimized compilation
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR SD_FAST_BUILD)
add_compile_options(-O0 -fno-inline-functions)
endif()
endif()
option(BUILD_PPSTEP "Build ppstep preprocessor debugging tool" OFF)
# --- Helper function for colored status messages ---
function(print_status_colored type message)
if(type STREQUAL "ERROR")
message(FATAL_ERROR "❌ ${message}")
elseif(type STREQUAL "WARNING")
message(WARNING "⚠️ ${message}")
elseif(type STREQUAL "SUCCESS")
message(STATUS "✅ ${message}")
elseif(type STREQUAL "INFO")
message(STATUS "️ ${message}")
elseif(type STREQUAL "DEBUG")
message(STATUS "🔍 ${message}")
elseif(type STREQUAL "NOTICE")
message(NOTICE "📢 ${message}")
else()
message(STATUS "${message}")
endif()
endfunction()
# --- NEW: Print build configuration summary ---
function(print_build_configuration)
message(STATUS "")
message(STATUS "=== Template Compilation Configuration ===")
message(STATUS "Type Profile: ${SD_TYPE_PROFILE}")
message(STATUS "Semantic Filtering: ${SD_ENABLE_SEMANTIC_FILTERING}")
message(STATUS "Aggressive Filtering: ${SD_AGGRESSIVE_SEMANTIC_FILTERING}")
message(STATUS "Max Template Combinations: ${SD_MAX_TEMPLATE_COMBINATIONS}")
message(STATUS "Chunk Target Size: ${CHUNK_TARGET_INSTANTIATIONS}")
message(STATUS "Unity Build: ${SD_UNITY_BUILD}")
message(STATUS "Fast Build Mode: ${SD_FAST_BUILD}")
if(DEFINED SD_TYPES_LIST)
message(STATUS "Active Types: ${SD_TYPES_LIST}")
endif()
message(STATUS "==========================================")
message(STATUS "")
endfunction()
# --- Macro for debugging all CMake variables ---
macro(print_all_variables)
message(STATUS "print_all_variables------------------------------------------{")
get_cmake_property(_variableNames VARIABLES)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
message(STATUS "print_all_variables------------------------------------------}")
endmacro()
# --- NEW: Validation and warnings ---
if(SD_TYPE_PROFILE STREQUAL "ESSENTIAL" OR SD_TYPE_PROFILE STREQUAL "TRAINING")
message(WARNING "⚠️ Using '${SD_TYPE_PROFILE}' profile will generate many template instantiations and slow compilation. Consider 'MINIMAL' or 'INFERENCE' for faster builds.")
endif()
if(CHUNK_TARGET_INSTANTIATIONS LESS 20)
message(WARNING "⚠️ CHUNK_TARGET_INSTANTIATIONS is very low (${CHUNK_TARGET_INSTANTIATIONS}). This will create many small files and slow compilation.")
endif()
+101
View File
@@ -0,0 +1,101 @@
# cmake/Platform.cmake
# Detects OS and CPU architecture and sets platform-specific flags.
# --- Platform and Architecture Detection ---
set(SD_X86_BUILD false)
set(SD_ARM_BUILD false)
if(SD_ANDROID_BUILD)
if(ANDROID_ABI MATCHES "x86_64")
set(SD_X86_BUILD true)
set(SD_ARCH "x86-64")
elseif(ANDROID_ABI MATCHES "x86")
set(SD_X86_BUILD true)
set(SD_ARCH "x86")
elseif(ANDROID_ABI MATCHES "arm64-v8a")
set(SD_ARM_BUILD true)
set(SD_ARCH "arm64-v8a")
elseif(ANDROID_ABI MATCHES "armeabi-v7a")
set(SD_ARM_BUILD true)
set(SD_ARCH "armv7-a")
endif()
elseif(NOT SD_IOS_BUILD)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64")
set(SD_X86_BUILD true)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
set(SD_ARCH "x86-64")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm*|aarch64")
set(SD_ARM_BUILD true)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
set(SD_ARCH "armv8-a")
else()
set(SD_ARCH "armv7-a")
endif()
endif()
endif()
endif()
if(SD_ARM_BUILD)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
message(STATUS "Warning: SD_ARCH was not set for this ARM build. Defaulting to 'armv8-a'.")
set(SD_ARCH "armv8-a")
endif()
endif()
message(STATUS "Build flags determined: SD_ANDROID_BUILD=${SD_ANDROID_BUILD}, SD_X86_BUILD=${SD_X86_BUILD}, SD_ARM_BUILD=${SD_ARM_BUILD}, SD_ARCH=${SD_ARCH}")
# --- Architecture-Specific Tuning ---
set(ARCH_TUNE "")
if(SD_ARCH MATCHES "armv8")
set(ARCH_TUNE "-march=${SD_ARCH}")
elseif(SD_ARCH MATCHES "armv7")
set(ARCH_TUNE "-march=${SD_ARCH} -mfpu=neon")
elseif(SD_EXTENSION MATCHES "avx512")
message("Building AVX512 binary...")
set(ARCH_TUNE "-mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mavx512f -mavx512vl -mavx512bw -mavx512dq -mavx512cd -mbmi -mbmi2 -mprefetchwt1 -mclflushopt -mxsavec -mxsaves -DSD_F16C=true -DF_AVX512=true")
elseif(SD_EXTENSION MATCHES "avx2")
message("Building AVX2 binary...")
set(ARCH_TUNE "-mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mprefetchwt1 -DSD_F16C=true -DF_AVX2=true")
if(NO_AVX256_SPLIT)
set(ARCH_TUNE "${ARCH_TUNE} -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store")
endif()
elseif(SD_NATIVE)
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64*" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64*")
set(ARCH_TUNE "-mcpu=native")
else()
set(ARCH_TUNE "-march=native")
endif()
endif()
if(NOT ARCH_TUNE STREQUAL "")
message(STATUS "Applying architecture tuning flags: ${ARCH_TUNE}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_TUNE}")
endif()
# --- OS-Specific Build Flags ---
if(SD_APPLE_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_APPLE_BUILD=true -mmacosx-version-min=10.10")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_APPLE_BUILD=true -mmacosx-version-min=10.10")
elseif(SD_ARM_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_ARM_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_ARM_BUILD=true")
elseif(SD_ANDROID_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_ANDROID_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_ANDROID_BUILD=true")
elseif(SD_IOS_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_IOS_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_IOS_BUILD=true")
endif()
# --- External Include Directories ---
if(UNIX)
link_directories(/usr/local/lib /usr/lib /lib)
endif()
if(APPLE)
message("Using Apple")
link_directories(/usr/local/lib /usr/lib /lib)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
list(APPEND EXTERNAL_INCLUDE_DIRS "/usr/include" "/usr/local/include")
endif()
+116
View File
@@ -0,0 +1,116 @@
# PlatformDetection.cmake - Platform and architecture detection
# Ensure SD_CPU is TRUE if neither SD_CUDA nor SD_CPU is set
if(NOT SD_CUDA)
if(NOT SD_CPU)
set(SD_CUDA FALSE)
set(SD_CPU TRUE)
endif()
endif()
# Set SD_LIBRARY_NAME Based on Build Type
if(NOT DEFINED SD_LIBRARY_NAME)
if(SD_CUDA)
set(SD_LIBRARY_NAME nd4jcuda)
else()
set(SD_LIBRARY_NAME nd4jcpu)
endif()
endif()
# Set default engine
if(SD_CUDA)
set(DEFAULT_ENGINE "samediff::ENGINE_CUDA")
else()
set(DEFAULT_ENGINE "samediff::ENGINE_CPU")
endif()
# MSVC runtime lib can be either "MultiThreaded" or "MultiThreadedDLL", /MT and /MD respectively
set(MSVC_RT_LIB "MultiThreadedDLL")
# Determine platform type more accurately
set(SD_X86_BUILD false)
set(SD_ARM_BUILD false)
if(SD_ANDROID_BUILD)
if(ANDROID_ABI MATCHES "x86_64")
set(SD_X86_BUILD true)
set(SD_ARCH "x86-64")
elseif(ANDROID_ABI MATCHES "x86")
set(SD_X86_BUILD true)
set(SD_ARCH "x86")
elseif(ANDROID_ABI MATCHES "arm64-v8a")
set(SD_ARM_BUILD true)
set(SD_ARCH "arm64-v8a")
elseif(ANDROID_ABI MATCHES "armeabi-v7a")
set(SD_ARM_BUILD true)
set(SD_ARCH "armv7-a")
endif()
elseif(NOT SD_IOS_BUILD)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64")
set(SD_X86_BUILD true)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
set(SD_ARCH "x86-64")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm*|aarch64")
set(SD_ARM_BUILD true)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
set(SD_ARCH "armv8-a")
else()
set(SD_ARCH "armv7-a")
endif()
endif()
endif()
endif()
if(SD_ARM_BUILD)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
message(STATUS "Warning: SD_ARCH was not set for this ARM build. Defaulting to 'armv8-a'.")
set(SD_ARCH "armv8-a")
endif()
if(SD_ANDROID)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
endif()
# Define Compiler Flags for Specific Builds
if(SD_APPLE_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_APPLE_BUILD=true -mmacosx-version-min=10.10")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_APPLE_BUILD=true -mmacosx-version-min=10.10")
endif()
if(SD_ARM_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_ARM_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_ARM_BUILD=true")
endif()
if(SD_ANDROID_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_ANDROID_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_ANDROID_BUILD=true")
endif()
if(SD_IOS_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_IOS_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_IOS_BUILD=true")
endif()
message(STATUS "Build flags determined: SD_ANDROID_BUILD=${SD_ANDROID_BUILD}, SD_X86_BUILD=${SD_X86_BUILD}, SD_ARM_BUILD=${SD_ARM_BUILD}, SD_ARCH=${SD_ARCH}")
# Include Directories Based on OS
if(UNIX)
link_directories(/usr/local/lib /usr/lib /lib)
endif()
if(APPLE)
message("Using Apple")
link_directories(/usr/local/lib /usr/lib /lib)
endif()
# External Include Directories
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
list(APPEND EXTERNAL_INCLUDE_DIRS "/usr/include" "/usr/local/include")
endif()
# Initialize job pools for parallel builds
set_property(GLOBAL PROPERTY JOB_POOLS one_jobs=1 two_jobs=2)
+292
View File
@@ -0,0 +1,292 @@
################################################################################
# Platform Optimization Functions
# Platform-specific compiler optimizations and build configurations
################################################################################
# Function to apply Android x86_64 PLT fixes for large template libraries
function(apply_android_x86_64_plt_fixes target_name)
if(NOT (SD_ANDROID_BUILD AND ANDROID_ABI MATCHES "x86_64"))
return()
endif()
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(${target_name} PRIVATE
-ffunction-sections
-fdata-sections
-fvisibility=hidden
-fvisibility-inlines-hidden
-fno-plt
-fno-semantic-interposition
)
else()
# MSVC equivalent flags
target_compile_options(${target_name} PRIVATE
/Gy # Function-level linking
)
endif()
# Target-specific preprocessor definitions
target_compile_definitions(${target_name} PRIVATE
ANDROID_X86_64_OPTIMIZED=1
)
# Apply linker flags only to shared/executable targets
get_target_property(target_type ${target_name} TYPE)
message(STATUS "Applied verified Android x86_64 optimizations to target: ${target_name}")
endfunction()
# Comprehensive linker configuration for large template libraries
function(configure_large_template_linker)
if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND SD_X86_BUILD))
return()
endif()
message(STATUS "Configuring linker for large template library with PLT overflow prevention")
# Clear any existing conflicting linker flags
string(REGEX REPLACE "-fuse-ld=[a-zA-Z]+" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
string(REGEX REPLACE "-fuse-ld=[a-zA-Z]+" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
# Test if linker supports --plt-align before using it
execute_process(
COMMAND ${CMAKE_LINKER} --help
OUTPUT_VARIABLE LD_HELP_OUTPUT
ERROR_QUIET
)
string(FIND "${LD_HELP_OUTPUT}" "--plt-align" PLT_ALIGN_SUPPORTED)
message(STATUS "Applied PLT overflow prevention for large template library")
endfunction()
# Function to configure memory model based on architecture
function(configure_memory_model)
# Memory model is now configured in CompilerFlags.cmake to avoid conflicts
# (Sanitizer builds use -mcmodel=large, non-sanitizer builds use -mcmodel=medium)
if(SD_X86_BUILD AND NOT WIN32)
# Removed: -mcmodel setting now in CompilerFlags.cmake only
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=medium -fPIC" PARENT_SCOPE)
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcmodel=medium" PARENT_SCOPE)
message(STATUS "Memory model configuration deferred to CompilerFlags.cmake")
else()
if(SD_ARM_BUILD OR SD_ANDROID_BUILD)
message(STATUS "Skipping large memory model for ARM/Android architecture (not supported)")
elseif(WIN32)
message(STATUS "Skipping large memory model for Windows (using alternative approach)")
endif()
endif()
endfunction()
# Function to apply memory optimization during compilation
function(configure_compilation_memory_optimization)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --param ggc-min-expand=100 --param ggc-min-heapsize=131072" PARENT_SCOPE)
message(STATUS "Applied GCC memory optimization flags")
endif()
endfunction()
# Function to configure section splitting for better linker handling
function(configure_section_splitting)
# MSVC-specific optimizations
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# MSVC equivalent optimizations
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Gy" PARENT_SCOPE) # Function-level linking
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gy" PARENT_SCOPE) # Function-level linking
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /OPT:REF /OPT:ICF" PARENT_SCOPE) # Remove unreferenced code
message(STATUS "Applied MSVC function-level linking optimizations")
endif()
endfunction()
# Function to disable PLT completely for memory issues
function(configure_plt_disable)
# For CUDA builds, disable PLT in host compiler flags
if(SD_CUDA AND CMAKE_CUDA_COMPILER)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler -fno-plt" PARENT_SCOPE)
message(STATUS "Disabled PLT for CUDA host compiler")
endif()
endfunction()
# Function to determine platform type accurately
function(determine_platform_type)
set(SD_X86_BUILD false PARENT_SCOPE)
set(SD_ARM_BUILD false PARENT_SCOPE)
if(SD_ANDROID_BUILD)
if(ANDROID_ABI MATCHES "x86_64")
set(SD_X86_BUILD true PARENT_SCOPE)
set(SD_ARCH "x86-64" PARENT_SCOPE)
elseif(ANDROID_ABI MATCHES "x86")
set(SD_X86_BUILD true PARENT_SCOPE)
set(SD_ARCH "x86" PARENT_SCOPE)
elseif(ANDROID_ABI MATCHES "arm64-v8a")
set(SD_ARM_BUILD true PARENT_SCOPE)
set(SD_ARCH "arm64-v8a" PARENT_SCOPE)
elseif(ANDROID_ABI MATCHES "armeabi-v7a")
set(SD_ARM_BUILD true PARENT_SCOPE)
set(SD_ARCH "armv7-a" PARENT_SCOPE)
endif()
elseif(NOT SD_IOS_BUILD)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64")
set(SD_X86_BUILD true PARENT_SCOPE)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
set(SD_ARCH "x86-64" PARENT_SCOPE)
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm*|aarch64")
set(SD_ARM_BUILD true PARENT_SCOPE)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
set(SD_ARCH "armv8-a" PARENT_SCOPE)
else()
set(SD_ARCH "armv7-a" PARENT_SCOPE)
endif()
endif()
endif()
endif()
# Set default for ARM builds if not specified
if(SD_ARM_BUILD)
if(NOT DEFINED SD_ARCH OR SD_ARCH STREQUAL "")
message(STATUS "Warning: SD_ARCH was not set for this ARM build. Defaulting to 'armv8-a'.")
set(SD_ARCH "armv8-a" PARENT_SCOPE)
endif()
if(SD_ANDROID)
set(CMAKE_POSITION_INDEPENDENT_CODE ON PARENT_SCOPE)
endif()
endif()
message(STATUS "Platform detection results: SD_X86_BUILD=${SD_X86_BUILD}, SD_ARM_BUILD=${SD_ARM_BUILD}, SD_ARCH=${SD_ARCH}")
endfunction()
# Function to configure architecture tuning
function(configure_architecture_tuning)
if(SD_ARCH MATCHES "armv8")
set(ARCH_TUNE "-march=${SD_ARCH}" PARENT_SCOPE)
message(STATUS "ARM64 architecture tuning: ${SD_ARCH}")
elseif(SD_ARCH MATCHES "armv7")
set(ARCH_TUNE "-march=${SD_ARCH} -mfpu=neon" PARENT_SCOPE)
message(STATUS "ARM32 architecture tuning: ${SD_ARCH} with NEON")
elseif(SD_EXTENSION MATCHES "avx2")
message(STATUS "Building AVX2 binary...")
set(ARCH_TUNE "-mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mprefetchwt1 -DSD_F16C=true -DF_AVX2=true" PARENT_SCOPE)
if(NO_AVX256_SPLIT)
set(ARCH_TUNE "${ARCH_TUNE} -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store" PARENT_SCOPE)
endif()
else()
if("${SD_ARCH}" STREQUAL "x86-64")
message(STATUS "Building x86_64 binary...")
set(ARCH_TYPE "generic")
add_compile_definitions(F_X64=true)
else()
set(ARCH_TYPE "${SD_ARCH}")
endif()
if(SD_EXTENSION MATCHES "avx512")
message(STATUS "Building AVX512 binary...")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse2 -msse3 -msse4.1 -msse4.2 -mavx -mavx2 -mfma -mf16c -mavx512f -mavx512vl -mavx512bw -mavx512dq -mavx512cd -mbmi -mbmi2 -mprefetchwt1 -mclflushopt -mxsavec -mxsaves -DSD_F16C=true -DF_AVX512=true" PARENT_SCOPE)
endif()
if(NOT WIN32 AND NOT SD_CUDA)
if(DEFINED SD_ARCH AND NOT SD_ARCH STREQUAL "" AND DEFINED ARCH_TYPE AND NOT ARCH_TYPE STREQUAL "")
set(ARCH_TUNE "-march=${SD_ARCH} -mtune=${ARCH_TYPE}" PARENT_SCOPE)
elseif(DEFINED SD_ARCH AND NOT SD_ARCH STREQUAL "")
# Fallback if ARCH_TYPE is not set
set(ARCH_TUNE "-march=${SD_ARCH}" PARENT_SCOPE)
endif()
endif()
endif()
endfunction()
# Function to apply compiler-specific flags with architecture tuning
function(apply_compiler_specific_flags ARCH_TUNE)
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND SD_X86_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE}" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE}" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE} -O${SD_OPTIMIZATION_LEVEL} -fp-model fast" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_TUNE}" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT SD_CUDA)
message(STATUS "Adding GCC memory optimization flag: --param ggc-min-expand=10")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --param ggc-min-expand=10 ${ARCH_TUNE} ${INFORMATIVE_FLAGS} -std=c++17 -fPIC" PARENT_SCOPE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --param ggc-min-expand=10 -fPIC" PARENT_SCOPE)
if(UNIX)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,$ORIGIN/,-z,--no-undefined,--verbose" PARENT_SCOPE)
else()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,$ORIGIN/,--no-undefined,--verbose" PARENT_SCOPE)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE AND NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic -Wl,-export-dynamic,--verbose" PARENT_SCOPE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -export-dynamic,--verbose" PARENT_SCOPE)
endif()
if(SD_GCC_FUNCTRACE)
set(COMPILER_IS_NVCC false)
get_filename_component(COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME)
if(COMPILER_NAME MATCHES "^nvcc")
set(COMPILER_IS_NVCC TRUE)
endif()
if(DEFINED ENV{OMPI_CXX} OR DEFINED ENV{MPICH_CXX})
if("$ENV{OMPI_CXX}" MATCHES "nvcc" OR "$ENV{MPICH_CXX}" MATCHES "nvcc")
set(COMPILER_IS_NVCC TRUE)
endif()
endif()
set(CMAKE_CXX_STANDARD_REQUIRED TRUE PARENT_SCOPE)
if(COMPILER_IS_NVCC)
set(CMAKE_CXX_EXTENSIONS OFF PARENT_SCOPE)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-backtrace-limit=0 -gno-record-gcc-switches -ftrack-macro-expansion=0 -fstack-protector -fstack-protector-all -Wall -Wextra -Wno-return-type -Wno-error=int-in-bool-context -Wno-unused-variable -Wno-error=implicit-fallthrough -Wno-return-type -Wno-unused-parameter -Wno-error=unknown-pragmas -ggdb3 -pthread -MT -Bsymbolic -rdynamic -fno-omit-frame-pointer -fno-optimize-sibling-calls -rdynamic -finstrument-functions -O0 -fPIC" PARENT_SCOPE)
# Session #1045 FIX: Removed -lunwind - conflicts with JVM's libgcc_s causing _Unwind_SetGR crashes
# Use system libgcc_s for exception handling (JVM compatible)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread -lbfd -ldw -ldl -lelf" PARENT_SCOPE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lpthread -lbfd -ldw -ldl -lelf" PARENT_SCOPE)
add_compile_definitions(SD_GCC_FUNCTRACE=ON)
endif()
endif()
endfunction()
# Main function to setup all platform optimizations
function(setup_platform_optimizations)
message(STATUS "Setting up platform-specific optimizations...")
# Determine platform type
determine_platform_type()
# Configure PLT disable
configure_plt_disable()
# Configure memory model
configure_memory_model()
# Configure compilation memory optimization
configure_compilation_memory_optimization()
# Configure section splitting
configure_section_splitting()
# Configure large template linker
configure_large_template_linker()
# Configure architecture tuning
configure_architecture_tuning()
# Apply architecture tuning based on calculated ARCH_TUNE
if(DEFINED ARCH_TUNE)
apply_compiler_specific_flags("${ARCH_TUNE}")
endif()
message(STATUS "Platform optimizations setup complete")
endfunction()
+399
View File
@@ -0,0 +1,399 @@
# cmake/PostBuild.cmake
# Configures optional post-build targets like tests and analysis tools.
# ============================================================================
# HELPER FUNCTION: Write file only if content changed (preserves mtime for PCH)
# This prevents PCH invalidation during builds when config.h content is identical
# ============================================================================
function(_postbuild_write_if_different filepath content)
set(should_write TRUE)
# Check if file already exists
if(EXISTS "${filepath}")
# Read existing content
file(READ "${filepath}" existing_content)
# Compare content
if("${existing_content}" STREQUAL "${content}")
set(should_write FALSE)
endif()
endif()
# Only write if content changed or file doesn't exist
if(should_write)
file(WRITE "${filepath}" "${content}")
endif()
endfunction()
# --- Configuration file ---
# Build TYPE_DEFINES string from current type configuration
# This ensures JavaCPP sees the same type availability as the CMake build
set(TYPE_DEFINES "")
# Check if we're in selective types mode
if(DEFINED SD_TYPES_LIST AND NOT SD_TYPES_LIST STREQUAL "")
# Selective types mode - export only enabled types
# The HAS_* macros were already set by apply_type_definitions_to_target
# We need to capture them and add to TYPE_DEFINES
# Get all HAS_* definitions that were set
get_directory_property(COMPILE_DEFS COMPILE_DEFINITIONS)
foreach(def IN LISTS COMPILE_DEFS)
if(def MATCHES "^HAS_")
string(APPEND TYPE_DEFINES "#define ${def}\n")
endif()
endforeach()
else()
# All types mode - define all HAS_* macros
string(APPEND TYPE_DEFINES "#define HAS_BOOL 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_DOUBLE 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT64 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_HALF 1\n")
string(APPEND TYPE_DEFINES "#define HAS_BFLOAT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_BFLOAT 1\n")
string(APPEND TYPE_DEFINES "#define HAS_FLOAT8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_HALF2 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT8_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT16_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT32_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT64 1\n")
string(APPEND TYPE_DEFINES "#define HAS_INT64_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_LONG 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT8_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT16_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT32_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT64 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UINT64_T 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UNSIGNEDLONG 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UTF8 1\n")
string(APPEND TYPE_DEFINES "#define HAS_STD_STRING 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UTF16 1\n")
string(APPEND TYPE_DEFINES "#define HAS_STD_U16STRING 1\n")
string(APPEND TYPE_DEFINES "#define HAS_UTF32 1\n")
string(APPEND TYPE_DEFINES "#define HAS_STD_U32STRING 1\n")
endif()
# Generate config.h with write-if-different to preserve PCH
# This prevents PCH invalidation during the build when content hasn't changed
set(CONFIG_H_IN "${CMAKE_CURRENT_SOURCE_DIR}/include/config.h.in")
set(CONFIG_H_OUT "${CMAKE_CURRENT_BINARY_DIR}/include/config.h")
# Read the template
file(READ "${CONFIG_H_IN}" CONFIG_H_CONTENT)
# Perform variable substitutions (mimics configure_file behavior)
# Handle cmakedefine01 directives
if(HAVE_ONEDNN)
string(REPLACE "#cmakedefine01 HAVE_ONEDNN" "#define HAVE_ONEDNN 1" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REPLACE "#cmakedefine01 HAVE_ONEDNN" "#define HAVE_ONEDNN 0" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(HAVE_ARMCOMPUTE)
string(REPLACE "#cmakedefine01 HAVE_ARMCOMPUTE" "#define HAVE_ARMCOMPUTE 1" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REPLACE "#cmakedefine01 HAVE_ARMCOMPUTE" "#define HAVE_ARMCOMPUTE 0" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(HAVE_CUDNN)
string(REPLACE "#cmakedefine01 HAVE_CUDNN" "#define HAVE_CUDNN 1" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REPLACE "#cmakedefine01 HAVE_CUDNN" "#define HAVE_CUDNN 0" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(HAVE_OPENBLAS)
string(REPLACE "#cmakedefine01 HAVE_OPENBLAS" "#define HAVE_OPENBLAS 1" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REPLACE "#cmakedefine01 HAVE_OPENBLAS" "#define HAVE_OPENBLAS 0" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(HAVE_FLATBUFFERS)
string(REPLACE "#cmakedefine01 HAVE_FLATBUFFERS" "#define HAVE_FLATBUFFERS 1" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REPLACE "#cmakedefine01 HAVE_FLATBUFFERS" "#define HAVE_FLATBUFFERS 0" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(SD_SELECTIVE_TYPES)
string(REPLACE "#cmakedefine01 SD_SELECTIVE_TYPES" "#define SD_SELECTIVE_TYPES 1" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REPLACE "#cmakedefine01 SD_SELECTIVE_TYPES" "#define SD_SELECTIVE_TYPES 0" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
# Handle @VAR@ substitutions
if(DEFINED SD_LIBRARY_NAME)
string(REPLACE "@SD_LIBRARY_NAME@" "${SD_LIBRARY_NAME}" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
# Remove the line if variable not defined
string(REGEX REPLACE "#cmakedefine SD_LIBRARY_NAME[^\n]*\n" "" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(DEFINED ONEDNN_PATH)
string(REPLACE "@ONEDNN_PATH@" "${ONEDNN_PATH}" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REGEX REPLACE "#cmakedefine ONEDNN_PATH[^\n]*\n" "" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(DEFINED OPENBLAS_PATH)
string(REPLACE "@OPENBLAS_PATH@" "${OPENBLAS_PATH}" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REGEX REPLACE "#cmakedefine OPENBLAS_PATH[^\n]*\n" "" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(DEFINED FLATBUFFERS_PATH)
string(REPLACE "@FLATBUFFERS_PATH@" "${FLATBUFFERS_PATH}" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REGEX REPLACE "#cmakedefine FLATBUFFERS_PATH[^\n]*\n" "" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
if(DEFINED DEFAULT_ENGINE)
string(REPLACE "@DEFAULT_ENGINE@" "${DEFAULT_ENGINE}" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
else()
string(REGEX REPLACE "#cmakedefine DEFAULT_ENGINE[^\n]*\n" "" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
endif()
# Substitute TYPE_DEFINES
string(REPLACE "@TYPE_DEFINES@" "${TYPE_DEFINES}" CONFIG_H_CONTENT "${CONFIG_H_CONTENT}")
# Write config.h only if content changed (preserves mtime for PCH)
_postbuild_write_if_different("${CONFIG_H_OUT}" "${CONFIG_H_CONTENT}")
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# --- Flatbuffers Header and Java Generation ---
if(DEFINED ENV{GENERATE_FLATC} OR DEFINED GENERATE_FLATC)
set(FLATC_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build/flatc")
set(MAIN_GENERATED_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/include/graph/generated.h")
add_custom_command(
OUTPUT ${MAIN_GENERATED_HEADER}
COMMAND ${CMAKE_COMMAND} -E env "FLATC_PATH=${FLATC_EXECUTABLE}" bash ${CMAKE_CURRENT_SOURCE_DIR}/flatc-generate.sh
DEPENDS flatbuffers_external
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running flatc to generate C++ headers"
VERBATIM
)
add_custom_target(generate_flatbuffers_headers DEPENDS ${MAIN_GENERATED_HEADER})
add_custom_command(
TARGET generate_flatbuffers_headers POST_BUILD
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/copy-flatc-java.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Copying generated Java files"
VERBATIM
)
endif()
if(SD_EXTRACT_INSTANTIATIONS)
include(ExtractInstantiations)
endif()
# --- Self-Contained Preprocessing Target ---
if(SD_PREPROCESS)
message("Preprocessing enabled: ${CMAKE_BINARY_DIR}")
message("Setting up self-contained preprocessing with FlatBuffers...")
include(ExternalProject)
# Build FlatBuffers for preprocessing (minimal build, just need headers)
set(PREPROCESS_FLATBUFFERS_VERSION "25.2.10")
set(PREPROCESS_FLATBUFFERS_URL "https://github.com/google/flatbuffers/archive/v${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz")
set(PREPROCESS_FB_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/preprocess-flatbuffers-src")
set(PREPROCESS_FB_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/preprocess-flatbuffers-build")
# Check if we already have FlatBuffers headers
set(PREPROCESS_FB_HEADER "${PREPROCESS_FB_SOURCE_DIR}/include/flatbuffers/flatbuffers.h")
if(NOT EXISTS ${PREPROCESS_FB_HEADER})
message("Downloading and extracting FlatBuffers for preprocessing...")
# Download and extract FlatBuffers
file(DOWNLOAD ${PREPROCESS_FLATBUFFERS_URL}
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz"
SHOW_PROGRESS
STATUS download_status)
list(GET download_status 0 download_result)
if(NOT download_result EQUAL 0)
message(FATAL_ERROR "Failed to download FlatBuffers for preprocessing")
endif()
# Extract the archive
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}.tar.gz"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
RESULT_VARIABLE extract_result
)
if(NOT extract_result EQUAL 0)
message(FATAL_ERROR "Failed to extract FlatBuffers for preprocessing")
endif()
# Move the extracted directory to our expected location
file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-${PREPROCESS_FLATBUFFERS_VERSION}"
"${PREPROCESS_FB_SOURCE_DIR}")
endif()
# Verify FlatBuffers headers are now available
if(NOT EXISTS ${PREPROCESS_FB_HEADER})
message(FATAL_ERROR "FlatBuffers headers not found for preprocessing: ${PREPROCESS_FB_HEADER}")
endif()
message("✅ FlatBuffers headers available for preprocessing: ${PREPROCESS_FB_SOURCE_DIR}/include")
# Get ALL subdirectories under include/ and add the root include directory first
set(all_includes "${CMAKE_CURRENT_SOURCE_DIR}/include")
file(GLOB_RECURSE all_dirs LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/include/*")
foreach(item ${all_dirs})
if(IS_DIRECTORY ${item})
list(APPEND all_includes ${item})
endif()
endforeach()
# Add binary include directory
list(APPEND all_includes "${CMAKE_CURRENT_BINARY_DIR}/include")
# Also add build directories
list(APPEND all_includes
"${CMAKE_SOURCE_DIR}/include/"
"${CMAKE_SOURCE_DIR}/include/system"
"${CMAKE_BINARY_DIR}/compilation_units"
"${CMAKE_BINARY_DIR}/cpu_instantiations"
"${CMAKE_BINARY_DIR}/cuda_instantiations"
"${CMAKE_BINARY_DIR}/include"
)
# Add our self-contained FlatBuffers include directory
list(APPEND all_includes "${PREPROCESS_FB_SOURCE_DIR}/include")
# Build include flags
set(include_flags "")
foreach(dir IN LISTS all_includes)
if(EXISTS ${dir})
string(APPEND include_flags " -I${dir}")
endif()
endforeach()
set(defs_flags "")
# Add basic platform definitions
string(APPEND defs_flags " -D__CPUBLAS__=true")
if(SD_CUDA)
string(APPEND defs_flags " -D__CUDABLAS__=true -DHAVE_CUDA=1")
endif()
if(HAVE_OPENBLAS)
string(APPEND defs_flags " -DHAVE_OPENBLAS=1")
endif()
if(SD_ALL_OPS OR "${SD_OPS_LIST}" STREQUAL "")
string(APPEND defs_flags " -DSD_ALL_OPS=1")
# When SD_ALL_OPS=1, NOT_EXCLUDED should evaluate to 1 for all ops
string(APPEND defs_flags " -DNOT_EXCLUDED(x)=1")
else()
# Add specific operation definitions
foreach(OP ${SD_OPS_LIST})
string(APPEND defs_flags " -DOP_${OP}=1")
endforeach()
# Define NOT_EXCLUDED macro for selective ops
string(APPEND defs_flags " -DNOT_EXCLUDED(x)=\\(defined\\(x\\)\\)")
endif()
# Add build type definitions
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
string(APPEND defs_flags " -DDEBUG=1 -D_DEBUG=1")
else()
string(APPEND defs_flags " -DNDEBUG=1")
endif()
# Add any additional compile definitions from the main build
if(compile_defs AND NOT compile_defs STREQUAL "compile_defs-NOTFOUND")
foreach(def IN LISTS compile_defs)
string(APPEND defs_flags " -D${def}")
endforeach()
endif()
set(PREPROCESSED_DIR "${CMAKE_SOURCE_DIR}/preprocessed")
file(MAKE_DIRECTORY ${PREPROCESSED_DIR})
set(PREPROCESSED_FILES)
set(PROCESSED_SOURCES "")
# Use ALL_SOURCES from global scope
if(DEFINED ALL_SOURCES AND ALL_SOURCES)
set(SOURCE_LIST ${ALL_SOURCES})
elseif(DEFINED ALL_SOURCES_LIST AND ALL_SOURCES_LIST)
set(SOURCE_LIST ${ALL_SOURCES_LIST})
else()
message(WARNING "No source list available for preprocessing. Skipping.")
add_custom_target(preprocess_sources ALL
COMMAND ${CMAKE_COMMAND} -E echo "Preprocessing skipped - no source files available")
return()
endif()
list(LENGTH SOURCE_LIST source_count)
message("Starting preprocessing of ${source_count} source files...")
message("Operation definitions: SD_ALL_OPS=${SD_ALL_OPS}, SD_OPS_LIST=${SD_OPS_LIST}")
foreach(src IN LISTS SOURCE_LIST)
if(NOT EXISTS ${src} OR NOT src MATCHES "\\.(c|cpp|cxx|cc|cu)$")
continue()
endif()
if(NOT src IN_LIST PROCESSED_SOURCES)
get_filename_component(src_name ${src} NAME_WE)
get_filename_component(src_path ${src} PATH)
file(RELATIVE_PATH rel_path ${CMAKE_SOURCE_DIR} ${src_path})
string(REPLACE "/" "_" src_dir_ "${rel_path}")
set(preprocessed_file "${PREPROCESSED_DIR}/${src_dir_}_${src_name}.i")
if(NOT EXISTS "${preprocessed_file}")
if(src MATCHES "\\.cu$")
set(compiler "${CMAKE_CUDA_COMPILER}")
set(lang_flags "${CMAKE_CUDA_FLAGS} ${CMAKE_CUDA_FLAGS_${CMAKE_BUILD_TYPE}}")
elseif(src MATCHES "\\.c$")
set(compiler "${CMAKE_C_COMPILER}")
set(lang_flags "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}")
else()
set(compiler "${CMAKE_CXX_COMPILER}")
set(lang_flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
endif()
# Split the flags properly for execute_process
separate_arguments(lang_flags_list UNIX_COMMAND "${lang_flags}")
separate_arguments(defs_flags_list UNIX_COMMAND "${defs_flags}")
separate_arguments(include_flags_list UNIX_COMMAND "${include_flags}")
execute_process(
COMMAND ${compiler} -E -P -C ${lang_flags_list} ${defs_flags_list} ${include_flags_list} "${src}" -o "${preprocessed_file}"
RESULT_VARIABLE result
ERROR_VARIABLE error_output
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
if(result EQUAL 0)
list(APPEND PREPROCESSED_FILES ${preprocessed_file})
message(STATUS "✅ Preprocessed: ${src}")
else()
message(WARNING "❌ Failed to preprocess ${src}")
message(WARNING " Error: ${error_output}")
endif()
else()
list(APPEND PREPROCESSED_FILES ${preprocessed_file})
message(STATUS "✓ Already preprocessed: ${src}")
endif()
list(APPEND PROCESSED_SOURCES ${src})
endif()
endforeach()
list(LENGTH PREPROCESSED_FILES processed_count)
message("✅ Preprocessing complete. Generated ${processed_count} preprocessed files in ${PREPROCESSED_DIR}")
add_custom_target(preprocess_sources ALL DEPENDS ${PREPROCESSED_FILES})
endif()
+480
View File
@@ -0,0 +1,480 @@
# cmake/Ppstep.cmake
# Builds ppstep preprocessor tool with robust include path discovery
if(BUILD_PPSTEP)
message(STATUS "🔧 PPSTEP BUILD MODE - Building ppstep tool only")
message(STATUS "Setting up ppstep build in: ${CMAKE_BINARY_DIR}")
# Check for Boost (required for ppstep)
find_package(Boost COMPONENTS system filesystem program_options thread wave QUIET)
if(NOT Boost_FOUND)
message(FATAL_ERROR "❌ Boost not found - cannot build ppstep. Install with: apt-get install libboost-all-dev")
endif()
include(ExternalProject)
# Configure ppstep as external project
set(PPSTEP_PREFIX "${CMAKE_BINARY_DIR}/ppstep_external")
set(PPSTEP_SOURCE_DIR "${PPSTEP_PREFIX}/src/ppstep")
set(PPSTEP_BUILD_DIR "${PPSTEP_PREFIX}/build")
# Clean up any previous failed attempts
if(EXISTS "${PPSTEP_PREFIX}/src/ppstep_build-stamp")
file(REMOVE_RECURSE "${PPSTEP_PREFIX}/src/ppstep_build-stamp")
endif()
message(STATUS "Cloning and building ppstep...")
# Set up CMAKE_ARGS conditionally to avoid empty values
set(PPSTEP_CMAKE_ARGS
-DCMAKE_BUILD_TYPE=Release
)
if(CMAKE_CXX_COMPILER)
list(APPEND PPSTEP_CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
endif()
if(CMAKE_C_COMPILER)
list(APPEND PPSTEP_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER})
endif()
if(BOOST_ROOT)
list(APPEND PPSTEP_CMAKE_ARGS -DBOOST_ROOT=${BOOST_ROOT})
endif()
ExternalProject_Add(ppstep_build
PREFIX "${PPSTEP_PREFIX}"
GIT_REPOSITORY "https://github.com/agibsonccc/ppstep.git"
GIT_TAG "master"
GIT_SHALLOW TRUE
SOURCE_DIR "${PPSTEP_SOURCE_DIR}"
BINARY_DIR "${PPSTEP_BUILD_DIR}"
STAMP_DIR "${PPSTEP_PREFIX}/stamp"
TMP_DIR "${PPSTEP_PREFIX}/tmp"
DOWNLOAD_DIR "${PPSTEP_PREFIX}/download"
CMAKE_ARGS ${PPSTEP_CMAKE_ARGS}
BUILD_COMMAND make
INSTALL_COMMAND ""
BUILD_BYPRODUCTS "${PPSTEP_BUILD_DIR}/ppstep"
LOG_DOWNLOAD TRUE
LOG_CONFIGURE TRUE
LOG_BUILD TRUE
)
# ============================================================================
# ROBUST INCLUDE PATH DISCOVERY AT CMAKE CONFIGURE TIME
# ============================================================================
message(STATUS "Discovering system include paths...")
set(DISCOVERED_INCLUDE_PATHS "")
# Method 1: Use CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
foreach(dir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
if(EXISTS "${dir}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${dir}")
endif()
endforeach()
# Method 2: Get from compiler using execute_process
if(CMAKE_CXX_COMPILER)
# Get verbose output from compiler
execute_process(
COMMAND echo ""
COMMAND ${CMAKE_CXX_COMPILER} -E -x c++ -Wp,-v -
OUTPUT_VARIABLE COMPILER_OUTPUT
ERROR_VARIABLE COMPILER_ERROR
INPUT_FILE /dev/null
RESULT_VARIABLE COMPILER_RESULT
)
# Parse the output to extract include paths
string(REGEX MATCHALL "#include [<\"].*[>\"] search starts here:.*End of search list" INCLUDE_SECTION "${COMPILER_ERROR}")
if(INCLUDE_SECTION)
string(REGEX REPLACE "#include [<\"].*[>\"] search starts here:" "" INCLUDE_SECTION "${INCLUDE_SECTION}")
string(REGEX REPLACE "End of search list" "" INCLUDE_SECTION "${INCLUDE_SECTION}")
string(REGEX REPLACE "\n" ";" INCLUDE_LINES "${INCLUDE_SECTION}")
foreach(line ${INCLUDE_LINES})
string(STRIP "${line}" line)
if(EXISTS "${line}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${line}")
endif()
endforeach()
endif()
# Also try cpp directly
find_program(CPP_EXECUTABLE cpp)
if(CPP_EXECUTABLE)
execute_process(
COMMAND ${CPP_EXECUTABLE} -x c++ -v
OUTPUT_VARIABLE CPP_OUTPUT
ERROR_VARIABLE CPP_ERROR
INPUT_FILE /dev/null
RESULT_VARIABLE CPP_RESULT
)
string(REGEX MATCHALL "/[^\n]*include[^\n]*" INCLUDE_DIRS "${CPP_ERROR}")
foreach(dir ${INCLUDE_DIRS})
string(STRIP "${dir}" dir)
if(EXISTS "${dir}" AND IS_DIRECTORY "${dir}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${dir}")
endif()
endforeach()
endif()
endif()
# Method 3: Get GCC-specific paths
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=include
OUTPUT_VARIABLE GCC_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(EXISTS "${GCC_INCLUDE_DIR}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${GCC_INCLUDE_DIR}")
endif()
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-search-dirs
OUTPUT_VARIABLE GCC_SEARCH_DIRS
ERROR_QUIET
)
if(GCC_SEARCH_DIRS)
string(REGEX MATCH "install: ([^\n]*)" INSTALL_LINE "${GCC_SEARCH_DIRS}")
if(CMAKE_MATCH_1)
string(STRIP "${CMAKE_MATCH_1}" INSTALL_DIR)
if(EXISTS "${INSTALL_DIR}/include")
list(APPEND DISCOVERED_INCLUDE_PATHS "${INSTALL_DIR}/include")
endif()
endif()
endif()
# Method 4: Get target-specific paths
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine
OUTPUT_VARIABLE GCC_TARGET
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(GCC_TARGET AND GCC_VERSION)
# Extract major version
string(REGEX MATCH "^([0-9]+)" GCC_MAJOR "${GCC_VERSION}")
# Check common GCC installation paths
foreach(base_path "/usr/lib/gcc" "/usr/lib64/gcc" "/usr/local/lib/gcc")
foreach(version ${GCC_VERSION} ${GCC_MAJOR})
foreach(subdir "include" "include-fixed")
set(test_path "${base_path}/${GCC_TARGET}/${version}/${subdir}")
if(EXISTS "${test_path}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${test_path}")
endif()
endforeach()
endforeach()
endforeach()
endif()
# Method 5: Common system paths
set(COMMON_INCLUDE_PATHS
/usr/include
/usr/local/include
/usr/include/linux
/usr/include/x86_64-linux-gnu
/usr/include/i386-linux-gnu
/usr/include/aarch64-linux-gnu
/opt/local/include
/opt/include
)
foreach(path ${COMMON_INCLUDE_PATHS})
if(EXISTS "${path}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${path}")
endif()
endforeach()
# Add C++ standard library paths
foreach(version RANGE 5 15)
set(cpp_paths
"/usr/include/c++/${version}"
"/usr/include/c++/${version}/x86_64-linux-gnu"
"/usr/include/c++/${version}/x86_64-redhat-linux"
"/usr/include/c++/${version}/aarch64-linux-gnu"
"/usr/include/c++/${version}/backward"
)
foreach(path ${cpp_paths})
if(EXISTS "${path}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${path}")
endif()
endforeach()
endforeach()
# Method 6: Try to compile a test file and extract includes
file(WRITE "${CMAKE_BINARY_DIR}/test_includes.cpp" "
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
int main() { return 0; }
")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -H -E "${CMAKE_BINARY_DIR}/test_includes.cpp"
OUTPUT_VARIABLE HEADER_OUTPUT
ERROR_VARIABLE HEADER_ERROR
RESULT_VARIABLE HEADER_RESULT
)
# Parse the -H output to find include directories
string(REGEX MATCHALL "\\. /[^\n]*\\.h" HEADER_LINES "${HEADER_ERROR}")
foreach(line ${HEADER_LINES})
string(REGEX REPLACE "^\\. " "" header_file "${line}")
get_filename_component(header_dir "${header_file}" DIRECTORY)
if(EXISTS "${header_dir}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${header_dir}")
endif()
endforeach()
# Method 7: Check if clang is available and get its paths
find_program(CLANG_CXX clang++)
if(CLANG_CXX)
execute_process(
COMMAND ${CLANG_CXX} -print-resource-dir
OUTPUT_VARIABLE CLANG_RESOURCE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(EXISTS "${CLANG_RESOURCE_DIR}/include")
list(APPEND DISCOVERED_INCLUDE_PATHS "${CLANG_RESOURCE_DIR}/include")
endif()
endif()
# Remove duplicates
list(REMOVE_DUPLICATES DISCOVERED_INCLUDE_PATHS)
# Validate that we found critical headers
set(CRITICAL_HEADERS limits.h stdio.h stdlib.h stddef.h stdint.h)
set(MISSING_HEADERS "")
foreach(header ${CRITICAL_HEADERS})
set(HEADER_FOUND FALSE)
foreach(dir ${DISCOVERED_INCLUDE_PATHS})
if(EXISTS "${dir}/${header}")
set(HEADER_FOUND TRUE)
break()
endif()
endforeach()
if(NOT HEADER_FOUND)
list(APPEND MISSING_HEADERS ${header})
message(WARNING "Critical header ${header} not found in discovered paths")
# Try to find it
execute_process(
COMMAND find /usr -name ${header} -type f -print -quit
OUTPUT_VARIABLE FOUND_HEADER
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
TIMEOUT 5
)
if(FOUND_HEADER)
get_filename_component(FOUND_DIR "${FOUND_HEADER}" DIRECTORY)
message(STATUS " Found ${header} in ${FOUND_DIR}")
list(APPEND DISCOVERED_INCLUDE_PATHS "${FOUND_DIR}")
endif()
endif()
endforeach()
# Remove duplicates again after adding missing headers
list(REMOVE_DUPLICATES DISCOVERED_INCLUDE_PATHS)
# Convert to -I flags
set(SYSTEM_INCLUDE_FLAGS "")
foreach(dir ${DISCOVERED_INCLUDE_PATHS})
set(SYSTEM_INCLUDE_FLAGS "${SYSTEM_INCLUDE_FLAGS} -I${dir}")
endforeach()
message(STATUS "Found ${CMAKE_WORDS_BIGENDIAN} system include directories")
message(STATUS "System include flags: ${SYSTEM_INCLUDE_FLAGS}")
# Write the discovered paths to a file for debugging
file(WRITE "${CMAKE_BINARY_DIR}/discovered_includes.txt" "${SYSTEM_INCLUDE_FLAGS}")
# ============================================================================
# GENERATE WRAPPER SCRIPT WITH DISCOVERED PATHS
# ============================================================================
set(PPSTEP_WRAPPER "${CMAKE_BINARY_DIR}/ppstep-nd4j")
# Generate wrapper with the discovered paths baked in
file(WRITE ${PPSTEP_WRAPPER}
"#!/bin/bash
# Auto-generated ppstep wrapper for libnd4j
# Generated at CMake configure time with discovered include paths
PPSTEP_BIN=\"${PPSTEP_BUILD_DIR}/ppstep\"
if [ ! -f \"\$PPSTEP_BIN\" ]; then
echo \"Error: ppstep not built yet. Run 'make ppstep_build' first\"
exit 1
fi
# System includes discovered at CMake configure time
SYSTEM_INCLUDES=\"${SYSTEM_INCLUDE_FLAGS}\"
# Additional runtime discovery (fallback)
if [ -z \"\$SYSTEM_INCLUDES\" ] || [ \"\$1\" = \"--rediscover\" ]; then
echo \"Warning: No includes from CMake or rediscovery requested\" >&2
# Try runtime discovery
RUNTIME_INCLUDES=\"\"
# Method 1: cpp -v
if command -v cpp &> /dev/null; then
while IFS= read -r dir; do
[ -d \"\$dir\" ] && RUNTIME_INCLUDES=\"\$RUNTIME_INCLUDES -I\$dir\"
done < <(cpp -x c++ -v < /dev/null 2>&1 | awk '
/^#include <...> search starts here:/ { flag=1; next }
/^End of search list./ { flag=0 }
flag { gsub(/^[ \t]+/, \"\"); print }
')
fi
# Method 2: Direct paths
for dir in /usr/include /usr/local/include /usr/include/linux; do
[ -d \"\$dir\" ] && RUNTIME_INCLUDES=\"\$RUNTIME_INCLUDES -I\$dir\"
done
SYSTEM_INCLUDES=\"\$RUNTIME_INCLUDES\"
fi
# Include paths for libnd4j
INCLUDES=\"-I${CMAKE_CURRENT_SOURCE_DIR}/include\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_BINARY_DIR}/include\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/array\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/blas\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/cnpy\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/exceptions\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/execution\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/flatbuffers\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/generated\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/graph\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/helpers\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/indexing\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/legacy\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/loops\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/math\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/memory\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/ops\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/system\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/types\"
INCLUDES=\"\$INCLUDES -I${CMAKE_CURRENT_SOURCE_DIR}/include/performance\"
# Add OpenBLAS if available
if [ -n \"${OPENBLAS_PATH}\" ] && [ -d \"${OPENBLAS_PATH}/include\" ]; then
INCLUDES=\"\$INCLUDES -I${OPENBLAS_PATH}/include\"
fi
# Basic defines
DEFINES=\"-D__CPUBLAS__=1 -DSD_CPU=1\"
DEFINES=\"\$DEFINES -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS\"
DEFINES=\"\$DEFINES -D_GNU_SOURCE\"
# Handle special arguments
case \"\$1\" in
--debug|--show-includes)
echo \"System includes:\"
echo \$SYSTEM_INCLUDES | tr ' ' '\\n' | grep '^-I' | while read inc; do
dir=\${inc#-I}
echo \" \$inc\"
for h in limits.h stdio.h stdlib.h stddef.h; do
[ -f \"\$dir/\$h\" ] && echo \" has \$h\"
done
done
echo \"\"
echo \"Project includes:\"
echo \$INCLUDES | tr ' ' '\\n' | grep '^-I'
echo \"\"
echo \"Defines:\"
echo \$DEFINES | tr ' ' '\\n'
exit 0
;;
--version)
echo \"ppstep wrapper generated by CMake\"
echo \"Binary: \$PPSTEP_BIN\"
\$PPSTEP_BIN --version 2>/dev/null || echo \"ppstep version unknown\"
exit 0
;;
-h|--help)
echo \"Usage: \$0 [options] <source_file.cpp>\"
echo \"Options:\"
echo \" --debug, --show-includes Show include paths and exit\"
echo \" --rediscover Force runtime include discovery\"
echo \" --version Show version information\"
echo \" -h, --help Show this help\"
exit 0
;;
esac
# Remove special arguments if rediscovery was requested
[ \"\$1\" = \"--rediscover\" ] && shift
# Run ppstep
exec \"\$PPSTEP_BIN\" \$SYSTEM_INCLUDES \$INCLUDES \$DEFINES \"\$@\"
")
# Make wrapper executable
file(CHMOD ${PPSTEP_WRAPPER}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
# Also generate a CMake include file with the discovered paths
file(WRITE "${CMAKE_BINARY_DIR}/ppstep_includes.cmake"
"# Auto-generated by Ppstep.cmake
# System include directories discovered during configuration
set(PPSTEP_SYSTEM_INCLUDE_DIRS
")
foreach(dir ${DISCOVERED_INCLUDE_PATHS})
file(APPEND "${CMAKE_BINARY_DIR}/ppstep_includes.cmake" " \"${dir}\"\n")
endforeach()
file(APPEND "${CMAKE_BINARY_DIR}/ppstep_includes.cmake" ")\n")
# Add custom target
add_custom_target(ppstep ALL
DEPENDS ppstep_build
COMMAND ${CMAKE_COMMAND} -E echo "✅ ppstep built successfully"
COMMAND ${CMAKE_COMMAND} -E echo " Executable: ${PPSTEP_BUILD_DIR}/ppstep"
COMMAND ${CMAKE_COMMAND} -E echo " Wrapper: ${PPSTEP_WRAPPER}"
COMMAND ${CMAKE_COMMAND} -E echo " Include paths: ${CMAKE_BINARY_DIR}/discovered_includes.txt"
COMMAND ${CMAKE_COMMAND} -E echo ""
COMMAND ${CMAKE_COMMAND} -E echo "Usage:"
COMMAND ${CMAKE_COMMAND} -E echo " ${PPSTEP_WRAPPER} [source_file.cpp]"
COMMAND ${CMAKE_COMMAND} -E echo " ${PPSTEP_WRAPPER} --debug # Show include paths"
COMMAND ${CMAKE_COMMAND} -E echo ""
COMMENT "ppstep preprocessor tool ready"
)
# Custom target to regenerate wrapper if needed
add_custom_target(ppstep-regenerate
COMMAND ${CMAKE_COMMAND} -E echo "Regenerating ppstep wrapper..."
COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR}
COMMENT "Regenerating ppstep wrapper with updated paths"
)
message(STATUS "✅ ppstep target configured")
message(STATUS "Exiting after ppstep setup - run 'make' to build ppstep")
# CRITICAL: EARLY EXIT - Don't process the rest of CMakeLists.txt
return()
endif()
+87
View File
@@ -0,0 +1,87 @@
################################################################################
# Colored Status Printing and Utility Functions
# Common utility functions for enhanced CMake output and debugging
################################################################################
# Enhanced colored status printing function
function(print_status_colored type message)
if(type STREQUAL "ERROR")
message(FATAL_ERROR "❌ ${message}")
elseif(type STREQUAL "WARNING")
message(WARNING "⚠️ ${message}")
elseif(type STREQUAL "SUCCESS")
message(STATUS "✅ ${message}")
elseif(type STREQUAL "INFO")
message(STATUS "️ ${message}")
elseif(type STREQUAL "DEBUG")
message(STATUS "🔍 ${message}")
elseif(type STREQUAL "NOTICE")
message(NOTICE "📢 ${message}")
else()
message(STATUS "${message}")
endif()
endfunction()
# Print all CMake variables for debugging
macro(print_all_variables)
message(STATUS "print_all_variables------------------------------------------{")
get_cmake_property(_variableNames VARIABLES)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
message(STATUS "print_all_variables------------------------------------------}")
endmacro()
# Function to verify template processing worked
function(verify_template_processing GENERATED_FILE)
if(EXISTS "${GENERATED_FILE}")
file(READ "${GENERATED_FILE}" FILE_CONTENT)
# Check for unprocessed #cmakedefine
if(FILE_CONTENT MATCHES "#cmakedefine[ \t]+[A-Za-z_]+")
message(FATAL_ERROR "❌ Template processing FAILED: ${GENERATED_FILE} contains unprocessed #cmakedefine directives")
endif()
# Check for unprocessed @VAR@
if(FILE_CONTENT MATCHES "@[A-Za-z_]+@")
message(FATAL_ERROR "❌ Template processing FAILED: ${GENERATED_FILE} contains unprocessed @VAR@ tokens")
endif()
message(STATUS "✅ Template processing verified: ${GENERATED_FILE}")
return()
else()
message(FATAL_ERROR "❌ Generated file does not exist: ${GENERATED_FILE}")
endif()
endfunction()
# Function to safely remove files if they match exclusion criteria
function(removeFileIfExcluded)
cmake_parse_arguments(
PARSED_ARGS
""
"FILE_ITEM"
"LIST_ITEM"
${ARGN}
)
file(READ ${PARSED_ARGS_FILE_ITEM} FILE_CONTENTS)
string(FIND "${FILE_CONTENTS}" "NOT_EXCLUDED" NOT_EXCLUDED_IDX)
if(${NOT_EXCLUDED_IDX} GREATER_EQUAL 0)
set(local_list ${${PARSED_ARGS_LIST_ITEM}})
set(file_removed FALSE)
foreach(OP ${SD_OPS_LIST})
string(FIND "${FILE_CONTENTS}" "NOT_EXCLUDED(OP_${OP})" NOT_EXCLUDED_OP_IDX)
if(${NOT_EXCLUDED_OP_IDX} LESS 0)
list(REMOVE_ITEM local_list "${PARSED_ARGS_FILE_ITEM}")
set(file_removed TRUE)
break()
endif()
endforeach()
if(file_removed)
set(${PARSED_ARGS_LIST_ITEM} ${local_list} PARENT_SCOPE)
endif()
endif()
endfunction()
@@ -0,0 +1,207 @@
# cmake/ProcessInstantiationBatch.cmake
# Worker script for processing a batch of source files in parallel
# This script is executed as a separate CMake process for each batch
# Get batch ID from command line
if(NOT DEFINED BATCH_ID)
message(FATAL_ERROR "BATCH_ID not defined")
endif()
message("[Batch ${BATCH_ID}] Starting batch processor")
# Determine paths
get_filename_component(CMAKE_SCRIPT_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
set(CMAKE_SOURCE_DIR "${CMAKE_SCRIPT_DIR}/..")
set(INST_DIR "${CMAKE_SOURCE_DIR}/instantiation_analysis")
set(INST_BATCH_DIR "${INST_DIR}/batches")
# Load configuration
set(BATCH_CONFIG_FILE "${INST_BATCH_DIR}/config.cmake")
if(NOT EXISTS ${BATCH_CONFIG_FILE})
message(FATAL_ERROR "[Batch ${BATCH_ID}] Configuration file not found: ${BATCH_CONFIG_FILE}")
endif()
include(${BATCH_CONFIG_FILE})
# Include helper functions
include(${CMAKE_SCRIPT_DIR}/InstantiationHelpers.cmake)
# Read list of files to process
set(BATCH_FILE "${INST_BATCH_DIR}/batch_${BATCH_ID}.txt")
if(NOT EXISTS ${BATCH_FILE})
message(WARNING "[Batch ${BATCH_ID}] Batch file not found: ${BATCH_FILE}")
file(WRITE "${INST_BATCH_DIR}/batch_${BATCH_ID}.done" "")
return()
endif()
file(STRINGS ${BATCH_FILE} FILES_TO_PROCESS)
list(LENGTH FILES_TO_PROCESS batch_size)
message("[Batch ${BATCH_ID}] Processing ${batch_size} files")
# Process each file in the batch
set(batch_results "")
set(processed_count 0)
set(failed_count 0)
foreach(src IN LISTS FILES_TO_PROCESS)
if(NOT EXISTS ${src})
message("[Batch ${BATCH_ID}] Warning: File not found: ${src}")
math(EXPR failed_count "${failed_count} + 1")
continue()
endif()
# Extract file information
get_filename_component(src_name ${src} NAME_WE)
get_filename_component(src_path ${src} PATH)
get_filename_component(src_full_name ${src} NAME)
file(RELATIVE_PATH rel_path ${CMAKE_SOURCE_DIR} ${src_path})
string(REPLACE "/" "_" safe_name "${rel_path}_${src_name}")
# Determine if this is a generated file
set(IS_GENERATED FALSE)
if(src MATCHES "${CMAKE_BINARY_DIR}")
set(IS_GENERATED TRUE)
endif()
message("[Batch ${BATCH_ID}] [${processed_count}/${batch_size}] Analyzing: ${src_full_name}")
# Create a sub-temp directory for this batch
set(BATCH_TEMP_DIR "${INST_TEMP_DIR}/batch_${BATCH_ID}")
if(NOT EXISTS ${BATCH_TEMP_DIR})
file(MAKE_DIRECTORY ${BATCH_TEMP_DIR})
endif()
set(INST_TEMP_DIR ${BATCH_TEMP_DIR})
# Extract used templates
set(used_file "${INST_USED_DIR}/${safe_name}.used")
extract_used_templates("${src}" "${used_file}" "${safe_name}")
# Extract provided templates
set(provided_file "${INST_PROVIDED_DIR}/${safe_name}.provided")
extract_provided_templates("${src}" "${provided_file}" "${safe_name}")
# Calculate missing templates
set(missing_templates "")
set(missing_count 0)
# Read used templates
if(EXISTS ${used_file})
file(STRINGS ${used_file} used_list)
else()
set(used_list "")
endif()
# Read provided templates
if(EXISTS ${provided_file})
file(STRINGS ${provided_file} provided_list)
else()
set(provided_list "")
endif()
# Simple missing calculation (can be enhanced with normalization)
foreach(used_tmpl ${used_list})
set(found FALSE)
foreach(provided_tmpl ${provided_list})
if(used_tmpl STREQUAL provided_tmpl)
set(found TRUE)
break()
endif()
endforeach()
if(NOT found)
list(APPEND missing_templates "${used_tmpl}")
endif()
endforeach()
# Write missing templates
set(missing_file "${INST_MISSING_DIR}/${safe_name}.missing")
if(missing_templates)
list(REMOVE_DUPLICATES missing_templates)
string(REPLACE ";" "\n" missing_content "${missing_templates}")
file(WRITE ${missing_file} "${missing_content}")
list(LENGTH missing_templates missing_count)
else()
file(WRITE ${missing_file} "")
set(missing_count 0)
endif()
# Count templates
list(LENGTH used_list used_count)
list(LENGTH provided_list provided_count)
# Create per-file summary
file(WRITE ${INST_BY_FILE_DIR}/${safe_name}.summary "File: ${src_full_name}\n")
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "Path: ${rel_path}\n")
if(IS_GENERATED)
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "Type: generated\n")
else()
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "Type: original\n")
endif()
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "Used: ${used_count}\n")
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "Provided: ${provided_count}\n")
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "Missing: ${missing_count}\n")
# Add details if there are templates
if(used_count GREATER 0)
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "\nUsed Templates (first 10):\n")
set(shown 0)
foreach(tmpl ${used_list})
if(shown LESS 10)
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary " - ${tmpl}\n")
math(EXPR shown "${shown} + 1")
else()
break()
endif()
endforeach()
endif()
if(provided_count GREATER 0)
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "\nProvided Templates (first 10):\n")
set(shown 0)
foreach(tmpl ${provided_list})
if(shown LESS 10)
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary " - ${tmpl}\n")
math(EXPR shown "${shown} + 1")
else()
break()
endif()
endforeach()
endif()
if(missing_count GREATER 0)
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary "\nMissing Templates:\n")
foreach(tmpl ${missing_templates})
file(APPEND ${INST_BY_FILE_DIR}/${safe_name}.summary " - ${tmpl}\n")
endforeach()
endif()
# Append to batch results
string(APPEND batch_results "${src}|${safe_name}|${used_count}|${provided_count}|${missing_count}|${IS_GENERATED}\n")
math(EXPR processed_count "${processed_count} + 1")
# Progress reporting
math(EXPR progress_pct "(${processed_count} * 100) / ${batch_size}")
if(progress_pct GREATER 0 AND NOT progress_pct EQUAL last_progress)
message("[Batch ${BATCH_ID}] Progress: ${progress_pct}% (${processed_count}/${batch_size})")
set(last_progress ${progress_pct})
endif()
endforeach()
# Clean up batch temp directory
if(EXISTS ${BATCH_TEMP_DIR})
file(REMOVE_RECURSE ${BATCH_TEMP_DIR})
endif()
# Write batch completion marker with results
file(WRITE "${INST_BATCH_DIR}/batch_${BATCH_ID}.done" "${batch_results}")
message("[Batch ${BATCH_ID}] Completed: ${processed_count} processed, ${failed_count} failed")
# Write batch summary
set(BATCH_SUMMARY_FILE "${INST_BATCH_DIR}/batch_${BATCH_ID}.summary")
file(WRITE ${BATCH_SUMMARY_FILE} "Batch ${BATCH_ID} Summary\n")
file(APPEND ${BATCH_SUMMARY_FILE} "====================\n")
file(APPEND ${BATCH_SUMMARY_FILE} "Files processed: ${processed_count}\n")
file(APPEND ${BATCH_SUMMARY_FILE} "Files failed: ${failed_count}\n")
file(APPEND ${BATCH_SUMMARY_FILE} "Total in batch: ${batch_size}\n")
+38
View File
@@ -0,0 +1,38 @@
include(SelectiveRenderingCore)
# Wrapper for the original setup_selective_rendering function
function(setup_selective_rendering)
message(STATUS "🔄 SelectiveRendering.cmake: Calling unified core system")
# Call the unified system
setup_selective_rendering_unified_safe()
# Map results to legacy variables that existing code expects
if(DEFINED UNIFIED_COMBINATIONS_2)
set(COMBINATIONS_2 "${UNIFIED_COMBINATIONS_2}" PARENT_SCOPE)
endif()
if(DEFINED UNIFIED_COMBINATIONS_3)
set(COMBINATIONS_3 "${UNIFIED_COMBINATIONS_3}" PARENT_SCOPE)
endif()
if(DEFINED UNIFIED_ACTIVE_TYPES)
set(ACTIVE_TYPES "${UNIFIED_ACTIVE_TYPES}" PARENT_SCOPE)
endif()
message(STATUS "✅ SelectiveRendering.cmake: Setup complete via unified core")
endfunction()
# Legacy wrapper functions for other entry points
function(track_combination_states active_types combinations_3)
# This function is now handled internally by the core system
message(STATUS "🔄 track_combination_states: Handled by unified core")
endfunction()
function(generate_selective_rendering_header)
# This function is now handled internally by the core system
message(STATUS "🔄 generate_selective_rendering_header: Handled by unified core")
endfunction()
function(generate_selective_wrapper_header)
# This function is now handled internally by the core system
message(STATUS "🔄 generate_selective_wrapper_header: Handled by unified core")
endfunction()
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
function(setup_definitive_semantic_filtering_with_selective_rendering)
message(STATUS "🔄 SelectiveRenderingIntegration.cmake: Calling unified core system")
# Enable both semantic filtering and selective rendering
set(SD_ENABLE_SEMANTIC_FILTERING TRUE PARENT_SCOPE)
set(SD_ENABLE_SELECTIVE_RENDERING TRUE PARENT_SCOPE)
# Call unified system
setup_selective_rendering_unified_safe()
# Legacy variable mapping
if(DEFINED UNIFIED_COMBINATIONS_2)
set(COMBINATIONS_2 "${UNIFIED_COMBINATIONS_2}" PARENT_SCOPE)
endif()
if(DEFINED UNIFIED_COMBINATIONS_3)
set(COMBINATIONS_3 "${UNIFIED_COMBINATIONS_3}" PARENT_SCOPE)
endif()
message(STATUS "✅ SelectiveRenderingIntegration.cmake: Setup complete via unified core")
endfunction()
function(enhanced_semantic_filtering_setup)
setup_definitive_semantic_filtering_with_selective_rendering()
endfunction()
# Override the main setup function
macro(setup_definitive_semantic_filtering)
enhanced_semantic_filtering_setup()
endmacro()
File diff suppressed because it is too large Load Diff
+107
View File
@@ -0,0 +1,107 @@
# cmake/SemanticEngine.cmake
# Implements the ML-aware semantic type filtering system.
option(SD_ENABLE_SEMANTIC_FILTERING "Enable ML-aware semantic type filtering" ON)
option(SD_SHOW_COMBINATION_ANALYSIS "Show type combination analysis" ON)
set(SD_TYPE_PROFILE "" CACHE STRING "ML workload profile (quantization/training/inference/nlp/cv)")
if(NOT SD_ENABLE_SEMANTIC_FILTERING)
message(STATUS "Semantic filtering disabled. Using traditional type combination.")
set(USE_SEMANTIC_PAIRWISE_GENERATION FALSE CACHE BOOL "Use semantic generation for pairwise templates")
return()
endif()
print_status_colored("INFO" "=== SEMANTIC TYPE COMBINATION GENERATION ===")
setup_enhanced_semantic_validation()
# Auto-detect profile from type selection if none specified
if((NOT SD_TYPE_PROFILE OR SD_TYPE_PROFILE STREQUAL "") AND SD_TYPES_LIST_COUNT GREATER 0)
set(detected_profile "")
if("int8_t" IN_LIST SD_TYPES_LIST AND "uint8_t" IN_LIST SD_TYPES_LIST)
set(detected_profile "quantization")
elseif("float16" IN_LIST SD_TYPES_LIST OR "bfloat16" IN_LIST SD_TYPES_LIST)
set(detected_profile "training")
elseif(SD_TYPES_LIST MATCHES ".*string.*")
set(detected_profile "nlp")
endif()
if(NOT detected_profile STREQUAL "")
print_status_colored("INFO" "Auto-detected ML workload profile: ${detected_profile}")
set(SD_TYPE_PROFILE "${detected_profile}")
else()
print_status_colored("INFO" "No specific workload detected - using inference profile as default")
set(SD_TYPE_PROFILE "inference")
endif()
elseif(NOT SD_TYPE_PROFILE OR SD_TYPE_PROFILE STREQUAL "")
print_status_colored("INFO" "No workload profile specified - using inference as default")
set(SD_TYPE_PROFILE "inference")
endif()
# Apply type profile if specified
if(SD_TYPE_PROFILE AND NOT SD_TYPE_PROFILE STREQUAL "")
print_status_colored("INFO" "Applying ML workload profile: ${SD_TYPE_PROFILE}")
if(COMMAND apply_type_profile)
apply_type_profile(${SD_TYPE_PROFILE})
else()
message(STATUS "Type profiles not available - using default types")
endif()
endif()
# Generate ML-aware type combinations
message(STATUS "Generating ML-aware type combinations...")
if(SD_TYPE_PROFILE AND NOT SD_TYPE_PROFILE STREQUAL "")
if(COMMAND generate_workload_combinations)
generate_workload_combinations("${SD_TYPE_PROFILE}" optimized_combinations)
set(GENERATED_TYPE_COMBINATIONS "${optimized_combinations}")
else()
message(STATUS "generate_workload_combinations function not available - using traditional approach")
if(COMMAND generate_type_combinations)
generate_type_combinations()
endif()
endif()
else()
if(COMMAND generate_type_combinations)
generate_type_combinations()
endif()
endif()
if(SD_SHOW_COMBINATION_ANALYSIS)
if(SD_TYPES_LIST_COUNT GREATER 0)
validate_ml_type_combinations("${SD_TYPES_LIST}")
endif()
if(DEFINED GENERATED_TYPE_COMBINATIONS)
analyze_combination_patterns("${GENERATED_TYPE_COMBINATIONS}" "${SD_TYPE_PROFILE}")
endif()
endif()
# Process template files with semantic filtering
message(STATUS "Processing template files with semantic filtering...")
#process_template_files()
# Process pairwise templates with enhanced semantic filtering
message(STATUS "Processing pairwise templates with enhanced semantic filtering...")
if(COMMAND process_pairwise_templates_semantic)
process_pairwise_templates_semantic()
else()
message(STATUS "process_pairwise_templates_semantic function not available - skipping")
endif()
# --- PAIRWISE SEMANTIC TYPE PROCESSING ---
print_status_colored("INFO" "=== PAIRWISE SEMANTIC TYPE PROCESSING ===")
message(STATUS "Applying semantic type processing to pairwise instantiations...")
if(SD_TYPE_PROFILE AND NOT SD_TYPE_PROFILE STREQUAL "")
message(STATUS "Using workload profile '${SD_TYPE_PROFILE}' for pairwise semantic processing")
if(COMMAND generate_pairwise_semantic_combinations)
generate_pairwise_semantic_combinations("${SD_TYPE_PROFILE}" SEMANTIC_PAIRWISE_COMBINATIONS)
list(LENGTH SEMANTIC_PAIRWISE_COMBINATIONS semantic_count)
message(STATUS "Generated ${semantic_count} semantic pairwise combinations")
set(PAIRWISE_SEMANTIC_COMBINATIONS "${SEMANTIC_PAIRWISE_COMBINATIONS}" CACHE INTERNAL "Semantic pairwise combinations")
set(USE_SEMANTIC_PAIRWISE_GENERATION TRUE CACHE BOOL "Use semantic generation for pairwise templates")
else()
message(STATUS "generate_pairwise_semantic_combinations function not available.")
set(USE_SEMANTIC_PAIRWISE_GENERATION FALSE CACHE BOOL "Use semantic generation for pairwise templates")
endif()
else()
message(STATUS "No workload profile specified - using traditional pairwise processing")
set(USE_SEMANTIC_PAIRWISE_GENERATION FALSE CACHE BOOL "Use semantic generation for pairwise templates")
endif()
+56
View File
@@ -0,0 +1,56 @@
function(setup_definitive_semantic_filtering)
message(STATUS "🔄 SemanticTypeFiltering.cmake: Calling unified core system")
# Call the unified system with semantic filtering enabled
set(SD_ENABLE_SEMANTIC_FILTERING TRUE PARENT_SCOPE)
setup_selective_rendering_unified_safe(TYPE_PROFILE "${SD_TYPE_PROFILE}")
# Map to expected variables
if(DEFINED UNIFIED_COMBINATIONS_2)
set(COMBINATIONS_2 "${UNIFIED_COMBINATIONS_2}" PARENT_SCOPE)
set(COMBINATIONS_2 "${UNIFIED_COMBINATIONS_2}" CACHE INTERNAL "2-type combinations" FORCE)
endif()
if(DEFINED UNIFIED_COMBINATIONS_3)
set(COMBINATIONS_3 "${UNIFIED_COMBINATIONS_3}" PARENT_SCOPE)
set(COMBINATIONS_3 "${UNIFIED_COMBINATIONS_3}" CACHE INTERNAL "3-type combinations" FORCE)
endif()
if(DEFINED UNIFIED_ACTIVE_TYPES)
set(ACTIVE_TYPES "${UNIFIED_ACTIVE_TYPES}" PARENT_SCOPE)
set(ACTIVE_TYPES "${UNIFIED_ACTIVE_TYPES}" CACHE INTERNAL "Active type list" FORCE)
endif()
message(STATUS "✅ SemanticTypeFiltering.cmake: Setup complete via unified core")
endfunction()
# Wrapper for initialize_definitive_combinations
function(initialize_definitive_combinations)
message(STATUS "🔄 initialize_definitive_combinations: Calling unified core system")
setup_definitive_semantic_filtering()
endfunction()
# Legacy helper functions (now handled by core)
function(extract_definitive_types result_var)
if(DEFINED UNIFIED_ACTIVE_TYPES)
set(${result_var} "${UNIFIED_ACTIVE_TYPES}" PARENT_SCOPE)
else()
srcore_auto_setup()
set(${result_var} "${UNIFIED_ACTIVE_TYPES}" PARENT_SCOPE)
endif()
endfunction()
function(generate_definitive_combinations active_types result_2_var result_3_var)
message(STATUS "🔄 generate_definitive_combinations: Using cached unified core results")
if(DEFINED UNIFIED_COMBINATIONS_2 AND DEFINED UNIFIED_COMBINATIONS_3)
set(${result_2_var} "${UNIFIED_COMBINATIONS_2}" PARENT_SCOPE)
set(${result_3_var} "${UNIFIED_COMBINATIONS_3}" PARENT_SCOPE)
else()
srcore_auto_setup()
set(${result_2_var} "${UNIFIED_COMBINATIONS_2}" PARENT_SCOPE)
set(${result_3_var} "${UNIFIED_COMBINATIONS_3}" PARENT_SCOPE)
endif()
endfunction()
function(validate_critical_types_coverage active_types combinations_3)
# This validation is now handled internally by the core system
message(STATUS "🔄 validate_critical_types_coverage: Handled by unified core")
endfunction()
+37
View File
@@ -0,0 +1,37 @@
# cmake/Setup.cmake
# Handles initial project setup and global configurations.
# Basic CMake Configuration
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF)
set(CMAKE_VERBOSE_MAKEFILE OFF)
# Standard Settings
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
include(CheckCXXCompilerFlag)
# MSVC runtime lib can be either "MultiThreaded" or "MultiThreadedDLL", /MT and /MD respectively
set(MSVC_RT_LIB "MultiThreadedDLL")
# Initialize job pools for parallel builds
set_property(GLOBAL PROPERTY JOB_POOLS one_jobs=1 two_jobs=2)
# Set Windows specific flags
if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSD_WINDOWS_BUILD=true")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSD_WINDOWS_BUILD=true")
endif()
# NOTE: SD_CPU/SD_CUDA logic, SD_LIBRARY_NAME, and DEFAULT_ENGINE
# are now handled in the main CMakeLists.txt before this file is included
# Set optimization level based on GCC_FUNCTRACE
if(SD_GCC_FUNCTRACE)
message("Set optimization for functrace ${SD_GCC_FUNCTRACE}")
set(SD_OPTIMIZATION_LEVEL "0")
else()
message("Set optimization level for no functrace ${SD_GCC_FUNCTRACE}")
set(SD_OPTIMIZATION_LEVEL "3")
endif()
message("Set default optimization level ${SD_OPTIMIZATION_LEVEL}")
+413
View File
@@ -0,0 +1,413 @@
# cmake/TemplateCorrelation.cmake
# Template correlation analysis and reporting functions
# Initialize global correlation tracking variables
function(initialize_correlation_tracking)
set(GLOBAL_USED_TEMPLATES "" CACHE INTERNAL "")
set(GLOBAL_PROVIDED_TEMPLATES "" CACHE INTERNAL "")
set(GLOBAL_MISSING_TEMPLATES "" CACHE INTERNAL "")
set(CORRELATION_DATA "" CACHE INTERNAL "")
set(FILE_ANALYSIS_DATA "" CACHE INTERNAL "")
endfunction()
include(InstantiationHelpers)
# Process a single source file for template analysis
function(process_source_file SOURCE_FILE SAFE_NAME)
message(STATUS "Analyzing: ${SOURCE_FILE}")
# Extract used templates - FIX: Added SAFE_NAME as third parameter
set(used_file "${INST_USED_DIR}/${SAFE_NAME}.used")
extract_used_templates(${SOURCE_FILE} ${used_file} ${SAFE_NAME})
set(used_templates ${EXTRACTED_USED_TEMPLATES})
# Extract provided templates
set(provided_file "${INST_PROVIDED_DIR}/${SAFE_NAME}.provided")
extract_provided_templates(${SOURCE_FILE} ${provided_file} ${SAFE_NAME})
set(provided_templates ${EXTRACTED_PROVIDED_TEMPLATES})
# Find missing templates for this file
set(missing_templates "")
foreach(used_tmpl ${used_templates})
normalize_template_name("${used_tmpl}" normalized_used)
set(found FALSE)
foreach(provided_tmpl ${provided_templates})
normalize_template_name("${provided_tmpl}" normalized_provided)
if("${normalized_used}" STREQUAL "${normalized_provided}")
set(found TRUE)
break()
endif()
endforeach()
if(NOT found)
list(APPEND missing_templates "${used_tmpl}")
endif()
endforeach()
# Write missing templates file
if(missing_templates)
string(REPLACE ";" "\n" missing_content "${missing_templates}")
file(WRITE "${INST_MISSING_DIR}/${SAFE_NAME}.missing" "${missing_content}")
else()
file(WRITE "${INST_MISSING_DIR}/${SAFE_NAME}.missing" "")
endif()
# Update global lists
set(current_global_used ${GLOBAL_USED_TEMPLATES})
list(APPEND current_global_used ${used_templates})
set(GLOBAL_USED_TEMPLATES ${current_global_used} CACHE INTERNAL "")
set(current_global_provided ${GLOBAL_PROVIDED_TEMPLATES})
list(APPEND current_global_provided ${provided_templates})
set(GLOBAL_PROVIDED_TEMPLATES ${current_global_provided} CACHE INTERNAL "")
set(current_global_missing ${GLOBAL_MISSING_TEMPLATES})
list(APPEND current_global_missing ${missing_templates})
set(GLOBAL_MISSING_TEMPLATES ${current_global_missing} CACHE INTERNAL "")
# Collect analysis data for reporting
list(LENGTH used_templates used_count)
list(LENGTH provided_templates provided_count)
list(LENGTH missing_templates missing_count)
get_filename_component(src_name ${SOURCE_FILE} NAME)
set(current_data ${FILE_ANALYSIS_DATA})
string(APPEND current_data " {\n")
string(APPEND current_data " \"file\": \"${src_name}\",\n")
string(APPEND current_data " \"safe_name\": \"${SAFE_NAME}\",\n")
string(APPEND current_data " \"used_count\": ${used_count},\n")
string(APPEND current_data " \"provided_count\": ${provided_count},\n")
string(APPEND current_data " \"missing_count\": ${missing_count}\n")
string(APPEND current_data " },\n")
set(FILE_ANALYSIS_DATA ${current_data} CACHE INTERNAL "")
endfunction()
# Perform correlation analysis on all collected data
function(perform_correlation_analysis)
message(STATUS "Performing correlation analysis...")
# Remove duplicates from global lists
set(all_used ${GLOBAL_USED_TEMPLATES})
set(all_provided ${GLOBAL_PROVIDED_TEMPLATES})
set(all_missing ${GLOBAL_MISSING_TEMPLATES})
if(all_used)
list(REMOVE_DUPLICATES all_used)
endif()
if(all_provided)
list(REMOVE_DUPLICATES all_provided)
endif()
if(all_missing)
list(REMOVE_DUPLICATES all_missing)
endif()
# Find truly missing templates (used but not provided anywhere)
set(truly_missing "")
foreach(used_tmpl ${all_used})
normalize_template_name("${used_tmpl}" normalized_used)
set(found FALSE)
foreach(provided_tmpl ${all_provided})
normalize_template_name("${provided_tmpl}" normalized_provided)
if("${normalized_used}" STREQUAL "${normalized_provided}")
set(found TRUE)
break()
endif()
endforeach()
if(NOT found)
list(APPEND truly_missing "${used_tmpl}")
endif()
endforeach()
# Find unused templates (provided but never used)
set(unused_templates "")
foreach(provided_tmpl ${all_provided})
normalize_template_name("${provided_tmpl}" normalized_provided)
set(found FALSE)
foreach(used_tmpl ${all_used})
normalize_template_name("${used_tmpl}" normalized_used)
if("${normalized_provided}" STREQUAL "${normalized_used}")
set(found TRUE)
break()
endif()
endforeach()
if(NOT found)
list(APPEND unused_templates "${provided_tmpl}")
endif()
endforeach()
# Update global variables with final results
set(GLOBAL_USED_TEMPLATES ${all_used} CACHE INTERNAL "")
set(GLOBAL_PROVIDED_TEMPLATES ${all_provided} CACHE INTERNAL "")
set(GLOBAL_MISSING_TEMPLATES ${truly_missing} CACHE INTERNAL "")
set(GLOBAL_UNUSED_TEMPLATES ${unused_templates} CACHE INTERNAL "")
# Write consolidated files
if(all_used)
string(REPLACE ";" "\n" content "${all_used}")
file(WRITE "${INST_DIR}/all_used.txt" "${content}")
endif()
if(all_provided)
string(REPLACE ";" "\n" content "${all_provided}")
file(WRITE "${INST_DIR}/all_provided.txt" "${content}")
endif()
if(truly_missing)
string(REPLACE ";" "\n" content "${truly_missing}")
file(WRITE "${INST_DIR}/all_missing.txt" "${content}")
endif()
if(unused_templates)
string(REPLACE ";" "\n" content "${unused_templates}")
file(WRITE "${INST_DIR}/all_unused.txt" "${content}")
endif()
endfunction()
# Generate correlation reports
function(generate_correlation_reports)
message(STATUS "Generating correlation reports...")
set(all_used ${GLOBAL_USED_TEMPLATES})
set(all_provided ${GLOBAL_PROVIDED_TEMPLATES})
set(truly_missing ${GLOBAL_MISSING_TEMPLATES})
set(unused ${GLOBAL_UNUSED_TEMPLATES})
list(LENGTH all_used total_used)
list(LENGTH all_provided total_provided)
list(LENGTH truly_missing total_missing)
list(LENGTH unused total_unused)
# Generate text report
set(report_file "${INST_REPORTS_DIR}/correlation_report.txt")
file(WRITE ${report_file} "=== TEMPLATE INSTANTIATION CORRELATION REPORT ===\n")
file(APPEND ${report_file} "Generated: ${CMAKE_HOST_SYSTEM_PROCESSOR} ${CMAKE_HOST_SYSTEM_NAME}\n")
file(APPEND ${report_file} "Build Type: ${CMAKE_BUILD_TYPE}\n")
file(APPEND ${report_file} "Datatypes: ${SD_TYPES_LIST}\n")
file(APPEND ${report_file} "All Ops: ${SD_ALL_OPS}\n\n")
file(APPEND ${report_file} "SUMMARY:\n")
file(APPEND ${report_file} " Total Templates Used: ${total_used}\n")
file(APPEND ${report_file} " Total Templates Provided: ${total_provided}\n")
file(APPEND ${report_file} " Total Templates Missing: ${total_missing}\n")
file(APPEND ${report_file} " Total Templates Unused: ${total_unused}\n\n")
if(total_missing GREATER 0)
file(APPEND ${report_file} "⚠️ MISSING TEMPLATES (WILL CAUSE LINK ERRORS):\n")
foreach(tmpl ${truly_missing})
file(APPEND ${report_file} " - ${tmpl}\n")
endforeach()
file(APPEND ${report_file} "\n")
endif()
if(total_unused GREATER 20)
file(APPEND ${report_file} "UNUSED TEMPLATES (showing first 20 of ${total_unused}):\n")
set(count 0)
foreach(tmpl ${unused})
if(count LESS 20)
file(APPEND ${report_file} " - ${tmpl}\n")
math(EXPR count "${count} + 1")
else()
break()
endif()
endforeach()
file(APPEND ${report_file} " ... and ${total_unused} - 20 more\n\n")
elseif(total_unused GREATER 0)
file(APPEND ${report_file} "UNUSED TEMPLATES:\n")
foreach(tmpl ${unused})
file(APPEND ${report_file} " - ${tmpl}\n")
endforeach()
file(APPEND ${report_file} "\n")
endif()
# Generate JSON report
set(json_file "${INST_REPORTS_DIR}/correlation.json")
file(WRITE ${json_file} "{\n")
file(APPEND ${json_file} " \"metadata\": {\n")
file(APPEND ${json_file} " \"build_type\": \"${CMAKE_BUILD_TYPE}\",\n")
file(APPEND ${json_file} " \"datatypes\": \"${SD_TYPES_LIST}\",\n")
file(APPEND ${json_file} " \"all_ops\": ${SD_ALL_OPS}\n")
file(APPEND ${json_file} " },\n")
file(APPEND ${json_file} " \"summary\": {\n")
file(APPEND ${json_file} " \"total_used\": ${total_used},\n")
file(APPEND ${json_file} " \"total_provided\": ${total_provided},\n")
file(APPEND ${json_file} " \"total_missing\": ${total_missing},\n")
file(APPEND ${json_file} " \"total_unused\": ${total_unused}\n")
file(APPEND ${json_file} " },\n")
file(APPEND ${json_file} " \"files\": [\n")
file(APPEND ${json_file} "${FILE_ANALYSIS_DATA}")
file(APPEND ${json_file} " {}\n")
file(APPEND ${json_file} " ]\n")
file(APPEND ${json_file} "}\n")
# Generate recommendations
generate_recommendations(${total_missing} ${total_unused})
endfunction()
# Generate actionable recommendations
function(generate_recommendations MISSING_COUNT UNUSED_COUNT)
set(recommend_file "${INST_REPORTS_DIR}/recommendations.txt")
file(WRITE ${recommend_file} "=== ACTIONABLE RECOMMENDATIONS ===\n\n")
if(MISSING_COUNT GREATER 0)
file(APPEND ${recommend_file} "⚠️ CRITICAL: ${MISSING_COUNT} missing template instantiations detected!\n")
file(APPEND ${recommend_file} "These WILL cause link-time errors.\n\n")
file(APPEND ${recommend_file} "SOLUTION:\n")
file(APPEND ${recommend_file} "1. Add the file '${INST_DIR}/fixes/missing_instantiations.cpp' to your build\n")
file(APPEND ${recommend_file} "2. Or add explicit instantiations to the relevant source files\n\n")
file(APPEND ${recommend_file} "The missing templates are listed in:\n")
file(APPEND ${recommend_file} " ${INST_DIR}/all_missing.txt\n\n")
else()
file(APPEND ${recommend_file} "✅ No missing template instantiations detected.\n\n")
endif()
if(UNUSED_COUNT GREATER 50)
file(APPEND ${recommend_file} "💡 OPTIMIZATION OPPORTUNITY:\n")
file(APPEND ${recommend_file} "${UNUSED_COUNT} unused template instantiations found.\n")
file(APPEND ${recommend_file} "Removing these could significantly reduce binary size.\n\n")
file(APPEND ${recommend_file} "Review the list in: ${INST_DIR}/all_unused.txt\n\n")
endif()
# Add type-specific recommendations
if(SD_TYPES_LIST)
file(APPEND ${recommend_file} "TYPE CONFIGURATION:\n")
file(APPEND ${recommend_file} "Current types: ${SD_TYPES_LIST}\n")
if(MISSING_COUNT GREATER 0)
file(APPEND ${recommend_file} "Some missing instantiations may be due to type restrictions.\n")
file(APPEND ${recommend_file} "Consider if all necessary types are included.\n")
endif()
endif()
endfunction()
# Generate fix files for missing instantiations
function(generate_instantiation_fixes)
set(fixes_dir "${INST_DIR}/fixes")
file(MAKE_DIRECTORY ${fixes_dir})
set(missing ${GLOBAL_MISSING_TEMPLATES})
if(NOT missing)
return()
endif()
message(STATUS "Generating instantiation fix files...")
# Generate main fix file
set(fix_file "${fixes_dir}/missing_instantiations.cpp")
file(WRITE ${fix_file} "// Auto-generated template instantiation fixes\n")
file(APPEND ${fix_file} "// Generated by cmake/ExtractInstantiations.cmake\n")
file(APPEND ${fix_file} "// Add this file to your build to resolve missing instantiations\n\n")
# Add necessary includes (customize based on your project)
file(APPEND ${fix_file} "#include <array/NDArray.h>\n")
file(APPEND ${fix_file} "#include <array/DataBuffer.h>\n")
file(APPEND ${fix_file} "#include <helpers/BroadcastHelper.h>\n")
file(APPEND ${fix_file} "#include <helpers/LoopKind.h>\n")
file(APPEND ${fix_file} "#include <execution/LaunchContext.h>\n\n")
# Group templates by base class
set(ndarray_instantiations "")
set(databuffer_instantiations "")
set(broadcast_instantiations "")
set(other_instantiations "")
foreach(tmpl ${missing})
if(tmpl MATCHES "^NDArray<")
list(APPEND ndarray_instantiations "${tmpl}")
elseif(tmpl MATCHES "^DataBuffer<")
list(APPEND databuffer_instantiations "${tmpl}")
elseif(tmpl MATCHES "^BroadcastHelper<")
list(APPEND broadcast_instantiations "${tmpl}")
else()
list(APPEND other_instantiations "${tmpl}")
endif()
endforeach()
# Write grouped instantiations
if(ndarray_instantiations)
file(APPEND ${fix_file} "// NDArray instantiations\n")
file(APPEND ${fix_file} "namespace sd {\n")
foreach(tmpl ${ndarray_instantiations})
file(APPEND ${fix_file} "template class ${tmpl};\n")
endforeach()
file(APPEND ${fix_file} "}\n\n")
endif()
if(databuffer_instantiations)
file(APPEND ${fix_file} "// DataBuffer instantiations\n")
file(APPEND ${fix_file} "namespace sd {\n")
foreach(tmpl ${databuffer_instantiations})
file(APPEND ${fix_file} "template class ${tmpl};\n")
endforeach()
file(APPEND ${fix_file} "}\n\n")
endif()
if(broadcast_instantiations)
file(APPEND ${fix_file} "// BroadcastHelper instantiations\n")
file(APPEND ${fix_file} "namespace sd {\n")
file(APPEND ${fix_file} "namespace helpers {\n")
foreach(tmpl ${broadcast_instantiations})
file(APPEND ${fix_file} "template class ${tmpl};\n")
endforeach()
file(APPEND ${fix_file} "}\n}\n\n")
endif()
if(other_instantiations)
file(APPEND ${fix_file} "// Other instantiations\n")
foreach(tmpl ${other_instantiations})
file(APPEND ${fix_file} "template class ${tmpl};\n")
endforeach()
endif()
message(STATUS "Generated fix file: ${fix_file}")
endfunction()
# Display final summary
function(display_analysis_summary)
set(all_used ${GLOBAL_USED_TEMPLATES})
set(all_provided ${GLOBAL_PROVIDED_TEMPLATES})
set(truly_missing ${GLOBAL_MISSING_TEMPLATES})
set(unused ${GLOBAL_UNUSED_TEMPLATES})
list(LENGTH all_used total_used)
list(LENGTH all_provided total_provided)
list(LENGTH truly_missing total_missing)
list(LENGTH unused total_unused)
message(STATUS "")
message(STATUS "=== INSTANTIATION CORRELATION COMPLETE ===")
message(STATUS "Templates Used: ${total_used}")
message(STATUS "Templates Provided: ${total_provided}")
if(total_missing GREATER 0)
message(WARNING "Templates Missing: ${total_missing} - WILL CAUSE LINK ERRORS!")
message(STATUS " Fix file generated: ${INST_DIR}/fixes/missing_instantiations.cpp")
else()
message(STATUS "Templates Missing: 0 ✓")
endif()
if(total_unused GREATER 50)
message(STATUS "Templates Unused: ${total_unused} (optimization opportunity)")
else()
message(STATUS "Templates Unused: ${total_unused}")
endif()
message(STATUS "")
message(STATUS "Reports generated in: ${INST_REPORTS_DIR}/")
message(STATUS " - correlation_report.txt (human readable)")
message(STATUS " - correlation.json (machine readable)")
message(STATUS " - recommendations.txt (actionable items)")
if(total_missing GREATER 0)
message(STATUS "")
message(STATUS "⚠️ ACTION REQUIRED: Add missing instantiations to fix link errors")
message(STATUS " See: ${INST_DIR}/all_missing.txt")
endif()
message(STATUS "==========================================")
endfunction()
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
# Wrapper for initialize_dynamic_combinations
function(initialize_dynamic_combinations)
message(STATUS "🔄 TypeCombinationEngine.cmake: Calling unified core system")
# Call the unified system
srcore_auto_setup()
# Map results to the expected legacy variables
if(DEFINED UNIFIED_COMBINATIONS_2)
set(COMBINATIONS_2 "${UNIFIED_COMBINATIONS_2}" PARENT_SCOPE)
set(COMBINATIONS_2 "${UNIFIED_COMBINATIONS_2}" CACHE INTERNAL "2-type combinations" FORCE)
endif()
if(DEFINED UNIFIED_COMBINATIONS_3)
set(COMBINATIONS_3 "${UNIFIED_COMBINATIONS_3}" PARENT_SCOPE)
set(COMBINATIONS_3 "${UNIFIED_COMBINATIONS_3}" CACHE INTERNAL "3-type combinations" FORCE)
endif()
message(STATUS "✅ TypeCombinationEngine.cmake: Setup complete via unified core")
endfunction()
# Legacy utility functions (now thin wrappers)
function(normalize_type input_type output_var)
srcore_normalize_type("${input_type}" result)
set(${output_var} "${result}" PARENT_SCOPE)
endfunction()
function(get_type_name_from_index index result_var)
# Try the unified core first
if(DEFINED SRCORE_TYPE_NAME_${index})
set(${result_var} "${SRCORE_TYPE_NAME_${index}}" PARENT_SCOPE)
return()
endif()
# Fallback to legacy system
if(DEFINED TYPE_NAME_${index})
set(${result_var} "${TYPE_NAME_${index}}" PARENT_SCOPE)
return()
endif()
# Emergency setup if nothing is available
srcore_auto_setup()
if(DEFINED SRCORE_TYPE_NAME_${index})
set(${result_var} "${SRCORE_TYPE_NAME_${index}}" PARENT_SCOPE)
else()
set(${result_var} "unknown_type_${index}" PARENT_SCOPE)
endif()
endfunction()
+37
View File
@@ -0,0 +1,37 @@
# TypeMST.cmake - Zero-indexed type combinations
# Option to enable MST-based type selection
option(SD_USE_MST_TYPES "Use optimized type combinations" ON)
# Function to generate a set of type combinations with 0-based indexing
function(generate_mst_combinations)
message(STATUS "TypeMST: Generating zero-indexed type combinations")
# Using 0-based indices that match the macros
set(_COMBINATIONS)
# Add homogeneous combinations
list(APPEND _COMBINATIONS "0,0,0") # BFLOAT16
list(APPEND _COMBINATIONS "1,1,1") # FLOAT32
list(APPEND _COMBINATIONS "2,2,2") # DOUBLE
list(APPEND _COMBINATIONS "3,3,3") # FLOAT16
list(APPEND _COMBINATIONS "4,4,4") # INT32
list(APPEND _COMBINATIONS "5,5,5") # INT64
list(APPEND _COMBINATIONS "6,6,6") # INT8
list(APPEND _COMBINATIONS "7,7,7") # INT16
list(APPEND _COMBINATIONS "8,8,8") # UINT8
list(APPEND _COMBINATIONS "9,9,9") # UINT16
# Add critical mixed-type combinations
list(APPEND _COMBINATIONS "1,4,1") # float32, int32, float32
list(APPEND _COMBINATIONS "4,1,1") # int32, float32, float32
list(APPEND _COMBINATIONS "2,4,2") # double, int32, double
list(APPEND _COMBINATIONS "4,2,2") # int32, double, double
# Set result
set(COMBINATIONS_3 ${_COMBINATIONS} PARENT_SCOPE)
# Report
list(LENGTH _COMBINATIONS COMBO_COUNT)
message(STATUS "TypeMST: Generated ${COMBO_COUNT} zero-indexed type combinations")
endfunction()
+425
View File
@@ -0,0 +1,425 @@
# TypeProfiles.cmake - OPTIMIZED VERSION
# Reduces compilation times by using focused type sets
# ============================================================================
# OPTIMIZED DEFAULT TYPES (10 types instead of 16+)
# ============================================================================
# Type profiles for different ML workloads
set(QUANTIZATION_TYPES "int8_t;uint8_t;float;int32_t" CACHE INTERNAL "Types for quantization workloads")
set(TRAINING_TYPES "float16;bfloat16;float;double;int32_t;int64_t" CACHE INTERNAL "Types for training workloads")
set(INFERENCE_TYPES "int8_t;uint8_t;float16;float;int32_t" CACHE INTERNAL "Types for inference workloads")
set(NLP_TYPES "std::string;float;int32_t;int64_t" CACHE INTERNAL "Types for NLP workloads")
set(CV_TYPES "uint8_t;float16;float;int32_t" CACHE INTERNAL "Types for computer vision workloads")
# OPTIMIZED: Data pipeline with essential types only (was 6, now 10)
set(DATA_PIPELINE
"bool;int8_t;uint8_t;int32_t;int64_t;float16;bfloat16;float;double;std::string"
CACHE INTERNAL "Optimized data pipeline with essential types")
# OPTIMIZED: Reduced from 16+ types to 10 essential types
set(STANDARD_ALL_TYPES
"bool;int8_t;uint8_t;int32_t;int64_t;float16;bfloat16;float;double;std::string"
CACHE INTERNAL "Optimized all types - removed int16, uint16, uint32, uint64, utf16, utf32")
# Set quantization type profile
function(set_quantization_type_profile)
set(SD_SELECTED_TYPES ${QUANTIZATION_TYPES} CACHE STRING "Selected types for quantization profile" FORCE)
set(SD_TYPE_PROFILE "quantization" CACHE STRING "Active type profile" FORCE)
message(STATUS "Applied quantization type profile")
message(STATUS "Selected types: ${SD_SELECTED_TYPES}")
set(SD_OPTIMIZE_QUANTIZATION ON CACHE BOOL "Enable quantization optimizations" FORCE)
set(SD_PRESERVE_QUANTIZATION_PATTERNS ON CACHE BOOL "Preserve quantization patterns" FORCE)
set(SD_ELIMINATE_PRECISION_WASTE ON CACHE BOOL "Eliminate precision waste" FORCE)
endfunction()
# Set training type profile
function(set_training_type_profile)
set(SD_SELECTED_TYPES ${TRAINING_TYPES} CACHE STRING "Selected types for training profile" FORCE)
set(SD_TYPE_PROFILE "training" CACHE STRING "Active type profile" FORCE)
message(STATUS "Applied training type profile")
message(STATUS "Selected types: ${SD_SELECTED_TYPES}")
set(SD_OPTIMIZE_MIXED_PRECISION ON CACHE BOOL "Enable mixed precision optimizations" FORCE)
set(SD_PRESERVE_GRADIENT_TYPES ON CACHE BOOL "Preserve gradient accumulation types" FORCE)
set(SD_ENABLE_FP16_TRAINING ON CACHE BOOL "Enable FP16 training support" FORCE)
endfunction()
# Set inference type profile
function(set_inference_type_profile)
set(SD_SELECTED_TYPES ${INFERENCE_TYPES} CACHE STRING "Selected types for inference profile" FORCE)
set(SD_TYPE_PROFILE "inference" CACHE STRING "Active type profile" FORCE)
message(STATUS "Applied inference type profile")
message(STATUS "Selected types: ${SD_SELECTED_TYPES}")
set(SD_OPTIMIZE_INFERENCE ON CACHE BOOL "Enable inference optimizations" FORCE)
set(SD_ENABLE_QUANTIZED_INFERENCE ON CACHE BOOL "Enable quantized inference" FORCE)
set(SD_MINIMIZE_MEMORY_FOOTPRINT ON CACHE BOOL "Minimize memory footprint" FORCE)
endfunction()
# Set NLP type profile
function(set_nlp_type_profile)
set(SD_SELECTED_TYPES ${NLP_TYPES} CACHE STRING "Selected types for NLP profile" FORCE)
set(SD_TYPE_PROFILE "nlp" CACHE STRING "Active type profile" FORCE)
message(STATUS "Applied NLP type profile")
message(STATUS "Selected types: ${SD_SELECTED_TYPES}")
set(SD_ENABLE_STRING_OPERATIONS ON CACHE BOOL "Enable string operations" FORCE)
set(SD_OPTIMIZE_TOKENIZATION ON CACHE BOOL "Optimize tokenization operations" FORCE)
set(SD_PRESERVE_TEXT_ENCODINGS ON CACHE BOOL "Preserve text encoding types" FORCE)
endfunction()
# Set computer vision type profile
function(set_cv_type_profile)
set(SD_SELECTED_TYPES ${CV_TYPES} CACHE STRING "Selected types for CV profile" FORCE)
set(SD_TYPE_PROFILE "cv" CACHE STRING "Active type profile" FORCE)
message(STATUS "Applied computer vision type profile")
message(STATUS "Selected types: ${SD_SELECTED_TYPES}")
set(SD_OPTIMIZE_IMAGE_PROCESSING ON CACHE BOOL "Enable image processing optimizations" FORCE)
set(SD_ENABLE_UINT8_IMAGES ON CACHE BOOL "Enable UINT8 image support" FORCE)
set(SD_OPTIMIZE_CONVOLUTION ON CACHE BOOL "Optimize convolution operations" FORCE)
endfunction()
# Set data pipeline type profile - NOW OPTIMIZED
function(set_data_pipeline_type_profile)
set(SD_SELECTED_TYPES ${DATA_PIPELINE} CACHE STRING "Selected types for data pipeline profile" FORCE)
set(SD_TYPE_PROFILE "data_pipeline" CACHE STRING "Active type profile" FORCE)
message(STATUS "Applied OPTIMIZED data pipeline type profile")
message(STATUS "Selected types: ${SD_SELECTED_TYPES}")
message(STATUS "Removed unnecessary types: int16, uint16, uint32, uint64, utf16, utf32")
set(SD_ENABLE_STRING_OPERATIONS ON CACHE BOOL "Enable string operations" FORCE)
set(SD_OPTIMIZE_DATA_LOADING ON CACHE BOOL "Optimize data loading operations" FORCE)
# Enable aggressive filtering with reduced type set
set(SD_AGGRESSIVE_SEMANTIC_FILTERING ON CACHE BOOL "Enable aggressive semantic filtering" FORCE)
endfunction()
# Set standard all types profile with aggressive filtering - NOW OPTIMIZED
function(set_standard_all_types_profile)
set(SD_SELECTED_TYPES ${STANDARD_ALL_TYPES} CACHE STRING "All essential types with semantic filtering" FORCE)
set(SD_TYPE_PROFILE "standard_all" CACHE STRING "Active type profile" FORCE)
message(STATUS "Applied OPTIMIZED STANDARD_ALL profile - 10 essential types (was 16+)")
message(STATUS "Selected types: ${SD_SELECTED_TYPES}")
message(STATUS "Removed types: int16, uint16, uint32, uint64, utf16, utf32")
set(SD_ENABLE_STRING_OPERATIONS ON CACHE BOOL "Enable string operations" FORCE)
set(SD_AGGRESSIVE_SEMANTIC_FILTERING ON CACHE BOOL "Enable aggressive semantic filtering" FORCE)
set(SD_STANDARD_PROFILE_RULES ON CACHE BOOL "Use standard profile filtering rules" FORCE)
endfunction()
# Apply type profile based on profile name
function(apply_type_profile profile_name)
if(profile_name STREQUAL "quantization")
set_quantization_type_profile()
elseif(profile_name STREQUAL "training")
set_training_type_profile()
elseif(profile_name STREQUAL "inference")
set_inference_type_profile()
elseif(profile_name STREQUAL "nlp")
set_nlp_type_profile()
elseif(profile_name STREQUAL "cv")
set_cv_type_profile()
elseif(profile_name STREQUAL "data_pipeline")
set_data_pipeline_type_profile()
elseif(profile_name STREQUAL "standard_all")
set_standard_all_types_profile()
else()
message(WARNING "Unknown type profile: ${profile_name}")
message(STATUS "Available profiles: quantization, training, inference, nlp, cv, data_pipeline, standard_all")
endif()
endfunction()
# Get profile-specific type combinations - OPTIMIZED
function(get_profile_type_combinations profile_name result_var)
if(profile_name STREQUAL "quantization")
set(profile_types ${QUANTIZATION_TYPES})
elseif(profile_name STREQUAL "training")
set(profile_types ${TRAINING_TYPES})
elseif(profile_name STREQUAL "inference")
set(profile_types ${INFERENCE_TYPES})
elseif(profile_name STREQUAL "nlp")
set(profile_types ${NLP_TYPES})
elseif(profile_name STREQUAL "cv")
set(profile_types ${CV_TYPES})
elseif(profile_name STREQUAL "data_pipeline")
set(profile_types ${DATA_PIPELINE})
elseif(profile_name STREQUAL "standard_all")
set(profile_types ${STANDARD_ALL_TYPES})
else()
# DEFAULT: Use optimized set instead of all types
set(profile_types ${STANDARD_ALL_TYPES})
endif()
set(${result_var} "${profile_types}" PARENT_SCOPE)
endfunction()
# OPTIMIZED: Override get_all_types to return our reduced set
function(get_all_types result_var)
# Return our optimized type set instead of all possible types
set(all_types ${STANDARD_ALL_TYPES})
set(${result_var} "${all_types}" PARENT_SCOPE)
endfunction()
# Get valid type combinations for standard_all profile
function(get_standard_all_valid_patterns result_var)
set(valid_patterns
# Same type operations (always valid)
"*,*,*:SAME_TYPE"
# Numeric operations
"INT*,INT*,INT*"
"FLOAT*,FLOAT*,FLOAT*"
"NUMERIC,NUMERIC,BOOL" # Comparisons
# Mixed precision patterns
"HALF,HALF,FLOAT32"
"BFLOAT16,BFLOAT16,FLOAT32"
"FLOAT32,FLOAT32,DOUBLE"
# Quantization patterns (INT8 specific)
"INT8,INT8,INT32" # INT8 accumulation
"INT8,FLOAT32,FLOAT32" # Dequantization
"FLOAT32,FLOAT32,INT8" # Quantization
"UINT8,UINT8,INT32" # UINT8 accumulation
"UINT8,FLOAT32,FLOAT32" # Image normalization
# String operations (UTF8 only now)
"UTF8,UTF8,UTF8" # String operations
"UTF8,INT32,INT32" # String indexing
"UTF8,INT64,INT64" # String indexing
# Reductions
"NUMERIC,NUMERIC,FLOAT32" # Sum/mean to float
"NUMERIC,NUMERIC,DOUBLE" # High precision reductions
"NUMERIC,NUMERIC,INT64" # Count/argmax
# Boolean logic
"BOOL,BOOL,BOOL"
# Indexing
"INT32,INT32,INT32"
"INT64,INT64,INT64"
)
set(invalid_patterns
# String to numeric conversions (except indexing)
"UTF*,*,FLOAT*"
"UTF*,*,DOUBLE"
"*,UTF*,FLOAT*"
"*,UTF*,DOUBLE"
"FLOAT*,UTF*,*"
"DOUBLE,UTF*,*"
# Bool to float conversions
"BOOL,BOOL,FLOAT*"
"BOOL,BOOL,DOUBLE"
"BOOL,BOOL,HALF"
"BOOL,BOOL,BFLOAT16"
# Precision downgrades that lose information
"DOUBLE,DOUBLE,FLOAT32"
"DOUBLE,DOUBLE,HALF"
"DOUBLE,DOUBLE,INT*"
"FLOAT32,FLOAT32,HALF"
"FLOAT32,FLOAT32,INT8" # Except quantization pattern
"INT64,INT64,INT32"
"INT32,INT32,INT8" # Except quantization
# Mixed string and numeric (except valid patterns)
"UTF*,FLOAT*,*"
"UTF*,DOUBLE,*"
"FLOAT*,UTF*,*"
"DOUBLE,UTF*,*"
)
set(${result_var} "${valid_patterns};INVALID:${invalid_patterns}" PARENT_SCOPE)
endfunction()
# Filter combinations based on active profile
function(filter_combinations_for_profile profile_name combinations result_var)
if(NOT DEFINED profile_name OR profile_name STREQUAL "")
set(${result_var} "${combinations}" PARENT_SCOPE)
return()
endif()
# Special handling for standard_all profile
if(profile_name STREQUAL "standard_all" AND SD_AGGRESSIVE_SEMANTIC_FILTERING)
filter_standard_all_combinations("${combinations}" filtered_combinations)
set(${result_var} "${filtered_combinations}" PARENT_SCOPE)
return()
endif()
get_profile_type_combinations(${profile_name} profile_types)
set(filtered_combinations "")
foreach(combination ${combinations})
string(REPLACE "," ";" combo_parts ${combination})
set(valid_combination TRUE)
foreach(type ${combo_parts})
list(FIND profile_types ${type} type_index)
if(type_index EQUAL -1)
set(valid_combination FALSE)
break()
endif()
endforeach()
if(valid_combination)
list(APPEND filtered_combinations ${combination})
endif()
endforeach()
set(${result_var} "${filtered_combinations}" PARENT_SCOPE)
endfunction()
# Filter combinations for standard_all profile
function(filter_standard_all_combinations combinations result_var)
get_standard_all_valid_patterns(patterns)
set(filtered_combinations "")
foreach(combination ${combinations})
if(is_combination_valid_for_standard_all("${combination}" "${patterns}"))
list(APPEND filtered_combinations ${combination})
endif()
endforeach()
set(${result_var} "${filtered_combinations}" PARENT_SCOPE)
endfunction()
# Check if a combination is valid for standard_all profile
function(is_combination_valid_for_standard_all combination patterns result)
# This would need to implement the pattern matching logic
# For now, return TRUE to not break existing functionality
set(${result} TRUE PARENT_SCOPE)
endfunction()
# Get optimized type list for profile
function(get_optimized_types_for_profile profile_name result_var)
get_profile_type_combinations(${profile_name} profile_types)
if(profile_name STREQUAL "quantization")
set(optimized_types "")
foreach(type ${profile_types})
if(type MATCHES "int8_t|uint8_t")
list(INSERT optimized_types 0 ${type})
else()
list(APPEND optimized_types ${type})
endif()
endforeach()
set(${result_var} "${optimized_types}" PARENT_SCOPE)
elseif(profile_name STREQUAL "training")
set(optimized_types "")
foreach(type ${profile_types})
if(type MATCHES "float16|bfloat16")
list(INSERT optimized_types 0 ${type})
else()
list(APPEND optimized_types ${type})
endif()
endforeach()
set(${result_var} "${optimized_types}" PARENT_SCOPE)
else()
set(${result_var} "${profile_types}" PARENT_SCOPE)
endif()
endfunction()
# Validate profile configuration
function(validate_profile_configuration profile_name)
if(NOT profile_name)
message(STATUS "No type profile specified - using optimized default types")
return()
endif()
get_profile_type_combinations(${profile_name} profile_types)
list(LENGTH profile_types type_count)
if(type_count EQUAL 0)
message(FATAL_ERROR "Profile '${profile_name}' has no valid types")
endif()
message(STATUS "Profile '${profile_name}' validated with ${type_count} types")
math(EXPR estimated_2_combinations "${type_count} * ${type_count}")
math(EXPR estimated_3_combinations "${type_count} * ${type_count} * ${type_count}")
message(STATUS "Estimated 2-type combinations: ${estimated_2_combinations}")
message(STATUS "Estimated 3-type combinations: ${estimated_3_combinations}")
# OPTIMIZED: Lower threshold for warnings
if(estimated_3_combinations GREATER 500)
message(STATUS "Large combination count detected - consider using more selective types")
message(STATUS "Current optimized profiles reduce combinations by 60-70%")
endif()
endfunction()
# Auto-detect optimal profile based on build configuration
function(auto_detect_optimal_profile result_var)
set(detected_profile "")
if(DEFINED SD_QUANTIZATION OR DEFINED SD_INT8 OR DEFINED SD_UINT8)
set(detected_profile "quantization")
elseif(DEFINED SD_TRAINING OR DEFINED SD_MIXED_PRECISION OR DEFINED SD_FP16)
set(detected_profile "training")
elseif(DEFINED SD_INFERENCE OR DEFINED SD_DEPLOYMENT)
set(detected_profile "inference")
elseif(DEFINED SD_NLP OR DEFINED SD_STRING_OPS)
set(detected_profile "nlp")
elseif(DEFINED SD_CV OR DEFINED SD_IMAGE_PROCESSING)
set(detected_profile "cv")
else()
# DEFAULT: Use optimized data_pipeline for general ML workloads
set(detected_profile "data_pipeline")
endif()
if(NOT detected_profile STREQUAL "")
message(STATUS "Auto-detected optimal profile: ${detected_profile}")
endif()
set(${result_var} "${detected_profile}" PARENT_SCOPE)
endfunction()
# Print profile information - UPDATED
function(print_profile_info profile_name)
if(NOT profile_name)
message(STATUS "No active type profile - using optimized defaults")
return()
endif()
message(STATUS "=== Type Profile Information ===")
message(STATUS "Active Profile: ${profile_name}")
get_profile_type_combinations(${profile_name} profile_types)
message(STATUS "Profile Types: ${profile_types}")
list(LENGTH profile_types type_count)
message(STATUS "Type Count: ${type_count}")
if(profile_name STREQUAL "quantization")
message(STATUS "Optimizations: INT8/UINT8 inference, quantization patterns")
elseif(profile_name STREQUAL "training")
message(STATUS "Optimizations: Mixed precision, gradient accumulation, FP64 for stability")
elseif(profile_name STREQUAL "inference")
message(STATUS "Optimizations: Deployment, quantized inference, INT8 support")
elseif(profile_name STREQUAL "nlp")
message(STATUS "Optimizations: String operations (UTF8 only), tokenization")
elseif(profile_name STREQUAL "cv")
message(STATUS "Optimizations: Image processing, convolution, UINT8 support")
elseif(profile_name STREQUAL "data_pipeline")
message(STATUS "Optimizations: All essential types for ML pipelines")
message(STATUS "Includes: INT8 quantization, FP16/BF16 mixed precision, UTF8 strings")
elseif(profile_name STREQUAL "standard_all")
message(STATUS "Optimizations: Reduced from 16+ to 10 essential types")
message(STATUS "Filtering: Aggressive semantic filtering enabled")
message(STATUS "Removed: int16, uint16, uint32, uint64, utf16, utf32")
endif()
message(STATUS "=== End Profile Information ===")
endfunction()
+139
View File
@@ -0,0 +1,139 @@
function(dump_type_macros_to_disk)
set(output_file "${CMAKE_BINARY_DIR}/resolved_type_macros.txt")
message(STATUS "🔍 Extracting macro values: ${output_file}")
# Create a stub header that blocks CUDA includes
set(stub_header "${CMAKE_BINARY_DIR}/cuda_stub.h")
file(WRITE "${stub_header}" "#ifndef CUDA_STUB_H
#define CUDA_STUB_H
#define __CUDA_RUNTIME_H__
#define __CUDA_H__
#define __DRIVER_TYPES_H__
struct cudaStream_t {};
struct cublasHandle_t {};
#endif")
# Create minimal extraction file
set(extraction_file "${CMAKE_BINARY_DIR}/extract_types.cpp")
file(WRITE "${extraction_file}" "#include \"${stub_header}\"
#define SD_CUDA 0
#define HAVE_ONEDNN 0
#define HAVE_ARMCOMPUTE 0
#define HAVE_CUDNN 0
#define COUNT_NARG(...) 1
#include <types/types.h>
===BEGIN_SD_COMMON_TYPES===
SD_COMMON_TYPES
===END_SD_COMMON_TYPES===
===BEGIN_SD_FLOAT_TYPES===
SD_FLOAT_TYPES
===END_SD_FLOAT_TYPES===
===BEGIN_SD_INTEGER_TYPES===
SD_INTEGER_TYPES
===END_SD_INTEGER_TYPES===
===BEGIN_SD_NUMERIC_TYPES===
SD_NUMERIC_TYPES
===END_SD_NUMERIC_TYPES===
===BEGIN_SD_COMMON_TYPES_PART_0===
SD_COMMON_TYPES_PART_0
===END_SD_COMMON_TYPES_PART_0===
===BEGIN_SD_COMMON_TYPES_PART_1===
SD_COMMON_TYPES_PART_1
===END_SD_COMMON_TYPES_PART_1===
===BEGIN_SD_COMMON_TYPES_PART_2===
SD_COMMON_TYPES_PART_2
===END_SD_COMMON_TYPES_PART_2===")
# Get basic include paths
set(include_flags
"-I${CMAKE_CURRENT_SOURCE_DIR}/include"
"-I${CMAKE_CURRENT_BINARY_DIR}/include"
"-I${CMAKE_CURRENT_BINARY_DIR}"
)
# Add FlatBuffers if available
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src/include")
list(APPEND include_flags "-I${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-src/include")
endif()
# Run preprocessor
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -E -P -w -std=c++11
${include_flags}
-DSD_CUDA=0 -DHAVE_ONEDNN=0 -DHAVE_ARMCOMPUTE=0
"${extraction_file}"
OUTPUT_VARIABLE preprocessed_output
ERROR_VARIABLE compiler_errors
RESULT_VARIABLE compiler_result
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
# Initialize output
set(output_content "RESOLVED MACRO VALUES\n=====================\n\n")
string(TIMESTAMP current_time "%Y-%m-%d %H:%M:%S")
string(APPEND output_content "Generated: ${current_time}\n")
string(APPEND output_content "Compiler: ${CMAKE_CXX_COMPILER}\n\n")
if(compiler_result EQUAL 0 AND preprocessed_output)
message(STATUS "✅ Macro extraction succeeded")
# Extract macros
set(macro_names "SD_COMMON_TYPES" "SD_FLOAT_TYPES" "SD_INTEGER_TYPES" "SD_NUMERIC_TYPES"
"SD_COMMON_TYPES_PART_0" "SD_COMMON_TYPES_PART_1" "SD_COMMON_TYPES_PART_2")
set(found_macros 0)
foreach(macro_name ${macro_names})
set(begin_marker "===BEGIN_${macro_name}===")
set(end_marker "===END_${macro_name}===")
string(FIND "${preprocessed_output}" "${begin_marker}" begin_pos)
string(FIND "${preprocessed_output}" "${end_marker}" end_pos)
if(begin_pos GREATER -1 AND end_pos GREATER begin_pos)
string(LENGTH "${begin_marker}" begin_len)
math(EXPR content_start "${begin_pos} + ${begin_len}")
math(EXPR content_length "${end_pos} - ${content_start}")
if(content_length GREATER 0)
string(SUBSTRING "${preprocessed_output}" ${content_start} ${content_length} macro_value)
string(STRIP "${macro_value}" macro_value)
string(REGEX REPLACE "[\r\n]+" " " macro_value "${macro_value}")
string(REGEX REPLACE " +" " " macro_value "${macro_value}")
if(NOT macro_value STREQUAL "" AND NOT macro_value STREQUAL macro_name)
string(APPEND output_content "${macro_name}:\n ${macro_value}\n\n")
math(EXPR found_macros "${found_macros} + 1")
else()
string(APPEND output_content "${macro_name}: (undefined)\n\n")
endif()
endif()
else()
string(APPEND output_content "${macro_name}: (not found)\n\n")
endif()
endforeach()
message(STATUS "📊 Found ${found_macros} expanded macros")
else()
string(APPEND output_content "ERROR: Preprocessor failed\nResult: ${compiler_result}\n")
if(compiler_errors)
string(APPEND output_content "Errors:\n${compiler_errors}\n")
endif()
message(STATUS "❌ Macro extraction failed")
endif()
# Write results
file(WRITE "${output_file}" "${output_content}")
message(STATUS "✅ Results written to: ${output_file}")
# Cleanup
file(REMOVE "${extraction_file}" "${stub_header}")
endfunction()
+79
View File
@@ -0,0 +1,79 @@
function(build_indexed_type_lists)
message(STATUS "🔄 TypeSystem.cmake: build_indexed_type_lists calling unified core")
# Ensure unified system is set up
srcore_auto_setup()
# Map unified results to legacy TypeSystem variables
if(DEFINED UNIFIED_ACTIVE_TYPES)
set(SD_ACTIVE_TYPES "${UNIFIED_ACTIVE_TYPES}" CACHE INTERNAL "List of active types for the build")
list(LENGTH UNIFIED_ACTIVE_TYPES type_count)
set(SD_COMMON_TYPES_COUNT ${type_count} CACHE INTERNAL "Total count of common types")
# Create TYPE_NAME_X mappings for legacy compatibility
set(index 0)
foreach(type_name ${UNIFIED_ACTIVE_TYPES})
set(TYPE_NAME_${index} "${type_name}" CACHE INTERNAL "Legacy reverse type lookup")
set(TYPE_NAME_${index} "${type_name}" PARENT_SCOPE)
math(EXPR index "${index} + 1")
endforeach()
# Also set float/integer type counts for compatibility
set(float_count 0)
set(integer_count 0)
foreach(type_name ${UNIFIED_ACTIVE_TYPES})
if(type_name MATCHES "(float|double|half|bfloat)")
math(EXPR float_count "${float_count} + 1")
elseif(type_name MATCHES "(int|uint|long)")
math(EXPR integer_count "${integer_count} + 1")
endif()
endforeach()
set(SD_FLOAT_TYPES_COUNT ${float_count} CACHE INTERNAL "Total count of float types")
set(SD_INTEGER_TYPES_COUNT ${integer_count} CACHE INTERNAL "Total count of integer types")
endif()
message(STATUS "✅ TypeSystem.cmake: build_indexed_type_lists complete via unified core")
endfunction()
# Ensure the critical get_type_name_from_index function works
function(get_type_name_from_index index result_var)
# First try the unified system
if(DEFINED SRCORE_TYPE_NAME_${index})
set(${result_var} "${SRCORE_TYPE_NAME_${index}}" PARENT_SCOPE)
return()
endif()
# Then try legacy system
if(DEFINED TYPE_NAME_${index})
set(${result_var} "${TYPE_NAME_${index}}" PARENT_SCOPE)
return()
endif()
# Auto-setup if needed
if(NOT DEFINED SRCORE_SETUP_COMPLETE)
message(STATUS "🔄 get_type_name_from_index: Auto-setting up unified core")
srcore_auto_setup()
if(DEFINED SRCORE_TYPE_NAME_${index})
set(${result_var} "${SRCORE_TYPE_NAME_${index}}" PARENT_SCOPE)
return()
endif()
endif()
# Final fallback
message(WARNING "❌ get_type_name_from_index(${index}): No type found in any system")
set(${result_var} "unknown_type_${index}" PARENT_SCOPE)
endfunction()
# Wrapper for extract_type_definitions_from_header (used by legacy code)
function(extract_type_definitions_from_header result_var)
message(STATUS "🔄 extract_type_definitions_from_header: Using unified core result")
if(DEFINED UNIFIED_ACTIVE_TYPES)
set(${result_var} "${UNIFIED_ACTIVE_TYPES}" PARENT_SCOPE)
else()
srcore_auto_setup()
set(${result_var} "${UNIFIED_ACTIVE_TYPES}" PARENT_SCOPE)
endif()
endfunction()
File diff suppressed because it is too large Load Diff
+273
View File
@@ -0,0 +1,273 @@
# =============================================================================
# ValidationSuite.cmake - Comprehensive Build Validation for libnd4j
# =============================================================================
if(NOT COMMAND print_status_colored)
include(${CMAKE_CURRENT_LIST_DIR}/PrintingUtilities.cmake)
endif()
# Master validation function
function(run_comprehensive_validation)
print_status_colored("INFO" "=== RUNNING COMPREHENSIVE BUILD VALIDATION ===")
validate_build_environment_comprehensive()
validate_cmake_variables_comprehensive()
validate_type_system_comprehensive()
validate_template_system_comprehensive()
validate_dependencies_comprehensive()
validate_generated_files_comprehensive()
validate_platform_specific_configuration()
print_status_colored("SUCCESS" "All validation checks passed")
endfunction()
# Environment validation
function(validate_build_environment_comprehensive)
print_status_colored("INFO" "Phase 1: Environment validation")
set(validation_errors "")
set(validation_warnings "")
if(CMAKE_VERSION VERSION_LESS "3.15")
list(APPEND validation_errors "CMake 3.15+ required, found ${CMAKE_VERSION}")
endif()
set(REQUIRED_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
foreach(dir ${REQUIRED_DIRS})
if(NOT EXISTS "${dir}")
list(APPEND validation_errors "Required directory not found: ${dir}")
endif()
endforeach()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9")
list(APPEND validation_errors "GCC 4.9+ required, found ${CMAKE_CXX_COMPILER_VERSION}")
endif()
list(LENGTH validation_errors error_count)
if(error_count GREATER 0)
foreach(error ${validation_errors})
print_status_colored("ERROR" " - ${error}")
endforeach()
message(FATAL_ERROR "Environment validation failed")
endif()
print_status_colored("SUCCESS" "Environment validation passed")
endfunction()
# CMake variables validation
function(validate_cmake_variables_comprehensive)
print_status_colored("INFO" "Phase 2: CMake variables validation")
set(validation_warnings "")
if(SD_CUDA AND SD_CPU AND SD_CPU STREQUAL "ON")
list(APPEND validation_warnings "Both SD_CUDA and SD_CPU enabled, SD_CUDA takes precedence")
endif()
if(DEFINED SD_TYPE_LIST AND NOT DEFINED SD_TYPES_LIST)
list(APPEND validation_warnings "Found SD_TYPE_LIST, converting to SD_TYPES_LIST")
set(SD_TYPES_LIST "${SD_TYPE_LIST}" PARENT_SCOPE)
endif()
if(DEFINED SD_TYPES_LIST AND SD_TYPES_LIST MATCHES ".*,.*")
list(APPEND validation_warnings "Converting comma-separated to semicolon-separated types")
string(REPLACE "," ";" SD_TYPES_LIST "${SD_TYPES_LIST}")
set(SD_TYPES_LIST "${SD_TYPES_LIST}" PARENT_SCOPE)
endif()
list(LENGTH validation_warnings warning_count)
if(warning_count GREATER 0)
foreach(warning ${validation_warnings})
print_status_colored("WARNING" " - ${warning}")
endforeach()
endif()
print_status_colored("SUCCESS" "CMake variables validation passed")
endfunction()
# Type system validation
function(validate_type_system_comprehensive)
print_status_colored("INFO" "Phase 3: Type system validation")
set(validation_errors "")
if(NOT DEFINED SD_COMMON_TYPES_COUNT OR SD_COMMON_TYPES_COUNT EQUAL 0)
list(APPEND validation_errors "Type system not initialized")
endif()
if(DEFINED COMBINATIONS_3 AND DEFINED COMBINATIONS_2)
list(LENGTH COMBINATIONS_3 combo_3_count)
list(LENGTH COMBINATIONS_2 combo_2_count)
if(combo_3_count EQUAL 0 AND combo_2_count EQUAL 0)
list(APPEND validation_errors "No type combinations generated")
endif()
endif()
list(LENGTH validation_errors error_count)
if(error_count GREATER 0)
foreach(error ${validation_errors})
print_status_colored("ERROR" " - ${error}")
endforeach()
message(FATAL_ERROR "Type system validation failed")
endif()
print_status_colored("SUCCESS" "Type system validation passed")
endfunction()
# Template system validation
function(validate_template_system_comprehensive)
print_status_colored("INFO" "Phase 4: Template system validation")
set(validation_errors "")
if(DEFINED CUSTOMOPS_GENERIC_SOURCES)
list(LENGTH CUSTOMOPS_GENERIC_SOURCES generated_count)
if(generated_count GREATER 0)
set(check_count 0)
foreach(generated_file ${CUSTOMOPS_GENERIC_SOURCES})
if(check_count LESS 3 AND EXISTS "${generated_file}")
file(READ "${generated_file}" file_content)
if(file_content MATCHES "#cmakedefine|@[A-Za-z_]+@")
list(APPEND validation_errors "Unprocessed template: ${generated_file}")
endif()
math(EXPR check_count "${check_count} + 1")
endif()
endforeach()
endif()
endif()
list(LENGTH validation_errors error_count)
if(error_count GREATER 0)
foreach(error ${validation_errors})
print_status_colored("ERROR" " - ${error}")
endforeach()
message(FATAL_ERROR "Template system validation failed")
endif()
print_status_colored("SUCCESS" "Template system validation passed")
endfunction()
# Dependency validation
function(validate_dependencies_comprehensive)
print_status_colored("INFO" "Phase 5: Dependency validation")
set(validation_warnings "")
if(NOT TARGET flatbuffers_interface)
list(APPEND validation_warnings "FlatBuffers interface target not found")
endif()
if(HELPERS_onednn AND (NOT DEFINED HAVE_ONEDNN OR NOT HAVE_ONEDNN))
list(APPEND validation_warnings "OneDNN enabled but not configured")
endif()
if(HELPERS_cudnn AND SD_CUDA AND (NOT DEFINED HAVE_CUDNN OR NOT HAVE_CUDNN))
list(APPEND validation_warnings "cuDNN enabled but not configured")
endif()
if(SD_CUDA AND NOT CMAKE_CUDA_COMPILER)
list(APPEND validation_warnings "CUDA build but no CUDA compiler")
endif()
list(LENGTH validation_warnings warning_count)
if(warning_count GREATER 0)
foreach(warning ${validation_warnings})
print_status_colored("WARNING" " - ${warning}")
endforeach()
endif()
print_status_colored("SUCCESS" "Dependency validation passed")
endfunction()
# Generated files validation
function(validate_generated_files_comprehensive)
print_status_colored("INFO" "Phase 6: Generated files validation")
set(validation_warnings "")
set(INCLUDE_OPS_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/generated/include_ops.h")
if(NOT EXISTS "${INCLUDE_OPS_FILE}")
list(APPEND validation_warnings "Generated include_ops.h not found")
else()
file(READ "${INCLUDE_OPS_FILE}" ops_content)
if(NOT ops_content MATCHES "#define")
list(APPEND validation_warnings "include_ops.h appears empty or malformed")
endif()
endif()
list(LENGTH validation_warnings warning_count)
if(warning_count GREATER 0)
foreach(warning ${validation_warnings})
print_status_colored("WARNING" " - ${warning}")
endforeach()
endif()
print_status_colored("SUCCESS" "Generated files validation passed")
endfunction()
# Platform-specific validation
function(validate_platform_specific_configuration)
print_status_colored("INFO" "Phase 7: Platform-specific validation")
set(validation_warnings "")
if(WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(NOT CMAKE_CXX_FLAGS MATCHES "-Wa,-mbig-obj")
list(APPEND validation_warnings "Windows GCC build may need -Wa,-mbig-obj flag")
endif()
endif()
if(SD_ARM_BUILD AND NOT DEFINED SD_ARCH)
list(APPEND validation_warnings "ARM build without SD_ARCH specification")
endif()
if(ANDROID AND NOT ANDROID_ABI)
list(APPEND validation_warnings "Android build without ABI specification")
endif()
list(LENGTH validation_warnings warning_count)
if(warning_count GREATER 0)
foreach(warning ${validation_warnings})
print_status_colored("WARNING" " - ${warning}")
endforeach()
endif()
print_status_colored("SUCCESS" "Platform validation passed")
endfunction()
# Quick validation for development
function(run_quick_validation)
print_status_colored("INFO" "=== RUNNING QUICK VALIDATION ===")
if(CMAKE_VERSION VERSION_LESS "3.15")
message(FATAL_ERROR "CMake 3.15+ required")
endif()
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include")
message(FATAL_ERROR "Include directory not found")
endif()
if(SD_CUDA AND NOT CMAKE_CUDA_COMPILER)
print_status_colored("WARNING" "CUDA build requested but compiler not found")
endif()
print_status_colored("SUCCESS" "Quick validation passed")
endfunction()
# Validation for CI/CD
function(run_ci_validation)
print_status_colored("INFO" "=== RUNNING CI/CD VALIDATION ===")
run_comprehensive_validation()
# Additional CI-specific checks
if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
print_status_colored("WARNING" "BUILD_TYPE not specified for CI build")
endif()
if(DEFINED ENV{CI} AND SD_GCC_FUNCTRACE)
print_status_colored("WARNING" "Function tracing enabled in CI environment")
endif()
print_status_colored("SUCCESS" "CI validation completed")
endfunction()
+39
View File
@@ -0,0 +1,39 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build for Android 5.0 or newer. Sample usage:
#
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
set(CMAKE_ANDROID_NDK "$ENV{ANDROID_NDK}")
set(CMAKE_ANDROID_STL_TYPE c++_static)
set(CMAKE_SYSTEM_VERSION "$ENV{ANDROID_VERSION}")
set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)
set(ANDROID TRUE)
if (WIN32)
set(CMAKE_C_COMPILER "$ENV{ANDROID_CC}.exe")
set(CMAKE_CXX_COMPILER "$ENV{ANDROID_CC}++.exe")
else()
set(CMAKE_C_COMPILER "$ENV{ANDROID_CC}")
set(CMAKE_CXX_COMPILER "$ENV{ANDROID_CC}++")
endif (WIN32)
add_definitions(-D__ANDROID_API__=$ENV{ANDROID_VERSION} -DANDROID -fPIC -ffunction-sections -funwind-tables -fstack-protector-strong -target armv7a-linux-androideabi)
+147
View File
@@ -0,0 +1,147 @@
# android-arm64.cmake - Intel x86_64 to ARM64 cross-compilation toolchain
# Set the system and processor for cross-compilation
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
# Flexible API level - can be overridden via command line or environment
if(NOT DEFINED ANDROID_NATIVE_API_LEVEL AND DEFINED ENV{ANDROID_VERSION})
set(ANDROID_NATIVE_API_LEVEL $ENV{ANDROID_VERSION})
elseif(NOT DEFINED ANDROID_NATIVE_API_LEVEL)
set(ANDROID_NATIVE_API_LEVEL 21) # Default API level
endif()
set(CMAKE_SYSTEM_VERSION ${ANDROID_NATIVE_API_LEVEL})
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
# Flexible NDK path detection
if(NOT DEFINED CMAKE_ANDROID_NDK)
if(DEFINED ENV{ANDROID_NDK_ROOT})
set(CMAKE_ANDROID_NDK $ENV{ANDROID_NDK_ROOT})
elseif(DEFINED ENV{ANDROID_NDK_HOME})
set(CMAKE_ANDROID_NDK $ENV{ANDROID_NDK_HOME})
elseif(DEFINED ENV{ANDROID_NDK})
set(CMAKE_ANDROID_NDK $ENV{ANDROID_NDK})
else()
message(FATAL_ERROR "Android NDK not found. Please set ANDROID_NDK_ROOT, ANDROID_NDK_HOME, or ANDROID_NDK environment variable")
endif()
endif()
# Verify NDK exists
if(NOT EXISTS "${CMAKE_ANDROID_NDK}")
message(FATAL_ERROR "Android NDK directory does not exist: ${CMAKE_ANDROID_NDK}")
endif()
# Set Android STL
set(CMAKE_ANDROID_STL_TYPE c++_shared)
# Set NDK toolchain paths for Intel x86_64 host
set(NDK_TOOLCHAIN_PATH "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64")
# Check if the toolchain path exists
if(NOT EXISTS "${NDK_TOOLCHAIN_PATH}")
message(FATAL_ERROR "NDK toolchain path does not exist: ${NDK_TOOLCHAIN_PATH}")
endif()
# Set sysroot
set(CMAKE_SYSROOT "${NDK_TOOLCHAIN_PATH}/sysroot")
# Verify sysroot exists
if(NOT EXISTS "${CMAKE_SYSROOT}")
message(FATAL_ERROR "NDK sysroot does not exist: ${CMAKE_SYSROOT}")
endif()
# Use NDK compilers for cross-compilation
set(CMAKE_C_COMPILER "${NDK_TOOLCHAIN_PATH}/bin/aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang")
set(CMAKE_CXX_COMPILER "${NDK_TOOLCHAIN_PATH}/bin/aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang++")
set(CMAKE_AR "${NDK_TOOLCHAIN_PATH}/bin/llvm-ar")
set(CMAKE_STRIP "${NDK_TOOLCHAIN_PATH}/bin/llvm-strip")
set(CMAKE_RANLIB "${NDK_TOOLCHAIN_PATH}/bin/llvm-ranlib")
# Verify compilers exist
if(NOT EXISTS "${CMAKE_C_COMPILER}")
message(FATAL_ERROR "C compiler does not exist: ${CMAKE_C_COMPILER}")
endif()
if(NOT EXISTS "${CMAKE_CXX_COMPILER}")
message(FATAL_ERROR "C++ compiler does not exist: ${CMAKE_CXX_COMPILER}")
endif()
# Set cross-compilation flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -march=armv8-a")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -march=armv8-a -std=c++14")
# Set NDK library paths for linking
set(NDK_SYSROOT_LIB_PATH "${CMAKE_SYSROOT}/usr/lib/aarch64-linux-android/${ANDROID_NATIVE_API_LEVEL}")
set(NDK_TOOLCHAIN_LIB_PATH "${NDK_TOOLCHAIN_PATH}/lib64/clang/14.0.6/lib/linux")
# Linker flags
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id=sha1")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-rosegment")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--fatal-warnings")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=sha1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-rosegment")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--fatal-warnings")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
# Additional Android-specific flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
# Set the find root path for cross-compilation
set(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}" "${CMAKE_ANDROID_NDK}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# Configure for cross-compilation
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_CROSSCOMPILING_EMULATOR "")
# Android specific settings
set(ANDROID TRUE)
set(ANDROID_ABI "arm64-v8a")
set(ANDROID_PLATFORM "android-${ANDROID_NATIVE_API_LEVEL}")
set(ANDROID_STL "c++_shared")
# Debug information
message(STATUS "Cross-compiling from Intel x86_64 to ARM64")
message(STATUS "Android NDK: ${CMAKE_ANDROID_NDK}")
message(STATUS "Android API Level: ${ANDROID_NATIVE_API_LEVEL}")
message(STATUS "Android ABI: ${CMAKE_ANDROID_ARCH_ABI}")
message(STATUS "Android Sysroot: ${CMAKE_SYSROOT}")
message(STATUS "C Compiler: ${CMAKE_C_COMPILER}")
message(STATUS "C++ Compiler: ${CMAKE_CXX_COMPILER}")
message(STATUS "Toolchain Path: ${NDK_TOOLCHAIN_PATH}")
# Ensure we don't accidentally use host tools
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# Set compiler identification to prevent issues
set(CMAKE_C_COMPILER_ID "Clang")
set(CMAKE_CXX_COMPILER_ID "Clang")
# Additional search paths for Android-specific libraries
if(EXISTS "${NDK_SYSROOT_LIB_PATH}")
set(CMAKE_LIBRARY_PATH "${CMAKE_LIBRARY_PATH}:${NDK_SYSROOT_LIB_PATH}")
endif()
if(EXISTS "${NDK_TOOLCHAIN_LIB_PATH}")
set(CMAKE_LIBRARY_PATH "${CMAKE_LIBRARY_PATH}:${NDK_TOOLCHAIN_LIB_PATH}")
endif()
# Set Android-specific preprocessor definitions
add_definitions(-DANDROID -D__ANDROID__ -D__ANDROID_API__=${ANDROID_NATIVE_API_LEVEL})
# Optimization flags for ARM64
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG")
message(STATUS "Android ARM64 cross-compilation toolchain configured successfully")
+39
View File
@@ -0,0 +1,39 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build for Android 5.0 or newer. Sample usage:
#
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI x86)
set(CMAKE_ANDROID_NDK "$ENV{ANDROID_NDK}")
set(CMAKE_ANDROID_STL_TYPE c++_static)
set(CMAKE_SYSTEM_VERSION "$ENV{ANDROID_VERSION}")
set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)
set(ANDROID TRUE)
if (WIN32)
set(CMAKE_C_COMPILER "$ENV{ANDROID_CC}.exe")
set(CMAKE_CXX_COMPILER "$ENV{ANDROID_CC}++.exe")
else()
set(CMAKE_C_COMPILER "$ENV{ANDROID_CC}")
set(CMAKE_CXX_COMPILER "$ENV{ANDROID_CC}++")
endif (WIN32)
add_definitions(-D__ANDROID_API__=$ENV{ANDROID_VERSION} -DANDROID -fPIC -ffunction-sections -funwind-tables -fstack-protector-strong -target i686-linux-android)
+38
View File
@@ -0,0 +1,38 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build for Android 5.0 or newer. Sample usage:
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI x86_64)
set(CMAKE_ANDROID_NDK "$ENV{ANDROID_NDK}")
set(CMAKE_ANDROID_STL_TYPE c++_shared)
set(CMAKE_SYSTEM_VERSION "$ENV{ANDROID_VERSION}")
set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)
set(ANDROID TRUE)
if (WIN32)
set(CMAKE_C_COMPILER "$ENV{ANDROID_CC}.exe")
set(CMAKE_CXX_COMPILER "$ENV{ANDROID_CC}++.exe")
else()
set(CMAKE_C_COMPILER "$ENV{ANDROID_CC}")
set(CMAKE_CXX_COMPILER "$ENV{ANDROID_CC}++")
endif (WIN32)
add_definitions(-D__ANDROID_API__=$ENV{ANDROID_VERSION} -DANDROID -fPIC -ffunction-sections -funwind-tables -fstack-protector-strong -target x86_64-none-linux-android)
+33
View File
@@ -0,0 +1,33 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build libnd4j for iOS for 32-bit architecture cpu armv7. Sample usage:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=ios-arm.cmake -DCMAKE_INSTALL_PREFIX=..
#
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR armv7)
set(IOS TRUE)
set(CFLAGS, "-miphoneos-version-min=6.0 -arch armv7")
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang")
set(CMAKE_C_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY "libtool -o <TARGET> <OBJECTS> <LINK_LIBRARIES> -syslibroot $ENV{IOS_SDK} -L$ENV{IOS_SDK}/usr/lib/")
add_definitions("-DIOS -stdlib=libc++ -miphoneos-version-min=6.0 -arch armv7 -isysroot $ENV{IOS_SDK} -I/usr/local/opt/llvm/4.0.0/include/c++/v1 -I/usr/local/opt/llvm/4.0.0/lib/clang/4.0.0/include -fPIC -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing")
+35
View File
@@ -0,0 +1,35 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build libnd4j for iOS for 64-bit architecture cpu arm64. Sample usage:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=ios-arm64.cmake -DCMAKE_INSTALL_PREFIX=..
#
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm64)
set(IOS TRUE)
set(CFLAGS, "-miphoneos-version-min=6.0 -arch arm64")
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang")
set(CMAKE_C_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY "libtool -o <TARGET> <OBJECTS> <LINK_LIBRARIES> -syslibroot $ENV{IOS_SDK} -L$ENV{IOS_SDK}/usr/lib/")
add_definitions("-DIOS -stdlib=libc++ -miphoneos-version-min=6.0 -arch arm64 -isysroot $ENV{IOS_SDK} -I/usr/local/opt/llvm/4.0.0/include/c++/v1 -I/usr/local/opt/llvm/4.0.0/lib/clang/4.0.0/include -fPIC -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing")
+46
View File
@@ -0,0 +1,46 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build libnd4j for iOS armv7. Sample usage:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=ios-armv7.cmake -DCMAKE_INSTALL_PREFIX=..
#
# If you really need to use libnd4j on a CPU with no FPU, replace "libs/armeabi-v7a" by "libs/armeabi" and
# "-march=armv7-a with "-march=armv5te -mtune=xscale -msoft-float"
set(CMAKE_SYSTEM_NAME UnixPaths)
set(CMAKE_SYSTEM_PROCESSOR armv)
set(IOS TRUE)
set(CFLAGS, "-miphoneos-version-min=6.0 -arch armv7")
set(CMAKE_C_COMPILER "clang-omp")
set(CMAKE_CXX_COMPILER "clang-omp")
# set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ")
# set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ")
set(CMAKE_C_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_C_CREATE_STATIC_LIBRARY "libtool <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -Wl,--no-undefined -z text -o <TARGET> <OBJECTS> <LINK_LIBRARIES> -L$ENV{ANDROID_ROOT}/usr/lib/ --sysroot=$ENV{ANDROID_ROOT}")
# set(CMAKE_CXX_CREATE_STATIC_LIBRARY "libtool <CMAKE_STATIC_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_STATIC_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_STATIC_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -Wl,--no-undefined -z text -o <TARGET> <OBJECTS> <LINK_LIBRARIES> -L$ENV{IOS_ROOT}/usr/lib/ --sysroot=$ENV{IOS_ROOT}")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY "libtool -o <TARGET> <OBJECTS> <LINK_LIBRARIES> -syslibroot $ENV{IOS_SDK} -L$ENV{IOS_SDK}/usr/lib/")
add_definitions("-DIOS -miphoneos-version-min=6.0 -arch armv7 -isysroot $ENV{IOS_SDK} -I/usr/local/Cellar/llvm/4.0.0/include/c++/v1 -I/usr/local/Cellar/llvm/4.0.0/lib/clang/4.0.0/include -fPIC -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing")
# include_directories("$ENV{ANDROID_CPP}/include/" "$ENV{ANDROID_CPP}/libs/armeabi-v7a/include/" "$ENV{ANDROID_ROOT}/usr/include/")
+33
View File
@@ -0,0 +1,33 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build libnd4j for 32-bit iOS Simulator. Sample usage:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=ios-x86.cmake -DCMAKE_INSTALL_PREFIX=..
#
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR "i386")
set(IOS TRUE)
set(CFLAGS, "-miphoneos-version-min=6.0 -arch i386")
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang")
set(CMAKE_C_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY "libtool -o <TARGET> <OBJECTS> <LINK_LIBRARIES> -syslibroot $ENV{IOS_SDK} -L$ENV{IOS_SDK}/usr/lib/")
add_definitions("-DIOS -stdlib=libc++ -miphoneos-version-min=6.0 -arch i386 -isysroot $ENV{IOS_SDK} -I/usr/local/opt/llvm/4.0.0/include/c++/v1 -I/usr/local/opt/llvm/4.0.0/lib/clang/4.0.0/include -fPIC -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing")
+33
View File
@@ -0,0 +1,33 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# CMake toolchain to build libnd4j for 64-bit iOS Simulator. Sample usage:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=ios-x86_64.cmake -DCMAKE_INSTALL_PREFIX=..
#
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
set(IOS TRUE)
set(CFLAGS, "-miphoneos-version-min=6.0 -arch x86_64")
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang")
set(CMAKE_C_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_LINK_EXECUTABLE "libtool -static <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L$ENV{IOS_SDK}/usr/lib/ -syslibroot $ENV{IOS_SDK}")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY "libtool -o <TARGET> <OBJECTS> <LINK_LIBRARIES> -syslibroot $ENV{IOS_SDK} -L$ENV{IOS_SDK}/usr/lib/")
add_definitions("-DIOS -stdlib=libc++ -miphoneos-version-min=6.0 -arch x86_64 -isysroot $ENV{IOS_SDK} -I/usr/local/opt/llvm/4.0.0/include/c++/v1 -I/usr/local/opt/llvm/4.0.0/lib/clang/4.0.0/include -fPIC -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing")
+73
View File
@@ -0,0 +1,73 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# Use this command to build the Windows port of Allegro
# with a mingw cross compiler:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-mingw.cmake .
#
# or for out of source:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw.cmake ..
#
# You will need at least CMake 2.6.0.
#
# Adjust the following paths to suit your environment.
#
# This file was based on http://www.cmake.org/Wiki/CmakeMingw
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Windows)
message("Using msys2")
# Assume the target architecture.
# XXX for some reason the value set here gets cleared before we reach the
# main CMakeLists.txt; see that file for a workaround.
# set(CMAKE_SYSTEM_PROCESSOR i686)
# Which compilers to use for C and C++, and location of target
# environment.
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
# First look in standard location as used by Debian/Ubuntu/etc.
set(CMAKE_C_COMPILER /mingw64/bin/gcc)
set(CMAKE_CXX_COMPILER /mingw64/bin/g++)
set(CMAKE_RC_COMPILER /mingw64/bin/windres)
set(CMAKE_FIND_ROOT_PATH /mingw64)
else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
# First look in standard location as used by Debian/Ubuntu/etc.
set(CMAKE_C_COMPILER /mingw32/bin/gcc)
set(CMAKE_CXX_COMPILER /mingw32/bin/g++)
set(CMAKE_RC_COMPILER /mingw64/bin/windres)
set(CMAKE_FIND_ROOT_PATH /mingw32)
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
# Adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Tell pkg-config not to look at the target environment's .pc files.
# Setting PKG_CONFIG_LIBDIR sets the default search directory, but we have to
# set PKG_CONFIG_PATH as well to prevent pkg-config falling back to the host's
# path.
set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_FIND_ROOT_PATH}/lib/pkgconfig)
set(ENV{PKG_CONFIG_PATH} ${CMAKE_FIND_ROOT_PATH}/lib/pkgconfig)
set(ENV{MINGDIR} ${CMAKE_FIND_ROOT_PATH})
+23
View File
@@ -0,0 +1,23 @@
set(NDK_MIN_PLATFORM_LEVEL "21")
set(NDK_MAX_PLATFORM_LEVEL "35")
set(NDK_PLATFORM_ALIAS_20 "android-19")
set(NDK_PLATFORM_ALIAS_25 "android-24")
set(NDK_PLATFORM_ALIAS_J "android-16")
set(NDK_PLATFORM_ALIAS_J-MR1 "android-17")
set(NDK_PLATFORM_ALIAS_J-MR2 "android-18")
set(NDK_PLATFORM_ALIAS_K "android-19")
set(NDK_PLATFORM_ALIAS_L "android-21")
set(NDK_PLATFORM_ALIAS_L-MR1 "android-22")
set(NDK_PLATFORM_ALIAS_M "android-23")
set(NDK_PLATFORM_ALIAS_N "android-24")
set(NDK_PLATFORM_ALIAS_N-MR1 "android-24")
set(NDK_PLATFORM_ALIAS_O "android-26")
set(NDK_PLATFORM_ALIAS_O-MR1 "android-27")
set(NDK_PLATFORM_ALIAS_P "android-28")
set(NDK_PLATFORM_ALIAS_Q "android-29")
set(NDK_PLATFORM_ALIAS_R "android-30")
set(NDK_PLATFORM_ALIAS_S "android-31")
set(NDK_PLATFORM_ALIAS_Sv2 "android-32")
set(NDK_PLATFORM_ALIAS_Tiramisu "android-33")
set(NDK_PLATFORM_ALIAS_UpsideDownCake "android-34")
set(NDK_PLATFORM_ALIAS_VanillaIceCream "android-35")
+32
View File
@@ -0,0 +1,32 @@
#!/bin/sh
#
# /* ******************************************************************************
# *
# *
# * This program and the accompanying materials are made available under the
# * terms of the Apache License, Version 2.0 which is available at
# * https://www.apache.org/licenses/LICENSE-2.0.
# *
# * See the NOTICE file distributed with this work for additional
# * information regarding copyright ownership.
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# * License for the specific language governing permissions and limitations
# * under the License.
# *
# * SPDX-License-Identifier: Apache-2.0
# ******************************************************************************/
#
if [ -f "/usr/local/lib/libnd4jcpu.so" ]; then
cat >/etc/ld.so.conf.d/libnd4jcpu.conf <<EOF
/usr/local/lib/libnd4jcpu.so
EOF
else if [ -f "/usr/local/lib/libnd4jcuda.so" ]; then
cat >/etc/ld.so.conf.d/libnd4jcuda.conf <<EOF
/usr/local/lib/libnd4jcuda.so
EOF
fi
fi
ldconfig
+34
View File
@@ -0,0 +1,34 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER powerpc-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER powerpc-linux-gnu-g++)
# here is the target environment located
set(CMAKE_FIND_ROOT_PATH /usr/powerpc-linux-gnu )
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+58
View File
@@ -0,0 +1,58 @@
################################################################################
#
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# See the NOTICE file distributed with this work for additional
# information regarding copyright ownership.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_C_COMPILER "$ENV{RPI_BIN}-gcc" )
set(CMAKE_CXX_COMPILER "$ENV{RPI_BIN}-g++" )
if (SD_CUDA)
if(${SD_ARCH} MATCHES "armv8")
set(CMAKE_SYSTEM_PROCESSOR aarch64)
else()
set(CMAKE_SYSTEM_PROCESSOR ${SD_ARCH})
endif()
set(CUDA_TARGET_CPU_ARCH ${CMAKE_SYSTEM_PROCESSOR})
set(CUDA_TARGET_OS_VARIANT "linux")
if (SD_CUDA)
set(ENV{CUDAHOSTCXX} "${CMAKE_CXX_COMPILER}")
endif()
endif()
set(CMAKE_FIND_ROOT_PATH "")
if(DEFINED ENV{SYSROOT})
set(CMAKE_SYSROOT "$ENV{SYSROOT}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --sysroot=$ENV{SYSROOT}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=$ENV{SYSROOT}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --sysroot=$ENV{SYSROOT}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --sysroot=$ENV{SYSROOT}")
list(APPEND CMAKE_FIND_ROOT_PATH "$ENV{SYSROOT}")
endif()
if(DEFINED ENV{CUDNN_ROOT_DIR})
list(APPEND CMAKE_FIND_ROOT_PATH "$ENV{CUDNN_ROOT_DIR}")
endif()
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#search only in target path
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+1
View File
@@ -0,0 +1 @@
set(NDK_SYSTEM_LIBS "libEGL.so;libGLESv1_CM.so;libGLESv2.so;libGLESv3.so;libOpenMAXAL.so;libOpenSLES.so;libaaudio.so;libamidi.so;libandroid.so;libbinder_ndk.so;libc.so;libcamera2ndk.so;libdl.so;libicu.so;libjnigraphics.so;liblog.so;libm.so;libmediandk.so;libnativehelper.so;libnativewindow.so;libneuralnetworks.so;libstdc++.so;libsync.so;libvulkan.so;libz.so")