Skip to content

Commit

Permalink
Fix field arithmetic benchmark cairo related bug + perf (#518)
Browse files Browse the repository at this point in the history
fix constants bug + update field arithmetic cairo + optimize split 64/128
  • Loading branch information
StringNick authored Jun 19, 2024
1 parent 6287655 commit 06328b3
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ docsite/
cairo-vm-env
cairo-vm
tmp/
profile.json

# we dont need compiled cairo programs in repo
/cairo_programs/*.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.bool import TRUE
from uint384 import u384, Uint384
from uint384_extension import u384_ext
from field_arithmetic import field_arithmetic
from cairo_programs.uint384 import u384, Uint384
from cairo_programs.uint384_extension import u384_ext
from cairo_programs.field_arithmetic import field_arithmetic

func run_get_square{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}(
prime: Uint384, generator: Uint384, num: Uint384, iterations: felt
Expand Down
11 changes: 6 additions & 5 deletions scripts/benchmarks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
set -e
. ../cairo-vm-env/bin/activate

BENCH_DIR=../cairo_programs/benchmarks
CAIRO_DIR=../cairo_programs/
CAIRO_VM_CLI=../cairo-vm/target/release/cairo-vm-cli
ZIG_CLI=../zig-out/bin/ziggy-starkdust
cd ..
BENCH_DIR=cairo_programs/benchmarks
CAIRO_DIR=cairo_programs/
CAIRO_VM_CLI=cairo-vm/target/release/cairo-vm-cli
ZIG_CLI=zig-out/bin/ziggy-starkdust

for file in $(ls ${BENCH_DIR} | grep .cairo | sed -E 's/\.cairo//'); do
echo "Compiling ${file} program..."
cairo-compile --cairo_path="${CAIRO_DIR}" ${BENCH_DIR}/${file}.cairo --output ${BENCH_DIR}/${file}.json --proof_mode
cairo-compile --cairo_path="${CAIRO_DIR}:../${CAIRO_DIR}" ${BENCH_DIR}/${file}.cairo --output ${BENCH_DIR}/${file}.json --proof_mode
echo "Running ${file} benchmark"
hyperfine --show-output --warmup 2 \
-n "cairo-vm (Rust)" "${CAIRO_VM_CLI} ${BENCH_DIR}/${file}.json --memory_file /dev/null --trace_file /dev/null --layout all_cairo" \
Expand Down
11 changes: 9 additions & 2 deletions scripts/build_cairo_programs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ set -e

cd ..
CAIRO_PROGRAMS_DIR=cairo_programs
CAIRO_PROGRAMS_BENCHMARK_DIR=cairo_programs/benchmarks
CAIRO_DIR=cairo_programs

for file in $(ls ${CAIRO_PROGRAMS_DIR} | grep .cairo | sed -E 's/\.cairo//'); do
echo "Compiling benchmark cairo programs"
for file in $(ls ${CAIRO_PROGRAMS_BENCHMARK_DIR} | grep .cairo | sed -E 's/\.cairo//'); do
echo "Compiling ${file} program..."
cairo-compile --cairo_path="${CAIRO_DIR}:" ${CAIRO_PROGRAMS_DIR}/${file}.cairo --output ${CAIRO_PROGRAMS_DIR}/${file}.json --proof_mode
cairo-compile --cairo_path="${CAIRO_DIR}:../${CAIRO_DIR}" ${CAIRO_PROGRAMS_BENCHMARK_DIR}/${file}.cairo --output ${CAIRO_PROGRAMS_BENCHMARK_DIR}/${file}.json --proof_mode
done

echo "Compiling cairo programs"
for file in $(ls ${CAIRO_PROGRAMS_DIR} | grep .cairo | sed -E 's/\.cairo//'); do
echo "Compiling ${file} program..."
cairo-compile --cairo_path="${CAIRO_DIR}:../${CAIRO_DIR}" ${CAIRO_PROGRAMS_DIR}/${file}.cairo --output ${CAIRO_PROGRAMS_DIR}/${file}.json --proof_mode
done
1 change: 1 addition & 0 deletions src/hint_processor/field_arithmetic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ pub fn bigIntIntGetSquareRoot(
(try field_helper.sqrtPrimePower(allocator, gx, p)) orelse try Int.initSet(allocator, 0)
else
try Int.initSet(allocator, 0);

defer root_gx.deinit();

if (!x.eqlZero() and (@intFromBool(success_x) ^ @intFromBool(success_gx)) == 0)
Expand Down
6 changes: 5 additions & 1 deletion src/hint_processor/hint_utils.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ pub fn getConstantFromVarName(
var it = constants.iterator();
while (it.next()) |k| {
if (k.key_ptr.*.len < var_name.len) continue;
if (std.mem.eql(u8, var_name, k.key_ptr.*[k.key_ptr.*.len - var_name.len ..]))
var iter =
std.mem.splitBackwardsSequence(u8, k.key_ptr.*, ".");

const v = iter.next() orelse continue;
if (std.mem.eql(u8, var_name, v))
return k.value_ptr.*;
}

Expand Down
11 changes: 3 additions & 8 deletions src/hint_processor/uint256_utils.zig
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,10 @@ pub fn split64(
ap_tracking: ApTracking,
) !void {
const a = try hint_utils.getIntegerFromVarName("a", vm, ids_data, ap_tracking);
const digits = a.toLeDigits();
var bytes = [_]u8{0} ** 32;
const numb = a.toU256();

inline for (1..4) |i| {
std.mem.writeInt(u64, bytes[(i - 1) * 8 .. i * 8], digits[i], .little);
}

const low = Felt252.fromInt(u64, digits[0]);
const high = Felt252.fromBytesLe(bytes);
const low = Felt252.fromInt(u256, numb & ((1 << 64) - 1));
const high = Felt252.fromInt(u256, numb >> 64);

try hint_utils.insertValueFromVarName(allocator, "high", MaybeRelocatable.fromFelt(high), vm, ids_data, ap_tracking);
try hint_utils.insertValueFromVarName(allocator, "low", MaybeRelocatable.fromFelt(low), vm, ids_data, ap_tracking);
Expand Down
12 changes: 7 additions & 5 deletions src/hint_processor/uint384.zig
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,15 @@ pub fn uint384Split128(
ids_data: std.StringHashMap(HintReference),
ap_tracking: ApTracking,
) !void {
const bound = Felt252.pow2Const(128);
const a = try hint_utils.getIntegerFromVarName("a", vm, ids_data, ap_tracking);

const high, const low = a.divRem(bound);
const number = a.toU256();

try hint_utils.insertValueFromVarName(allocator, "low", MaybeRelocatable.fromFelt(low), vm, ids_data, ap_tracking);
try hint_utils.insertValueFromVarName(allocator, "high", MaybeRelocatable.fromFelt(high), vm, ids_data, ap_tracking);
const low = number & ((1 << 128) - 1);
const high = number >> 128;

try hint_utils.insertValueFromVarName(allocator, "low", MaybeRelocatable.fromInt(u256, low), vm, ids_data, ap_tracking);
try hint_utils.insertValueFromVarName(allocator, "high", MaybeRelocatable.fromInt(u256, high), vm, ids_data, ap_tracking);
}

// Implements Hint:
Expand Down Expand Up @@ -129,7 +131,7 @@ pub fn addNoUint384Check(
var buffer: [20]u8 = undefined;

inline for (0..3) |i| {
var sum = try a.limbs[i].toInt(u258) + try b.limbs[i].toInt(u258);
var sum = try a.limbs[i].toInt(u512) + try b.limbs[i].toInt(u512);

if (prev_carry) sum += 1;

Expand Down
6 changes: 3 additions & 3 deletions src/vm/core.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1407,11 +1407,11 @@ pub const OperandsResult = struct {
/// The second operand value.
op_1: MaybeRelocatable = undefined,
/// The relocatable address of the destination operand.
dst_addr: Relocatable = .{},
dst_addr: Relocatable = undefined,
/// The relocatable address of the first operand.
op_0_addr: Relocatable = .{},
op_0_addr: Relocatable = undefined,
/// The relocatable address of the second operand.
op_1_addr: Relocatable = .{},
op_1_addr: Relocatable = undefined,
/// Indicator for deduced operands.
deduced_operands: u8 = 0,

Expand Down
15 changes: 6 additions & 9 deletions src/vm/memory/memory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -442,15 +442,12 @@ pub const Memory = struct {
// TODO: rewrite all on self rel address
// Return null if either the segment index or offset is not valid.
// Otherwise, return the maybe_relocatable value at the specified address.
return if (data.items[segment_index].items[address.offset].getValue()) |val|
switch (val) {
.relocatable => |addr| self.relAddress(
addr,
) catch unreachable,
else => |_| val,
}
else
null;
return switch (data.items[segment_index].items[address.offset].getValue() orelse return null) {
.relocatable => |addr| self.relAddress(
addr,
) catch unreachable,
else => |v| v,
};
}

/// Retrieves a `Felt252` value from the memory at the specified relocatable address.
Expand Down
20 changes: 20 additions & 0 deletions src/vm/memory/relocatable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,26 @@ pub const MaybeRelocatable = union(enum) {
relocatable: Relocatable,
felt: Felt252,

/// This method is interface method, when format is calling for this struct, this method is called
///
pub fn format(
self: Self,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
switch (self) {
.relocatable => |r| {
try writer.print("MaybeRelocatable(Relocatable(offset={},index={}))", .{ r.offset, r.segment_index });
},
.felt => |f| {
try writer.print("MaybeRelocatable(Felt({}))", .{f.toU256()});
},
}
}

/// Determines if two `MaybeRelocatable` instances are equal.
///
/// This method compares the variant type and the contained value. If both the variant
Expand Down

0 comments on commit 06328b3

Please sign in to comment.