Skip to content

Commit

Permalink
add qm31 operations to VM
Browse files Browse the repository at this point in the history
  • Loading branch information
ohad-nir-starkware committed Feb 9, 2025
1 parent e15c6e6 commit daafda5
Show file tree
Hide file tree
Showing 13 changed files with 875 additions and 85 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
cairo_bench_programs,
cairo_proof_programs,
cairo_test_programs,
cairo_stwo_exclusive_programs,
cairo_1_test_contracts,
cairo_2_test_contracts,
]
Expand Down Expand Up @@ -124,6 +125,12 @@ jobs:
path: ${{ env.CAIRO_PROGRAMS_PATH }}
key: cairo_test_programs-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'examples/wasm-demo/src/array_sum.cairo') }}
fail-on-cache-miss: true
- name: Fetch cairo stwo exclusive programs
uses: actions/cache/restore@v3
with:
path: ${{ env.CAIRO_PROGRAMS_PATH }}
key: cairo_stwo_exclusive_programs-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'examples/wasm-demo/src/array_sum.cairo') }}
fail-on-cache-miss: true
- name: Fetch proof programs
uses: actions/cache/restore@v3
with:
Expand Down Expand Up @@ -486,6 +493,9 @@ jobs:
- program-target: cairo_test_programs
programs-dir: cairo_programs
extra-args: '--cairo_pie_output {program}.rs.pie.zip'
- program-target: cairo_stwo_exclusive_programs
programs-dir: cairo_programs
extra-args: '--cairo_pie_output {program}.rs.pie.zip'
name: Compute memory and execution traces with cairo-vm
needs: [ build-programs, build-release ]
runs-on: ubuntu-22.04
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ ark-std = { version = "0.4.0", default-features = false }
# For fuzzing
arbitrary = { version = "1.3.0", features = ["derive"] }

#stwo-prover = { git = "https://github.com/starkware-libs/stwo", rev = "a194fad", features = [
# "parallel",
#], default-features = false }

[profile.test]
opt-level = 2

Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ CAIRO_RS_MEM:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.rs.memory, $(COMPILED
CAIRO_RS_TRACE:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.rs.trace, $(COMPILED_TESTS))
CAIRO_RS_PIE:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.rs.pie.zip, $(COMPILED_TESTS))

