Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactor PerfConfig #1144

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion benches/bench.env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Lurk config, used only in `justfile` by default
LURK_PERF=max-parallel-simple
LURK_PERF=fully-parallel
LURK_RC=100,600
LURK_BENCH_NOISE_THRESHOLD=0.05
107 changes: 56 additions & 51 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl Settings {
Config::builder()
// Default settings if unspecified in the config file
.set_default(public_params, public_params_default_dir().to_string())?
.set_default("perf", "max-parallel-simple".to_string())?
.set_default("perf", "fully-parallel".to_string())?
.add_source(File::with_name(config_file.as_str()).required(false))
// Then override with any `LURK` environment variables
.add_source(Environment::with_prefix("LURK"))
Expand Down Expand Up @@ -117,59 +117,68 @@ pub fn home_dir() -> Utf8PathBuf {
pub struct PerfConfig {
/// Parallelism settings
pub parallelism: ParallelConfig,
/// Witness generation settings
pub witness_generation: WitnessGeneration,
}

impl PerfConfig {
/// Every config attribute set to sequential
#[inline]
fn fully_sequential() -> Self {
Self {
parallelism: ParallelConfig {
recursive_steps: Flow::Sequential,
synthesis: Flow::Sequential,
poseidon_witnesses: Flow::Sequential,
},
witness_generation: WitnessGeneration {
precompute_neptune: false,
wit_gen_vs_folding: Flow::Sequential,
frames: Flow::Sequential,
slots: Flow::Sequential,
},
}
}

fn max_parallel_simple() -> Self {
/// Every config attribute set to sequential, except for witness generation
/// vs folding
#[inline]
fn parallel_wit_gen_vs_folding() -> Self {
Self {
parallelism: ParallelConfig {
recursive_steps: Flow::Parallel,
synthesis: Flow::Parallel,
poseidon_witnesses: Flow::Parallel,
},
witness_generation: WitnessGeneration {
precompute_neptune: true,
wit_gen_vs_folding: Flow::Parallel,
frames: Flow::Sequential,
slots: Flow::Sequential,
},
}
}

fn parallel_synthesis() -> Self {
/// Every config attribute set to sequential, except for witness generation
/// for the slots
#[inline]
fn parallel_slots() -> Self {
Self {
parallelism: ParallelConfig {
recursive_steps: Flow::Parallel,
synthesis: Flow::Parallel,
poseidon_witnesses: Flow::Sequential,
},
witness_generation: WitnessGeneration {
precompute_neptune: true,
wit_gen_vs_folding: Flow::Sequential,
frames: Flow::Sequential,
slots: Flow::Parallel,
},
}
}

fn parallel_steps_only() -> Self {
/// Every config attribute set to sequential, except for witness generation
/// for each Frame within a MultiFrame
#[inline]
fn parallel_frames() -> Self {
Self {
parallelism: ParallelConfig {
recursive_steps: Flow::Parallel,
synthesis: Flow::Sequential,
poseidon_witnesses: Flow::Sequential,
wit_gen_vs_folding: Flow::Sequential,
frames: Flow::Parallel,
slots: Flow::Sequential,
},
witness_generation: WitnessGeneration {
precompute_neptune: true,
}
}

/// Every config attribute set to parallel
#[inline]
fn fully_parallel() -> Self {
Self {
parallelism: ParallelConfig {
wit_gen_vs_folding: Flow::Parallel,
frames: Flow::Parallel,
slots: Flow::Parallel,
},
}
}
Expand All @@ -178,20 +187,12 @@ impl PerfConfig {
/// Parallel configuration settings
#[derive(Default, Debug, PartialEq, Eq)]
pub struct ParallelConfig {
/// Multiple `StepCircuit`s.
pub recursive_steps: Flow,
/// Synthesis (within one `StepCircuit`)
pub synthesis: Flow,
/// The poseidon witness part of synthesis.
pub poseidon_witnesses: Flow,
}

/// Should we use optimized witness-generation when possible?
#[derive(Debug, Default, PartialEq, Eq)]
pub struct WitnessGeneration {
/// NOTE: Neptune itself *will* do this transparently at the level of individual hashes, where possible.
/// so this configuration is only required for higher-level decisions.
pub precompute_neptune: bool,
/// Witnesses generation for MultiFrames in parallel with folding.
pub wit_gen_vs_folding: Flow,
/// Parallel witness generation for each Frame within a MultiFrame
pub frames: Flow,
/// Parallel witness generation for each slot in a Frame
pub slots: Flow,
}

/// The level of parallelism used when synthesizing the Lurk circuit
Expand All @@ -208,11 +209,13 @@ pub enum Flow {

impl Flow {
/// Returns `true` on `Flow::Sequential`
#[inline]
pub fn is_sequential(&self) -> bool {
matches!(self, Self::Sequential)
}

/// Returns `true` on `Flow::Parallel` or `Flow::ParallelN`
#[inline]
pub fn is_parallel(&self) -> bool {
!self.is_sequential()
}
Expand All @@ -223,19 +226,21 @@ impl Flow {
#[serde(rename_all = "kebab-case")]
enum CannedConfig {
FullySequential,
ParallelSlots,
ParallelFrames,
ParallelWitGenVsFolding,
#[default]
MaxParallelSimple,
ParallelStepsOnly,
ParallelSynthesis,
FullyParallel,
}

impl From<CannedConfig> for PerfConfig {
fn from(canned: CannedConfig) -> Self {
match canned {
CannedConfig::FullySequential => Self::fully_sequential(),
CannedConfig::MaxParallelSimple => Self::max_parallel_simple(),
CannedConfig::ParallelSynthesis => Self::parallel_synthesis(),
CannedConfig::ParallelStepsOnly => Self::parallel_steps_only(),
CannedConfig::ParallelSlots => Self::parallel_slots(),
CannedConfig::ParallelFrames => Self::parallel_frames(),
CannedConfig::ParallelWitGenVsFolding => Self::parallel_wit_gen_vs_folding(),
CannedConfig::FullyParallel => Self::fully_parallel(),
}
}
}
Expand Down Expand Up @@ -287,7 +292,7 @@ mod tests {
.write_all(format!("public_params_dir = \"{public_params_dir}\"\n").as_bytes())
.unwrap();
config_file
.write_all("perf = \"parallel-steps-only\"\n".as_bytes())
.write_all("perf = \"parallel-wit-gen-vs-folding\"\n".as_bytes())
.unwrap();

// Overwrite public params dir to simulate CLI setting
Expand All @@ -298,7 +303,7 @@ mod tests {
let config = Settings::from_config(&config_dir, Some(&overrides)).unwrap();

assert_eq!(config.public_params_dir, public_params_dir_cli);
assert_eq!(config.perf, PerfConfig::parallel_steps_only());
assert_eq!(config.perf, PerfConfig::parallel_wit_gen_vs_folding());
}

// Tests that duplicate config keys result in an error
Expand Down
8 changes: 2 additions & 6 deletions src/lem/multiframe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,12 @@ impl<'a, F: LurkField, C: Coprocessor<F>> MultiFrame<'a, F, C> {
store,
frames,
num_slots_per_frame,
lurk_config(None, None)
.perf
.parallelism
.poseidon_witnesses
.is_parallel(),
lurk_config(None, None).perf.parallelism.slots.is_parallel(),
);
if lurk_config(None, None)
.perf
.parallelism
.synthesis
.frames
.is_parallel()
{
Ok(synthesize_frames_parallel(
Expand Down
2 changes: 1 addition & 1 deletion src/proof/nova.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl<'a, F: CurveCycleEquipped, C: Coprocessor<F>> RecursiveSNARKTrait<F, C1LEM<
recursive_snark_option = if lurk_config(None, None)
.perf
.parallelism
.recursive_steps
.wit_gen_vs_folding
.is_parallel()
{
let cc = steps.into_iter().map(Mutex::new).collect::<Vec<_>>();
Expand Down
2 changes: 1 addition & 1 deletion src/proof/supernova.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl<'a, F: CurveCycleEquipped, C: Coprocessor<F>> RecursiveSNARKTrait<F, C1LEM<
recursive_snark_option = if lurk_config(None, None)
.perf
.parallelism
.recursive_steps
.wit_gen_vs_folding
.is_parallel()
{
let cc = steps
Expand Down
2 changes: 1 addition & 1 deletion tests/lurk-cli-tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn test_prove_and_verify() {
file.write_all(b"!(verify \"supernova_bn256_10_18748ce7ba3dd0e7560ec64983d6b01d84a6303880b3b0b24878133aa1b4a6bb\")\n").unwrap();

let mut cmd = lurk_cmd();
cmd.env("LURK_PERF", "max-parallel-simple");
cmd.env("LURK_PERF", "fully-parallel");
cmd.arg("load");
cmd.arg(lurk_file.into_string());
cmd.arg("--public-params-dir");
Expand Down
1 change: 0 additions & 1 deletion tests/lurk-files-tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ fn test_demo() {

demo_examples.into_par_iter().for_each(|f| {
let mut cmd = lurk_cmd();
cmd.env("LURK_PERF", "max-parallel-simple");
cmd.arg(f);
cmd.assert().success();
});
Expand Down