Skip to content

support building with libgmp as well as num-bigint #152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,22 @@ jobs:
git clone https://github.com/Chia-Network/clvm_tools.git --branch=main --single-branch
python -m pip install ./clvm_tools
python -m pip install colorama
maturin develop --release
git clone https://github.com/Chia-Network/mpir_gc_x64.git --depth 1
maturin develop --release --cargo-extra-args="--features=mpir"

- name: Run benchmarks (Windows)
if: startsWith(matrix.os, 'windows')
run: |
. .\venv\Scripts\Activate.ps1
python benchmark/run-benchmark.py

- name: Install GMP
if: ${{ startsWith(matrix.os, 'ubuntu') }}
run: |
sudo apt install libgmp3-dev
ls -la /usr/lib64
ls -la /usr/lib

- name: Build
if: ${{ !startsWith(matrix.os, 'windows') }}
env:
Expand Down Expand Up @@ -108,6 +116,9 @@ jobs:
run: |
python -m pip install maturin
rustup target add x86_64-unknown-linux-musl
sudo apt install libgmp3-dev
ls -la /usr/lib64
ls -la /usr/lib

- name: Build
env:
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/build-arm64-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ jobs:
curl -L https://sh.rustup.rs > rustup-init.sh && \
sh rustup-init.sh -y && \
yum -y install openssl-devel && \
yum -y install gmp && \
pkg-config --libs gmp && \
source $HOME/.cargo/env && \
rustup target add aarch64-unknown-linux-musl && \
rm -rf venv && \
Expand All @@ -54,7 +56,7 @@ jobs:
if [ ! -f "activate" ]; then ln -s venv/bin/activate; fi && \
. ./activate && \
pip install maturin && \
CC=gcc maturin build --no-sdist --release --strip --manylinux 2014 --cargo-extra-args="--features=openssl" \
CC=gcc maturin build --no-sdist --release --strip --manylinux 2014 --cargo-extra-args="--features=openssl,libgmp10" \
'

- name: Upload artifacts
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/build-crate-and-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
run: cargo +stable fmt -- --files-with-diff --check
- name: clippy (stable)
run: cargo +stable clippy
- name: install GMP
run: sudo apt install libgmp3-dev
- name: tests
run: cargo test && cargo test --release
- name: build
Expand All @@ -56,7 +58,7 @@ jobs:
run: cargo install wasm-pack

- name: wasm-pack build and pack
run: wasm-pack build && wasm-pack pack
run: wasm-pack build --features=num-bigint && wasm-pack pack

- name: Upload npm pkg artifacts
uses: actions/upload-artifact@v2
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/build-m1-wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ jobs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rust.sh
arch -arm64 sh rust.sh -y

- name: install GMP
run: |
curl -L https://gmplib.org/download/gmp/gmp-6.2.1.tar.lz | tar x
cd gmp-6.2.1
./configure --enable-fat --with-pic
make -j 6
sudo make install
cd ..
rm -rf gmp-6.2.1

- name: Build m1 wheels
run: |
arch -arm64 python3 -m venv venv
Expand Down
14 changes: 11 additions & 3 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ jobs:
- name: Build MacOs with maturin on Python ${{ matrix.python }}
if: startsWith(matrix.os, 'macos')
run: |
brew install gmp
python -m venv venv
ln -s venv/bin/activate
. ./activate
Expand All @@ -70,6 +71,8 @@ jobs:
curl -L https://sh.rustup.rs > rustup-init.sh && \
sh rustup-init.sh -y && \
yum -y install openssl-devel && \
yum -y install gmp && \
pkg-config --libs gmp && \
source $HOME/.cargo/env && \
rustup target add x86_64-unknown-linux-musl && \
rm -rf venv && \
Expand All @@ -86,7 +89,7 @@ jobs:
. ./activate && \
pip install --upgrade pip && \
pip install maturin && \
CC=gcc maturin build --no-sdist --release --strip --manylinux 2010 --cargo-extra-args="--features=openssl" \
CC=gcc maturin build --no-sdist --release --strip --manylinux 2010 --cargo-extra-args="--features=openssl,libgmp" \
'

- name: Build Windows with maturin on Python ${{ matrix.python }}
Expand All @@ -95,12 +98,13 @@ jobs:
python -m venv venv
. .\venv\Scripts\Activate.ps1
ln -s venv\Scripts\Activate.ps1 activate
maturin build --no-sdist -i python --release --strip
git clone https://github.com/Chia-Network/mpir_gc_x64.git --depth 1
maturin build --no-sdist -i python --release --strip --cargo-extra-args="--features=mpir"
# this will install into the venv
# it'd be better to use the wheel, but I can't figure out how to do that
# TODO: figure this out
# this does NOT work: pip install target/wheels/clvm_rs-*.whl
maturin develop --release
maturin develop --release --cargo-extra-args="--features=mpir"
# the line above also doesn't seem to work

