mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-08 22:28:01 -05:00
141 lines
5.7 KiB
Rust
141 lines
5.7 KiB
Rust
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
|
|
fn main() {
|
|
if let Ok(val) = std::env::var("DOCS_RS") {
|
|
if val.parse::<u32>() == Ok(1) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// This is a workaround to the current nightly toolchain (2024-06-27 which started with
|
|
// toolchain 2024-05-05) build issue
|
|
// Essentially if cbindgen is running, a wrong argument ends up forwarded to the cuda backend
|
|
// "make" command during macro expansions for TFHE-rs C API, crashing make for make < 4.4 and
|
|
// thus crashing the build
|
|
// On the other hand, this speeds up C API build greatly given we don't have macro expansions
|
|
// in the CUDA backend so this skips the second compilation of TFHE-rs for macro inspection by
|
|
// cbindgen
|
|
if std::env::var("_CBINDGEN_IS_RUNNING").is_ok() {
|
|
return;
|
|
}
|
|
|
|
println!("Build tfhe-cuda-backend");
|
|
println!("cargo::rerun-if-changed=cuda/include");
|
|
println!("cargo::rerun-if-changed=cuda/src");
|
|
println!("cargo::rerun-if-changed=cuda/tests_and_benchmarks");
|
|
println!("cargo::rerun-if-changed=cuda/CMakeLists.txt");
|
|
println!("cargo::rerun-if-changed=src");
|
|
|
|
if std::env::consts::OS == "linux" {
|
|
let output = Command::new("./get_os_name.sh").output().unwrap();
|
|
let distribution = String::from_utf8(output.stdout).unwrap();
|
|
if distribution != "Ubuntu\n" {
|
|
println!(
|
|
"cargo:warning=This Linux distribution is not officially supported. \
|
|
Only Ubuntu is supported by tfhe-cuda-backend at this time. Build may fail\n"
|
|
);
|
|
}
|
|
|
|
let mut cmake_config = cmake::Config::new("cuda");
|
|
|
|
// Conditionally pass the "MULTI_ARCH" variable to CMake if the feature is enabled
|
|
if cfg!(feature = "experimental-multi-arch") {
|
|
cmake_config.define("MULTI_ARCH", "ON");
|
|
} else {
|
|
cmake_config.define("MULTI_ARCH", "OFF");
|
|
}
|
|
// Conditionally pass the "USE_NVTOOLS" variable to CMake if the feature is enabled
|
|
if cfg!(feature = "profile") {
|
|
cmake_config.define("USE_NVTOOLS", "ON");
|
|
} else {
|
|
cmake_config.define("USE_NVTOOLS", "OFF");
|
|
}
|
|
|
|
if cfg!(feature = "debug") {
|
|
cmake_config.define("CMAKE_BUILD_TYPE", "Debug");
|
|
} else if cfg!(feature = "debug-fake-multi-gpu") {
|
|
cmake_config.define("CMAKE_BUILD_TYPE", "DebugOnlyCpu");
|
|
cmake_config.define("CMAKE_VERBOSE_MAKEFILE", "ON");
|
|
cmake_config.define("FAKE_MULTI_GPU", "ON");
|
|
}
|
|
|
|
// Build the CMake project
|
|
let dest = cmake_config.build();
|
|
println!("cargo:rustc-link-search=native={}", dest.display());
|
|
println!("cargo:rustc-link-lib=static=tfhe_cuda_backend");
|
|
|
|
// Try to find the cuda libs with pkg-config, default to the path used by the nvidia runfile
|
|
if pkg_config::Config::new()
|
|
.atleast_version("10")
|
|
.probe("cuda")
|
|
.is_err()
|
|
{
|
|
println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64");
|
|
}
|
|
println!("cargo:rustc-link-lib=gomp");
|
|
println!("cargo:rustc-link-lib=cudart");
|
|
println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu/");
|
|
println!("cargo:rustc-link-lib=stdc++");
|
|
|
|
let header_path = "wrapper.h";
|
|
let headers = vec![
|
|
"wrapper.h",
|
|
"cuda/include/ciphertext.h",
|
|
"cuda/include/integer/compression/compression.h",
|
|
"cuda/include/integer/integer.h",
|
|
"cuda/include/aes/aes.h",
|
|
"cuda/include/zk/zk.h",
|
|
"cuda/include/keyswitch/keyswitch.h",
|
|
"cuda/include/keyswitch/ks_enums.h",
|
|
"cuda/include/linear_algebra.h",
|
|
"cuda/include/fft/fft128.h",
|
|
"cuda/include/pbs/programmable_bootstrap.h",
|
|
"cuda/include/pbs/programmable_bootstrap_multibit.h",
|
|
];
|
|
let out_path = PathBuf::from("src").join("bindings.rs");
|
|
let bindings_modified = if out_path.exists() {
|
|
std::fs::metadata(&out_path).unwrap().modified().unwrap()
|
|
} else {
|
|
std::time::SystemTime::UNIX_EPOCH // If bindings file doesn't exist, consider it older
|
|
};
|
|
let mut headers_modified = bindings_modified;
|
|
for header in headers {
|
|
println!("cargo:rerun-if-changed={header}");
|
|
// Check modification times
|
|
let header_modified = std::fs::metadata(header).unwrap().modified().unwrap();
|
|
if header_modified > headers_modified {
|
|
headers_modified = header_modified;
|
|
}
|
|
}
|
|
|
|
// Regenerate bindings only if header has been modified
|
|
if headers_modified > bindings_modified {
|
|
let bindings = bindgen::Builder::default()
|
|
.header(header_path)
|
|
// allow only what we are interested in, the custom types appearing in the interface
|
|
.allowlist_type("PBS_TYPE")
|
|
.allowlist_type("SHIFT_OR_ROTATE_TYPE")
|
|
// and the functions reachable from the headers included in wrapper.h
|
|
.allowlist_function(".*")
|
|
.clang_arg("-x")
|
|
.clang_arg("c++")
|
|
.clang_arg("-std=c++17")
|
|
.clang_arg("-I/usr/include")
|
|
.clang_arg("-I/usr/local/include")
|
|
.ctypes_prefix("ffi")
|
|
.raw_line("use crate::ffi;")
|
|
.generate()
|
|
.expect("Unable to generate bindings");
|
|
|
|
bindings
|
|
.write_to_file(&out_path)
|
|
.expect("Couldn't write bindings!");
|
|
}
|
|
} else {
|
|
panic!(
|
|
"Error: platform not supported, tfhe-cuda-backend not built (only Linux is supported)"
|
|
);
|
|
}
|
|
}
|