Skip to content
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

V3 golang bindings #594

Merged
merged 30 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0c5b6b2
pr fixes
nonam3e Aug 27, 2024
1bdcccd
update generators
nonam3e Aug 28, 2024
6bc9d37
update montgomery wrappers
nonam3e Aug 28, 2024
6e49a35
update runtime
nonam3e Aug 28, 2024
42aa21b
change golang ci
nonam3e Aug 29, 2024
7f7b432
fix malloc calls
nonam3e Aug 30, 2024
74fca20
generators
nonam3e Aug 30, 2024
d882ed6
update docs
nonam3e Aug 30, 2024
447c40c
fix typo
nonam3e Aug 30, 2024
fad0d85
update readme
nonam3e Aug 30, 2024
3cae409
r
nonam3e Aug 30, 2024
ff49d9d
First iteration of PR fixes
jeremyfelder Sep 1, 2024
945a44f
[ci skip] move extract cuda backend workflow to reusable workflow
jeremyfelder Sep 1, 2024
670f222
Add extern func for from_affine
jeremyfelder Sep 1, 2024
795a4ff
Docs WIP, add msm nof_chunks, revert cgo linkage for libs
jeremyfelder Sep 2, 2024
23fa362
fmt
jeremyfelder Sep 2, 2024
e25ab67
Run go generate for lib name revert
jeremyfelder Sep 2, 2024
c2bc65c
Fix from_affine
jeremyfelder Sep 2, 2024
88edc80
Fix cpu_msm implementation
jeremyfelder Sep 2, 2024
8bfdd04
Fix tests #1
jeremyfelder Sep 2, 2024
0e5a616
Fix golang workflow cuda backend branch ref
jeremyfelder Sep 2, 2024
0845fb1
update programmers_guide
nonam3e Sep 2, 2024
e8df7df
Merge branch 'yshekel/V3' into nonam3e/golang-bindings/V3
nonam3e Sep 2, 2024
2ea20f3
Remove TODO for SetFinalizers, update build script to not use ICICLE_…
jeremyfelder Sep 2, 2024
bdae646
Merge branch 'yshekel/V3' into nonam3e/golang-bindings/V3
yshekel Sep 2, 2024
2c21102
change cgo path
nonam3e Sep 3, 2024
8e033b6
runtime cgo
nonam3e Sep 3, 2024
8dfa22b
remove cuda_runtime import from go wrappers
nonam3e Sep 3, 2024
b5ec021
change ICICLE_BACKEND_INSTALL_DIR in golang workflow
nonam3e Sep 3, 2024
b0bf67c
Merge branch 'yshekel/V3' into nonam3e/golang-bindings/V3
nonam3e Sep 3, 2024
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
23 changes: 3 additions & 20 deletions .github/workflows/cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,9 @@ jobs:
run: if [[ $(find ./ \( -path ./icicle/build -prune -o -path ./**/target -prune -o -path ./examples -prune \) -iname *.h -or -iname *.cuh -or -iname *.cu -or -iname *.c -or -iname *.cpp | xargs clang-format --dry-run -ferror-limit=1 -style=file 2>&1) ]]; then echo "Please run clang-format"; exit 1; fi

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"
uses: ./.github/workflows/extract-backends.yml
with:
pr-number: ${{ github.event.pull_request.number }}

test-linux-curve:
name: Test on Linux
Expand Down
23 changes: 3 additions & 20 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,9 @@ jobs:
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"
uses: ./.github/workflows/extract-backends.yml
with:
pr-number: ${{ github.event.pull_request.number }}

run-examples:
runs-on: [self-hosted, Linux, X64, icicle, examples]
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/extract-backends.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Extract Icicle Backend Branch

on:
workflow_call:
inputs:
pr-number:
description: 'The PR number to fetch the description for'
required: true
type: number
outputs:
cuda-backend-branch:
description: "Branch name for cuda backend"
value: ${{ jobs.extract-cuda-backend-branch.outputs.cuda-backend-branch }}

