Skip to content

Commit

Permalink
golang docs (#413)
Browse files Browse the repository at this point in the history
## Describe the changes

This PR...

## Linked Issues

Resolves #

---------

Co-authored-by: Jeremy Felder <[email protected]>
Co-authored-by: DmytroTym <[email protected]>
  • Loading branch information
3 people authored Mar 6, 2024
1 parent 9fc0839 commit af6bfc9
Show file tree
Hide file tree
Showing 10 changed files with 960 additions and 178 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
paths:
- 'docs/*'
- 'docs/**'

permissions:
contents: write
Expand Down
104 changes: 103 additions & 1 deletion docs/docs/icicle/golang-bindings.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,105 @@
# Golang bindings

Golang is WIP in v1, coming soon. Please checkout a previous [release v0.1.0](https://github.com/ingonyama-zk/icicle/releases/tag/v0.1.0) for golang bindings.
Golang bindings allow you to use ICICLE as a golang library.
The source code for all Golang libraries 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.

Each curve has its own package which you can find [here](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/curves). If your project uses BN254 you only need to install that single package named [`bn254`](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/golang/curves/bn254).

## Using ICICLE Golang bindings in your project

To add ICICLE to your `go.mod` file.

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

If you want to specify a specific branch

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

For a specific commit

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

To build the shared libraries you can run this script:

```
./build <curve> [G2_enabled]
curve - The name of the curve to build or "all" to build all curves
G2_enabled - Optional - To build with G2 enabled
```

For example if you want to build all curves with G2 enabled you would run:

```bash
./build.sh all ON
```

If you are interested in building a specific curve you would run:

```bash
./build.sh bls12_381 ON
```

Now you can import ICICLE into your project

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

"github.com/ingonyama-zk/icicle/wrappers/golang/core"
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
)
...
```

## Running tests

To run all tests, for all curves:

```bash
go test --tags=g2 ./... -count=1
```

If you dont want to include g2 tests then drop `--tags=g2`.

If you wish to run test for a specific curve:

```bash
go test <path_to_curve> -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.

1. These libraries (named `libingo_<curve>.a`) can be imported in your Go project to leverage the GPU 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_bn254
#include "icicle.h" // make sure you use the correct header file(s)
*/
import "C"

func main() {
// Now you can call the C functions from the ICICLE libraries.
// Note that C function calls are prefixed with 'C.' in Go code.
}
```

Replace `/path/to/shared/libs` with the actual path where the shared libraries are located on your system.
200 changes: 200 additions & 0 deletions docs/docs/icicle/golang-bindings/msm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# MSM


### Supported curves

`bls12-377`, `bls12-381`, `bn254`, `bw6-761`

## MSM Example

```go
package main

import (
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
cr "github.com/ingonyama-zk/icicle/wrappers/golang/cuda_runtime"
)

func Main() {
// Obtain the default MSM configuration.
cfg := GetDefaultMSMConfig()

// Define the size of the problem, here 2^18.
size := 1 << 18

// Generate scalars and points for the MSM operation.
scalars := GenerateScalars(size)
points := GenerateAffinePoints(size)

// Create a CUDA stream for asynchronous operations.
stream, _ := cr.CreateStream()
var p Projective

// Allocate memory on the device for the result of the MSM operation.
var out core.DeviceSlice
_, e := out.MallocAsync(p.Size(), p.Size(), stream)

if e != cr.CudaSuccess {
panic(e)
}

// Set the CUDA stream in the MSM configuration.
cfg.Ctx.Stream = &stream
cfg.IsAsync = true

// Perform the MSM operation.
e = Msm(scalars, points, &cfg, out)

if e != cr.CudaSuccess {
panic(e)
}

// Allocate host memory for the results and copy the results from the device.
outHost := make(core.HostSlice[Projective], 1)
cr.SynchronizeStream(&stream)
outHost.CopyFromDevice(&out)

// Free the device memory allocated for the results.
out.Free()
}
```

## MSM Method

```go
func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *core.MSMConfig, results core.HostOrDeviceSlice) cr.CudaError
```

### Parameters

- **scalars**: A slice containing the scalars for multiplication. It can reside either in host memory or device memory.
- **points**: A slice containing the points to be multiplied with scalars. Like scalars, these can also be in host or device memory.
- **cfg**: A pointer to an `MSMConfig` object, which contains various configuration options for the MSM operation.
- **results**: A slice where the results of the MSM operation will be stored. This slice can be in host or device memory.

### Return Value

- **CudaError**: Returns a CUDA error code indicating the success or failure of the MSM operation.

## MSMConfig

The `MSMConfig` structure holds configuration parameters for the MSM operation, allowing customization of its behavior to optimize performance based on the specifics of the operation or the underlying hardware.

```go
type MSMConfig struct {
Ctx cr.DeviceContext
PrecomputeFactor int32
C int32
Bitsize int32
LargeBucketFactor int32
batchSize int32
areScalarsOnDevice bool
AreScalarsMontgomeryForm bool
arePointsOnDevice bool
ArePointsMontgomeryForm bool
areResultsOnDevice bool
IsBigTriangle bool
IsAsync bool
}
```

### Fields

- **Ctx**: Device context containing details like device id and stream.
- **PrecomputeFactor**: Controls the number of extra points to pre-compute.
- **C**: Window bitsize, a key parameter in the "bucket method" for MSM.
- **Bitsize**: Number of bits of the largest scalar.
- **LargeBucketFactor**: Sensitivity to frequently occurring buckets.
- **batchSize**: Number of results to compute in one batch.
- **areScalarsOnDevice**: Indicates if scalars are located on the device.
- **AreScalarsMontgomeryForm**: True if scalars are in Montgomery form.
- **arePointsOnDevice**: Indicates if points are located on the device.
- **ArePointsMontgomeryForm**: True if point coordinates are in Montgomery form.
- **areResultsOnDevice**: Indicates if results are stored on the device.
- **IsBigTriangle**: If `true` MSM will run in Large triangle accumulation if `false` Bucket accumulation will be chosen. Default value: false.
- **IsAsync**: If true, runs MSM asynchronously.

### Default Configuration

Use `GetDefaultMSMConfig` to obtain a default configuration, which can then be customized as needed.

```go
func GetDefaultMSMConfig() MSMConfig
```


## How do I toggle between the supported algorithms?

When creating your MSM Config you may state which algorithm you wish to use. `cfg.Ctx.IsBigTriangle = true` will activate Large triangle accumulation and `cfg.Ctx.IsBigTriangle = false` will activate Bucket accumulation.

```go
...

