Skip to content

Commit

Permalink
rework cmake option features
Browse files Browse the repository at this point in the history
  • Loading branch information
yshekel committed Aug 20, 2024
1 parent 98ad969 commit d772b1b
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 98 deletions.
31 changes: 18 additions & 13 deletions icicle_v3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# TODO Yuval remove those flags. Frontend will always have everything.
# CUDA backend may do it for faster dev.
# Build options
option(BUILD_TESTS "Build unit tests. Default=OFF" OFF)
option(CPU_BACKEND "Build CPU backend. Default=ON" ON)
option(CUDA_BACKEND "Branch/commit to pull for CUDA backend or `local` if under icicle/backend/cuda. Default=OFF" OFF)

# features that some fields/curves have and some don't.
# By default, it is defined in [TODO Yuval]. Override the option manually to disable features.
option(NTT "Build NTT" ON)
option(ECNTT "Build ECNTT" ON)
option(MSM "Build MSM" ON)
option(EXT_FIELD "Build extension field" OFF)
option(ECNTT "Build ECNTT" OFF)
option(G2 "Build G2" OFF)
# REMOVE END
option(BUILD_TESTS "Build unit tests" OFF)
option(CPU_BACKEND "Build CPU backend" ON)
option(CUDA_BACKEND "Branch/commit to pull for CUDA backend, local path or OFF to disable pulling" OFF)
option(G2 "Build G2 MSM" ON)
option(EXT_FIELD "Build extension field" ON)