jobs:
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 ${{ inputs.pr-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 "cuda-backend-branch=$CUDA_BE_BRANCH" >> "$GITHUB_OUTPUT"
126 changes: 126 additions & 0 deletions .github/workflows/golang.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: GoLang

on:
pull_request:
branches:
- V3
- yshekel/V3 # TODO remove when merged to V3
push:
branches:
- V3

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
check-changed-files:
uses: ./.github/workflows/check-changed-files.yml

check-format:
name: Check Code Format
runs-on: ubuntu-22.04
needs: check-changed-files
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: '1.20.0'
- name: Check gofmt
if: needs.check-changed-files.outputs.golang == 'true'
run: if [[ $(go list ./... | xargs go fmt) ]]; then echo "Please run go fmt"; exit 1; fi

extract-cuda-backend-branch:
uses: ./.github/workflows/extract-backends.yml
with:
pr-number: ${{ github.event.pull_request.number }}

build-curves-linux:
name: Build and test curves on Linux
runs-on: [self-hosted, Linux, X64, icicle]
needs: [check-changed-files, check-format, extract-cuda-backend-branch]
strategy:
matrix:
curve:
- name: bn254
build_args:
- name: bls12_381
build_args:
- name: bls12_377
build_args:
- name: bw6_761
build_args:
- name: grumpkin
build_args:
jeremyfelder marked this conversation as resolved.
Show resolved Hide resolved
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Checkout CUDA Backend
uses: actions/checkout@v4
with:
repository: ingonyama-zk/icicle-cuda-backend
path: ./icicle/backend/cuda
token: ${{ secrets.GITHUB_TOKEN }}
ssh-key: ${{ secrets.CUDA_PULL_KEY }}
ref: ${{ needs.extract-cuda-backend-branch.outputs.cuda-backend-branch }}
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: '1.20.0'
- name: Build
working-directory: ./wrappers/golang
if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
# builds a single curve with the curve's specified build args
run: |
export ICICLE_BACKEND_INSTALL_DIR=$PWD/../../build/
./build.sh -curve=${{ matrix.curve.name }} ${{ matrix.curve.build_args }} -cuda_backend=local
- name: Test
working-directory: ./wrappers/golang/curves
if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
run: |
CURVE=$(echo ${{ matrix.curve.name }} | sed -e 's/_//g')
export CPATH=$CPATH:/usr/local/cuda/include
export ICICLE_BACKEND_INSTALL_DIR=$PWD/../../../build/
go test ./$CURVE/tests -count=1 -failfast -p 2 -timeout 60m -v

build-fields-linux:
name: Build and test fields on Linux
runs-on: [self-hosted, Linux, X64, icicle]
needs: [check-changed-files, check-format, extract-cuda-backend-branch]
strategy:
matrix:
field:
- name: babybear
build_args:
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Checkout CUDA Backend
uses: actions/checkout@v4
with:
repository: ingonyama-zk/icicle-cuda-backend
path: ./icicle/backend/cuda
token: ${{ secrets.GITHUB_TOKEN }}
ssh-key: ${{ secrets.CUDA_PULL_KEY }}
ref: ${{ needs.extract-cuda-backend-branch.outputs.cuda-backend-branch }}
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: '1.20.0'
- name: Build
working-directory: ./wrappers/golang
if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
# builds a single field with the fields specified build args
run: |
export ICICLE_BACKEND_INSTALL_DIR=$PWD/../../build/
./build.sh -field=${{ matrix.field.name }} ${{ matrix.field.build_args }} -cuda_backend=local
- name: Test
working-directory: ./wrappers/golang/fields
if: needs.check-changed-files.outputs.golang == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true'
run: |
FIELD=$(echo ${{ matrix.field.name }} | sed -e 's/_//g')
export CPATH=$CPATH:/usr/local/cuda/include
export ICICLE_BACKEND_INSTALL_DIR=$PWD/../../../build/
go test ./$FIELD/tests -count=1 -failfast -p 2 -timeout 60m -v
23 changes: 3 additions & 20 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,9 @@ jobs:
run: if [[ $(find . -path ./icicle-curves/icicle-curve-template -prune -o -name target -prune -o -iname *.rs -print | xargs cargo fmt --check --) ]]; then echo "Please run cargo fmt"; exit 1; fi

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"
uses: ./.github/workflows/extract-backends.yml
with:
pr-number: ${{ github.event.pull_request.number }}

test-linux:
name: Test on Linux
Expand Down
46 changes: 21 additions & 25 deletions docs/docs/icicle/golang-bindings.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# Golang bindings

TODO update for V3

Golang bindings allow you to use ICICLE as a golang library.
The source code for all Golang packages can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang).

The Golang bindings are comprised of multiple packages.

[`core`](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/core) which defines all shared methods and structures, such as configuration structures, or memory slices.

[`cuda-runtime`](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/cuda_runtime) which defines abstractions for CUDA methods for allocating memory, initializing and managing streams, and `DeviceContext` which enables users to define and keep track of devices.
[`runtime`](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/runtime) which defines abstractions for ICICLE methods for allocating memory, initializing and managing streams, and `Device` which enables users to define and keep track of devices.

Each supported curve, field, and hash has its own package which you can find in the respective directories [here](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang). If your project uses BN254 you only need to import that single package named [`bn254`](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/curves/bn254).

Expand All @@ -18,48 +16,49 @@ Each supported curve, field, and hash has its own package which you can find in
To add ICICLE to your `go.mod` file.

```bash
go get github.com/ingonyama-zk/icicle
go get github.com/ingonyama-zk/icicle/v3
```

If you want to specify a specific branch

```bash
go get github.com/ingonyama-zk/icicle@<branch_name>
go get github.com/ingonyama-zk/icicle/v3@<branch_name>
```

For a specific commit

```bash
go get github.com/ingonyama-zk/icicle@<commit_id>
go get github.com/ingonyama-zk/icicle/v3@<commit_id>
```

To build the shared libraries you can run [this](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/build.sh) script:

```sh
./build.sh [-curve=<curve>] [-field=<field>] [-hash=<hash>] [-cuda_version=<version>] [-g2] [-ecntt] [-devmode]
./build.sh [-curve=<curve>] [-field=<field>] [-cuda_version=<version>] [-skip_msm] [-skip_ntt] [-skip_g2] [-skip_ecntt] [-skip_fieldext]

curve - The name of the curve to build or "all" to build all supported curves
field - The name of the field to build or "all" to build all supported fields
hash - The name of the hash to build or "all" to build all supported hashes
-g2 - Optional - build with G2 enabled
-ecntt - Optional - build with ECNTT enabled
-devmode - Optional - build in devmode
-skip_msm - Optional - build with MSM disabled
-skip_ntt - Optional - build with NTT disabled
-skip_g2 - Optional - build with G2 disabled
-skip_ecntt - Optional - build with ECNTT disabled
-skip_fieldext - Optional - build without field extension
-help - Optional - Displays usage information
```

:::note

If more than one curve or more than one field or more than one hash is supplied, the last one supplied will be built
If more than one curve or more than one field is supplied, the last one supplied will be built

:::

To build ICICLE libraries for all supported curves with G2 and ECNTT enabled.
To build ICICLE libraries for all supported curves without certain features, you can use their -skip_<feature> flags. For example, for disabling G2 and ECNTT:

```bash
./build.sh -curve=all -g2 -ecntt
./build.sh -curve=all -skip_g2 -skip_ecntt
```

If you wish to build for a specific curve, for example bn254, without G2 or ECNTT enabled.
By default, all features are enabled. To build for a specific field or curve, you can pass the `-field=<field_name>` or `-curve=<curve_name>` flags:

``` bash
./build.sh -curve=bn254
Expand All @@ -69,11 +68,8 @@ Now you can import ICICLE into your project

```go
import (
"github.com/stretchr/testify/assert"
"testing"

"github.com/ingonyama-zk/icicle/v2/wrappers/golang/core"
cr "github.com/ingonyama-zk/icicle/v2/wrappers/golang/cuda_runtime"
"github.com/ingonyama-zk/icicle/v3/wrappers/golang/core"
"github.com/ingonyama-zk/icicle/v3/wrappers/golang/runtime"
)
...
```
Expand All @@ -86,23 +82,23 @@ To run all tests, for all curves:
go test ./... -count=1
```

If you wish to run test for a specific curve:
If you wish to run test for a specific curve or field:

```bash
go test <path_to_curve> -count=1
go test <path_to_curve_or_field> -count=1
```

## How do Golang bindings work?

The libraries produced from the CUDA code compilation are used to bind Golang to ICICLE's CUDA code.
The golang packages are binded to the libraries produced from compiling ICICLE using cgo.

1. These libraries (named `libingo_curve_<curve>.a` and `libingo_field_<curve>.a`) can be imported in your Go project to leverage the GPU accelerated functionalities provided by ICICLE.
1. These libraries (named `libicicle_curve_<curve>.a` and `libicicle_field_<curve>.a`) can be imported in your Go project to leverage the accelerated functionalities provided by ICICLE.

2. In your Go project, you can use `cgo` to link these libraries. Here's a basic example on how you can use `cgo` to link these libraries:

```go
/*
#cgo LDFLAGS: -L/path/to/shared/libs -lingo_curve_bn254 -L$/path/to/shared/libs -lingo_field_bn254 -lstdc++ -lm
#cgo LDFLAGS: -L/path/to/shared/libs -licicle_device -lstdc++ -lm -Wl,-rpath=/path/to/shared/libs
#include "icicle.h" // make sure you use the correct header file(s)
*/
import "C"
Expand Down
Loading
Loading