sp1_core_executor/
opts.rs1use crate::{
2 cost_and_height_per_syscall, rv64im_costs, utils::trunc_32, RetainedEventsPreset, RiscvAirId,
3 SyscallCode, BYTE_NUM_ROWS, RANGE_NUM_ROWS,
4};
5use enum_map::EnumMap;
6use serde::{Deserialize, Serialize};
7use std::{collections::HashSet, env};
8
9const MAX_SHARD_SIZE: usize = 1 << 24;
10
11pub const ELEMENT_THRESHOLD: u64 = (1 << 28) + (1 << 27);
13pub const HEIGHT_THRESHOLD: u64 = 1 << 22;
15pub const MINIMAL_TRACE_CHUNK_THRESHOLD: u64 =
17 2147483648 / std::mem::size_of::<sp1_jit::MemValue>() as u64;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
21pub struct ShardingThreshold {
22 pub element_threshold: u64,
24 pub height_threshold: u64,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub struct SP1CoreOpts {
31 pub minimal_trace_chunk_threshold: u64,
33 pub shard_size: usize,
35 pub sharding_threshold: ShardingThreshold,
37 pub retained_events_presets: HashSet<RetainedEventsPreset>,
39 pub global_dependencies_opt: bool,
41}
42
43impl Default for SP1CoreOpts {
44 fn default() -> Self {
45 let minimal_trace_chunk_threshold = env::var("MINIMAL_TRACE_CHUNK_THRESHOLD").map_or_else(
46 |_| MINIMAL_TRACE_CHUNK_THRESHOLD,
47 |s| s.parse::<u64>().unwrap_or(MINIMAL_TRACE_CHUNK_THRESHOLD),
48 );
49
50 let shard_size = env::var("SHARD_SIZE")
51 .map_or_else(|_| MAX_SHARD_SIZE, |s| s.parse::<usize>().unwrap_or(MAX_SHARD_SIZE));
52
53 let element_threshold = env::var("ELEMENT_THRESHOLD")
54 .map_or_else(|_| ELEMENT_THRESHOLD, |s| s.parse::<u64>().unwrap_or(ELEMENT_THRESHOLD));
55
56 let height_threshold = env::var("HEIGHT_THRESHOLD")
57 .map_or_else(|_| HEIGHT_THRESHOLD, |s| s.parse::<u64>().unwrap_or(HEIGHT_THRESHOLD));
58
59 let sharding_threshold = ShardingThreshold { element_threshold, height_threshold };
60
61 let mut retained_events_presets = HashSet::new();
62 retained_events_presets.insert(RetainedEventsPreset::Bls12381Field);
63 retained_events_presets.insert(RetainedEventsPreset::Bn254Field);
64 retained_events_presets.insert(RetainedEventsPreset::Sha256);
65 retained_events_presets.insert(RetainedEventsPreset::Poseidon2);
66 retained_events_presets.insert(RetainedEventsPreset::U256Ops);
67
68 Self {
69 minimal_trace_chunk_threshold,
70 shard_size,
71 sharding_threshold,
72 retained_events_presets,
73 global_dependencies_opt: false,
74 }
75 }
76}
77
78#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
80pub struct SplitOpts {
81 pub pack_trace_threshold: u64,
84 pub combine_memory_threshold: usize,
87 pub combine_page_prot_threshold: usize,
90 pub syscall_threshold: EnumMap<SyscallCode, usize>,
92 pub memory: usize,
94 pub page_prot: usize,
96}
97
98impl SplitOpts {
99 #[must_use]
101 pub fn new(opts: &SP1CoreOpts, program_size: usize, page_protect_allowed: bool) -> Self {
102 assert!(!page_protect_allowed, "page protection is turned off");
103
104 let costs = rv64im_costs();
105
106 let mut available_trace_area = opts.sharding_threshold.element_threshold;
107 let mut fixed_trace_area = 0;
108 fixed_trace_area += program_size.next_multiple_of(32) * costs[&RiscvAirId::Program];
109 fixed_trace_area += BYTE_NUM_ROWS as usize * costs[&RiscvAirId::Byte];
110 fixed_trace_area += RANGE_NUM_ROWS as usize * costs[&RiscvAirId::Range];
111
112 assert!(
113 available_trace_area >= fixed_trace_area as u64,
114 "SP1CoreOpts's element threshold is too low"
115 );
116
117 available_trace_area -= fixed_trace_area as u64;
118
119 let max_height = opts.sharding_threshold.height_threshold;
120
121 let syscall_threshold = EnumMap::from_fn(|syscall_code: SyscallCode| {
122 if syscall_code.should_send() == 0 {
123 return 0;
124 }
125
126 let (cost_per_syscall, max_height_per_syscall) =
127 cost_and_height_per_syscall(syscall_code, &costs, page_protect_allowed);
128 let element_threshold = trunc_32(available_trace_area as usize / cost_per_syscall);
129 let height_threshold = trunc_32(max_height as usize / max_height_per_syscall);
130
131 element_threshold.min(height_threshold)
132 });
133
134 let cost_per_memory = costs[&RiscvAirId::MemoryGlobalInit] + costs[&RiscvAirId::Global];
135 let memory = trunc_32(
136 (available_trace_area as usize / cost_per_memory).min(max_height as usize) / 2,
137 );
138
139 let pack_trace_threshold = 2 * opts.sharding_threshold.element_threshold / 3;
141 let combine_memory_threshold =
143 trunc_32(3 * opts.sharding_threshold.element_threshold as usize / cost_per_memory / 20);
144
145 Self {
146 pack_trace_threshold,
147 combine_memory_threshold,
148 combine_page_prot_threshold: 0,
149 syscall_threshold,
150 memory,
151 page_prot: 0,
152 }
153 }
154}