ec_gpu_gen/
lib.rs

1#![warn(missing_docs)]
2//! CUDA/OpenCL code generator for finite-field arithmetic over prime fields and elliptic curve
3//! arithmetic constructed with Rust.
4//!
5//! There is also support for Fast Fourier Transform and Multiexponentiation.
6//!
7//! This crate usually creates GPU kernels at compile-time. CUDA generates a [fatbin], which OpenCL only generates the source code, which is then compiled at run-time.
8//!
9//! In order to make things easier to use, there are helper functions available. You would put some code into `build.rs`, that generates the kernels, and some code into your library which then consumes those generated kernels. The kernels will be directly embedded into your program/library. If something goes wrong, you will get an error at compile-time.
10//!
11//! In this example we will make use of the FFT functionality. Add to your `build.rs`:
12//!
13//! ```no_run
14//! use blstrs::Scalar;
15//! use ec_gpu_gen::SourceBuilder;
16//!
17//! let source_builder = SourceBuilder::new().add_fft::<Scalar>();
18//! ec_gpu_gen::generate(&source_builder);
19//! ```
20//!
21//! The `ec_gpu_gen::generate()` takes care of the actual code generation/compilation. It will automatically create a CUDA and/or OpenCL kernel. It will define two environment variables, which are meant for internal use. `_EC_GPU_CUDA_KERNEL_FATBIN` that points to the compiled CUDA kernel, and `_EC_GPU_OPENCL_KERNEL_SOURCE` that points to the generated OpenCL source.
22//!
23//! Those variables are then picked up by the `ec_gpu_gen::program!()` macro, which generates a program, for a given GPU device. Using FFT within your library would then look like this:
24//!
25//! ```no_compile
26//! use blstrs::Scalar;
27//! use ec_gpu_gen::{
28//!     rust_gpu_tools::Device,
29//! };
30//!
31//! let devices = Device::all();
32//! let programs = devices
33//!     .iter()
34//!     .map(|device| ec_gpu_gen::program!(device))
35//!     .collect::<Result<_, _>>()
36//!     .expect("Cannot create programs!");
37//!
38//! let mut kern = FftKernel::<Scalar>::create(programs).expect("Cannot initialize kernel!");
39//! kern.radix_fft_many(&mut [&mut coeffs], &[omega], &[log_d]).expect("GPU FFT failed!");
40//! ```
41//!
42//! Feature flags
43//! -------------
44//!
45//! CUDA and OpenCL are supprted, each be enabled with the `cuda` and `opencl` [feature flags].
46//!
47//! [fatbin]: https://en.wikipedia.org/wiki/Fat_binary#Heterogeneous_computing
48//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
49mod error;
50#[cfg(any(feature = "cuda", feature = "opencl"))]
51mod program;
52mod source;
53
54/// Fast Fourier Transform on the GPU.
55#[cfg(any(feature = "cuda", feature = "opencl"))]
56pub mod fft;
57/// Fast Fourier Transform on the CPU.
58pub mod fft_cpu;
59/// Multiexponentiation on the GPU.
60#[cfg(any(feature = "cuda", feature = "opencl"))]
61pub mod multiexp;
62/// Multiexponentiation on the CPU.
63pub mod multiexp_cpu;
64/// Helpers for multithreaded code.
65pub mod threadpool;
66
67/// Re-export rust-gpu-tools as things like [`rust_gpu_tools::Device`] might be needed.
68#[cfg(any(feature = "cuda", feature = "opencl"))]
69pub use rust_gpu_tools;
70
71pub use error::{EcError, EcResult};
72pub use source::{generate, SourceBuilder};