cbtop/grammar/
compute_block.rs1use std::collections::HashMap;
4use std::time::Duration;
5
6use super::composition::CompositionMode;
7use super::context::ExecutionContext;
8use super::error::{GrammarError, GrammarResult};
9use super::policy::ExecutionPolicy;
10use super::resources::ResourceMapping;
11use super::strategy::{ExecutionStrategy, StrategyLayer};
12use super::transform::DataTransform;
13use super::workload::WorkloadSpec;
14
15#[derive(Debug, Clone)]
17pub struct ExecutionResult {
18 pub duration: Duration,
20 pub gflops: f64,
22 pub bandwidth_gbps: f64,
24 pub strategy_used: String,
26 pub metrics: HashMap<String, f64>,
28}
29
30#[derive(Debug, Clone)]
32pub struct BuiltComputeBlock {
33 pub(crate) inner: ComputeBlock,
34}
35
36impl BuiltComputeBlock {
37 pub fn execute(&self) -> GrammarResult<ExecutionResult> {
39 let start = std::time::Instant::now();
40
41 let mut strategies = self.inner.strategies.clone();
43 strategies.sort_by(|a, b| b.priority.cmp(&a.priority));
44
45 let strategy_used = if let Some(layer) = strategies.first() {
46 format!("{:?}", layer.strategy)
47 } else {
48 "Sequential".to_string()
49 };
50
51 let duration = start.elapsed();
53 let flops = self
54 .inner
55 .workload
56 .as_ref()
57 .map(|w| w.flop_count())
58 .unwrap_or(0);
59 let gflops = if duration.as_secs_f64() > 0.0 {
60 flops as f64 / duration.as_secs_f64() / 1e9
61 } else {
62 0.0
63 };
64
65 Ok(ExecutionResult {
66 duration,
67 gflops,
68 bandwidth_gbps: 0.0,
69 strategy_used,
70 metrics: HashMap::new(),
71 })
72 }
73
74 pub fn workload(&self) -> Option<&WorkloadSpec> {
76 self.inner.workload.as_ref()
77 }
78}
79
80#[derive(Debug, Clone, Default)]
82pub struct ComputeBlock {
83 pub(crate) workload: Option<WorkloadSpec>,
85 pub(crate) resources: ResourceMapping,
87 pub(crate) strategies: Vec<StrategyLayer>,
89 pub(crate) transform: DataTransform,
91 pub(crate) context: ExecutionContext,
93 pub(crate) composition: CompositionMode,
95 pub(crate) policy: ExecutionPolicy,
97 pub(crate) facet_params: Option<(String, Vec<f64>)>,
99}
100
101impl ComputeBlock {
102 pub fn builder() -> ComputeBlockBuilder {
104 ComputeBlockBuilder::new()
105 }
106
107 fn validate(&self) -> GrammarResult<()> {
109 if self.workload.is_none() {
111 return Err(GrammarError::MissingWorkload);
112 }
113
114 Ok(())
118 }
119
120 pub fn build(self) -> GrammarResult<BuiltComputeBlock> {
122 self.validate()?;
123 Ok(BuiltComputeBlock { inner: self })
124 }
125}
126
127#[derive(Debug, Clone, Default)]
129pub struct ComputeBlockBuilder {
130 inner: ComputeBlock,
131}
132
133impl ComputeBlockBuilder {
134 pub fn new() -> Self {
136 Self {
137 inner: ComputeBlock {
138 transform: DataTransform::Identity,
139 context: ExecutionContext::Cpu {
140 affinity: None,
141 numa_node: None,
142 },
143 composition: CompositionMode::None,
144 policy: ExecutionPolicy::default(),
145 ..Default::default()
146 },
147 }
148 }
149
150 pub fn workload(mut self, workload: WorkloadSpec) -> Self {
152 self.inner.workload = Some(workload);
153 self
154 }
155
156 pub fn resources(mut self, resources: ResourceMapping) -> Self {
158 self.inner.resources = resources;
159 self
160 }
161
162 pub fn strategy(mut self, strategy: ExecutionStrategy) -> Self {
164 self.inner.strategies.push(StrategyLayer::new(strategy));
165 self
166 }
167
168 pub fn strategy_with_priority(mut self, strategy: ExecutionStrategy, priority: i32) -> Self {
170 self.inner
171 .strategies
172 .push(StrategyLayer::new(strategy).priority(priority));
173 self
174 }
175
176 pub fn transform(mut self, transform: DataTransform) -> Self {
178 self.inner.transform = transform;
179 self
180 }
181
182 pub fn context(mut self, context: ExecutionContext) -> Self {
184 self.inner.context = context;
185 self
186 }
187
188 pub fn composition(mut self, composition: CompositionMode) -> Self {
190 self.inner.composition = composition;
191 self
192 }
193
194 pub fn policy(mut self, policy: ExecutionPolicy) -> Self {
196 self.inner.policy = policy;
197 self
198 }
199
200 pub fn facet_by(mut self, param: impl Into<String>, values: Vec<f64>) -> Self {
202 self.inner.facet_params = Some((param.into(), values));
203 self
204 }
205
206 pub fn build(self) -> GrammarResult<BuiltComputeBlock> {
208 self.inner.build()
209 }
210}