The ModBuiltins runner is not able to manage empty add or mul
Describe the bug
This simple cairo code
from starkware.cairo.common.cairo_builtins import UInt384, ModBuiltin
from starkware.cairo.common.modulo import run_mod_p_circuit
from starkware.cairo.lang.compiler.lib.registers import get_fp_and_pc
func add{range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*}(
x: UInt384*, y: UInt384*, p: UInt384*
) -> UInt384* {
let (_, pc) = get_fp_and_pc();
pc_label:
let add_mod_offsets_ptr = pc + (add_offsets - pc_label);
let mul_mod_offsets_ptr = pc + (mul_offsets - pc_label);
assert [range_check96_ptr + 0] = x.d0;
assert [range_check96_ptr + 1] = x.d1;
assert [range_check96_ptr + 2] = x.d2;
assert [range_check96_ptr + 3] = x.d3;
assert [range_check96_ptr + 4] = y.d0;
assert [range_check96_ptr + 5] = y.d1;
assert [range_check96_ptr + 6] = y.d2;
assert [range_check96_ptr + 7] = y.d3;
run_mod_p_circuit(
p=[p],
values_ptr=cast(range_check96_ptr, UInt384*),
add_mod_offsets_ptr=add_mod_offsets_ptr,
add_mod_n=1,
mul_mod_offsets_ptr=mul_mod_offsets_ptr,
mul_mod_n=0,
);
let range_check96_ptr = range_check96_ptr + 12;
return cast(range_check96_ptr - 4, UInt384*);
add_offsets:
dw 0;
dw 4;
dw 8;
mul_offsets:
}
will raise
Exception: /Users/clementwalter/Documents/sayajin-labs/keth/.venv/lib/python3.10/site-packages/starkware/cairo/common/modulo.cairo:98:5: Error at pc=0:41:
E Got an exception while executing a hint: Unknown memory cell at address 4:4
E %{
Address 4:4 is actually mul_mod_ptr:values_ptr which is empty since no mul is to be performed.
Updating the above snippet to do only mul and no add will raise the same error but in segment 3:4:
func mul{range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*}(
x: UInt384*, y: UInt384*, p: UInt384*
) -> UInt384* {
let (_, pc) = get_fp_and_pc();
pc_label:
let add_mod_offsets_ptr = pc + (add_offsets - pc_label);
let mul_mod_offsets_ptr = pc + (mul_offsets - pc_label);
assert [range_check96_ptr + 0] = x.d0;
assert [range_check96_ptr + 1] = x.d1;
assert [range_check96_ptr + 2] = x.d2;
assert [range_check96_ptr + 3] = x.d3;
assert [range_check96_ptr + 4] = y.d0;
assert [range_check96_ptr + 5] = y.d1;
assert [range_check96_ptr + 6] = y.d2;
assert [range_check96_ptr + 7] = y.d3;
run_mod_p_circuit(
p=[p],
values_ptr=cast(range_check96_ptr, UInt384*),
add_mod_offsets_ptr=add_mod_offsets_ptr,
add_mod_n=0,
mul_mod_offsets_ptr=mul_mod_offsets_ptr,
mul_mod_n=1,
);
let range_check96_ptr = range_check96_ptr + 12;
return cast(range_check96_ptr - 4, UInt384*);
add_offsets:
mul_offsets:
dw 0;
dw 4;
dw 8;
}
Putting both add and mul works
func inv{range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*}(
x: UInt384*, p: UInt384*
) -> UInt384* {
let (_, pc) = get_fp_and_pc();
pc_label:
let add_mod_offsets_ptr = pc + (add_offsets - pc_label);
let mul_mod_offsets_ptr = pc + (mul_offsets - pc_label);
assert [range_check96_ptr + 0] = 1;
assert [range_check96_ptr + 1] = 0;
assert [range_check96_ptr + 2] = 0;
assert [range_check96_ptr + 3] = 0;
assert [range_check96_ptr + 4] = 0;
assert [range_check96_ptr + 5] = 0;
assert [range_check96_ptr + 6] = 0;
assert [range_check96_ptr + 7] = 0;
assert [range_check96_ptr + 8] = x.d0;
assert [range_check96_ptr + 9] = x.d1;
assert [range_check96_ptr + 10] = x.d2;
assert [range_check96_ptr + 11] = x.d3;
run_mod_p_circuit(
p=[p],
values_ptr=cast(range_check96_ptr, UInt384*),
add_mod_offsets_ptr=add_mod_offsets_ptr,
add_mod_n=1,
mul_mod_offsets_ptr=mul_mod_offsets_ptr,
mul_mod_n=1,
);
let range_check96_ptr = range_check96_ptr + 20;
return cast(range_check96_ptr - 4, UInt384*);
add_offsets:
dw 4;
dw 0;
dw 12;
mul_offsets:
dw 16;
dw 8;
dw 12;
}
It's worth noticing that the test program at https://github.com/lambdaclass/cairo-vm/blob/df12864e7a1ae5fe4aceb51954b03017ad508fb3/cairo_programs/mod_builtin_feature/common/modulo.cairo#L93-L124
slightly differs from the run_mod_p_circuit from the core lib because the assert are not being a if, see https://github.com/starkware-libs/cairo-lang/blob/8276ac35830148a397e1143389f23253c8b80e93/src/starkware/cairo/common/modulo.cairo#L12-L47
Problem is most probably located https://github.com/lambdaclass/cairo-vm/blob/main/vm/src/vm/runners/builtin_runner/modulo.rs#L521-L534 where one missed the none overriding https://github.com/starkware-libs/cairo-lang/blob/8276ac35830148a397e1143389f23253c8b80e93/src/starkware/cairo/lang/builtins/modulo/mod_builtin_runner.py#L349-L352
Let me handle this issue!
Hi, @ClementWalter! What's the status of this issue?
idle from my side, I don't use the cairo vm anymore. If you have not merged anything regarding it, the discrepancy probably persists, but I don't know if anyone apart us faced the issue