#![allow(dead_code, unused_macros, clippy::too_many_arguments)]
use crate::fixed_point_closure::FixedPointClosureLabels;
use crate::fixed_point_graph::{FixedPointAnalysisKind, FixedPointForwardGraph};
use crate::fixed_point_resident::FixedPointResidentClosureLabels;
use crate::fixed_point_scratch::FixedPointScratch;
use vyre::ir::Program;
use vyre_primitives::graph::program_graph::ProgramGraphShape;
pub(crate) mod private {
pub trait Sealed {}
}
pub(crate) trait AnalysisFamily: private::Sealed {
const KIND: FixedPointAnalysisKind;
const NAME: &'static str;
const INPUT_BUFFER: &'static str = "fin";
const OUTPUT_BUFFER: &'static str = "fout";
fn build_program(shape: ProgramGraphShape, input: &str, output: &str) -> Program;
fn prepare_graph(
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
) -> Result<FixedPointForwardGraph, String>;
fn prepare_graph_with_scratch(
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
scratch: &mut FixedPointScratch,
) -> Result<FixedPointForwardGraph, String>;
fn closure_labels() -> FixedPointClosureLabels {
FixedPointClosureLabels {
require_kind: Self::NAME,
iterations: Self::NAME,
word_capacity: Self::NAME,
bitset_words: Self::NAME,
seed_tail: Self::NAME,
unpack_outputs: Self::NAME,
frontier_output: "frontier",
output_tail: Self::concat_name_output(),
convergence: Self::NAME,
}
}
fn resident_labels() -> FixedPointResidentClosureLabels {
FixedPointResidentClosureLabels {
kind: Self::KIND,
analysis: Self::NAME,
capacity: Self::concat_name_resident(),
output: "frontier",
tail: Self::concat_name_output(),
}
}
#[doc(hidden)]
fn concat_name_output() -> &'static str {
Self::NAME
}
#[doc(hidden)]
fn concat_name_resident() -> &'static str {
Self::NAME
}
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_via<A, F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
F: Fn(&Program, &[Vec<u8>], Option<[u32; 3]>) -> Result<Vec<Vec<u8>>, String>,
{
let owned_inputs = crate::dispatch_input_cache::OwnedDispatchInputs::new();
closure_borrowed_via::<A, _>(
&|program, inputs, grid| {
owned_inputs.dispatch_refreshing_frontier(program, inputs, grid, dispatch)
},
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_borrowed_via<A, F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>) -> Result<Vec<Vec<u8>>, String>,
{
crate::dispatch_decode::require_positive_iterations(A::NAME, max_iterations)?;
crate::dispatch_decode::require_bitset_tail_clear(A::NAME, seed_bits, node_count)?;
let out = closure_borrowed_into_via::<A, _>(
&|program, inputs, grid, outputs| {
let result = dispatch(program, inputs, grid)?;
crate::output_scratch::replace_outputs_preserving_slots(outputs, result);
Ok(())
},
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
)?;
crate::dispatch_decode::require_bitset_tail_clear(
&format!("{} output", A::NAME),
&out,
node_count,
)?;
Ok(out)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_borrowed_into_via<A, F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
let mut scratch = FixedPointScratch::default();
closure_borrowed_into_with_scratch_via::<A, _>(
dispatch,
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
&mut scratch,
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_borrowed_into_with_scratch_via<A, F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut FixedPointScratch,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
let mut result = crate::staging_reserve::reserved_fixed_point_result(
&format!("{} result", A::NAME),
node_count,
)?;
closure_borrowed_into_result_with_scratch_via::<A, _>(
dispatch,
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
scratch,
&mut result,
)?;
Ok(result)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_borrowed_into_result_with_scratch_via<A, F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
crate::dispatch_decode::require_positive_iterations(A::NAME, max_iterations)?;
let words = crate::dispatch_decode::bitset_word_capacity(A::NAME, node_count)?;
crate::dispatch_decode::require_bitset_words(A::NAME, seed_bits, words)?;
crate::dispatch_decode::require_bitset_tail_clear(A::NAME, seed_bits, node_count)?;
let graph = A::prepare_graph_with_scratch(
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
scratch,
)?;
closure_prepared_borrowed_into_result_with_scratch_via::<A, _>(
dispatch,
&graph,
seed_bits,
max_iterations,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_prepared_borrowed_into_with_scratch_via<A, F>(
dispatch: &F,
graph: &FixedPointForwardGraph,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut FixedPointScratch,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
let mut result = crate::staging_reserve::reserved_fixed_point_result(
&format!("{} prepared result", A::NAME),
graph.node_count,
)?;
closure_prepared_borrowed_into_result_with_scratch_via::<A, _>(
dispatch,
graph,
seed_bits,
max_iterations,
scratch,
&mut result,
)?;
Ok(result)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_prepared_borrowed_into_result_with_scratch_via<A, F>(
dispatch: &F,
graph: &FixedPointForwardGraph,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
let program = A::build_program(
ProgramGraphShape::new(graph.node_count, graph.edge_count),
A::INPUT_BUFFER,
A::OUTPUT_BUFFER,
);
closure_prepared_program_borrowed_into_result_with_scratch_via::<A, _>(
dispatch,
graph,
&program,
seed_bits,
max_iterations,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_plan_borrowed_into_with_scratch_via<A, F>(
dispatch: &F,
plan: &crate::fixed_point_graph::FixedPointAnalysisPlan,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut FixedPointScratch,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
let mut result = crate::staging_reserve::reserved_fixed_point_result(
&format!("{} planned result", A::NAME),
plan.graph().node_count,
)?;
closure_plan_borrowed_into_result_with_scratch_via::<A, _>(
dispatch,
plan,
seed_bits,
max_iterations,
scratch,
&mut result,
)?;
Ok(result)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn closure_plan_borrowed_into_result_with_scratch_via<A, F>(
dispatch: &F,
plan: &crate::fixed_point_graph::FixedPointAnalysisPlan,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
plan.require_kind(
A::KIND,
&format!("{}_plan_borrowed_into_result_with_scratch_via", A::NAME),
)?;
closure_prepared_program_borrowed_into_result_with_scratch_via::<A, _>(
dispatch,
plan.graph(),
plan.program(),
seed_bits,
max_iterations,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
fn closure_prepared_program_borrowed_into_result_with_scratch_via<A, F>(
dispatch: &F,
graph: &FixedPointForwardGraph,
program: &Program,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
A: AnalysisFamily,
F: Fn(&Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
crate::fixed_point_closure::run_forward_bitset_closure_into(
dispatch,
graph,
A::KIND,
program,
seed_bits,
max_iterations,
scratch,
result,
A::closure_labels(),
)
}
use crate::fixed_point_resident::{FixedPointResidentFrontierScratch, FixedPointResidentGraph};
#[allow(clippy::too_many_arguments)]
pub(crate) fn resident_plan_with_scratch<A>(
pipeline: &dyn vyre::CompiledPipeline,
graph: &FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &vyre::DispatchConfig,
scratch: &mut FixedPointScratch,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
{
let mut result = crate::fixed_point_resident::reserved_resident_closure_result(
&format!("{} resident result", A::NAME),
graph,
)?;
resident_plan_with_scratch_into::<A>(
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
&mut result,
)?;
Ok(result)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn resident_plan_with_scratch_into<A>(
pipeline: &dyn vyre::CompiledPipeline,
graph: &FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &vyre::DispatchConfig,
scratch: &mut FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
A: AnalysisFamily,
{
crate::fixed_point_resident::run_borrowed_resident_closure_into(
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
result,
A::resident_labels(),
&format!("{}_resident_plan_with_scratch_into", A::NAME),
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn resident_plan_with_backend_scratch<A>(
backend: &dyn vyre::VyreBackend,
pipeline: &dyn vyre::CompiledPipeline,
graph: &FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &vyre::DispatchConfig,
scratch: &mut FixedPointScratch,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
{
let mut result = crate::fixed_point_resident::reserved_resident_closure_result(
&format!("{} resident backend result", A::NAME),
graph,
)?;
resident_plan_with_backend_scratch_into::<A>(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
&mut result,
)?;
Ok(result)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn resident_plan_with_backend_scratch_into<A>(
backend: &dyn vyre::VyreBackend,
pipeline: &dyn vyre::CompiledPipeline,
graph: &FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &vyre::DispatchConfig,
scratch: &mut FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
A: AnalysisFamily,
{
crate::fixed_point_resident::run_ephemeral_resident_closure_into(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
result,
A::resident_labels(),
&format!("{}_resident_plan_with_backend_scratch_into", A::NAME),
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn resident_plan_with_reusable_frontier_scratch<A>(
backend: &dyn vyre::VyreBackend,
pipeline: &dyn vyre::CompiledPipeline,
graph: &FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &vyre::DispatchConfig,
scratch: &mut FixedPointScratch,
resident_frontier: &mut FixedPointResidentFrontierScratch,
) -> Result<Vec<u32>, String>
where
A: AnalysisFamily,
{
let mut result = crate::fixed_point_resident::reserved_resident_closure_result(
&format!("{} resident reusable result", A::NAME),
graph,
)?;
resident_plan_with_reusable_frontier_scratch_into::<A>(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
resident_frontier,
&mut result,
)?;
Ok(result)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn resident_plan_with_reusable_frontier_scratch_into<A>(
backend: &dyn vyre::VyreBackend,
pipeline: &dyn vyre::CompiledPipeline,
graph: &FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &vyre::DispatchConfig,
scratch: &mut FixedPointScratch,
resident_frontier: &mut FixedPointResidentFrontierScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
A: AnalysisFamily,
{
crate::fixed_point_resident::run_reusable_resident_closure_into(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
resident_frontier,
result,
A::resident_labels(),
&format!(
"{}_resident_plan_with_reusable_frontier_scratch_into",
A::NAME
),
)
}
#[macro_export]
macro_rules! define_analysis_family {
(
family: $family:ident,
kind: $kind:expr,
name: $name:expr,
program_builder: $program_builder:path,
graph_prep: $graph_prep:path,
graph_prep_scratch: $graph_prep_scratch:path,
input_buffer: $input_buffer:expr,
output_buffer: $output_buffer:expr,
closure_prefix: $closure_prefix:ident,
resident_prefix: $resident_prefix:ident,
word_capacity: $word_capacity:expr,
frontier_output: $frontier_output:expr,
resident_capacity: $resident_capacity:expr,
resident_output: $resident_output:expr,
visibility: $vis:vis,
) => {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
$vis struct $family;
impl $crate::analysis_family::private::Sealed for $family {}
impl $crate::analysis_family::AnalysisFamily for $family {
const KIND: $crate::fixed_point_graph::FixedPointAnalysisKind = $kind;
const NAME: &'static str = $name;
const INPUT_BUFFER: &'static str = $input_buffer;
const OUTPUT_BUFFER: &'static str = $output_buffer;
fn build_program(
shape: ::vyre_primitives::graph::program_graph::ProgramGraphShape,
input: &str,
output: &str,
) -> ::vyre::ir::Program {
$program_builder(shape, input, output)
}
fn prepare_graph(
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
) -> Result<$crate::fixed_point_graph::FixedPointForwardGraph, String> {
let mut scratch = $crate::fixed_point_scratch::FixedPointScratch::default();
Self::prepare_graph_with_scratch(
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
&mut scratch,
)
}
fn prepare_graph_with_scratch(
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
) -> Result<$crate::fixed_point_graph::FixedPointForwardGraph, String> {
$graph_prep_scratch(node_count, edge_offsets, edge_targets, edge_kind_mask, scratch)
}
fn closure_labels() -> $crate::fixed_point_closure::FixedPointClosureLabels {
$crate::fixed_point_closure::FixedPointClosureLabels {
require_kind: $name,
iterations: $name,
word_capacity: $word_capacity,
bitset_words: $name,
seed_tail: $name,
unpack_outputs: $name,
frontier_output: $frontier_output,
output_tail: concat!($name, " output"),
convergence: $name,
}
}
fn resident_labels() -> $crate::fixed_point_resident::FixedPointResidentClosureLabels {
$crate::fixed_point_resident::FixedPointResidentClosureLabels {
kind: Self::KIND,
analysis: $name,
capacity: $resident_capacity,
output: $resident_output,
tail: concat!($name, " output"),
}
}
}
paste::paste! {
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _via>]<F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
) -> Result<Vec<u32>, String>
where
F: Fn(&::vyre::ir::Program, &[Vec<u8>], Option<[u32; 3]>) -> Result<Vec<Vec<u8>>, String>,
{
$crate::analysis_family::closure_via::<$family, _>(
dispatch,
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _borrowed_via>]<F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
) -> Result<Vec<u32>, String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>) -> Result<Vec<Vec<u8>>, String>,
{
$crate::analysis_family::closure_borrowed_via::<$family, _>(
dispatch,
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _borrowed_into_via>]<F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
) -> Result<Vec<u32>, String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
$crate::analysis_family::closure_borrowed_into_via::<$family, _>(
dispatch,
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _borrowed_into_with_scratch_via>]<F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
) -> Result<Vec<u32>, String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
$crate::analysis_family::closure_borrowed_into_with_scratch_via::<$family, _>(
dispatch,
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
scratch,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _borrowed_into_result_with_scratch_via>]<F>(
dispatch: &F,
node_count: u32,
edge_offsets: &[u32],
edge_targets: &[u32],
edge_kind_mask: &[u32],
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
$crate::analysis_family::closure_borrowed_into_result_with_scratch_via::<$family, _>(
dispatch,
node_count,
edge_offsets,
edge_targets,
edge_kind_mask,
seed_bits,
max_iterations,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _prepared_borrowed_into_with_scratch_via>]<F>(
dispatch: &F,
graph: &$crate::fixed_point_graph::FixedPointForwardGraph,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
) -> Result<Vec<u32>, String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
$crate::analysis_family::closure_prepared_borrowed_into_with_scratch_via::<$family, _>(
dispatch,
graph,
seed_bits,
max_iterations,
scratch,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _prepared_borrowed_into_result_with_scratch_via>]<F>(
dispatch: &F,
graph: &$crate::fixed_point_graph::FixedPointForwardGraph,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
$crate::analysis_family::closure_prepared_borrowed_into_result_with_scratch_via::<$family, _>(
dispatch,
graph,
seed_bits,
max_iterations,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _plan_borrowed_into_with_scratch_via>]<F>(
dispatch: &F,
plan: &$crate::fixed_point_graph::FixedPointAnalysisPlan,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
) -> Result<Vec<u32>, String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
$crate::analysis_family::closure_plan_borrowed_into_with_scratch_via::<$family, _>(
dispatch,
plan,
seed_bits,
max_iterations,
scratch,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$closure_prefix _plan_borrowed_into_result_with_scratch_via>]<F>(
dispatch: &F,
plan: &$crate::fixed_point_graph::FixedPointAnalysisPlan,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String>
where
F: Fn(&::vyre::ir::Program, &[&[u8]], Option<[u32; 3]>, &mut Vec<Vec<u8>>) -> Result<(), String>,
{
$crate::analysis_family::closure_plan_borrowed_into_result_with_scratch_via::<$family, _>(
dispatch,
plan,
seed_bits,
max_iterations,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_scratch>](
pipeline: &dyn ::vyre::CompiledPipeline,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &::vyre::DispatchConfig,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
) -> Result<Vec<u32>, String> {
$crate::analysis_family::resident_plan_with_scratch::<$family>(
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_scratch_into>](
pipeline: &dyn ::vyre::CompiledPipeline,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &::vyre::DispatchConfig,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String> {
$crate::analysis_family::resident_plan_with_scratch_into::<$family>(
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_backend_scratch>](
backend: &dyn ::vyre::VyreBackend,
pipeline: &dyn ::vyre::CompiledPipeline,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &::vyre::DispatchConfig,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
) -> Result<Vec<u32>, String> {
$crate::analysis_family::resident_plan_with_backend_scratch::<$family>(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_backend_scratch_into>](
backend: &dyn ::vyre::VyreBackend,
pipeline: &dyn ::vyre::CompiledPipeline,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &::vyre::DispatchConfig,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
result: &mut Vec<u32>,
) -> Result<(), String> {
$crate::analysis_family::resident_plan_with_backend_scratch_into::<$family>(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
result,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_reusable_frontier_scratch>](
backend: &dyn ::vyre::VyreBackend,
pipeline: &dyn ::vyre::CompiledPipeline,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &::vyre::DispatchConfig,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
resident_frontier: &mut $crate::fixed_point_resident::FixedPointResidentFrontierScratch,
) -> Result<Vec<u32>, String> {
$crate::analysis_family::resident_plan_with_reusable_frontier_scratch::<$family>(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
resident_frontier,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_reusable_frontier_scratch_into>](
backend: &dyn ::vyre::VyreBackend,
pipeline: &dyn ::vyre::CompiledPipeline,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
config: &::vyre::DispatchConfig,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
resident_frontier: &mut $crate::fixed_point_resident::FixedPointResidentFrontierScratch,
result: &mut Vec<u32>,
) -> Result<(), String> {
$crate::analysis_family::resident_plan_with_reusable_frontier_scratch_into::<$family>(
backend,
pipeline,
graph,
seed_bits,
max_iterations,
config,
scratch,
resident_frontier,
result,
)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_reusable_frontier_scratch_sequence_window>](
backend: &dyn ::vyre::VyreBackend,
program: &::vyre::ir::Program,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
resident_frontier: &mut $crate::fixed_point_resident::FixedPointResidentFrontierScratch,
) -> Result<Vec<u32>, String> {
let mut result = $crate::fixed_point_resident::reserved_resident_closure_result(
concat!(stringify!($resident_prefix), " sequence result"),
graph,
)?;
[<$resident_prefix _plan_with_reusable_frontier_scratch_sequence_window_into>](
backend,
program,
graph,
seed_bits,
max_iterations,
scratch,
resident_frontier,
&mut result,
)?;
Ok(result)
}
#[allow(clippy::too_many_arguments)]
$vis fn [<$resident_prefix _plan_with_reusable_frontier_scratch_sequence_window_into>](
backend: &dyn ::vyre::VyreBackend,
program: &::vyre::ir::Program,
graph: &$crate::fixed_point_resident::FixedPointResidentGraph,
seed_bits: &[u32],
max_iterations: u32,
scratch: &mut $crate::fixed_point_scratch::FixedPointScratch,
resident_frontier: &mut $crate::fixed_point_resident::FixedPointResidentFrontierScratch,
result: &mut Vec<u32>,
) -> Result<(), String> {
$crate::fixed_point_resident_sequence::run_resident_sequence_window_into(
backend,
program,
graph,
seed_bits,
max_iterations,
scratch,
resident_frontier,
result,
$kind,
concat!(stringify!($closure_prefix), " sequence-window"),
)
}
}
};
}
#[cfg(test)]
mod tests {
use super::*;
struct DummyFamily;
impl private::Sealed for DummyFamily {}
impl AnalysisFamily for DummyFamily {
const KIND: FixedPointAnalysisKind = FixedPointAnalysisKind::Generic;
const NAME: &'static str = "dummy";
fn build_program(_shape: ProgramGraphShape, _input: &str, _output: &str) -> Program {
panic!("dummy build_program called")
}
fn prepare_graph(
_node_count: u32,
_edge_offsets: &[u32],
_edge_targets: &[u32],
_edge_kind_mask: &[u32],
) -> Result<FixedPointForwardGraph, String> {
Err("dummy".into())
}
fn prepare_graph_with_scratch(
_node_count: u32,
_edge_offsets: &[u32],
_edge_targets: &[u32],
_edge_kind_mask: &[u32],
_scratch: &mut FixedPointScratch,
) -> Result<FixedPointForwardGraph, String> {
Err("dummy".into())
}
}
#[test]
fn analysis_family_trait_is_object_safe_for_labels() {
let _labels = <DummyFamily as AnalysisFamily>::closure_labels();
let _resident = <DummyFamily as AnalysisFamily>::resident_labels();
assert_eq!(DummyFamily::KIND, FixedPointAnalysisKind::Generic);
assert_eq!(DummyFamily::NAME, "dummy");
}
#[test]
fn generic_closure_functions_compile() {
fn dummy_dispatch(
_program: &Program,
_inputs: &[&[u8]],
_grid: Option<[u32; 3]>,
_outputs: &mut Vec<Vec<u8>>,
) -> Result<(), String> {
Ok(())
}
let result = closure_borrowed_into_via::<DummyFamily, _>(
&dummy_dispatch,
4,
&[0, 1, 2, 3, 3],
&[1, 2],
&[1, 1],
&[0b0001],
1,
);
assert!(result.is_err());
}
}