refactor C++ examples to work with install-dir, or build from source and choose device

This commit is contained in:
Yuval Shekel
2024-07-28 19:27:41 +03:00
parent 131e22d3c6
commit 5d821d3db1
25 changed files with 587 additions and 267 deletions

View File

@@ -24,12 +24,42 @@ jobs:
check-changed-files:
uses: ./.github/workflows/check-changed-files.yml
extract-cuda-backend-branch:
name: Extract cuda branch name
runs-on: ubuntu-22.04
outputs:
cuda-backend-branch: ${{ steps.extract.outputs.cuda-backend-branch }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Extract Private Branch from PR Description
id: extract
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DESCRIPTION=$(gh pr view ${{ github.event.pull_request.number }} --json body -q '.body')
echo "PR Description: $DESCRIPTION"
CUDA_BE_BRANCH=$(echo "$DESCRIPTION" | grep -oP 'cuda-backend-branch:\s*\K[^\s]+') || true
if [ -z "$CUDA_BE_BRANCH" ]; then
CUDA_BE_BRANCH="main" # Default branch if not specified
fi
echo "Extracted CUDA Backend Branch: $CUDA_BE_BRANCH"
echo "::set-output name=cuda-backend-branch::$CUDA_BE_BRANCH"
run-examples:
runs-on: [self-hosted, Linux, X64, icicle, examples]
runs-on: [self-hosted, Linux, X64, icicle, examples, extract-cuda-backend-branch]
needs: check-changed-files
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout CUDA Backend
uses: actions/checkout@v4
with:
repository: ingonyama-zk/icicle-cuda-backend
path: ./icicle_v3/backend/cuda
token: ${{ secrets.GITHUB_TOKEN }}
ssh-key: ${{ secrets.CUDA_PULL_KEY }}
ref: ${{ needs.extract-branch.outputs.cuda-backend-branch }}
- name: c++ examples
working-directory: ./examples/c++
if: needs.check-changed-files.outputs.cpp_cuda == 'true' || needs.check-changed-files.outputs.examples == 'true'
@@ -38,9 +68,8 @@ jobs:
for dir in $(find . -mindepth 1 -maxdepth 1 -type d); do
if [ -d "$dir" ]; then
echo "Running command in $dir"
cd $dir
./compile.sh
./run.sh
cd $dir
./run.sh -d CUDA
cd -
fi
done

View File

@@ -23,11 +23,13 @@ Typically, you concurrently
## Running the example
To change the default curve BN254, edit `compile.sh` and `CMakeLists.txt`
To change the default curve BN254, edit `run.sh` and `CMakeLists.txt`
```sh
./compile.sh
./run.sh
# for CPU
./run.sh -d CPU
# for CUDA
./run.sh -d CUDA -b /path/to/cuda/backend/install/dir
```
To compare with ICICLE baseline (i.e. non-concurrent) NTT, you can run [this example](../ntt/README.md).

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example -DBACKEND_DIR=$(realpath "build/icicle/backend")
else
echo "building icicle without CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
fi
cmake --build build/icicle -j
cmake --build build/example -j

View File

@@ -1,2 +1,65 @@
#!/bin/bash
./build/example/example
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage information
show_help() {
echo "Usage: $0 [-d DEVICE_TYPE] [-b BACKEND_INSTALL_DIR]"
echo
echo "Options:"
echo " -d DEVICE_TYPE Specify the device type (default: CPU)"
echo " -b BACKEND_INSTALL_DIR Specify the backend installation directory (default: empty)"
echo " -h Show this help message"
exit 0
}
# Parse command line options
while getopts ":d:b:h" opt; do
case ${opt} in
d )
DEVICE_TYPE=$OPTARG
;;
b )
BACKEND_INSTALL_DIR="$(realpath ${OPTARG})"
;;
h )
show_help
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
show_help
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
show_help
;;
esac
done
# Set default values if not provided
: "${DEVICE_TYPE:=CPU}"
: "${BACKEND_INSTALL_DIR:=}"
# Create necessary directories
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ "$DEVICE_TYPE" == "CUDA" ] && [ ! -d "${BACKEND_INSTALL_DIR}" ] && [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "Building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
BACKEND_INSTALL_DIR=$(realpath "build/icicle/backend")
else
echo "Building icicle without CUDA backend, BACKEND_INSTALL_DIR=${BACKEND_INSTALL_DIR}"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -S "${ICILE_DIR}" -B build/icicle
fi
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
cmake --build build/icicle -j
cmake --build build/example -j
./build/example/example "$DEVICE_TYPE" "$BACKEND_INSTALL_DIR"

View File

@@ -12,10 +12,11 @@ using FpMilliseconds = std::chrono::duration<float, std::chrono::milliseconds::p
// Load and choose backend
void try_load_and_set_backend_device(int argc = 0, char** argv = nullptr)
{
#ifdef BACKEND_DIR
std::cout << "Trying to load and backend device" << std::endl;
ICICLE_CHECK(icicle_load_backend(BACKEND_DIR, true));
#endif
if (argc > 2 && 0 != strcmp(argv[2], "")) {
const char* backend_install_dir = argv[2];
std::cout << "Trying to load and backend device from " << backend_install_dir << std::endl;
ICICLE_CHECK(icicle_load_backend(backend_install_dir, true));
}
const char* selected_device = argc > 1 ? argv[1] : nullptr;
if (selected_device) {

View File

@@ -32,9 +32,12 @@ The configuration is passed to the kernel as a structure of type `MSMConfig`. So
## Running the example
- `cd` to your example directory
- compile with `./compile.sh`
- run with `./run.sh`
```sh
# for CPU
./run.sh -d CPU
# for CUDA
./run.sh -d CUDA -b /path/to/cuda/backend/install/dir
```
## What's in the example

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DG2=ON -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example -DBACKEND_DIR=$(realpath "build/icicle/backend")
else
echo "building icicle without CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DG2=ON -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
fi
cmake --build build/icicle -j
cmake --build build/example -j

View File

@@ -1,2 +1,65 @@
#!/bin/bash
./build/example/example $1
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage information
show_help() {
echo "Usage: $0 [-d DEVICE_TYPE] [-b BACKEND_INSTALL_DIR]"
echo
echo "Options:"
echo " -d DEVICE_TYPE Specify the device type (default: CPU)"
echo " -b BACKEND_INSTALL_DIR Specify the backend installation directory (default: empty)"
echo " -h Show this help message"
exit 0
}
# Parse command line options
while getopts ":d:b:h" opt; do
case ${opt} in
d )
DEVICE_TYPE=$OPTARG
;;
b )
BACKEND_INSTALL_DIR="$(realpath ${OPTARG})"
;;
h )
show_help
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
show_help
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
show_help
;;
esac
done
# Set default values if not provided
: "${DEVICE_TYPE:=CPU}"
: "${BACKEND_INSTALL_DIR:=}"
# Create necessary directories
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ "$DEVICE_TYPE" == "CUDA" ] && [ ! -d "${BACKEND_INSTALL_DIR}" ] && [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "Building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DG2=ON -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
BACKEND_INSTALL_DIR=$(realpath "build/icicle/backend")
else
echo "Building icicle without CUDA backend, BACKEND_INSTALL_DIR=${BACKEND_INSTALL_DIR}"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DG2=ON -S "${ICILE_DIR}" -B build/icicle
fi
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
cmake --build build/icicle -j
cmake --build build/example -j
./build/example/example "$DEVICE_TYPE" "$BACKEND_INSTALL_DIR"

View File

@@ -24,9 +24,12 @@ bn254_ntt(input.get(), ntt_size, NTTDir::kForward, config, output.get())
## Running the example
- `cd` to your example directory
- compile with `./compile.sh`
- run with `./run.sh`
```sh
# for CPU
./run.sh -d CPU
# for CUDA
./run.sh -d CUDA -b /path/to/cuda/backend/install/dir
```
## What's in the example

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example -DBACKEND_DIR=$(realpath "build/icicle/backend")
else
echo "building icicle without CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
fi
cmake --build build/icicle -j
cmake --build build/example -j

View File

@@ -1,2 +1,65 @@
#!/bin/bash
./build/example/example $1
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage information
show_help() {
echo "Usage: $0 [-d DEVICE_TYPE] [-b BACKEND_INSTALL_DIR]"
echo
echo "Options:"
echo " -d DEVICE_TYPE Specify the device type (default: CPU)"
echo " -b BACKEND_INSTALL_DIR Specify the backend installation directory (default: empty)"
echo " -h Show this help message"
exit 0
}
# Parse command line options
while getopts ":d:b:h" opt; do
case ${opt} in
d )
DEVICE_TYPE=$OPTARG
;;
b )
BACKEND_INSTALL_DIR="$(realpath ${OPTARG})"
;;
h )
show_help
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
show_help
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
show_help
;;
esac
done
# Set default values if not provided
: "${DEVICE_TYPE:=CPU}"
: "${BACKEND_INSTALL_DIR:=}"
# Create necessary directories
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ "$DEVICE_TYPE" == "CUDA" ] && [ ! -d "${BACKEND_INSTALL_DIR}" ] && [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "Building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
BACKEND_INSTALL_DIR=$(realpath "build/icicle/backend")
else
echo "Building icicle without CUDA backend, BACKEND_INSTALL_DIR=${BACKEND_INSTALL_DIR}"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -S "${ICILE_DIR}" -B build/icicle
fi
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
cmake --build build/icicle -j
cmake --build build/example -j
./build/example/example "$DEVICE_TYPE" "$BACKEND_INSTALL_DIR"

View File

@@ -10,10 +10,12 @@ An example of MSM is [here](../msm/README.md).
## Running the example
- `cd` to your example directory
- compile with `./compile.sh`
- run with `./run.sh`
```sh
# for CPU
./run.sh -d CPU
# for CUDA
./run.sh -d CUDA -b /path/to/cuda/backend/install/dir
```
## Concise Explanation
We recommend this simple [explanation](https://www.rareskills.io/post/pedersen-commitment).

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example -DBACKEND_DIR=$(realpath "build/icicle/backend")
else
echo "building icicle without CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
fi
cmake --build build/icicle -j
cmake --build build/example -j

View File

@@ -1,2 +1,65 @@
#!/bin/bash
./build/example/example $1
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage information
show_help() {
echo "Usage: $0 [-d DEVICE_TYPE] [-b BACKEND_INSTALL_DIR]"
echo
echo "Options:"
echo " -d DEVICE_TYPE Specify the device type (default: CPU)"
echo " -b BACKEND_INSTALL_DIR Specify the backend installation directory (default: empty)"
echo " -h Show this help message"
exit 0
}
# Parse command line options
while getopts ":d:b:h" opt; do
case ${opt} in
d )
DEVICE_TYPE=$OPTARG
;;
b )
BACKEND_INSTALL_DIR="$(realpath ${OPTARG})"
;;
h )
show_help
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
show_help
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
show_help
;;
esac
done
# Set default values if not provided
: "${DEVICE_TYPE:=CPU}"
: "${BACKEND_INSTALL_DIR:=}"
# Create necessary directories
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ "$DEVICE_TYPE" == "CUDA" ] && [ ! -d "${BACKEND_INSTALL_DIR}" ] && [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "Building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
BACKEND_INSTALL_DIR=$(realpath "build/icicle/backend")
else
echo "Building icicle without CUDA backend, BACKEND_INSTALL_DIR=${BACKEND_INSTALL_DIR}"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -S "${ICILE_DIR}" -B build/icicle
fi
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
cmake --build build/icicle -j
cmake --build build/example -j
./build/example/example "$DEVICE_TYPE" "$BACKEND_INSTALL_DIR"

View File

@@ -9,9 +9,10 @@ Polynomials are crucial for Zero-Knowledge Proofs (ZKPs): they enable efficient
To run example, from project root directory:
```sh
cd examples/c++/polynomial-api
./compile.sh
./run.sh
# for CPU
./run.sh -d CPU
# for CUDA
./run.sh -d CUDA -b /path/to/cuda/backend/install/dir
```
To change the scalar field, modify `compile.h` to build the corresponding lib and `CMakeLists.txt` to link to that lib and set `FIELD_ID` correspondingly.

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example -DBACKEND_DIR=$(realpath "build/icicle/backend")
else
echo "building icicle without CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
fi
cmake --build build/icicle -j
cmake --build build/example -j

View File

@@ -21,27 +21,28 @@ const auto four = scalar_t::from(4);
const auto five = scalar_t::from(5);
const auto minus_one = zero - one;
static std::unique_ptr<scalar_t[]> generate_pows(scalar_t tau, uint32_t size){
auto vec = std::make_unique<scalar_t[]>(size);
vec[0] = scalar_t::one();
for (size_t i = 1; i < size; ++i) {
vec[i] = vec[i-1] * tau;
static std::unique_ptr<scalar_t[]> generate_pows(scalar_t tau, uint32_t size)
{
auto vec = std::make_unique<scalar_t[]>(size);
vec[0] = scalar_t::one();
for (size_t i = 1; i < size; ++i) {
vec[i] = vec[i - 1] * tau;
}
return std::move(vec);
}
static std::unique_ptr<affine_t[]> generate_SRS(uint32_t size) {
static std::unique_ptr<affine_t[]> generate_SRS(uint32_t size)
{
auto secret_scalar = scalar_t::rand_host();
auto gen = projective_t::generator();
auto pows_of_tau = generate_pows(secret_scalar,size);
auto pows_of_tau = generate_pows(secret_scalar, size);
auto SRS = std::make_unique<affine_t[]>(size);
for (size_t i = 0; i < size; ++i) {
SRS[i] = projective_t::to_affine(pows_of_tau[i] * gen);
SRS[i] = projective_t::to_affine(pows_of_tau[i] * gen);
}
return std::move(SRS);
}
void example_evaluate()
{
std::cout << std::endl << "Example: Polynomial evaluation on random value" << std::endl;
@@ -319,110 +320,108 @@ void example_device_memory_view()
ntt(d_coeffs.get(), size, NTTDir::kForward, ntt_config, coset_evals.get());
}
void example_commit_with_device_memory_view()
{
//declare time vars
// declare time vars
std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
std::chrono::milliseconds duration;
std::cout << std::endl << "Example: a) commit with Polynomial views [(f1+f2)^2 + (f1-f2)^2 ]_1 = [4 (f1^2+ f_2^2)]_1" << std::endl;
std::cout<< "Example: b) commit with Polynomial views [(f1+f2)^2 - (f1-f2)^2 ]_1 = [4 f1 *f_2]_1" << std::endl;
std::cout << std::endl
<< "Example: a) commit with Polynomial views [(f1+f2)^2 + (f1-f2)^2 ]_1 = [4 (f1^2+ f_2^2)]_1" << std::endl;
std::cout << "Example: b) commit with Polynomial views [(f1+f2)^2 - (f1-f2)^2 ]_1 = [4 f1 *f_2]_1" << std::endl;
int N = 1025;
//generate group elements string of length N: (1, beta,beta^2....,beta^{N-1}). g
// generate group elements string of length N: (1, beta,beta^2....,beta^{N-1}). g
std::cout << "Setup: Generating mock SRS" << std::endl;
start = std::chrono::high_resolution_clock::now();
auto SRS = generate_SRS(2*N);
//Allocate memory on device (points)
auto SRS = generate_SRS(2 * N);
// Allocate memory on device (points)
affine_t* points_d;
ICICLE_CHECK(icicle_malloc((void**)&points_d, sizeof(affine_t)* 2 * N));
ICICLE_CHECK(icicle_malloc((void**)&points_d, sizeof(affine_t) * 2 * N));
// copy SRS to device (could have generated on device, but gives an indicator)
ICICLE_CHECK(icicle_copy(points_d, SRS.get(), sizeof(affine_t)* 2 * N));
ICICLE_CHECK(icicle_copy(points_d, SRS.get(), sizeof(affine_t) * 2 * N));
end = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Setup: SRS of length "<< N << " generated and loaded to device. Took: " << duration.count() << " milliseconds" << std::endl;
//goal:
//test commitment equality [(f1+f2)^2 + (f1-f2)^2 ]_1 = [4 (f1^2+ f_2^2)]_1
//test commitment equality [(f1+f2)^2 - (f1-f2)^2 ]_1 = [4 f1 *f_2]_1
//note: using polyapi to gen scalars: already on device.
std::cout << "Setup: Generating polys (on device) f1,f2 of log degree " << log2(N-1) << std::endl;
std::cout << "Setup: SRS of length " << N << " generated and loaded to device. Took: " << duration.count()
<< " milliseconds" << std::endl;
// goal:
// test commitment equality [(f1+f2)^2 + (f1-f2)^2 ]_1 = [4 (f1^2+ f_2^2)]_1
// test commitment equality [(f1+f2)^2 - (f1-f2)^2 ]_1 = [4 f1 *f_2]_1
// note: using polyapi to gen scalars: already on device.
std::cout << "Setup: Generating polys (on device) f1,f2 of log degree " << log2(N - 1) << std::endl;
start = std::chrono::high_resolution_clock::now();
auto f1 = randomize_polynomial(N);
auto f2 = randomize_polynomial(N);
end = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Setup: Gen poly done. Took: " << duration.count() << " milliseconds" << std::endl;
//deg 2N constraints (f1+f2)^2 + (f1-f2)^2 = 2 (f1^2+ f_2^2)
std::cout << "Computing constraints..start "<< std::endl;
// deg 2N constraints (f1+f2)^2 + (f1-f2)^2 = 2 (f1^2+ f_2^2)
std::cout << "Computing constraints..start " << std::endl;
start = std::chrono::high_resolution_clock::now();
auto L1 = (f1+f2)*(f1+f2) + (f1-f2)*(f1-f2);
auto R1 = scalar_t::from(2) * (f1*f1 + f2*f2);
//deg 2N constraints (f1+f2)^2 - (f1-f2)^2 = 4 f1 *f_2
auto L2 = (f1+f2)*(f1+f2) - (f1-f2)*(f1-f2);
auto L1 = (f1 + f2) * (f1 + f2) + (f1 - f2) * (f1 - f2);
auto R1 = scalar_t::from(2) * (f1 * f1 + f2 * f2);
// deg 2N constraints (f1+f2)^2 - (f1-f2)^2 = 4 f1 *f_2
auto L2 = (f1 + f2) * (f1 + f2) - (f1 - f2) * (f1 - f2);
auto R2 = scalar_t::from(4) * f1 * f2;
end = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Computing constraints..done. Took: " << duration.count() << " milliseconds"<< std::endl;
std::cout << "Computing constraints..done. Took: " << duration.count() << " milliseconds" << std::endl;
// extract coeff using coeff view
auto [viewL1, sizeL1] = L1.get_coefficients_view();
auto [viewL2, sizeL2] = L2.get_coefficients_view();
auto [viewL2, sizeL2] = L2.get_coefficients_view();
auto [viewR1, sizeR1] = R1.get_coefficients_view();
auto [viewR2, sizeR2] = R2.get_coefficients_view();
std::cout << "Computing Commitments with poly view"<< std::endl;
std::cout << "Computing Commitments with poly view" << std::endl;
start = std::chrono::high_resolution_clock::now();
MSMConfig config = default_msm_config();
config.are_points_on_device = true;
config.are_scalars_on_device = true;
//host vars (for result)
// host vars (for result)
projective_t hL1{}, hL2{}, hR1{}, hR2{};
//straightforward msm bn254 api: no batching
msm(viewL1.get(),points_d,N,config,&hL1);
msm(viewL2.get(),points_d,N,config,&hL2);
msm(viewR1.get(),points_d,N,config,&hR1);
msm(viewR2.get(),points_d,N,config,&hR2);
// straightforward msm bn254 api: no batching
msm(viewL1.get(), points_d, N, config, &hL1);
msm(viewL2.get(), points_d, N, config, &hL2);
msm(viewR1.get(), points_d, N, config, &hR1);
msm(viewR2.get(), points_d, N, config, &hR2);
end = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Commitments done. Took: " << duration.count() << " milliseconds"<< std::endl;
//sanity checks
std::cout << "Commitments done. Took: " << duration.count() << " milliseconds" << std::endl;
// sanity checks
auto affL1 = projective_t::to_affine(hL1);
auto affR1 = projective_t::to_affine(hR1);
auto affL2 = projective_t::to_affine(hL2);
auto affR2 = projective_t::to_affine(hR2);
//test commitment equality [(f1+f2)^2 + (f1-f2)^2]_1 = [4 (f_1^2+f_2^2]_1
assert(affL1.x==affR1.x && affL1.y==affR1.y);
std::cout << "commitment [(f1+f2)^2 + (f1-f2)^2]_1:" << std::endl;
// test commitment equality [(f1+f2)^2 + (f1-f2)^2]_1 = [4 (f_1^2+f_2^2]_1
assert(affL1.x == affR1.x && affL1.y == affR1.y);
std::cout << "commitment [(f1+f2)^2 + (f1-f2)^2]_1:" << std::endl;
std::cout << "[x: " << affL1.x << ", y: " << affL1.y << "]" << std::endl;
std::cout << "commitment [[2 (f_1^2+f_2^2]_1:" <<std::endl;
std::cout << "commitment [[2 (f_1^2+f_2^2]_1:" << std::endl;
std::cout << "[x: " << affR1.x << ", y: " << affR1.y << "]" << std::endl;
assert(affL2.x==affR2.x && affL2.y==affR2.y);
std::cout << "commitment [(f1+f2)^2 - (f1-f2)^2]_1:"<< std::endl;
assert(affL2.x == affR2.x && affL2.y == affR2.y);
std::cout << "commitment [(f1+f2)^2 - (f1-f2)^2]_1:" << std::endl;
std::cout << "[x: " << affL2.x << ", y: " << affL2.y << "]" << std::endl;
std::cout << "commitment [4 f_1*f_2]_1:"<<std::endl;
std::cout << "commitment [4 f_1*f_2]_1:" << std::endl;
std::cout << "[x: " << affR2.x << ", y: " << affR2.y << "]" << std::endl;
}
int main(int argc, char** argv)
{
try_load_and_set_backend_device(argc, argv);
static const int MAX_NTT_LOG_SIZE = 24;
const scalar_t basic_root = scalar_t::omega(MAX_NTT_LOG_SIZE);
ntt_init_domain(basic_root, default_ntt_init_domain_config());
try_load_and_set_backend_device(argc, argv);
static const int MAX_NTT_LOG_SIZE = 24;
const scalar_t basic_root = scalar_t::omega(MAX_NTT_LOG_SIZE);
ntt_init_domain(basic_root, default_ntt_init_domain_config());
START_TIMER(polyapi);

View File

@@ -1,2 +1,65 @@
#!/bin/bash
./build/example/example $1
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage information
show_help() {
echo "Usage: $0 [-d DEVICE_TYPE] [-b BACKEND_INSTALL_DIR]"
echo
echo "Options:"
echo " -d DEVICE_TYPE Specify the device type (default: CPU)"
echo " -b BACKEND_INSTALL_DIR Specify the backend installation directory (default: empty)"
echo " -h Show this help message"
exit 0
}
# Parse command line options
while getopts ":d:b:h" opt; do
case ${opt} in
d )
DEVICE_TYPE=$OPTARG
;;
b )
BACKEND_INSTALL_DIR="$(realpath ${OPTARG})"
;;
h )
show_help
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
show_help
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
show_help
;;
esac
done
# Set default values if not provided
: "${DEVICE_TYPE:=CPU}"
: "${BACKEND_INSTALL_DIR:=}"
# Create necessary directories
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ "$DEVICE_TYPE" == "CUDA" ] && [ ! -d "${BACKEND_INSTALL_DIR}" ] && [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "Building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
BACKEND_INSTALL_DIR=$(realpath "build/icicle/backend")
else
echo "Building icicle without CUDA backend, BACKEND_INSTALL_DIR=${BACKEND_INSTALL_DIR}"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -S "${ICILE_DIR}" -B build/icicle
fi
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
cmake --build build/icicle -j
cmake --build build/example -j
./build/example/example "$DEVICE_TYPE" "$BACKEND_INSTALL_DIR"

View File

@@ -14,9 +14,12 @@ Icicle provides polynomial multiplication using the Number Theoretical Transform
## Running the example
- `cd` to your example directory
- compile with `./compile.sh`
- run with `./run.sh`
```sh
# for CPU
./run.sh -d CPU
# for CUDA
./run.sh -d CUDA -b /path/to/cuda/backend/install/dir
```
## What's in the example

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example -DBACKEND_DIR=$(realpath "build/icicle/backend")
else
echo "building icicle without CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
fi
cmake --build build/icicle -j
cmake --build build/example -j

View File

@@ -30,23 +30,12 @@ void incremental_values(scalar_t* res, uint32_t count)
int main(int argc, char** argv)
{
try_load_and_set_backend_device(argc - 1, argv + 1);
try_load_and_set_backend_device(argc, argv);
int NTT_LOG_SIZE = 18;
int NTT_LOG_SIZE = 20;
int NTT_SIZE = 1 << NTT_LOG_SIZE;
// init domain
auto ntt_config = default_ntt_config<scalar_t>();
ConfigExtension ntt_cfg_ext;
ntt_config.ext = &ntt_cfg_ext;
if (argc > 1) {
int ntt_algorithm = atoi(argv[1]);
ICICLE_ASSERT(ntt_algorithm >= 1 && ntt_algorithm <= 2) << "Invalid ntt-algorithm index";
ntt_cfg_ext.set("ntt_algorithm", ntt_algorithm);
const char* ntt_algorithm_str = ntt_algorithm == 1 ? "Radix-2" : "Mixed-Radix";
std::cout << "Polynomial multiplication with " << ntt_algorithm_str << " NTT: ";
}
scalar_t basic_root = scalar_t::omega(NTT_LOG_SIZE);
bn254_ntt_init_domain(&basic_root, default_ntt_init_domain_config());
@@ -71,6 +60,7 @@ int main(int argc, char** argv)
START_TIMER(poly_multiply)
// (3) NTT for A,B from host memory to device-memory
auto ntt_config = default_ntt_config<scalar_t>();
ntt_config.are_inputs_on_device = false;
ntt_config.are_outputs_on_device = true;
ntt_config.ordering = Ordering::kNM;
@@ -94,7 +84,7 @@ int main(int argc, char** argv)
ntt_config.ordering = Ordering::kMN;
ICICLE_CHECK(bn254_ntt(d_polyRes, NTT_SIZE, NTTDir::kInverse, ntt_config, d_polyRes));
if (print) { END_TIMER(poly_multiply, ""); }
if (print) { END_TIMER(poly_multiply, "polynomial multiplication took"); }
ICICLE_CHECK(icicle_free(d_polyA));
ICICLE_CHECK(icicle_free(d_polyB));

View File

@@ -1,3 +1,65 @@
#!/bin/bash
./build/example/example 1 $1 # radix2
./build/example/example 2 $1 # mixed-radix
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage information
show_help() {
echo "Usage: $0 [-d DEVICE_TYPE] [-b BACKEND_INSTALL_DIR]"
echo
echo "Options:"
echo " -d DEVICE_TYPE Specify the device type (default: CPU)"
echo " -b BACKEND_INSTALL_DIR Specify the backend installation directory (default: empty)"
echo " -h Show this help message"
exit 0
}
# Parse command line options
while getopts ":d:b:h" opt; do
case ${opt} in
d )
DEVICE_TYPE=$OPTARG
;;
b )
BACKEND_INSTALL_DIR="$(realpath ${OPTARG})"
;;
h )
show_help
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
show_help
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
show_help
;;
esac
done
# Set default values if not provided
: "${DEVICE_TYPE:=CPU}"
: "${BACKEND_INSTALL_DIR:=}"
# Create necessary directories
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ "$DEVICE_TYPE" == "CUDA" ] && [ ! -d "${BACKEND_INSTALL_DIR}" ] && [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "Building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
BACKEND_INSTALL_DIR=$(realpath "build/icicle/backend")
else
echo "Building icicle without CUDA backend, BACKEND_INSTALL_DIR=${BACKEND_INSTALL_DIR}"
cmake -DCMAKE_BUILD_TYPE=Release -DCURVE=bn254 -DMSM=OFF -S "${ICILE_DIR}" -B build/icicle
fi
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
cmake --build build/icicle -j
cmake --build build/example -j
./build/example/example "$DEVICE_TYPE" "$BACKEND_INSTALL_DIR"

View File

@@ -21,9 +21,10 @@ The key enabler for *recursion* is the *redundancy* of polynomial commitments, h
To run example, from project root directory:
```sh
cd examples/c++/risc0
./compile.sh
./run.sh
# for CPU
./run.sh -d CPU
# for CUDA
./run.sh -d CUDA -b /path/to/cuda/backend/install/dir
```
## What's in the example

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DFIELD=babybear -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example -DBACKEND_DIR=$(realpath "build/icicle/backend")
else
echo "building icicle without CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DFIELD=babybear -S "${ICILE_DIR}" -B build/icicle
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
fi
cmake --build build/icicle -j
cmake --build build/example -j

View File

@@ -1,2 +1,65 @@
#!/bin/bash
./build/example/example $1
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage information
show_help() {
echo "Usage: $0 [-d DEVICE_TYPE] [-b BACKEND_INSTALL_DIR]"
echo
echo "Options:"
echo " -d DEVICE_TYPE Specify the device type (default: CPU)"
echo " -b BACKEND_INSTALL_DIR Specify the backend installation directory (default: empty)"
echo " -h Show this help message"
exit 0
}
# Parse command line options
while getopts ":d:b:h" opt; do
case ${opt} in
d )
DEVICE_TYPE=$OPTARG
;;
b )
BACKEND_INSTALL_DIR="$(realpath ${OPTARG})"
;;
h )
show_help
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
show_help
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
show_help
;;
esac
done
# Set default values if not provided
: "${DEVICE_TYPE:=CPU}"
: "${BACKEND_INSTALL_DIR:=}"
# Create necessary directories
mkdir -p build/example
mkdir -p build/icicle
ICILE_DIR=$(realpath "../../../icicle_v3/")
ICICLE_CUDA_BACKEND_DIR="${ICILE_DIR}/backend/cuda"
# Build Icicle and the example app that links to it
if [ "$DEVICE_TYPE" == "CUDA" ] && [ ! -d "${BACKEND_INSTALL_DIR}" ] && [ -d "${ICICLE_CUDA_BACKEND_DIR}" ]; then
echo "Building icicle with CUDA backend"
cmake -DCMAKE_BUILD_TYPE=Release -DFIELD=babybear -DCUDA_BACKEND=local -S "${ICILE_DIR}" -B build/icicle
BACKEND_INSTALL_DIR=$(realpath "build/icicle/backend")
else
echo "Building icicle without CUDA backend, BACKEND_INSTALL_DIR=${BACKEND_INSTALL_DIR}"
cmake -DCMAKE_BUILD_TYPE=Release -DFIELD=babybear -S "${ICILE_DIR}" -B build/icicle
fi
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/example
cmake --build build/icicle -j
cmake --build build/example -j
./build/example/example "$DEVICE_TYPE" "$BACKEND_INSTALL_DIR"