From 32fa252e8abf6b88d9a6f93905c5a8f76edb82a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Sat, 6 Jan 2024 22:32:59 -0500 Subject: [PATCH] refactor: re-organize build script --- build.rs | 234 ++++++++++++++++++------------------------------------- 1 file changed, 76 insertions(+), 158 deletions(-) diff --git a/build.rs b/build.rs index 816ccae..f54a0e7 100644 --- a/build.rs +++ b/build.rs @@ -2,115 +2,41 @@ use std::env; use std::path::PathBuf; fn main() { - // account for cross-compilation [by examining environment variable] let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - // Set CXX environment variable to choose alternative C compiler. - // Optimization level depends on whether or not --release is passed - // or implied. - let mut cc = cc::Build::new(); - cc.cpp(true); - - let c_src_dir = PathBuf::from("src"); - let files = vec![ - c_src_dir.join("grumpkin_pippenger.cpp"), - // c_src_dir.join("pasta_pippenger.cpp"), - ]; - let mut cc_def = None; + compile_source("grumpkin_pippenger.cpp", "__BLST_PORTABLE__", "grumpkin_msm", &target_arch); + compile_source("pasta_pippenger.cpp", "__PASTA_PORTABLE__", "pasta_msm", &target_arch); - match (cfg!(feature = "portable"), cfg!(feature = "force-adx")) { - (true, false) => { - println!("Compiling in portable mode without ISA extensions"); - cc_def = Some("__BLST_PORTABLE__"); - } - (false, true) => { - if target_arch.eq("x86_64") { - println!("Enabling ADX support via `force-adx` feature"); - cc_def = Some("__ADX__"); - } else { - println!("`force-adx` is ignored for non-x86_64 targets"); - } - } - (false, false) => { - #[cfg(target_arch = "x86_64")] - if target_arch.eq("x86_64") && std::is_x86_feature_detected!("adx") - { - println!("Enabling ADX because it was detected on the host"); - cc_def = Some("__ADX__"); - } - } - (true, true) => panic!( - "Cannot compile with both `portable` and `force-adx` features" - ), + if cfg!(target_os = "windows") && !cfg!(target_env = "msvc") { + return; } - cc.flag_if_supported("-mno-avx") // avoid costly transitions - .flag_if_supported("-fno-builtin") - .flag_if_supported("-std=c++11") - .flag_if_supported("-Wno-unused-command-line-argument"); - if !cfg!(debug_assertions) { - cc.define("NDEBUG", None); - } - if let Some(def) = cc_def { - cc.define(def, None); - } - if let Some(include) = env::var_os("DEP_BLST_C_SRC") { - cc.include(include); - } - if let Some(include) = env::var_os("DEP_SPPARK_ROOT") { - cc.include(include); + if cuda_available() { + let mut implement_sort: bool = true; + compile_cuda("cuda/bn254.cu", "bn256_msm_cuda", implement_sort); + implement_sort = false; + compile_cuda("cuda/grumpkin.cu", "grumpkin_msm_cuda", implement_sort); + compile_cuda("cuda/pallas.cu", "pallas_msm_cuda", implement_sort); + compile_cuda("cuda/vesta.cu", "vesta_msm_cuda", implement_sort); + println!("cargo:rerun-if-changed=cuda"); } - cc.files(&files).compile("grumpkin_msm"); - - // ============================================================ - // ====================== PASTA BINDINGS ====================== - // ============================================================ + println!("cargo:rerun-if-env-changed=NVCC"); +} - // Set CXX environment variable to choose alternative C compiler. - // Optimization level depends on whether or not --release is passed - // or implied. +fn compile_source(file_name: &str, def: &str, output_name: &str, target_arch: &str) { let mut cc = cc::Build::new(); cc.cpp(true); let c_src_dir = PathBuf::from("src"); - let files = vec![c_src_dir.join("pasta_pippenger.cpp")]; - let mut cc_def = None; - - match (cfg!(feature = "portable"), cfg!(feature = "force-adx")) { - (true, false) => { - println!("Compiling in portable mode without ISA extensions"); - cc_def = Some("__PASTA_PORTABLE__"); - } - (false, true) => { - if target_arch.eq("x86_64") { - println!("Enabling ADX support via `force-adx` feature"); - cc_def = Some("__ADX__"); - } else { - println!("`force-adx` is ignored for non-x86_64 targets"); - } - } - (false, false) => { - #[cfg(target_arch = "x86_64")] - if target_arch.eq("x86_64") && std::is_x86_feature_detected!("adx") - { - println!("Enabling ADX because it was detected on the host"); - cc_def = Some("__ADX__"); - } - } - (true, true) => panic!( - "Cannot compile with both `portable` and `force-adx` features" - ), - } + let file = c_src_dir.join(file_name); + let cc_def = determine_cc_def(target_arch, def); - cc.flag_if_supported("-mno-avx") // avoid costly transitions - .flag_if_supported("-fno-builtin") - .flag_if_supported("-std=c++11") - .flag_if_supported("-Wno-unused-command-line-argument"); - if !cfg!(debug_assertions) { - cc.define("NDEBUG", None); + common_build_configurations(&mut cc); + if let Some(cc_def) = cc_def { + cc.define(&cc_def, None); } - if let Some(def) = cc_def { - cc.define(def, None); + if let Some(include) = env::var_os("DEP_BLST_C_SRC") { + cc.include(include); } if let Some(include) = env::var_os("DEP_SEMOLINA_C_INCLUDE") { cc.include(include); @@ -118,73 +44,65 @@ fn main() { if let Some(include) = env::var_os("DEP_SPPARK_ROOT") { cc.include(include); } - cc.files(&files).compile("pasta_msm"); + cc.file(file).compile(output_name); +} - if cfg!(target_os = "windows") && !cfg!(target_env = "msvc") { - return; +fn common_build_configurations(cc: &mut cc::Build) { + cc.flag_if_supported("-mno-avx") + .flag_if_supported("-fno-builtin") + .flag_if_supported("-std=c++11") + .flag_if_supported("-Wno-unused-command-line-argument"); + if !cfg!(debug_assertions) { + cc.define("NDEBUG", None); + } +} + +fn determine_cc_def(target_arch: &str, default_def: &str) -> Option { + match (cfg!(feature = "portable"), cfg!(feature = "force-adx")) { + (true, false) => Some(default_def.to_string()), + (false, true) if target_arch == "x86_64" => Some("__ADX__".to_string()), + (false, false) if target_arch == "x86_64" && std::is_x86_feature_detected!("adx") => Some("__ADX__".to_string()), + (true, true) => panic!("Cannot compile with both `portable` and `force-adx` features"), + _ => None, } - // Detect if there is CUDA compiler and engage "cuda" feature accordingly - let nvcc = match env::var("NVCC") { - Ok(var) => which::which(var), - Err(_) => which::which("nvcc"), - }; - if nvcc.is_ok() { - let mut nvcc = cc::Build::new(); - nvcc.cuda(true); - nvcc.flag("-arch=sm_80"); - nvcc.flag("-gencode").flag("arch=compute_70,code=sm_70"); - nvcc.flag("-t0"); - #[cfg(not(target_env = "msvc"))] - nvcc.flag("-Xcompiler").flag("-Wno-unused-function"); - nvcc.define("TAKE_RESPONSIBILITY_FOR_ERROR_MESSAGE", None); - #[cfg(feature = "cuda-mobile")] - nvcc.define("NTHREADS", "128"); - if let Some(def) = cc_def { - nvcc.define(def, None); - } +} - if let Some(include) = env::var_os("DEP_BLST_C_SRC") { - nvcc.include(include); - } - if let Some(include) = env::var_os("DEP_SPPARK_ROOT") { - nvcc.include(include); - } - nvcc.clone().file("cuda/bn254.cu").compile("bn256_msm_cuda"); - nvcc.define("__MSM_SORT_DONT_IMPLEMENT__", None) - .file("cuda/grumpkin.cu") - .compile("grumpkin_msm_cuda"); +fn cuda_available() -> bool { + match env::var("NVCC") { + Ok(var) => which::which(var).is_ok(), + Err(_) => which::which("nvcc").is_ok(), + } +} - let mut nvcc = cc::Build::new(); - nvcc.cuda(true); - nvcc.flag("-arch=sm_80"); - nvcc.flag("-gencode").flag("arch=compute_70,code=sm_70"); - nvcc.flag("-t0"); - #[cfg(not(target_env = "msvc"))] - nvcc.flag("-Xcompiler").flag("-Wno-unused-function"); - nvcc.define("TAKE_RESPONSIBILITY_FOR_ERROR_MESSAGE", None); - #[cfg(feature = "cuda-mobile")] - nvcc.define("NTHREADS", "128"); - if let Some(def) = cc_def { - nvcc.define(def, None); - } +fn compile_cuda(file_name: &str, output_name: &str, implement_sort: bool) { + let mut nvcc = cc::Build::new(); + nvcc.cuda(true); + nvcc.flag("-arch=sm_80"); + nvcc.flag("-gencode").flag("arch=compute_70,code=sm_70"); + nvcc.flag("-t0"); + #[cfg(not(target_env = "msvc"))] + nvcc.flag("-Xcompiler").flag("-Wno-unused-function"); + nvcc.define("TAKE_RESPONSIBILITY_FOR_ERROR_MESSAGE", None); + #[cfg(feature = "cuda-mobile")] + nvcc.define("NTHREADS", "128"); - if let Some(include) = env::var_os("DEP_SEMOLINA_C_INCLUDE") { - nvcc.include(include); - } - if let Some(include) = env::var_os("DEP_SPPARK_ROOT") { - nvcc.include(include); - } - nvcc.clone() - .define("__MSM_SORT_DONT_IMPLEMENT__", None) - .file("cuda/pallas.cu") - .compile("pallas_msm_cuda"); - nvcc.define("__MSM_SORT_DONT_IMPLEMENT__", None) - .file("cuda/vesta.cu") - .compile("vesta_msm_cuda"); + if let Some(def) = determine_cc_def(&env::var("CARGO_CFG_TARGET_ARCH").unwrap(), "__CUDA_PORTABLE__") { + nvcc.define(&def, None); + } - println!("cargo:rerun-if-changed=cuda"); - println!("cargo:rerun-if-env-changed=CXXFLAGS"); - println!("cargo:rustc-cfg=feature=\"cuda\""); + if let Some(include) = env::var_os("DEP_BLST_C_SRC") { + nvcc.include(include); } - println!("cargo:rerun-if-env-changed=NVCC"); + if let Some(include) = env::var_os("DEP_SEMOLINA_C_INCLUDE") { + nvcc.include(include); + } + if let Some(include) = env::var_os("DEP_SPPARK_ROOT") { + nvcc.include(include); + } + if implement_sort { + nvcc.file(file_name).compile(output_name); + } else { + nvcc.define("__MSM_SORT_DONT_IMPLEMENT__", None).file(file_name).compile(output_name); + } + }