- name: Install clvm_rs wheel
Expand Down Expand Up @@ -227,6 +231,8 @@ jobs:
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
- name: install GMP
run: sudo apt install libgmp-dev
- name: cargo-fuzz
run: cargo +nightly install cargo-fuzz
- name: build
Expand All @@ -244,5 +250,7 @@ jobs:
with:
toolchain: stable
components: rustfmt, clippy
- name: install GMP
run: sudo apt install libgmp-dev
- name: cargo test
run: cargo test
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ lto = true

[features]
extension-module = ["pyo3/extension-module"]
default = ["extension-module"]
libgmp = []
libgmp3 = []
libgmp10 = []
mpir = []
default = ["extension-module", "libgmp"]

[dependencies]
hex = "=0.4.3"
lazy_static = "=1.4.0"
num-bigint = "=0.4.0"
num-bigint = { version = "0.4.0", optional = true }
num-traits = "=0.2.14"
num-integer = "=0.1.44"
bls12_381 = "=0.5.0"
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Use `maturin` to build the python interface. First, install into current virtual
$ pip install maturin
```

As we need `MPIR` for MSVC builds, prepare this dependency with

```
$ git clone https://github.com/Chia-Network/mpir_gc_x64.git --depth 1
```

Build `clvm_rs` directly into the current virtualenv with

```
Expand Down
24 changes: 24 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::env;

fn main() {
if env::var_os("CARGO_FEATURE_MPIR").is_some() {
println!("cargo:rustc-link-lib=mpir");
println!("cargo:rustc-link-search=mpir_gc_x64");
} else if env::var_os("CARGO_FEATURE_LIBGMP3").is_some() {
println!("cargo:rustc-link-lib=libgmp.so.3");
} else if env::var_os("CARGO_FEATURE_LIBGMP10").is_some() {
println!("cargo:rustc-link-lib=libgmp.so.10");
} else if env::var_os("CARGO_FEATURE_LIBGMP").is_some() {
println!("cargo:rustc-link-lib=gmp");
}

#[cfg(target_os = "linux")]
{
println!("cargo:rustc-link-search=/usr/lib64");
println!("cargo:rustc-link-search=/usr/lib");
}
#[cfg(target_os = "macos")]
{
println!("cargo:rustc-link-search=/opt/homebrew/lib");
}
}
1 change: 1 addition & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ libfuzzer-sys = "0.4"
[dependencies.clvm_rs]
path = ".."
default-features = false
features = ["libgmp", "openssl"]

# Prevent this from interfering with workspaces
[workspace]
Expand Down
7 changes: 4 additions & 3 deletions src/gen/conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,6 @@ use crate::serialize::node_to_bytes;
#[cfg(test)]
use hex::FromHex;
#[cfg(test)]
use num_traits::Num;
#[cfg(test)]
use std::collections::HashMap;

