mirror of
https://github.com/pseXperiments/icicle.git
synced 2026-01-09 15:37:58 -05:00
MSM - supporting all window sizes (#534)
This PR enables using MSM with any value of c. Note: default c isn't necessarily optimal, the user is expected to choose c and the precomputation factor that give the best results for the relevant case. --------- Co-authored-by: Jeremy Felder <jeremy.felder1@gmail.com>
This commit is contained in:
@@ -116,13 +116,13 @@ func MsmCheck(scalars HostOrDeviceSlice, points HostOrDeviceSlice, cfg *MSMConfi
|
||||
return scalars.AsUnsafePointer(), points.AsUnsafePointer(), results.AsUnsafePointer(), size, unsafe.Pointer(cfg)
|
||||
}
|
||||
|
||||
func PrecomputeBasesCheck(points HostOrDeviceSlice, precomputeFactor int32, outputBases DeviceSlice) (unsafe.Pointer, unsafe.Pointer) {
|
||||
func PrecomputePointsCheck(points HostOrDeviceSlice, cfg *MSMConfig, outputBases DeviceSlice) (unsafe.Pointer, unsafe.Pointer) {
|
||||
outputBasesLength, pointsLength := outputBases.Len(), points.Len()
|
||||
if outputBasesLength != pointsLength*int(precomputeFactor) {
|
||||
if outputBasesLength != pointsLength*int(cfg.PrecomputeFactor) {
|
||||
errorString := fmt.Sprintf(
|
||||
"Precompute factor is probably incorrect: expected %d but got %d",
|
||||
outputBasesLength/pointsLength,
|
||||
precomputeFactor,
|
||||
cfg.PrecomputeFactor,
|
||||
)
|
||||
panic(errorString)
|
||||
}
|
||||
@@ -131,5 +131,8 @@ func PrecomputeBasesCheck(points HostOrDeviceSlice, precomputeFactor int32, outp
|
||||
points.(DeviceSlice).CheckDevice()
|
||||
}
|
||||
|
||||
cfg.pointsSize = int32(pointsLength)
|
||||
cfg.arePointsOnDevice = points.IsOnDevice()
|
||||
|
||||
return points.AsUnsafePointer(), outputBases.AsUnsafePointer()
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_377_g2_msm_cuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bls12_377_g2_precompute_msm_bases_cuda(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
cudaError_t bls12_377_g2_precompute_msm_points_cuda(g2_affine_t* points, int msm_size, MSMConfig* config, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *c
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: G2PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// G2PrecomputePoints should be used instead.
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := G2GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_377_g2_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_377_msm_cuda(const scalar_t* scalars,const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bls12_377_precompute_msm_bases_cuda(affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, affine_t* out);
|
||||
cudaError_t bls12_377_precompute_msm_points_cuda(affine_t* points, int msm_size, MSMConfig* config, affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *cor
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// PrecomputePoints should be used instead.
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c in
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_377_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -210,9 +210,11 @@ func TestMSMG2Batch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBaseG2(t *testing.T) {
|
||||
func TestPrecomputePointsG2(t *testing.T) {
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -222,20 +224,18 @@ func TestPrecomputeBaseG2(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = g2.G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = g2.G2PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = g2.G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -170,9 +170,11 @@ func TestMSMBatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBase(t *testing.T) {
|
||||
func TestPrecomputePoints(t *testing.T) {
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -182,20 +184,18 @@ func TestPrecomputeBase(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = msm.PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = msm.PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p icicleBls12_377.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = msm.Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[icicleBls12_377.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_381_g2_msm_cuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bls12_381_g2_precompute_msm_bases_cuda(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
cudaError_t bls12_381_g2_precompute_msm_points_cuda(g2_affine_t* points, int msm_size, MSMConfig* config, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *c
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: G2PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// G2PrecomputePoints should be used instead.
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := G2GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_381_g2_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bls12_381_msm_cuda(const scalar_t* scalars,const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bls12_381_precompute_msm_bases_cuda(affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, affine_t* out);
|
||||
cudaError_t bls12_381_precompute_msm_points_cuda(affine_t* points, int msm_size, MSMConfig* config, affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *cor
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// PrecomputePoints should be used instead.
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c in
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bls12_381_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -210,9 +210,11 @@ func TestMSMG2Batch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBaseG2(t *testing.T) {
|
||||
func TestPrecomputePointsG2(t *testing.T) {
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -222,20 +224,18 @@ func TestPrecomputeBaseG2(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = g2.G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = g2.G2PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = g2.G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -170,9 +170,11 @@ func TestMSMBatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBase(t *testing.T) {
|
||||
func TestPrecomputePoints(t *testing.T) {
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -182,20 +184,18 @@ func TestPrecomputeBase(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = msm.PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = msm.PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p icicleBls12_381.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = msm.Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[icicleBls12_381.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bn254_g2_msm_cuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bn254_g2_precompute_msm_bases_cuda(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
cudaError_t bn254_g2_precompute_msm_points_cuda(g2_affine_t* points, int msm_size, MSMConfig* config, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *c
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: G2PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// G2PrecomputePoints should be used instead.
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := G2GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bn254_g2_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bn254_msm_cuda(const scalar_t* scalars,const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bn254_precompute_msm_bases_cuda(affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, affine_t* out);
|
||||
cudaError_t bn254_precompute_msm_points_cuda(affine_t* points, int msm_size, MSMConfig* config, affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *cor
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// PrecomputePoints should be used instead.
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c in
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bn254_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -210,9 +210,11 @@ func TestMSMG2Batch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBaseG2(t *testing.T) {
|
||||
func TestPrecomputePointsG2(t *testing.T) {
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -222,20 +224,18 @@ func TestPrecomputeBaseG2(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = g2.G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = g2.G2PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = g2.G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -170,9 +170,11 @@ func TestMSMBatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBase(t *testing.T) {
|
||||
func TestPrecomputePoints(t *testing.T) {
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -182,20 +184,18 @@ func TestPrecomputeBase(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = msm.PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = msm.PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p icicleBn254.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = msm.Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[icicleBn254.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bw6_761_g2_msm_cuda(const scalar_t* scalars,const g2_affine_t* points, int count, MSMConfig* config, g2_projective_t* out);
|
||||
cudaError_t bw6_761_g2_precompute_msm_bases_cuda(g2_affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, g2_affine_t* out);
|
||||
cudaError_t bw6_761_g2_precompute_msm_points_cuda(g2_affine_t* points, int msm_size, MSMConfig* config, g2_affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func G2Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *c
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: G2PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// G2PrecomputePoints should be used instead.
|
||||
func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := G2GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func G2PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func G2PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.g2_affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.g2_affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bw6_761_g2_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t bw6_761_msm_cuda(const scalar_t* scalars,const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t bw6_761_precompute_msm_bases_cuda(affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, affine_t* out);
|
||||
cudaError_t bw6_761_precompute_msm_points_cuda(affine_t* points, int msm_size, MSMConfig* config, affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *cor
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// PrecomputePoints should be used instead.
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c in
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.bw6_761_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -170,9 +170,11 @@ func TestMSMG2Batch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBaseG2(t *testing.T) {
|
||||
func TestPrecomputePointsG2(t *testing.T) {
|
||||
cfg := g2.G2GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -182,20 +184,18 @@ func TestPrecomputeBaseG2(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = g2.G2PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = g2.G2PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p g2.G2Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = g2.G2Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[g2.G2Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -170,9 +170,11 @@ func TestMSMBatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBase(t *testing.T) {
|
||||
func TestPrecomputePoints(t *testing.T) {
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -182,20 +184,18 @@ func TestPrecomputeBase(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = msm.PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = msm.PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p icicleBw6_761.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = msm.Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[icicleBw6_761.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t grumpkin_msm_cuda(const scalar_t* scalars,const affine_t* points, int count, MSMConfig* config, projective_t* out);
|
||||
cudaError_t grumpkin_precompute_msm_bases_cuda(affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, affine_t* out);
|
||||
cudaError_t grumpkin_precompute_msm_points_cuda(affine_t* points, int msm_size, MSMConfig* config, affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ func Msm(scalars core.HostOrDeviceSlice, points core.HostOrDeviceSlice, cfg *cor
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// PrecomputePoints should be used instead.
|
||||
func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c in
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.grumpkin_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -64,9 +64,11 @@ func TestMSMBatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBase(t *testing.T) {
|
||||
func TestPrecomputePoints(t *testing.T) {
|
||||
cfg := msm.GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -76,20 +78,18 @@ func TestPrecomputeBase(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = msm.PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = msm.PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p icicleGrumpkin.Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = msm.Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[icicleGrumpkin.Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -28,8 +28,13 @@ func {{.CurvePrefix}}Msm(scalars core.HostOrDeviceSlice, points core.HostOrDevic
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: {{.CurvePrefix}}PrecomputeBases exists for backward compatibility.
|
||||
// It may cause issues if an MSM with a different `c` value is used with precomputed points and it will be removed in a future version.
|
||||
// {{.CurvePrefix}}PrecomputePoints should be used instead.
|
||||
func {{.CurvePrefix}}PrecomputeBases(points core.HostOrDeviceSlice, precomputeFactor int32, c int32, ctx *cr.DeviceContext, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputeBasesCheck(points, precomputeFactor, outputBases)
|
||||
cfg := {{.CurvePrefix}}GetDefaultMSMConfig()
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, &cfg, outputBases)
|
||||
|
||||
cPoints := (*C.{{toCName .CurvePrefix}}affine_t)(pointsPointer)
|
||||
cPointsLen := (C.int)(points.Len())
|
||||
@@ -43,3 +48,16 @@ func {{.CurvePrefix}}PrecomputeBases(points core.HostOrDeviceSlice, precomputeFa
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
func {{.CurvePrefix}}PrecomputePoints(points core.HostOrDeviceSlice, msmSize int, cfg *core.MSMConfig, outputBases core.DeviceSlice) cr.CudaError {
|
||||
pointsPointer, outputBasesPointer := core.PrecomputePointsCheck(points, cfg, outputBases)
|
||||
|
||||
cPoints := (*C.{{toCName .CurvePrefix}}affine_t)(pointsPointer)
|
||||
cMsmSize := (C.int)(msmSize)
|
||||
cCfg := (*C.MSMConfig)(unsafe.Pointer(cfg))
|
||||
cOutputBases := (*C.{{toCName .CurvePrefix}}affine_t)(outputBasesPointer)
|
||||
|
||||
__ret := C.{{.Curve}}{{toCNameBackwards .CurvePrefix}}_precompute_msm_points_cuda(cPoints, cMsmSize, cCfg, cOutputBases)
|
||||
err := (cr.CudaError)(__ret)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct DeviceContext DeviceContext;
|
||||
|
||||
cudaError_t {{.Curve}}{{toCNameBackwards .CurvePrefix}}_msm_cuda(const scalar_t* scalars,const {{toCName .CurvePrefix}}affine_t* points, int count, MSMConfig* config, {{toCName .CurvePrefix}}projective_t* out);
|
||||
cudaError_t {{.Curve}}{{toCNameBackwards .CurvePrefix}}_precompute_msm_bases_cuda({{toCName .CurvePrefix}}affine_t* points, int count, int precompute_factor, int _c, bool bases_on_device, DeviceContext* ctx, {{toCName .CurvePrefix}}affine_t* out);
|
||||
cudaError_t {{.Curve}}{{toCNameBackwards .CurvePrefix}}_precompute_msm_points_cuda({{toCName .CurvePrefix}}affine_t* points, int msm_size, MSMConfig* config, {{toCName .CurvePrefix}}affine_t* out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -251,9 +251,11 @@ func TestMSM{{.CurvePrefix}}Batch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrecomputeBase{{.CurvePrefix}}(t *testing.T) {
|
||||
func TestPrecomputePoints{{.CurvePrefix}}(t *testing.T) {
|
||||
cfg := {{if eq .CurvePrefix "G2"}}g2{{else}}msm{{end}}.{{.CurvePrefix}}GetDefaultMSMConfig()
|
||||
const precomputeFactor = 8
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
|
||||
for _, power := range []int{10, 16} {
|
||||
for _, batchSize := range []int{1, 3, 16} {
|
||||
size := 1 << power
|
||||
@@ -263,20 +265,18 @@ func TestPrecomputeBase{{.CurvePrefix}}(t *testing.T) {
|
||||
|
||||
var precomputeOut core.DeviceSlice
|
||||
_, e := precomputeOut.Malloc(points[0].Size()*points.Len()*int(precomputeFactor), points[0].Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for PrecomputeBases results failed")
|
||||
|
||||
e = {{if eq .CurvePrefix "G2"}}g2{{else}}msm{{end}}.{{.CurvePrefix}}PrecomputeBases(points, precomputeFactor, 0, &cfg.Ctx, precomputeOut)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "PrecomputeBases failed")
|
||||
e = {{if eq .CurvePrefix "G2"}}g2{{else}}msm{{end}}.{{.CurvePrefix}}PrecomputePoints(points, size, &cfg, precomputeOut)
|
||||
assert.Equal(t, cr.CudaSuccess, e, "PrecomputeBases failed")
|
||||
|
||||
var p {{if ne .CurvePrefix "G2"}}icicle{{capitalize .Curve}}{{else}}g2{{end}}.{{.CurvePrefix}}Projective
|
||||
var out core.DeviceSlice
|
||||
_, e = out.Malloc(batchSize*p.Size(), p.Size())
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
cfg.PrecomputeFactor = precomputeFactor
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Allocating bytes on device for Projective results failed")
|
||||
|
||||
e = {{if eq .CurvePrefix "G2"}}g2{{else}}msm{{end}}.{{.CurvePrefix}}Msm(scalars, precomputeOut, &cfg, out)
|
||||
assert.Equal(t, e, cr.CudaSuccess, "Msm failed")
|
||||
assert.Equal(t, cr.CudaSuccess, e, "Msm failed")
|
||||
outHost := make(core.HostSlice[{{if ne .CurvePrefix "G2"}}icicle{{capitalize .Curve}}{{else}}g2{{end}}.{{.CurvePrefix}}Projective], batchSize)
|
||||
outHost.CopyFromDevice(&out)
|
||||
out.Free()
|
||||
|
||||
@@ -105,6 +105,13 @@ pub trait MSM<C: Curve> {
|
||||
ctx: &DeviceContext,
|
||||
output_bases: &mut DeviceSlice<Affine<C>>,
|
||||
) -> IcicleResult<()>;
|
||||
|
||||
fn precompute_points_unchecked(
|
||||
points: &(impl HostOrDeviceSlice<Affine<C>> + ?Sized),
|
||||
msm_size: i32,
|
||||
cfg: &MSMConfig,
|
||||
output_bases: &mut DeviceSlice<Affine<C>>,
|
||||
) -> IcicleResult<()>;
|
||||
}
|
||||
|
||||
/// Computes the multi-scalar multiplication, or MSM: `s1*P1 + s2*P2 + ... + sn*Pn`, or a batch of several MSMs.
|
||||
@@ -188,7 +195,7 @@ pub fn msm<C: Curve + MSM<C>>(
|
||||
/// Extended points: \f$ P_0, P_1, P_2, ... P_{size}, 2^{l}P_0, 2^{l}P_1, ..., 2^{l}P_{size},
|
||||
/// 2^{2l}P_0, 2^{2l}P_1, ..., 2^{2cl}P_{size}, ... \f$
|
||||
///
|
||||
/// * `bases` - Bases \f$ P_i \f$. In case of batch MSM, all *unique* points are concatenated.
|
||||
/// * `points` - Bases \f$ P_i \f$. In case of batch MSM, all *unique* points are concatenated.
|
||||
///
|
||||
/// * `precompute_factor` - The number of total precomputed points for each base (including the base itself).
|
||||
///
|
||||
@@ -201,6 +208,7 @@ pub fn msm<C: Curve + MSM<C>>(
|
||||
/// * `output_bases` - Device-allocated buffer of size `bases_size` * `precompute_factor` for the extended bases.
|
||||
///
|
||||
/// Returns `Ok(())` if no errors occurred or a `CudaError` otherwise.
|
||||
#[deprecated(since = "2.5.0", note = "Please use `precompute_points` instead")]
|
||||
pub fn precompute_bases<C: Curve + MSM<C>>(
|
||||
points: &(impl HostOrDeviceSlice<Affine<C>> + ?Sized),
|
||||
precompute_factor: i32,
|
||||
@@ -220,6 +228,55 @@ pub fn precompute_bases<C: Curve + MSM<C>>(
|
||||
C::precompute_bases_unchecked(points, precompute_factor, _c, ctx, output_bases)
|
||||
}
|
||||
|
||||
/// A function that precomputes MSM bases by extending them with their shifted copies.
|
||||
/// e.g.:
|
||||
/// Original points: \f$ P_0, P_1, P_2, ... P_{size} \f$
|
||||
/// Extended points: \f$ P_0, P_1, P_2, ... P_{size}, 2^{l}P_0, 2^{l}P_1, ..., 2^{l}P_{size},
|
||||
/// 2^{2l}P_0, 2^{2l}P_1, ..., 2^{2cl}P_{size}, ... \f$
|
||||
///
|
||||
/// * `points` - Base points \f$ P_i \f$. In case of batch MSM, all *unique* points are concatenated.
|
||||
///
|
||||
/// * `msm_size` - The size of a single MSM to compute.
|
||||
///
|
||||
/// * `cfg` - config used to specify extra arguments of the MSM. NOTE: You should update the precompute_factor
|
||||
/// and potentially the c value inside this config. This config should be the same config used in msm.
|
||||
///
|
||||
/// * `output_bases` - Device-allocated buffer of size `bases_size` * `precompute_factor` for the extended bases.
|
||||
///
|
||||
/// Returns `Ok(())` if no errors occurred or a `CudaError` otherwise.
|
||||
pub fn precompute_points<C: Curve + MSM<C>>(
|
||||
points: &(impl HostOrDeviceSlice<Affine<C>> + ?Sized),
|
||||
msm_size: i32,
|
||||
cfg: &MSMConfig,
|
||||
output_bases: &mut DeviceSlice<Affine<C>>,
|
||||
) -> IcicleResult<()> {
|
||||
let precompute_factor = cfg.precompute_factor;
|
||||
assert_eq!(
|
||||
output_bases.len(),
|
||||
points.len() * (precompute_factor as usize),
|
||||
"Precompute factor is probably incorrect: expected {} but got {}",
|
||||
output_bases.len() / points.len(),
|
||||
precompute_factor
|
||||
);
|
||||
assert!(output_bases.is_on_device());
|
||||
|
||||
let ctx_device_id = cfg
|
||||
.ctx
|
||||
.device_id;
|
||||
if let Some(device_id) = points.device_id() {
|
||||
assert_eq!(
|
||||
device_id, ctx_device_id,
|
||||
"Device ids in points and context are different"
|
||||
);
|
||||
}
|
||||
check_device(ctx_device_id);
|
||||
let mut local_cfg = cfg.clone();
|
||||
local_cfg.points_size = points.len() as i32;
|
||||
local_cfg.are_points_on_device = points.is_on_device();
|
||||
|
||||
C::precompute_points_unchecked(points, msm_size, &local_cfg, output_bases)
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_msm {
|
||||
(
|
||||
@@ -250,6 +307,14 @@ macro_rules! impl_msm {
|
||||
ctx: &DeviceContext,
|
||||
output_bases: *mut Affine<$curve>,
|
||||
) -> CudaError;
|
||||
|
||||
#[link_name = concat!($curve_prefix, "_precompute_msm_points_cuda")]
|
||||
pub(crate) fn precompute_points_cuda(
|
||||
points: *const Affine<$curve>,
|
||||
msm_size: i32,
|
||||
cfg: &MSMConfig,
|
||||
output_bases: *mut Affine<$curve>,
|
||||
) -> CudaError;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,6 +357,23 @@ macro_rules! impl_msm {
|
||||
.wrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn precompute_points_unchecked(
|
||||
points: &(impl HostOrDeviceSlice<Affine<$curve>> + ?Sized),
|
||||
msm_size: i32,
|
||||
cfg: &MSMConfig,
|
||||
output_bases: &mut DeviceSlice<Affine<$curve>>,
|
||||
) -> IcicleResult<()> {
|
||||
unsafe {
|
||||
$curve_prefix_indent::precompute_points_cuda(
|
||||
points.as_ptr(),
|
||||
msm_size,
|
||||
cfg,
|
||||
output_bases.as_mut_ptr(),
|
||||
)
|
||||
.wrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -363,7 +445,7 @@ macro_rules! impl_msm_bench {
|
||||
group.sampling_mode(SamplingMode::Flat);
|
||||
group.sample_size(10);
|
||||
|
||||
use icicle_core::msm::precompute_bases;
|
||||
use icicle_core::msm::precompute_points;
|
||||
use icicle_core::msm::tests::generate_random_affine_points_with_zeroes;
|
||||
use icicle_cuda_runtime::stream::CudaStream;
|
||||
|
||||
@@ -396,11 +478,11 @@ macro_rules! impl_msm_bench {
|
||||
let points = generate_random_affine_points_with_zeroes(test_size, 10);
|
||||
for precompute_factor in [1, 4, 8] {
|
||||
let mut precomputed_points_d = DeviceVec::cuda_malloc(precompute_factor * test_size).unwrap();
|
||||
precompute_bases(
|
||||
cfg.precompute_factor = precompute_factor as i32;
|
||||
precompute_points(
|
||||
HostSlice::from_slice(&points),
|
||||
precompute_factor as i32,
|
||||
0,
|
||||
&cfg.ctx,
|
||||
test_size as i32,
|
||||
&cfg,
|
||||
&mut precomputed_points_d,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -419,7 +501,6 @@ macro_rules! impl_msm_bench {
|
||||
let scalars_h = HostSlice::from_slice(&scalars);
|
||||
|
||||
let mut msm_results = DeviceVec::<Projective<C>>::cuda_malloc(batch_size).unwrap();
|
||||
cfg.precompute_factor = precompute_factor as i32;
|
||||
|
||||
let bench_descr = format!(
|
||||
" {} x {} with precomp = {:?}",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::curve::{Affine, Curve, Projective};
|
||||
use crate::msm::{msm, precompute_bases, MSMConfig, MSM};
|
||||
use crate::msm::{msm, precompute_points, MSMConfig, MSM};
|
||||
use crate::traits::{FieldImpl, GenerateRandom};
|
||||
use icicle_cuda_runtime::device::{get_device_count, set_device, warmup};
|
||||
use icicle_cuda_runtime::memory::{DeviceVec, HostSlice};
|
||||
@@ -120,16 +120,16 @@ where
|
||||
cfg.is_async = true;
|
||||
cfg.large_bucket_factor = 5;
|
||||
cfg.c = 4;
|
||||
let precompute_factor = 8;
|
||||
warmup(&stream).unwrap();
|
||||
for test_size in test_sizes {
|
||||
let precompute_factor = 8;
|
||||
let points = generate_random_affine_points_with_zeroes(test_size, 10);
|
||||
let mut precomputed_points_d = DeviceVec::cuda_malloc(precompute_factor * test_size).unwrap();
|
||||
precompute_bases(
|
||||
cfg.precompute_factor = precompute_factor as i32;
|
||||
precompute_points(
|
||||
HostSlice::from_slice(&points),
|
||||
precompute_factor as i32,
|
||||
0,
|
||||
&cfg.ctx,
|
||||
test_size as i32,
|
||||
&cfg,
|
||||
&mut precomputed_points_d,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user