vyre_driver/backend/dispatch_config.rs
1//! Immutable dispatch policy supplied by callers before backend execution.
2
3use std::time::Duration;
4
5/// Immutable execution policy supplied by the caller before dispatch.
6///
7/// `DispatchConfig` is an additive, non-exhaustive struct so that new backend
8/// options (conformance profiles, adapter hints, etc.) can be added without
9/// breaking the frozen `VyreBackend::dispatch` signature. Backends must treat
10/// every field as read-only policy and must not assume the presence of any
11/// particular option.
12///
13/// # Examples
14///
15/// ```
16/// use vyre::DispatchConfig;
17///
18/// // DispatchConfig is `#[non_exhaustive]`; construct it through
19/// // `default()` and overwrite the fields you want to change.
20/// let mut config = DispatchConfig::default();
21/// config.profile = Some("stress".to_string());
22/// config.ulp_budget = None;
23/// ```
24#[derive(Clone, Debug, Default, PartialEq, Eq)]
25#[non_exhaustive]
26pub struct DispatchConfig {
27 /// Optional stable profile identifier such as `default`, `stress`, or a
28 /// backend-defined conformance mode.
29 pub profile: Option<String>,
30 /// Optional maximum ULP error budget for approximate transcendental lowering.
31 ///
32 /// `None` and `Some(0)` require the strict target-text intrinsic path. A positive
33 /// budget allows backends to select fast approximate intrinsic wrappers only
34 /// when the wrapper contract is bounded by the supplied ULP ceiling.
35 pub ulp_budget: Option<u8>,
36 /// Optional timeout for the dispatch.
37 pub timeout: Option<Duration>,
38 /// Optional label for the dispatch (for debugging/profiling).
39 pub label: Option<String>,
40 /// Optional maximum output byte limit.
41 pub max_output_bytes: Option<usize>,
42 /// Optional workgroup size override.
43 ///
44 /// When `Some`, the backend uses the supplied `[x, y, z]` workgroup size
45 /// instead of the one declared on the [`vyre_foundation::ir::Program`].
46 /// This lets callers tune workgroup sizing at dispatch time without
47 /// cloning the program metadata. When `None` (the default), the backend
48 /// falls back to `Program::workgroup_size`.
49 pub workgroup_override: Option<[u32; 3]>,
50 /// Optional grid size override (number of workgroups).
51 ///
52 /// When set, the backend launches the supplied workgroup count instead of
53 /// the one inferred from the program's output buffer size. This is
54 /// required for megakernels where the work queue length is managed through
55 /// storage buffers rather than the primary output slot.
56 pub grid_override: Option<[u32; 3]>,
57 /// Maximum back-to-back dispatch iterations the backend should run on
58 /// the same persistent input/output handles before reading back the
59 /// final outputs.
60 ///
61 /// `None` means one iteration. `Some(0)` is invalid: backends must reject
62 /// it instead of silently rewriting caller policy.
63 pub fixpoint_iterations: Option<u32>,
64 /// Optional speculation policy.
65 pub speculation: Option<crate::speculate::SpeculationMode>,
66 /// Optional persistent-thread dispatch policy.
67 pub persistent_thread: Option<crate::persistent::PersistentThreadMode>,
68 /// Whether the backend should launch through its cooperative-grid API.
69 ///
70 /// A backend MUST reject `cooperative = true` with `UnsupportedFeature`
71 /// when its `VyreBackend::supports_grid_sync()` returns `false`.
72 pub cooperative: bool,
73}
74
75impl DispatchConfig {
76 /// Construct a `DispatchConfig` from explicit fields in one call.
77 /// Complement to `DispatchConfig::default()` for external crates
78 /// that want all optional fields set up front.
79 #[must_use]
80 pub fn new(
81 profile: Option<String>,
82 ulp_budget: Option<u8>,
83 timeout: Option<Duration>,
84 label: Option<String>,
85 ) -> Self {
86 Self {
87 profile,
88 ulp_budget,
89 timeout,
90 label,
91 max_output_bytes: None,
92 workgroup_override: None,
93 grid_override: None,
94 fixpoint_iterations: None,
95 speculation: None,
96 persistent_thread: None,
97 cooperative: false,
98 }
99 }
100}