#[cfg(test)]
Expand Down Expand Up @@ -694,6 +692,9 @@ fn test_coin_id(parent_id: &[u8], puzzle_hash: &[u8], amount: u64) -> [u8; 32] {
// (1 (2 (3 ) means: (1 . (2 . (3 . ())))
// and:

#[cfg(test)]
use crate::number_traits::TestNumberTraits;

#[cfg(test)]
fn parse_list_impl(
a: &mut Allocator,
Expand Down Expand Up @@ -730,7 +731,7 @@ fn parse_list_impl(
(a.new_atom(&buf).unwrap(), v.len() + 1)
} else if input.starts_with("-") || "0123456789".contains(input.get(0..1).unwrap()) {
let v = input.split_once(" ").unwrap().0;
let num = Number::from_str_radix(v, 10).unwrap();
let num = Number::from_str_radix(v, 10);
(ptr_from_number(a, &num).unwrap(), v.len() + 1)
} else {
panic!("atom not supported \"{}\"", input);
Expand Down
118 changes: 118 additions & 0 deletions src/gmp_ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#![allow(non_camel_case_types, non_snake_case)]

use core::ptr::NonNull;
use std::ffi::c_void;

#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct mpz_t {
pub alloc: c_int,
pub size: c_int,
pub d: NonNull<c_ulonglong>,
}

type c_int = i32;
type c_long = i64;
type c_ulong = u64;
type c_ulonglong = u64;
type mpz_srcptr = *const mpz_t;
type mpz_ptr = *mut mpz_t;
type bitcnt_t = c_ulong;

extern "C" {
#[link_name = "__gmpz_init"]
pub fn mpz_init(x: mpz_ptr);
#[link_name = "__gmpz_import"]
pub fn mpz_import(
rop: mpz_ptr,
count: usize,
order: c_int,
size: usize,
endian: c_int,
nails: usize,
op: *const c_void,
);
#[link_name = "__gmpz_add_ui"]
pub fn mpz_add_ui(rop: mpz_ptr, op1: mpz_srcptr, op2: c_ulong);
#[link_name = "__gmpz_set"]
pub fn mpz_set(rop: mpz_ptr, op: mpz_srcptr);
#[link_name = "__gmpz_export"]
pub fn mpz_export(
rop: *mut c_void,
countp: *mut usize,
order: c_int,
size: usize,
endian: c_int,
nails: usize,
op: mpz_srcptr,
) -> *mut c_void;
#[link_name = "__gmpz_sizeinbase"]
pub fn mpz_sizeinbase(arg1: mpz_srcptr, arg2: c_int) -> usize;
#[link_name = "__gmpz_fdiv_qr"]
pub fn mpz_fdiv_qr(q: mpz_ptr, r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
#[link_name = "__gmpz_fdiv_q"]
pub fn mpz_fdiv_q(q: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
#[link_name = "__gmpz_fdiv_r"]
pub fn mpz_fdiv_r(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
#[link_name = "__gmpz_fdiv_q_2exp"]
pub fn mpz_fdiv_q_2exp(q: mpz_ptr, n: mpz_srcptr, b: bitcnt_t);
#[link_name = "__gmpz_init_set_ui"]
pub fn mpz_init_set_ui(rop: mpz_ptr, op: c_ulong);
#[link_name = "__gmpz_init_set_si"]
pub fn mpz_init_set_si(rop: mpz_ptr, op: c_long);
#[link_name = "__gmpz_clear"]
pub fn mpz_clear(x: mpz_ptr);
#[link_name = "__gmpz_add"]
pub fn mpz_add(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
#[link_name = "__gmpz_sub"]
pub fn mpz_sub(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
#[link_name = "__gmpz_mul"]
pub fn mpz_mul(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
#[link_name = "__gmpz_mul_2exp"]
pub fn mpz_mul_2exp(rop: mpz_ptr, op1: mpz_srcptr, op2: bitcnt_t);
#[link_name = "__gmpz_get_si"]
pub fn mpz_get_si(op: mpz_srcptr) -> c_long;
#[link_name = "__gmpz_and"]
pub fn mpz_and(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
#[link_name = "__gmpz_ior"]
pub fn mpz_ior(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
#[link_name = "__gmpz_xor"]
pub fn mpz_xor(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
#[link_name = "__gmpz_com"]
pub fn mpz_com(rop: mpz_ptr, op: mpz_srcptr);
#[link_name = "__gmpz_cmp"]
pub fn mpz_cmp(op1: mpz_srcptr, op2: mpz_srcptr) -> c_int;
#[link_name = "__gmpz_cmp_si"]
pub fn mpz_cmp_si(op1: mpz_srcptr, op2: c_long) -> c_int;
#[link_name = "__gmpz_cmp_ui"]
pub fn mpz_cmp_ui(op1: mpz_srcptr, op2: c_ulong) -> c_int;
}

#[cfg(test)]
type c_char = i8;

#[cfg(test)]
extern "C" {
#[link_name = "__gmpz_init_set_str"]
pub fn mpz_init_set_str(rop: mpz_ptr, str: *const c_char, base: c_int) -> c_int;
#[link_name = "__gmpz_get_str"]
pub fn mpz_get_str(str: *mut c_char, base: c_int, op: mpz_srcptr) -> *mut c_char;
}

#[inline]
pub unsafe extern "C" fn mpz_neg(rop: mpz_ptr, op: mpz_srcptr) {
if rop as mpz_srcptr != op {
mpz_set(rop, op);
}
(*rop).size = -(*rop).size;
}

#[inline]
pub unsafe extern "C" fn mpz_get_ui(op: mpz_srcptr) -> c_ulong {
if { (*op).size } != 0 {
let p = (*op).d.as_ptr();
(*p) as c_ulong
} else {
0
}
}
8 changes: 8 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ mod err_utils;
mod gen;
pub mod more_ops;
pub mod node;

#[cfg(not(feature = "num-bigint"))]
mod gmp_ffi;
#[cfg(not(feature = "num-bigint"))]
mod number_gmp;

mod number;
mod number_traits;

mod op_utils;
#[cfg(not(any(test, target_family = "wasm")))]
mod py;
Expand Down
Loading