Skip to main content

weir/fixed_point_resident_batch/
analysis_methods.rs

1#![allow(clippy::too_many_arguments)]
2
3use super::FixedPointResidentBatch;
4use crate::fixed_point_graph::{
5    FixedPointAnalysisKind, FixedPointAnalysisPlan, FixedPointForwardGraph,
6};
7use crate::fixed_point_resident_plan::FixedPointBorrowedResidentPlan;
8
9impl FixedPointResidentBatch {
10    pub fn reaching(
11        &mut self,
12        backend: &dyn vyre::VyreBackend,
13        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
14        graph: &FixedPointForwardGraph,
15        seed_bits: &[u32],
16        max_iterations: u32,
17        config: &vyre::DispatchConfig,
18    ) -> Result<Vec<u32>, String> {
19        graph.require_kind(
20            FixedPointAnalysisKind::Reaching,
21            "FixedPointResidentBatch::reaching",
22        )?;
23        self.require_frontier_budget(graph)?;
24        let before = self.frontier_state();
25        let result = {
26            let resident = self
27                .graph_cache
28                .get_or_upload(backend, graph)
29                .map_err(|error| error.to_string())?;
30            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
31            plan.reaching_reusing_frontier(
32                backend,
33                seed_bits,
34                max_iterations,
35                config,
36                &mut self.host_scratch,
37                &mut self.resident_frontier,
38            )
39        };
40        self.record_frontier_reuse(before)?;
41        self.record_execution_plan(backend, FixedPointAnalysisKind::Reaching, graph)?;
42        if let Ok(words) = &result {
43            self.record_resident_dispatch_io(seed_bits.len(), words.len())?;
44        }
45        result
46    }
47
48    /// Run reaching-definition closure into caller-owned result storage while
49    /// reusing cached graph resources, resident frontier buffers, host scratch,
50    /// and the caller's final `Vec<u32>` allocation.
51    pub fn reaching_into(
52        &mut self,
53        backend: &dyn vyre::VyreBackend,
54        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
55        graph: &FixedPointForwardGraph,
56        seed_bits: &[u32],
57        max_iterations: u32,
58        config: &vyre::DispatchConfig,
59        result: &mut Vec<u32>,
60    ) -> Result<(), String> {
61        graph.require_kind(
62            FixedPointAnalysisKind::Reaching,
63            "FixedPointResidentBatch::reaching_into",
64        )?;
65        self.require_frontier_budget(graph)?;
66        let before = self.frontier_state();
67        let run_result = {
68            let resident = self
69                .graph_cache
70                .get_or_upload(backend, graph)
71                .map_err(|error| error.to_string())?;
72            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
73            plan.reaching_reusing_frontier_into(
74                backend,
75                seed_bits,
76                max_iterations,
77                config,
78                &mut self.host_scratch,
79                &mut self.resident_frontier,
80                result,
81            )
82        };
83        self.record_frontier_reuse(before)?;
84        self.record_execution_plan(backend, FixedPointAnalysisKind::Reaching, graph)?;
85        if run_result.is_ok() {
86            self.record_resident_dispatch_io(seed_bits.len(), result.len())?;
87        }
88        run_result
89    }
90
91    /// Run live-variable closure through cached resident graph resources and
92    /// reusable resident frontier buffers.
93    pub fn live(
94        &mut self,
95        backend: &dyn vyre::VyreBackend,
96        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
97        graph: &FixedPointForwardGraph,
98        seed_bits: &[u32],
99        max_iterations: u32,
100        config: &vyre::DispatchConfig,
101    ) -> Result<Vec<u32>, String> {
102        graph.require_kind(
103            FixedPointAnalysisKind::Live,
104            "FixedPointResidentBatch::live",
105        )?;
106        self.require_frontier_budget(graph)?;
107        let before = self.frontier_state();
108        let result = {
109            let resident = self
110                .graph_cache
111                .get_or_upload(backend, graph)
112                .map_err(|error| error.to_string())?;
113            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
114            plan.live_reusing_frontier(
115                backend,
116                seed_bits,
117                max_iterations,
118                config,
119                &mut self.host_scratch,
120                &mut self.resident_frontier,
121            )
122        };
123        self.record_frontier_reuse(before)?;
124        self.record_execution_plan(backend, FixedPointAnalysisKind::Live, graph)?;
125        if let Ok(words) = &result {
126            self.record_resident_dispatch_io(seed_bits.len(), words.len())?;
127        }
128        result
129    }
130
131    /// Run live-variable closure into caller-owned result storage while
132    /// reusing cached graph resources, resident frontier buffers, host scratch,
133    /// and the caller's final `Vec<u32>` allocation.
134    pub fn live_into(
135        &mut self,
136        backend: &dyn vyre::VyreBackend,
137        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
138        graph: &FixedPointForwardGraph,
139        seed_bits: &[u32],
140        max_iterations: u32,
141        config: &vyre::DispatchConfig,
142        result: &mut Vec<u32>,
143    ) -> Result<(), String> {
144        graph.require_kind(
145            FixedPointAnalysisKind::Live,
146            "FixedPointResidentBatch::live_into",
147        )?;
148        self.require_frontier_budget(graph)?;
149        let before = self.frontier_state();
150        let run_result = {
151            let resident = self
152                .graph_cache
153                .get_or_upload(backend, graph)
154                .map_err(|error| error.to_string())?;
155            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
156            plan.live_reusing_frontier_into(
157                backend,
158                seed_bits,
159                max_iterations,
160                config,
161                &mut self.host_scratch,
162                &mut self.resident_frontier,
163                result,
164            )
165        };
166        self.record_frontier_reuse(before)?;
167        self.record_execution_plan(backend, FixedPointAnalysisKind::Live, graph)?;
168        if run_result.is_ok() {
169            self.record_resident_dispatch_io(seed_bits.len(), result.len())?;
170        }
171        run_result
172    }
173
174    /// Run points-to subset closure through cached resident graph resources and
175    /// reusable resident frontier buffers.
176    pub fn points_to_subset(
177        &mut self,
178        backend: &dyn vyre::VyreBackend,
179        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
180        graph: &FixedPointForwardGraph,
181        seed_bits: &[u32],
182        max_iterations: u32,
183        config: &vyre::DispatchConfig,
184    ) -> Result<Vec<u32>, String> {
185        graph.require_kind(
186            FixedPointAnalysisKind::PointsToSubset,
187            "FixedPointResidentBatch::points_to_subset",
188        )?;
189        self.require_frontier_budget(graph)?;
190        let before = self.frontier_state();
191        let result = {
192            let resident = self
193                .graph_cache
194                .get_or_upload(backend, graph)
195                .map_err(|error| error.to_string())?;
196            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
197            plan.points_to_subset_reusing_frontier(
198                backend,
199                seed_bits,
200                max_iterations,
201                config,
202                &mut self.host_scratch,
203                &mut self.resident_frontier,
204            )
205        };
206        self.record_frontier_reuse(before)?;
207        self.record_execution_plan(backend, FixedPointAnalysisKind::PointsToSubset, graph)?;
208        if let Ok(words) = &result {
209            self.record_resident_dispatch_io(seed_bits.len(), words.len())?;
210        }
211        result
212    }
213
214    /// Run points-to subset closure into caller-owned result storage while
215    /// reusing cached graph resources, resident frontier buffers, host scratch,
216    /// and the caller's final `Vec<u32>` allocation.
217    pub fn points_to_subset_into(
218        &mut self,
219        backend: &dyn vyre::VyreBackend,
220        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
221        graph: &FixedPointForwardGraph,
222        seed_bits: &[u32],
223        max_iterations: u32,
224        config: &vyre::DispatchConfig,
225        result: &mut Vec<u32>,
226    ) -> Result<(), String> {
227        graph.require_kind(
228            FixedPointAnalysisKind::PointsToSubset,
229            "FixedPointResidentBatch::points_to_subset_into",
230        )?;
231        self.require_frontier_budget(graph)?;
232        let before = self.frontier_state();
233        let run_result = {
234            let resident = self
235                .graph_cache
236                .get_or_upload(backend, graph)
237                .map_err(|error| error.to_string())?;
238            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
239            plan.points_to_subset_reusing_frontier_into(
240                backend,
241                seed_bits,
242                max_iterations,
243                config,
244                &mut self.host_scratch,
245                &mut self.resident_frontier,
246                result,
247            )
248        };
249        self.record_frontier_reuse(before)?;
250        self.record_execution_plan(backend, FixedPointAnalysisKind::PointsToSubset, graph)?;
251        if run_result.is_ok() {
252            self.record_resident_dispatch_io(seed_bits.len(), result.len())?;
253        }
254        run_result
255    }
256
257    /// Run backward-slice closure through cached resident graph resources and
258    /// reusable resident frontier buffers.
259    pub fn slice(
260        &mut self,
261        backend: &dyn vyre::VyreBackend,
262        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
263        graph: &FixedPointForwardGraph,
264        seed_bits: &[u32],
265        max_iterations: u32,
266        config: &vyre::DispatchConfig,
267    ) -> Result<Vec<u32>, String> {
268        graph.require_kind(
269            FixedPointAnalysisKind::Slice,
270            "FixedPointResidentBatch::slice",
271        )?;
272        self.require_frontier_budget(graph)?;
273        let before = self.frontier_state();
274        let result = {
275            let resident = self
276                .graph_cache
277                .get_or_upload(backend, graph)
278                .map_err(|error| error.to_string())?;
279            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
280            plan.slice_reusing_frontier(
281                backend,
282                seed_bits,
283                max_iterations,
284                config,
285                &mut self.host_scratch,
286                &mut self.resident_frontier,
287            )
288        };
289        self.record_frontier_reuse(before)?;
290        self.record_execution_plan(backend, FixedPointAnalysisKind::Slice, graph)?;
291        if let Ok(words) = &result {
292            self.record_resident_dispatch_io(seed_bits.len(), words.len())?;
293        }
294        result
295    }
296
297    /// Run backward-slice closure into caller-owned result storage while
298    /// reusing cached graph resources, resident frontier buffers, host scratch,
299    /// and the caller's final `Vec<u32>` allocation.
300    pub fn slice_into(
301        &mut self,
302        backend: &dyn vyre::VyreBackend,
303        pipeline: std::sync::Arc<dyn vyre::CompiledPipeline>,
304        graph: &FixedPointForwardGraph,
305        seed_bits: &[u32],
306        max_iterations: u32,
307        config: &vyre::DispatchConfig,
308        result: &mut Vec<u32>,
309    ) -> Result<(), String> {
310        graph.require_kind(
311            FixedPointAnalysisKind::Slice,
312            "FixedPointResidentBatch::slice_into",
313        )?;
314        self.require_frontier_budget(graph)?;
315        let before = self.frontier_state();
316        let run_result = {
317            let resident = self
318                .graph_cache
319                .get_or_upload(backend, graph)
320                .map_err(|error| error.to_string())?;
321            let plan = FixedPointBorrowedResidentPlan::new(resident, pipeline);
322            plan.slice_reusing_frontier_into(
323                backend,
324                seed_bits,
325                max_iterations,
326                config,
327                &mut self.host_scratch,
328                &mut self.resident_frontier,
329                result,
330            )
331        };
332        self.record_frontier_reuse(before)?;
333        self.record_execution_plan(backend, FixedPointAnalysisKind::Slice, graph)?;
334        if run_result.is_ok() {
335            self.record_resident_dispatch_io(seed_bits.len(), result.len())?;
336        }
337        run_result
338    }
339
340    /// Run reaching-definition closure through cached resident graph resources
341    /// using backend resident sequence replay.
342    pub fn reaching_sequence_window(
343        &mut self,
344        backend: &dyn vyre::VyreBackend,
345        plan: &FixedPointAnalysisPlan,
346        seed_bits: &[u32],
347        max_iterations: u32,
348    ) -> Result<Vec<u32>, String> {
349        plan.require_kind(
350            FixedPointAnalysisKind::Reaching,
351            "FixedPointResidentBatch::reaching_sequence_window",
352        )?;
353        let graph = plan.graph();
354        self.require_frontier_budget(graph)?;
355        let before = self.frontier_state();
356        let result = {
357            let resident = self
358                .graph_cache
359                .get_or_upload(backend, graph)
360                .map_err(|error| error.to_string())?;
361            crate::reaching::reaching_closure_resident_plan_with_reusable_frontier_scratch_sequence_window(
362                backend,
363                plan.program(),
364                resident,
365                seed_bits,
366                max_iterations,
367                &mut self.host_scratch,
368                &mut self.resident_frontier,
369            )
370        };
371        self.record_frontier_reuse(before)?;
372        self.record_execution_plan(backend, FixedPointAnalysisKind::Reaching, graph)?;
373        if let Ok(words) = &result {
374            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), words.len())?;
375        }
376        result
377    }
378
379    /// Run reaching-definition closure through backend resident sequence replay
380    /// into caller-owned result storage.
381    pub fn reaching_sequence_window_into(
382        &mut self,
383        backend: &dyn vyre::VyreBackend,
384        plan: &FixedPointAnalysisPlan,
385        seed_bits: &[u32],
386        max_iterations: u32,
387        result: &mut Vec<u32>,
388    ) -> Result<(), String> {
389        plan.require_kind(
390            FixedPointAnalysisKind::Reaching,
391            "FixedPointResidentBatch::reaching_sequence_window_into",
392        )?;
393        let graph = plan.graph();
394        self.require_frontier_budget(graph)?;
395        let before = self.frontier_state();
396        let run_result = {
397            let resident = self
398                .graph_cache
399                .get_or_upload(backend, graph)
400                .map_err(|error| error.to_string())?;
401            crate::reaching::reaching_closure_resident_plan_with_reusable_frontier_scratch_sequence_window_into(
402                backend,
403                plan.program(),
404                resident,
405                seed_bits,
406                max_iterations,
407                &mut self.host_scratch,
408                &mut self.resident_frontier,
409                result,
410            )
411        };
412        self.record_frontier_reuse(before)?;
413        self.record_execution_plan(backend, FixedPointAnalysisKind::Reaching, graph)?;
414        if run_result.is_ok() {
415            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), result.len())?;
416        }
417        run_result
418    }
419
420    /// Run live-variable closure through cached resident graph resources using
421    /// backend resident sequence replay.
422    pub fn live_sequence_window(
423        &mut self,
424        backend: &dyn vyre::VyreBackend,
425        plan: &FixedPointAnalysisPlan,
426        seed_bits: &[u32],
427        max_iterations: u32,
428    ) -> Result<Vec<u32>, String> {
429        plan.require_kind(
430            FixedPointAnalysisKind::Live,
431            "FixedPointResidentBatch::live_sequence_window",
432        )?;
433        let graph = plan.graph();
434        self.require_frontier_budget(graph)?;
435        let before = self.frontier_state();
436        let result = {
437            let resident = self
438                .graph_cache
439                .get_or_upload(backend, graph)
440                .map_err(|error| error.to_string())?;
441            crate::live::live_closure_resident_plan_with_reusable_frontier_scratch_sequence_window(
442                backend,
443                plan.program(),
444                resident,
445                seed_bits,
446                max_iterations,
447                &mut self.host_scratch,
448                &mut self.resident_frontier,
449            )
450        };
451        self.record_frontier_reuse(before)?;
452        self.record_execution_plan(backend, FixedPointAnalysisKind::Live, graph)?;
453        if let Ok(words) = &result {
454            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), words.len())?;
455        }
456        result
457    }
458
459    /// Run live-variable closure through backend resident sequence replay into
460    /// caller-owned result storage.
461    pub fn live_sequence_window_into(
462        &mut self,
463        backend: &dyn vyre::VyreBackend,
464        plan: &FixedPointAnalysisPlan,
465        seed_bits: &[u32],
466        max_iterations: u32,
467        result: &mut Vec<u32>,
468    ) -> Result<(), String> {
469        plan.require_kind(
470            FixedPointAnalysisKind::Live,
471            "FixedPointResidentBatch::live_sequence_window_into",
472        )?;
473        let graph = plan.graph();
474        self.require_frontier_budget(graph)?;
475        let before = self.frontier_state();
476        let run_result = {
477            let resident = self
478                .graph_cache
479                .get_or_upload(backend, graph)
480                .map_err(|error| error.to_string())?;
481            crate::live::live_closure_resident_plan_with_reusable_frontier_scratch_sequence_window_into(
482                backend,
483                plan.program(),
484                resident,
485                seed_bits,
486                max_iterations,
487                &mut self.host_scratch,
488                &mut self.resident_frontier,
489                result,
490            )
491        };
492        self.record_frontier_reuse(before)?;
493        self.record_execution_plan(backend, FixedPointAnalysisKind::Live, graph)?;
494        if run_result.is_ok() {
495            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), result.len())?;
496        }
497        run_result
498    }
499
500    /// Run points-to subset closure through cached resident graph resources
501    /// using backend resident sequence replay.
502    pub fn points_to_subset_sequence_window(
503        &mut self,
504        backend: &dyn vyre::VyreBackend,
505        plan: &FixedPointAnalysisPlan,
506        seed_bits: &[u32],
507        max_iterations: u32,
508    ) -> Result<Vec<u32>, String> {
509        plan.require_kind(
510            FixedPointAnalysisKind::PointsToSubset,
511            "FixedPointResidentBatch::points_to_subset_sequence_window",
512        )?;
513        let graph = plan.graph();
514        self.require_frontier_budget(graph)?;
515        let before = self.frontier_state();
516        let result = {
517            let resident = self
518                .graph_cache
519                .get_or_upload(backend, graph)
520                .map_err(|error| error.to_string())?;
521            crate::points_to::subset_closure_resident_plan_with_reusable_frontier_scratch_sequence_window(
522                backend,
523                plan.program(),
524                resident,
525                seed_bits,
526                max_iterations,
527                &mut self.host_scratch,
528                &mut self.resident_frontier,
529            )
530        };
531        self.record_frontier_reuse(before)?;
532        self.record_execution_plan(backend, FixedPointAnalysisKind::PointsToSubset, graph)?;
533        if let Ok(words) = &result {
534            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), words.len())?;
535        }
536        result
537    }
538
539    /// Run points-to subset closure through backend resident sequence replay
540    /// into caller-owned result storage.
541    pub fn points_to_subset_sequence_window_into(
542        &mut self,
543        backend: &dyn vyre::VyreBackend,
544        plan: &FixedPointAnalysisPlan,
545        seed_bits: &[u32],
546        max_iterations: u32,
547        result: &mut Vec<u32>,
548    ) -> Result<(), String> {
549        plan.require_kind(
550            FixedPointAnalysisKind::PointsToSubset,
551            "FixedPointResidentBatch::points_to_subset_sequence_window_into",
552        )?;
553        let graph = plan.graph();
554        self.require_frontier_budget(graph)?;
555        let before = self.frontier_state();
556        let run_result = {
557            let resident = self
558                .graph_cache
559                .get_or_upload(backend, graph)
560                .map_err(|error| error.to_string())?;
561            crate::points_to::subset_closure_resident_plan_with_reusable_frontier_scratch_sequence_window_into(
562                backend,
563                plan.program(),
564                resident,
565                seed_bits,
566                max_iterations,
567                &mut self.host_scratch,
568                &mut self.resident_frontier,
569                result,
570            )
571        };
572        self.record_frontier_reuse(before)?;
573        self.record_execution_plan(backend, FixedPointAnalysisKind::PointsToSubset, graph)?;
574        if run_result.is_ok() {
575            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), result.len())?;
576        }
577        run_result
578    }
579
580    /// Run backward-slice closure through cached resident graph resources using
581    /// backend resident sequence replay.
582    pub fn slice_sequence_window(
583        &mut self,
584        backend: &dyn vyre::VyreBackend,
585        plan: &FixedPointAnalysisPlan,
586        seed_bits: &[u32],
587        max_iterations: u32,
588    ) -> Result<Vec<u32>, String> {
589        plan.require_kind(
590            FixedPointAnalysisKind::Slice,
591            "FixedPointResidentBatch::slice_sequence_window",
592        )?;
593        let graph = plan.graph();
594        self.require_frontier_budget(graph)?;
595        let before = self.frontier_state();
596        let result = {
597            let resident = self
598                .graph_cache
599                .get_or_upload(backend, graph)
600                .map_err(|error| error.to_string())?;
601            crate::slice::slice_closure_resident_plan_with_reusable_frontier_scratch_sequence_window(
602                backend,
603                plan.program(),
604                resident,
605                seed_bits,
606                max_iterations,
607                &mut self.host_scratch,
608                &mut self.resident_frontier,
609            )
610        };
611        self.record_frontier_reuse(before)?;
612        self.record_execution_plan(backend, FixedPointAnalysisKind::Slice, graph)?;
613        if let Ok(words) = &result {
614            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), words.len())?;
615        }
616        result
617    }
618
619    /// Run backward-slice closure through backend resident sequence replay into
620    /// caller-owned result storage.
621    pub fn slice_sequence_window_into(
622        &mut self,
623        backend: &dyn vyre::VyreBackend,
624        plan: &FixedPointAnalysisPlan,
625        seed_bits: &[u32],
626        max_iterations: u32,
627        result: &mut Vec<u32>,
628    ) -> Result<(), String> {
629        plan.require_kind(
630            FixedPointAnalysisKind::Slice,
631            "FixedPointResidentBatch::slice_sequence_window_into",
632        )?;
633        let graph = plan.graph();
634        self.require_frontier_budget(graph)?;
635        let before = self.frontier_state();
636        let run_result = {
637            let resident = self
638                .graph_cache
639                .get_or_upload(backend, graph)
640                .map_err(|error| error.to_string())?;
641            crate::slice::slice_closure_resident_plan_with_reusable_frontier_scratch_sequence_window_into(
642                backend,
643                plan.program(),
644                resident,
645                seed_bits,
646                max_iterations,
647                &mut self.host_scratch,
648                &mut self.resident_frontier,
649                result,
650            )
651        };
652        self.record_frontier_reuse(before)?;
653        self.record_execution_plan(backend, FixedPointAnalysisKind::Slice, graph)?;
654        if run_result.is_ok() {
655            self.record_resident_changed_flag_sequence_window_io(seed_bits.len(), result.len())?;
656        }
657        run_result
658    }
659}