# device API library
add_library(icicle_device SHARED
Expand Down Expand Up @@ -62,11 +63,15 @@ endif()

# curve is building the scalar field too
if(CURVE)
check_curve()
setup_curve_target()
set(CURVE_INDEX -1)
set(FEATURES_STRING "")
check_curve(${CURVE} CURVE_INDEX FEATURES_STRING)
setup_curve_target(${CURVE} ${CURVE_INDEX} ${FEATURES_STRING})
elseif(FIELD)
check_field()
setup_field_target()
set(FIELD_INDEX -1)
set(FEATURES_STRING "")
check_field(${FIELD} FIELD_INDEX FEATURES_STRING)
setup_field_target(${FIELD} ${FIELD_INDEX} ${FEATURES_STRING})
endif()

if (CPU_BACKEND)
Expand Down
10 changes: 6 additions & 4 deletions icicle_v3/backend/cpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ target_sources(icicle_device PRIVATE src/cpu_device_api.cpp)
# field API library
if (FIELD)
target_sources(icicle_field PRIVATE
src/field/cpu_vec_ops.cpp
src/field/cpu_vec_ops.cpp
)
if (NTT)
target_sources(icicle_field PRIVATE src/field/cpu_ntt.cpp src/polynomials/cpu_polynomial_backend.cpp)
endif()
endif()
target_include_directories(icicle_field PRIVATE include)
endif() # FIELD

# curve API library
if (CURVE)
target_sources(icicle_curve PRIVATE
src/curve/cpu_msm.cpp
target_sources(icicle_curve PRIVATE
src/curve/cpu_mont_conversion.cpp
)
if (MSM)
target_sources(icicle_curve PRIVATE src/curve/cpu_msm.cpp)
endif()
if (ECNTT)
target_sources(icicle_curve PRIVATE src/curve/cpu_ecntt.cpp)
endif()
Expand Down
86 changes: 54 additions & 32 deletions icicle_v3/cmake/curve.cmake
Original file line number Diff line number Diff line change
@@ -1,49 +1,71 @@
function(check_curve)
set(SUPPORTED_CURVES bn254;bls12_381;bls12_377;bw6_761;grumpkin)
include(cmake/fields_and_curves.cmake)
include(cmake/target_editor.cmake)

function(extract_curve_names CURVE_NAMES_OUT)
set(CURVE_NAMES "")

foreach (ITEM ${ICICLE_CURVES})
string(REPLACE ":" ";" ITEM_SPLIT ${ITEM})
list(GET ITEM_SPLIT 1 CURVE_NAME)
list(APPEND CURVE_NAMES ${CURVE_NAME})
endforeach()

# Output the list of curve names
set(${CURVE_NAMES_OUT} "${CURVE_NAMES}" PARENT_SCOPE)
endfunction()

function(check_curve CURVE CURVE_INDEX_OUT FEATURES_STRING_OUT)
set(IS_CURVE_SUPPORTED FALSE)
set(I 0)
foreach (SUPPORTED_CURVE ${SUPPORTED_CURVES})
math(EXPR I "${I} + 1")
if (CURVE STREQUAL SUPPORTED_CURVE)
add_compile_definitions(FIELD_ID=${I})
add_compile_definitions(CURVE_ID=${I})
foreach (ITEM ${ICICLE_CURVES})
string(REPLACE ":" ";" ITEM_SPLIT ${ITEM})
list(GET ITEM_SPLIT 0 CURVE_INDEX)
list(GET ITEM_SPLIT 1 CURVE_NAME)
list(GET ITEM_SPLIT 2 FEATURES_STRING)

if (CURVE STREQUAL CURVE_NAME)
set(IS_CURVE_SUPPORTED TRUE)
message(STATUS "building CURVE_NAME=${CURVE_NAME} ; CURVE_INDEX=${CURVE_INDEX} ; FEATURES=${FEATURES_STRING}")
# Output the CURVE_INDEX and FEATURES_STRING
set(${CURVE_INDEX_OUT} "${CURVE_INDEX}" PARENT_SCOPE)
set(${FEATURES_STRING_OUT} "${FEATURES_STRING}" PARENT_SCOPE)
break()
endif ()
endforeach()

if (NOT IS_CURVE_SUPPORTED)
message( FATAL_ERROR "The value of CURVE variable: ${CURVE} is not one of the supported curves: ${SUPPORTED_CURVES}" )
set(ALL_CURVES "")
extract_curve_names(ALL_CURVES)
message(FATAL_ERROR "The value of CURVE variable: ${CURVE} is not supported: choose from [${ALL_CURVES}]")
endif ()
endfunction()

function(setup_curve_target)
set(FIELD ${CURVE})
setup_field_target()

add_library(icicle_curve SHARED
src/msm.cpp
src/curves/ffi_extern.cpp
src/curves/montgomery_conversion.cpp
)
target_link_libraries(icicle_curve PUBLIC icicle_device icicle_field pthread)
function(setup_curve_target CURVE_NAME CURVE_INDEX FEATURES_STRING)
# the scalar field of the curve is built to a field library (like babybear is built)
setup_field_target(${CURVE_NAME} ${CURVE_INDEX} ${FEATURES_STRING})

add_library(icicle_curve SHARED)

# Split FEATURES_STRING into a list using "," as the separator
string(REPLACE "," ";" FEATURES_LIST ${FEATURES_STRING})

# customize the curve lib to choose what to include
handle_curve(icicle_curve) # basic curve and field methods, including vec ops
# Handle features
handle_msm(icicle_curve "${FEATURES_LIST}")
handle_g2(icicle_curve "${FEATURES_LIST}")
handle_ecntt(icicle_curve "${FEATURES_LIST}")
# Add additional feature handling calls here

set_target_properties(icicle_curve PROPERTIES OUTPUT_NAME "icicle_curve_${CURVE}")
target_link_libraries(icicle_curve PUBLIC icicle_device icicle_field pthread)

# Make sure CURVE is defined in the cache for backends to see
# Ensure CURVE is defined in the cache for backends to see
set(CURVE "${CURVE}" CACHE STRING "")
target_compile_definitions(icicle_curve PUBLIC CURVE=${CURVE})
if (G2)
set(G2 "${G2}" CACHE STRING "")
target_compile_definitions(icicle_curve PUBLIC G2=${G2})
endif()
if (ECNTT)
target_sources(icicle_curve PRIVATE src/ecntt.cpp)
set(ECNTT "${ECNTT}" CACHE STRING "")
target_compile_definitions(icicle_curve PUBLIC ECNTT=${ECNTT})
endif()
target_compile_definitions(icicle_curve PUBLIC CURVE=${CURVE} CURVE_ID=${CURVE_INDEX})

install(TARGETS icicle_curve
RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/"
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/"
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/")
endfunction()
102 changes: 55 additions & 47 deletions icicle_v3/cmake/field.cmake
Original file line number Diff line number Diff line change
@@ -1,59 +1,67 @@
function(check_field)
set(SUPPORTED_FIELDS babybear;stark252)
include(cmake/fields_and_curves.cmake)
include(cmake/target_editor.cmake)

function(extract_field_names FIELD_NAMES_OUT)
set(FIELD_NAMES "")

foreach (ITEM ${ICICLE_FIELDS})
string(REPLACE ":" ";" ITEM_SPLIT ${ITEM})
list(GET ITEM_SPLIT 1 FIELD_NAME)
list(APPEND FIELD_NAMES ${FIELD_NAME})
endforeach()

# Output the list of field names
set(${FIELD_NAMES_OUT} "${FIELD_NAMES}" PARENT_SCOPE)
endfunction()

function(check_field FIELD FIELD_INDEX_OUT FEATURES_STRING_OUT)
set(IS_FIELD_SUPPORTED FALSE)
set(I 1000)
foreach (SUPPORTED_FIELD ${SUPPORTED_FIELDS})
math(EXPR I "${I} + 1")
if (FIELD STREQUAL SUPPORTED_FIELD)
add_compile_definitions(FIELD_ID=${I})
foreach (ITEM ${ICICLE_FIELDS})
string(REPLACE ":" ";" ITEM_SPLIT ${ITEM})
list(GET ITEM_SPLIT 0 FIELD_INDEX)
list(GET ITEM_SPLIT 1 FIELD_NAME)
list(GET ITEM_SPLIT 2 FEATURES_STRING)

if (FIELD STREQUAL FIELD_NAME)
set(IS_FIELD_SUPPORTED TRUE)
message(STATUS "building FIELD_NAME=${FIELD_NAME} ; FIELD_INDEX=${FIELD_INDEX} ; FEATURES=${FEATURES_STRING}")
# Output the FIELD_INDEX and FEATURES_STRING
set(${FIELD_INDEX_OUT} "${FIELD_INDEX}" PARENT_SCOPE)
set(${FEATURES_STRING_OUT} "${FEATURES_STRING}" PARENT_SCOPE)
break()
endif ()
endforeach()

if (NOT IS_FIELD_SUPPORTED)
message( FATAL_ERROR "The value of FIELD variable: ${FIELD} is not one of the supported fields: ${SUPPORTED_FIELDS}" )
set(ALL_FIELDS "")
extract_field_names(ALL_FIELDS)
message(FATAL_ERROR "The value of FIELD variable: ${FIELD} is not supported: choose from [${ALL_FIELDS}]")
endif ()
endfunction()

function(setup_field_target)
add_library(icicle_field SHARED
src/fields/ffi_extern.cpp
src/vec_ops.cpp
src/matrix_ops.cpp
)
# handle APIs that are for some curves only
add_ntt_sources_or_disable()
set_target_properties(icicle_field PROPERTIES OUTPUT_NAME "icicle_field_${FIELD}")
target_link_libraries(icicle_field PUBLIC icicle_device pthread)

# Make sure FIELD is defined in the cache for backends to see
set(FIELD "${FIELD}" CACHE STRING "")
target_compile_definitions(icicle_field PUBLIC FIELD=${FIELD})
if (EXT_FIELD)
set(EXT_FIELD "${EXT_FIELD}" CACHE STRING "")
target_compile_definitions(icicle_field PUBLIC EXT_FIELD=${EXT_FIELD})
endif()

install(TARGETS icicle_field
RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/"
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/"
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/")
function(setup_field_target FIELD_NAME FIELD_INDEX FEATURES_STRING)
add_library(icicle_field SHARED)

# Split FEATURES_STRING into a list using "," as the separator
string(REPLACE "," ";" FEATURES_LIST ${FEATURES_STRING})

# customize the field lib to choose what to include
handle_field(icicle_field) # basic field methods, including vec ops
# Handle features
handle_ntt(icicle_field "${FEATURES_LIST}")
handle_ext_field(icicle_field "${FEATURES_LIST}")
# Add additional feature handling calls here

set_target_properties(icicle_field PROPERTIES OUTPUT_NAME "icicle_field_${FIELD}")
target_link_libraries(icicle_field PUBLIC icicle_device pthread)

# Ensure FIELD is defined in the cache for backends to see
set(FIELD "${FIELD_NAME}" CACHE STRING "")
add_compile_definitions(FIELD=${FIELD} FIELD_ID=${FIELD_INDEX})

install(TARGETS icicle_field
RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/"
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/"
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/")
endfunction()

function(add_ntt_sources_or_disable)
set(SUPPORTED_FIELDS_WITHOUT_NTT grumpkin)

if (NOT FIELD IN_LIST SUPPORTED_FIELDS_WITHOUT_NTT)
add_compile_definitions(NTT_ENABLED)
target_sources(icicle_field PRIVATE
src/ntt.cpp
src/polynomials/polynomials.cpp
src/polynomials/polynomials_c_api.cpp
src/polynomials/polynomials_abstract_factory.cpp
)
else()
set(NTT OFF CACHE BOOL "NTT not available for field" FORCE)
endif()

endfunction()
17 changes: 17 additions & 0 deletions icicle_v3/cmake/fields_and_curves.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

# Define available fields with an index and their supported features
# Format: index:field:features
set(ICICLE_FIELDS
1001:babybear:NTT,EXT_FIELD
1002:stark252:NTT
)

# Define available curves with an index and their supported features
# Format: index:curve:features
set(ICICLE_CURVES
1:bn254:NTT,MSM,G2,ECNTT
2:bls12_381:NTT,MSM,G2,ECNTT
3:bls12_377:NTT,MSM,G2,ECNTT
4:bw6_761:NTT,MSM,G2,ECNTT
5:grumpkin:MSM
)
73 changes: 73 additions & 0 deletions icicle_v3/cmake/target_editor.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

# The following functions, each adds a function to a target.
# In addition, some can check feature is enabled for target, given FEATURE_LIST.

function(handle_field TARGET)
target_sources(${TARGET} PRIVATE
src/fields/ffi_extern.cpp
src/vec_ops.cpp
src/matrix_ops.cpp
)
endfunction()

function(handle_curve TARGET)
target_sources(${TARGET} PRIVATE
src/curves/ffi_extern.cpp
src/curves/montgomery_conversion.cpp
)
endfunction()

function(handle_ntt TARGET FEATURE_LIST)
if(NTT AND "NTT" IN_LIST FEATURE_LIST)
target_compile_definitions(${TARGET} PUBLIC NTT=${NTT})
target_sources(${TARGET} PRIVATE
src/ntt.cpp
src/polynomials/polynomials.cpp
src/polynomials/polynomials_c_api.cpp
src/polynomials/polynomials_abstract_factory.cpp
)
set(NTT ON CACHE BOOL "Enable NTT feature" FORCE)
else()
set(NTT OFF CACHE BOOL "NTT not available for this field" FORCE)
message(STATUS "NTT not available for this field")
endif()
endfunction()

function(handle_ext_field TARGET FEATURE_LIST)
if(EXT_FIELD AND "EXT_FIELD" IN_LIST FEATURE_LIST)
target_compile_definitions(${TARGET} PUBLIC EXT_FIELD=${EXT_FIELD})
set(EXT_FIELD ON CACHE BOOL "Enable EXT_FIELD feature" FORCE)
else()
set(EXT_FIELD OFF CACHE BOOL "EXT_FIELD not available for this field" FORCE)
endif()
endfunction()

function(handle_msm TARGET FEATURE_LIST)
if(MSM AND "MSM" IN_LIST FEATURE_LIST)
target_compile_definitions(${TARGET} PUBLIC MSM=${MSM})
target_sources(${TARGET} PRIVATE src/msm.cpp)
set(MSM ON CACHE BOOL "Enable MSM feature" FORCE)
else()
set(MSM OFF CACHE BOOL "MSM not available for this curve" FORCE)
endif()
endfunction()

function(handle_g2 TARGET FEATURE_LIST)
if(G2 AND "G2" IN_LIST FEATURE_LIST)
target_compile_definitions(${TARGET} PUBLIC G2=${G2})
set(G2 ON CACHE BOOL "Enable G2 feature" FORCE)
else()
set(G2 OFF CACHE BOOL "G2 not available for this curve" FORCE)
endif()
endfunction()

function(handle_ecntt TARGET FEATURE_LIST)
if(ECNTT AND "ECNTT" IN_LIST FEATURE_LIST)
target_compile_definitions(${TARGET} PUBLIC ECNTT=${ECNTT})
target_sources(icicle_curve PRIVATE src/ecntt.cpp)
set(ECNTT ON CACHE BOOL "Enable ECNTT feature" FORCE)
else()
set(ECNTT OFF CACHE BOOL "ECNTT not available for this curve" FORCE)
endif()
endfunction()

Loading

0 comments on commit d772b1b

Please sign in to comment.