Skip to content

Commit

Permalink
msm/pippenger: add automatic window calculation
Browse files Browse the repository at this point in the history
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
  • Loading branch information
jsign committed Oct 6, 2023
1 parent f7830b5 commit c11b3f1
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 148 deletions.
99 changes: 60 additions & 39 deletions src/bench.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const fields = @import("fields/fields.zig");
const crs = @import("crs/crs.zig");
const Fp = fields.BandersnatchFields.BaseField;
Expand All @@ -8,15 +9,24 @@ const multiproof = @import("multiproof/multiproof.zig");
const polynomials = @import("polynomial/lagrange_basis.zig");
const ipa = @import("ipa/ipa.zig");
const Transcript = @import("ipa/transcript.zig");
const msm = @import("msm/precomp.zig");
const msmprecomp = @import("msm/precomp.zig");
const pippenger = @import("msm/pippenger.zig");

pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const deinit_status = gpa.deinit();
if (deinit_status == .leak) std.testing.expect(false) catch @panic("memory leak");
}
var allocator = gpa.allocator();

try benchFields();
try benchPedersenHash();
try benchIPAs();
try benchMultiproofs();
try benchPedersenHash(allocator);
try benchIPAs(allocator);
try benchMultiproofs(allocator);

try analyzePedersenHashConfigs();
try analyzePedersenHashConfigs(allocator);
try analyzePippengerWindowSize(allocator);
}

fn benchFields() !void {
Expand Down Expand Up @@ -74,17 +84,10 @@ fn benchFields() !void {
std.debug.print("\n", .{});
}

fn benchPedersenHash() !void {
fn benchPedersenHash(allocator: Allocator) !void {
std.debug.print("Benchmarking Pedersen hashing...\n", .{});
const N = 5000;

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const deinit_status = gpa.deinit();
if (deinit_status == .leak) std.testing.expect(false) catch @panic("memory leak");
}
var allocator = gpa.allocator();

var xcrs = try crs.CRS.init(allocator);
defer xcrs.deinit();

Expand Down Expand Up @@ -112,16 +115,9 @@ fn benchPedersenHash() !void {
std.debug.print("\n", .{});
}

fn benchIPAs() !void {
fn benchIPAs(allocator: Allocator) !void {
const N = 100;

std.debug.print("Setting up IPA benchmark...\n", .{});
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const deinit_status = gpa.deinit();
if (deinit_status == .leak) std.testing.expect(false) catch @panic("memory leak");
}
var allocator = gpa.allocator();

var xcrs = try crs.CRS.init(allocator);
defer xcrs.deinit();
Expand Down Expand Up @@ -172,20 +168,13 @@ fn benchIPAs() !void {
std.debug.print("\n", .{});
}

fn benchMultiproofs() !void {
fn benchMultiproofs(allocator: Allocator) !void {
const LagrangeBasis = polynomials.LagrangeBasis(crs.DomainSize, crs.Domain);

std.debug.print("Setting up multiproofs benchmark...\n", .{});
const N = 25;
const openings = [_]u16{ 100, 1_000, 5_000, 10_000 };

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const deinit_status = gpa.deinit();
if (deinit_status == .leak) std.testing.expect(false) catch @panic("memory leak");
}
var allocator = gpa.allocator();

var xcrs = try crs.CRS.init(allocator);
defer xcrs.deinit();

Expand Down Expand Up @@ -279,14 +268,7 @@ fn genBaseFieldElements(comptime N: usize) [N]Fp {
return fps;
}

fn analyzePedersenHashConfigs() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const deinit_status = gpa.deinit();
if (deinit_status == .leak) std.testing.expect(false) catch @panic("memory leak");
}
var allocator = gpa.allocator();

fn analyzePedersenHashConfigs(allocator: Allocator) !void {
const N = 1_000;

var scalars: [crs.DomainSize]Fr = undefined;
Expand All @@ -304,7 +286,7 @@ fn analyzePedersenHashConfigs() !void {

inline for (ts) |t| {
inline for (bs) |b| {
var precomp = try msm.PrecompMSM(t, b).init(allocator, &xcrs.Gs);
var precomp = try msmprecomp.PrecompMSM(t, b).init(allocator, &xcrs.Gs);
defer precomp.deinit();

const table_size = precomp.table.len * @sizeOf(banderwagon.ElementMSM) >> 20;
Expand All @@ -331,7 +313,7 @@ fn analyzePedersenHashConfigs() !void {

inline for (ts) |t| {
inline for (bs) |b| {
var hybprecomp = try msm.HybridPrecompMSM(cutoff, t, b, 4, 8).init(allocator, &xcrs.Gs);
var hybprecomp = try msmprecomp.HybridPrecompMSM(cutoff, t, b, 4, 8).init(allocator, &xcrs.Gs);
defer hybprecomp.deinit();

const table_size1 = hybprecomp.precomp1.table.len * @sizeOf(banderwagon.ElementMSM) >> 20;
Expand All @@ -352,3 +334,42 @@ fn analyzePedersenHashConfigs() !void {
}
std.debug.print("\n", .{});
}

fn analyzePippengerWindowSize(allocator: Allocator) !void {
const N = 1_000;
const msm_lengths = [_]usize{ 3, 10, 100, 500, 1000, 5000, 10000 };

var tmp_basis: [msm_lengths[msm_lengths.len - 1]]banderwagon.Element = undefined;
tmp_basis[0] = banderwagon.Element.generator();
for (1..msm_lengths.len) |i| {
tmp_basis[i].double(tmp_basis[i - 1]);
}
var basis: [msm_lengths[msm_lengths.len - 1]]banderwagon.ElementMSM = undefined;
banderwagon.ElementMSM.fromElements(&basis, &tmp_basis);

var scalars: [msm_lengths[msm_lengths.len - 1]]Fr = undefined;
for (0..scalars.len) |i| {
scalars[i] = Fr.fromInteger(i + 0x424242);
}
var optimal: [msm_lengths.len]usize = std.mem.zeroes([msm_lengths.len]usize);
inline for (0..msm_lengths.len) |i| {
var lowest_duration: i64 = std.math.maxInt(i64);
std.debug.print("MSM length {}:\n", .{msm_lengths[i]});
inline for (2..10) |window_size| {
const start = std.time.microTimestamp();
for (0..N) |_| {
_ = try pippenger.msmWithWindowSize(allocator, window_size, basis[0..msm_lengths[i]], scalars[0..msm_lengths[i]]);
}
const duration: i64 = @divTrunc((std.time.microTimestamp() - start), N);
if (duration < lowest_duration) {
optimal[i] = window_size;
lowest_duration = duration;
}
std.debug.print("\tw={}:{}µs\n", .{ window_size, duration });
}
}
std.debug.print("\nOptimal window sizes:\n", .{});
for (0..msm_lengths.len) |i| {
std.debug.print("\tmsm_length={} w={}\n", .{ msm_lengths[i], optimal[i] });
}
}
Loading

0 comments on commit c11b3f1

Please sign in to comment.