File size: 10,254 Bytes
26d5b81 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | cmake_minimum_required(VERSION 3.14)
option(NEUROFLOW_USE_CUDA "Enable CUDA/cuBLAS backend" OFF)
if(NEUROFLOW_USE_CUDA)
project(neuroflow_core VERSION 1.0.0 LANGUAGES CXX CUDA)
else()
project(neuroflow_core VERSION 1.0.0 LANGUAGES CXX)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(NEUROFLOW_BUILD_TESTS "Build unit tests" OFF)
option(NEUROFLOW_BUILD_PYTHON "Build Python bindings" OFF)
option(NEUROFLOW_USE_AVX2 "Enable AVX2 SIMD" ON)
option(NEUROFLOW_USE_BLAS "Use external BLAS (OpenBLAS/MKL) for GEMM" ON)
option(NEUROFLOW_USE_AMP "Enable mixed precision training (FP16/BF16)" OFF)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /GR /EHsc /utf-8")
if(NEUROFLOW_USE_AVX2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
message(STATUS "AVX2 SIMD enabled (MSVC)")
endif()
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /DNDEBUG /GL")
set(CMAKE_CXX_FLAGS_DEBUG "/Od /Zi /DDEBUG")
find_package(OpenMP)
else()
find_package(OpenMP REQUIRED)
if(NEUROFLOW_USE_AVX2)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-mavx2" COMPILER_SUPPORTS_AVX2)
if(COMPILER_SUPPORTS_AVX2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2")
message(STATUS "AVX2 SIMD enabled")
else()
message(STATUS "AVX2 not supported by compiler")
endif()
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=native -mtune=native -funroll-loops -ffast-math -ftree-vectorize")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG")
endif()
add_library(neuroflow_core STATIC
src/tensor.cpp
src/model.cpp
src/weight_io.cpp
src/tokenizer.cpp
src/sampling.cpp
src/causal_lm.cpp
src/tensor_ops.cpp
src/generative_model.cpp
src/rope.cpp
src/swiglu.cpp
src/rms_norm.cpp
src/adamw.cpp
src/scheduler.cpp
src/train_lm.cpp
src/grad_scaler.cpp
src/sft_train.cpp
src/dpo_train.cpp
)
if(NEUROFLOW_USE_CUDA)
find_package(CUDAToolkit REQUIRED)
if(CUDAToolkit_VERSION VERSION_LESS "11.0")
message(FATAL_ERROR "CUDA >= 11.0 required, found ${CUDAToolkit_VERSION}")
endif()
target_compile_definitions(neuroflow_core PUBLIC USE_CUDA)
target_include_directories(neuroflow_core PUBLIC ${CUDAToolkit_INCLUDE_DIRS})
target_link_libraries(neuroflow_core PUBLIC CUDA::cudart CUDA::cublas)
target_sources(neuroflow_core PRIVATE src/cuda_context.cpp)
set_source_files_properties(src/cuda_context.cpp PROPERTIES LANGUAGE CUDA)
target_compile_options(neuroflow_core PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:--generate-code=arch=compute_80,code=[sm_80,compute_80]>
$<$<COMPILE_LANGUAGE:CUDA>:--expt-relaxed-constexpr>
$<$<COMPILE_LANGUAGE:CUDA>:--extended-lambda>
)
set(NEUROFLOW_CUDA_FOUND TRUE)
message(STATUS "CUDA backend enabled: ${CUDAToolkit_VERSION}")
else()
set(NEUROFLOW_CUDA_FOUND FALSE)
endif()
target_include_directories(neuroflow_core PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
)
target_compile_definitions(neuroflow_core PRIVATE
$<$<CONFIG:DEBUG>:DEBUG>
)
if(NEUROFLOW_USE_BLAS)
find_package(BLAS)
if(BLAS_FOUND)
target_compile_definitions(neuroflow_core PUBLIC USE_CBLAS)
target_link_libraries(neuroflow_core PUBLIC ${BLAS_LIBRARIES})
if(BLAS_INCLUDE_DIRS)
target_include_directories(neuroflow_core PUBLIC ${BLAS_INCLUDE_DIRS})
endif()
set(NEUROFLOW_BLAS_FOUND TRUE)
message(STATUS "External BLAS found: ${BLAS_LIBRARIES}")
message(STATUS " NOTE: Set OPENBLAS_NUM_THREADS=1 at runtime to avoid thread oversubscription with OpenMP")
else()
set(OPENBLAS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/openblas")
if(EXISTS "${OPENBLAS_DIR}/include/cblas.h" AND EXISTS "${OPENBLAS_DIR}/lib/libscipy_openblas.lib")
target_compile_definitions(neuroflow_core PUBLIC USE_CBLAS)
target_include_directories(neuroflow_core PUBLIC "${OPENBLAS_DIR}/include")
target_link_libraries(neuroflow_core PUBLIC "${OPENBLAS_DIR}/lib/libscipy_openblas.lib")
set(NEUROFLOW_BLAS_FOUND TRUE)
message(STATUS "Using bundled OpenBLAS from: ${OPENBLAS_DIR}")
message(STATUS " NOTE: Set OPENBLAS_NUM_THREADS=1 at runtime to avoid thread oversubscription with OpenMP")
else()
set(NEUROFLOW_BLAS_FOUND FALSE)
message(STATUS "External BLAS not found, using built-in GEMM")
endif()
endif()
else()
set(NEUROFLOW_BLAS_FOUND FALSE)
endif()
if(NEUROFLOW_USE_AMP)
if(NOT NEUROFLOW_USE_CUDA)
message(WARNING "NEUROFLOW_USE_AMP requires CUDA, enabling CUDA automatically")
set(NEUROFLOW_USE_CUDA ON)
endif()
target_compile_definitions(neuroflow_core PUBLIC NEUROFLOW_USE_AMP)
message(STATUS "Mixed precision training (AMP) enabled")
endif()
if(OpenMP_CXX_FOUND)
target_link_libraries(neuroflow_core PUBLIC OpenMP::OpenMP_CXX)
endif()
add_executable(neuroflow_train_v2 src/train_v2.cpp)
target_link_libraries(neuroflow_train_v2 PRIVATE neuroflow_core)
if(OpenMP_CXX_FOUND)
target_link_libraries(neuroflow_train_v2 PRIVATE OpenMP::OpenMP_CXX)
endif()
add_executable(neuroflow_infer_v2 src/infer_v2.cpp)
target_link_libraries(neuroflow_infer_v2 PRIVATE neuroflow_core)
if(OpenMP_CXX_FOUND)
target_link_libraries(neuroflow_infer_v2 PRIVATE OpenMP::OpenMP_CXX)
endif()
add_executable(neuroflow_sft src/sft_main.cpp)
target_link_libraries(neuroflow_sft PRIVATE neuroflow_core)
if(OpenMP_CXX_FOUND)
target_link_libraries(neuroflow_sft PRIVATE OpenMP::OpenMP_CXX)
endif()
add_executable(neuroflow_dpo src/dpo_main.cpp)
target_link_libraries(neuroflow_dpo PRIVATE neuroflow_core)
if(OpenMP_CXX_FOUND)
target_link_libraries(neuroflow_dpo PRIVATE OpenMP::OpenMP_CXX)
endif()
if(NEUROFLOW_BUILD_TESTS)
enable_testing()
set(NEUROFLOW_TEST_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/tests)
add_executable(neuroflow_test_lm tests/test_lm_pathway.cpp)
target_link_libraries(neuroflow_test_lm PRIVATE neuroflow_core)
target_include_directories(neuroflow_test_lm PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME lm_pathway_test COMMAND neuroflow_test_lm)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_tensor.cpp)
add_executable(neuroflow_tensor_test tests/test_tensor.cpp)
target_link_libraries(neuroflow_tensor_test PRIVATE neuroflow_core)
target_include_directories(neuroflow_tensor_test PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME tensor_test COMMAND neuroflow_tensor_test)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_model.cpp)
add_executable(neuroflow_model_test tests/test_model.cpp)
target_link_libraries(neuroflow_model_test PRIVATE neuroflow_core)
target_include_directories(neuroflow_model_test PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME model_test COMMAND neuroflow_model_test)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_rope.cpp)
add_executable(neuroflow_test_rope tests/test_rope.cpp)
target_link_libraries(neuroflow_test_rope PRIVATE neuroflow_core)
target_include_directories(neuroflow_test_rope PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME rope_test COMMAND neuroflow_test_rope)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_swiglu.cpp)
add_executable(neuroflow_test_swiglu tests/test_swiglu.cpp)
target_link_libraries(neuroflow_test_swiglu PRIVATE neuroflow_core)
target_include_directories(neuroflow_test_swiglu PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME swiglu_test COMMAND neuroflow_test_swiglu)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_rms_norm.cpp)
add_executable(neuroflow_test_rms_norm tests/test_rms_norm.cpp)
target_link_libraries(neuroflow_test_rms_norm PRIVATE neuroflow_core)
target_include_directories(neuroflow_test_rms_norm PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME rms_norm_test COMMAND neuroflow_test_rms_norm)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_adamw.cpp)
add_executable(neuroflow_test_adamw tests/test_adamw.cpp)
target_link_libraries(neuroflow_test_adamw PRIVATE neuroflow_core)
target_include_directories(neuroflow_test_adamw PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME adamw_test COMMAND neuroflow_test_adamw)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_scheduler.cpp)
add_executable(neuroflow_test_scheduler tests/test_scheduler.cpp)
target_link_libraries(neuroflow_test_scheduler PRIVATE neuroflow_core)
target_include_directories(neuroflow_test_scheduler PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME scheduler_test COMMAND neuroflow_test_scheduler)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_gqa.cpp)
add_executable(neuroflow_test_gqa tests/test_gqa.cpp)
target_link_libraries(neuroflow_test_gqa PRIVATE neuroflow_core)
target_include_directories(neuroflow_test_gqa PRIVATE ${NEUROFLOW_TEST_INCLUDE})
add_test(NAME gqa_test COMMAND neuroflow_test_gqa)
endif()
message(STATUS "Unit tests enabled (built-in test framework)")
endif()
install(TARGETS neuroflow_core
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
install(DIRECTORY include/neuroflow
DESTINATION include
)
message(STATUS "")
message(STATUS "NeuroFlow Core Build Configuration:")
message(STATUS " Version: ${PROJECT_VERSION}")
message(STATUS " C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS " Build Type: ${CMAKE_BUILD_TYPE}")
message(STATUS " AVX2: ${NEUROFLOW_USE_AVX2}")
message(STATUS " AMP: ${NEUROFLOW_USE_AMP}")
message(STATUS " Tests: ${NEUROFLOW_BUILD_TESTS}")
message(STATUS " Python: ${NEUROFLOW_BUILD_PYTHON}")
message(STATUS " OpenMP: ${OpenMP_CXX_FOUND}")
message(STATUS " BLAS: ${NEUROFLOW_BLAS_FOUND}")
message(STATUS " CUDA: ${NEUROFLOW_CUDA_FOUND}")
|