STWO_EXCLUSIVE_DIR=cairo_programs/stwo_exclusive_programs
STWO_EXCLUSIVE_FILES:=$(wildcard $(STWO_EXCLUSIVE_DIR)/*.cairo)
COMPILED_STWO_EXCLUSIVE_TESTS:=$(patsubst $(STWO_EXCLUSIVE_DIR)/%.cairo, $(STWO_EXCLUSIVE_DIR)/%.json, $(STWO_EXCLUSIVE_FILES))

BENCH_DIR=cairo_programs/benchmarks
BENCH_FILES:=$(wildcard $(BENCH_DIR)/*.cairo)
COMPILED_BENCHES:=$(patsubst $(BENCH_DIR)/%.cairo, $(BENCH_DIR)/%.json, $(BENCH_FILES))
Expand Down Expand Up @@ -249,6 +253,7 @@ check:

cairo_test_programs: $(COMPILED_TESTS) $(COMPILED_BAD_TESTS) $(COMPILED_NORETROCOMPAT_TESTS) $(COMPILED_PRINT_TESTS) $(COMPILED_MOD_BUILTIN_TESTS) $(COMPILED_SECP_CAIRO0_HINTS) $(COMPILED_KZG_DA_CAIRO0_HINTS)
cairo_proof_programs: $(COMPILED_PROOF_TESTS) $(COMPILED_MOD_BUILTIN_PROOF_TESTS)
cairo_stwo_exclusive_programs: $(COMPILED_STWO_EXCLUSIVE_TESTS)
cairo_bench_programs: $(COMPILED_BENCHES)
cairo_1_test_contracts: $(CAIRO_1_COMPILED_CASM_CONTRACTS)
cairo_2_test_contracts: $(CAIRO_2_COMPILED_CASM_CONTRACTS)
Expand Down
2 changes: 1 addition & 1 deletion cairo-vm-tracer/src/tracer_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl TracerData {
let (instruction_encoding, _) =
get_instruction_encoding(entry.pc, &memory, program.prime())?;

let instruction_encoding = instruction_encoding.to_u64();
let instruction_encoding = instruction_encoding.to_u128();

Check warning on line 146 in cairo-vm-tracer/src/tracer_data.rs

View check run for this annotation

Codecov / codecov/patch

cairo-vm-tracer/src/tracer_data.rs#L146

Added line #L146 was not covered by tests
if instruction_encoding.is_none() {
return Err(TraceDataError::FailedToConvertInstructionEncoding);
}
Expand Down
274 changes: 274 additions & 0 deletions cairo_programs/stwo_exclusive_programs/qm31_opcodes_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import FALSE, TRUE

func main{}() {
alloc_locals;
// x*y coordinates_to_packed([947980980, 1510986506, 623360030, 1260310989]),
// x+y coordinates_to_packed([526650964, 1026816730, 1318309406, 1181635724]),
// x coordinates_to_packed([1414213562, 1732050807, 1618033988, 1234567890]),
// y coordinates_to_packed([1259921049, 1442249570, 1847759065, 2094551481]),
let (local qm31_op0_coordinates) = alloc();
assert qm31_op0_coordinates[0] = 1414213562;
assert qm31_op0_coordinates[1] = 1732050807;
assert qm31_op0_coordinates[2] = 1618033988;
assert qm31_op0_coordinates[3] = 1234567890;
let qm31_op0 = qm31_op0_coordinates[0] + qm31_op0_coordinates[1]*(2**36) + qm31_op0_coordinates[2]*(2**72) + qm31_op0_coordinates[3]*(2**108);

let (local qm31_op1_coordinates) = alloc();
assert qm31_op1_coordinates[0] = 1259921049;
assert qm31_op1_coordinates[1] = 1442249570;
assert qm31_op1_coordinates[2] = 1847759065;
assert qm31_op1_coordinates[3] = 2094551481;
let qm31_op1 = qm31_op1_coordinates[0] + qm31_op1_coordinates[1]*(2**36) + qm31_op1_coordinates[2]*(2**72) + qm31_op1_coordinates[3]*(2**108);

let (local qm31_add_dst_coordinates) = alloc();
assert qm31_add_dst_coordinates[0] = 526650964;
assert qm31_add_dst_coordinates[1] = 1026816730;
assert qm31_add_dst_coordinates[2] = 1318309406;
assert qm31_add_dst_coordinates[3] = 1181635724;
let qm31_add_dst = qm31_add_dst_coordinates[0] + qm31_add_dst_coordinates[1]*(2**36) + qm31_add_dst_coordinates[2]*(2**72) + qm31_add_dst_coordinates[3]*(2**108);

let (local qm31_mul_dst_coordinates) = alloc();
assert qm31_mul_dst_coordinates[0] = 947980980;
assert qm31_mul_dst_coordinates[1] = 1510986506;
assert qm31_mul_dst_coordinates[2] = 623360030;
assert qm31_mul_dst_coordinates[3] = 1260310989;
let qm31_mul_dst = qm31_mul_dst_coordinates[0] + qm31_mul_dst_coordinates[1]*(2**36) + qm31_mul_dst_coordinates[2]*(2**72) + qm31_mul_dst_coordinates[3]*(2**108);

let runner_output_mul_dst = run_qm31_operation_get_dst(is_mul=TRUE, op0=qm31_op0, op1=qm31_op1);
assert runner_output_mul_dst = qm31_mul_dst;
let runner_output_add_dst = run_qm31_operation_get_dst(is_mul=FALSE, op0=qm31_op0, op1=qm31_op1);
assert runner_output_add_dst = qm31_add_dst;
//let runner_output_mul_dst = run_qm31_operation_get_dst(is_mul=TRUE, op0=qm31_op0, op1=qm31_op1);
// assert runner_output_mul_dst = qm31_mul_dst;

let runner_output_mul_op1 = run_qm31_operation_get_op1(is_mul=TRUE, dst=qm31_mul_dst, op0=qm31_op0);
assert runner_output_mul_op1 = qm31_op1;
let runner_output_add_op1 = run_qm31_operation_get_op1(is_mul=FALSE, dst=qm31_add_dst, op0=qm31_op0);
assert runner_output_add_op1 = qm31_op1;

let runner_output_mul_op0 = run_qm31_operation_get_op0(is_mul=TRUE, dst=qm31_mul_dst, op1=qm31_op1);
assert runner_output_mul_op0 = qm31_op0;
let runner_output_add_op0 = run_qm31_operation_get_op0(is_mul=FALSE, dst=qm31_add_dst, op1=qm31_op1);
assert runner_output_add_op0 = qm31_op0;

// let runner_output_mul_op0 = run_qm31_operation_get_op0(is_mul=TRUE, dst=qm31_mul_dst, op1=qm31_op1);
// //assert qm31_op1 = qm31_op0;
// assert runner_output_mul_op0 = qm31_op0;
// let runner_output_mul_op1 = run_qm31_operation_get_op1(is_mul=TRUE, dst=qm31_mul_dst, op0=qm31_op0);
// assert runner_output_mul_op1 = qm31_op1;

return ();
}

// missing_operand_index
func run_qm31_operation_get_dst(
is_mul: felt,
op0: felt,
op1: felt,
) -> felt {
//alloc_locals;
let offset0 = 2**15;
let offset1 = (2**15)-4;
let offset2 = (2**15)-3;
let flag_dst_base_fp = 0;
let flag_op0_base_fp = 1;
let flag_op1_imm = 0;
let flag_op1_base_fp = 1;
let flag_op1_base_ap = 0;
let flag_res_add = 0;
let flag_res_mul = is_mul; //
let flag_PC_update_jump = 0;
let flag_PC_update_jump_rel = 0;
let flag_PC_update_jnz = 0;
let flag_ap_update_add = 0;
let flag_ap_update_add_1 = 0;
let flag_opcode_call = 0;
let flag_opcode_ret = 0;
let flag_opcode_assert_eq = 1;
let flag_num_qm31_add = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+0*(2**6)+flag_opcode_assert_eq*(2**14);
let flag_num_qm31_mul = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+1*(2**6)+flag_opcode_assert_eq*(2**14);
let qm31_opcode_extension_num = 3;
let qm31_add_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_add*(2**48) + qm31_opcode_extension_num*(2**63);
let qm31_mul_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_mul*(2**48) + qm31_opcode_extension_num*(2**63);
static_assert qm31_mul_instruction_num==32302772004019011584;
static_assert qm31_add_instruction_num==32284757605509529600;
if (is_mul == TRUE) {
dw 32302772004019011584;
return [ap];
} else {
dw 32284757605509529600;
}
// dw 32302772004019011584;
return [ap];
}

// offset0 = 0;
// offset1 = (2**15)-4
// offset2 = (2**15)-3

// flag_dst_base_fp = 0
// flag_op0_base_fp = 1
// flag_op1_imm = 0
// flag_op1_base_fp = 1
// flag_op1_base_ap = 0
// flag_res_add = 0
// flag_res_mul = is_mul #
// flag_PC_update_jump = 0
// flag_PC_update_jump_rel = 0
// flag_PC_update_jnz = 0
// flag_ap_update_add = 0
// flag_ap_update_add_1 = 0
// flag_opcode_call = 0
// flag_opcode_ret = 0
// flag_opcode_assert_eq = 1

// flag_num_qm31_add = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+0*(2**6)+flag_opcode_assert_eq*(2**14)
// flag_num_qm31_mul = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+1*(2**6)+flag_opcode_assert_eq*(2**14)
// qm31_opcode_extension_num = 3
// qm31_add_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_add*(2**48) + qm31_opcode_extension_num*(2**63)
// qm31_mul_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_mul*(2**48) + qm31_opcode_extension_num*(2**63)

func run_qm31_operation_get_op1(
is_mul: felt,
dst: felt,
op0: felt,
) -> felt {
//alloc_locals;
let offset0 = (2**15)-4;
let offset1 = (2**15)-3;
let offset2 = 2**15;
let flag_dst_base_fp = 1;
let flag_op0_base_fp = 1;
let flag_op1_imm = 0;
let flag_op1_base_fp = 0;
let flag_op1_base_ap = 1;
let flag_res_add = 0;
let flag_res_mul = is_mul; //
let flag_PC_update_jump = 0;
let flag_PC_update_jump_rel = 0;
let flag_PC_update_jnz = 0;
let flag_ap_update_add = 0;
let flag_ap_update_add_1 = 0;
let flag_opcode_call = 0;
let flag_opcode_ret = 0;
let flag_opcode_assert_eq = 1;
let flag_num_qm31_add = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+0*(2**6)+flag_opcode_assert_eq*(2**14);
let flag_num_qm31_mul = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+1*(2**6)+flag_opcode_assert_eq*(2**14);
let qm31_opcode_extension_num = 3;
let qm31_add_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_add*(2**48) + qm31_opcode_extension_num*(2**63);
let qm31_mul_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_mul*(2**48) + qm31_opcode_extension_num*(2**63);
static_assert qm31_mul_instruction_num==32305305291694374908;
static_assert qm31_add_instruction_num==32287290893184892924;
if (is_mul == TRUE) {
dw 32305305291694374908;
return [ap];
} else {
dw 32287290893184892924;
}
return [ap];
}

// offset0 = (2**15)-4
// offset1 = (2**15)-3
// offset2 = 2**15

// flag_dst_base_fp = 1
// flag_op0_base_fp = 1
// flag_op1_imm = 0
// flag_op1_base_fp = 0
// flag_op1_base_ap = 1
// flag_res_add = 0
// flag_res_mul = is_mul //
// flag_PC_update_jump = 0
// flag_PC_update_jump_rel = 0
// flag_PC_update_jnz = 0
// flag_ap_update_add = 0
// flag_ap_update_add_1 = 0
// flag_opcode_call = 0
// flag_opcode_ret = 0
// flag_opcode_assert_eq = 1

// flag_num_qm31_add = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+0*(2**6)+flag_opcode_assert_eq*(2**14)
// flag_num_qm31_mul = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+1*(2**6)+flag_opcode_assert_eq*(2**14)
// qm31_opcode_extension_num = 3;
// qm31_add_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_add*(2**48) + qm31_opcode_extension_num*(2**63);
// qm31_mul_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_mul*(2**48) + qm31_opcode_extension_num*(2**63);

func run_qm31_operation_get_op0(
is_mul: felt,
dst: felt,
op1: felt,
) -> felt {
//alloc_locals;
let offset0 = (2**15)-4;
let offset1 = 2**15;
let offset2 = (2**15)-3;
let flag_dst_base_fp = 1;
let flag_op0_base_fp = 0;
let flag_op1_imm = 0;
let flag_op1_base_fp = 1;
let flag_op1_base_ap = 0;
let flag_res_add = 0;
let flag_res_mul = is_mul; //
let flag_PC_update_jump = 0;
let flag_PC_update_jump_rel = 0;
let flag_PC_update_jnz = 0;
let flag_ap_update_add = 0;
let flag_ap_update_add_1 = 0;
let flag_opcode_call = 0;
let flag_opcode_ret = 0;
let flag_opcode_assert_eq = 1;
let flag_num_qm31_add = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+0*(2**6)+flag_opcode_assert_eq*(2**14);
let flag_num_qm31_mul = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+1*(2**6)+flag_opcode_assert_eq*(2**14);
let qm31_opcode_extension_num = 3;
let qm31_add_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_add*(2**48) + qm31_opcode_extension_num*(2**63);
let qm31_mul_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_mul*(2**48) + qm31_opcode_extension_num*(2**63);
static_assert qm31_mul_instruction_num==32302490529042563068;
static_assert qm31_add_instruction_num==32284476130533081084;
if (is_mul == TRUE) {
dw 32302490529042563068;
return [ap];
} else {
dw 32284476130533081084;
}
return [ap];
}

// offset0 = (2**15)-4
// offset1 = 2**15
// offset2 = (2**15)-3

// flag_dst_base_fp = 1
// flag_op0_base_fp = 0
// flag_op1_imm = 0
// flag_op1_base_fp = 1
// flag_op1_base_ap = 0
// flag_res_add = 0
// flag_res_mul = is_mul //
// flag_PC_update_jump = 0
// flag_PC_update_jump_rel = 0
// flag_PC_update_jnz = 0
// flag_ap_update_add = 0
// flag_ap_update_add_1 = 0
// flag_opcode_call = 0
// flag_opcode_ret = 0
// flag_opcode_assert_eq = 1

// flag_num_qm31_add = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+0*(2**6)+flag_opcode_assert_eq*(2**14)
// flag_num_qm31_mul = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_op1_base_ap*(2**4)+1*(2**6)+flag_opcode_assert_eq*(2**14)
// qm31_opcode_extension_num = 3
// qm31_add_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_add*(2**48) + qm31_opcode_extension_num*(2**63)
// qm31_mul_instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num_qm31_mul*(2**48) + qm31_opcode_extension_num*(2**63)
Loading

0 comments on commit daafda5

Please sign in to comment.