// Obtain the default MSM configuration.
cfg := GetDefaultMSMConfig()

cfg.Ctx.IsBigTriangle = true

...
```

## How do I toggle between MSM modes?

Toggling between MSM modes occurs automatically based on the number of results you are expecting from the `MSM` function.

The number of results is interpreted from the size of `var out core.DeviceSlice`. Thus its important when allocating memory for `var out core.DeviceSlice` to make sure that you are allocating `<number of results> X <size of a single point>`.

```go
...

batchSize := 3
var p G2Projective
var out core.DeviceSlice
out.Malloc(batchSize*p.Size(), p.Size())

...
```

## Support for G2 group

To activate G2 support first you must make sure you are building the static libraries with G2 feature enabled.

```bash
./build.sh bls12_381 ON
```

Now when importing `icicle`, you should have access to G2 features.

```go
import (
"github.com/ingonyama-zk/icicle/wrappers/golang/core"
)
```

These features include `G2Projective` and `G2Affine` points as well as a `G2Msm` method.

```go
...

cfg := GetDefaultMSMConfig()
size := 1 << 12
batchSize := 3
totalSize := size * batchSize
scalars := GenerateScalars(totalSize)
points := G2GenerateAffinePoints(totalSize)

var p G2Projective
var out core.DeviceSlice
out.Malloc(batchSize*p.Size(), p.Size())
G2Msm(scalars, points, &cfg, out)

...
```

`G2Msm` works the same way as normal MSM, the difference is that it uses G2 Points.

Additionally when you are building your application make sure to use the g2 feature flag

```bash
go build -tags=g2
```
Loading

0 comments on commit af6bfc9

Please sign in to comment.