oar_ocr/core/config/
parallel.rs

1//! Shared parallel processing configuration types.
2
3use serde::{Deserialize, Serialize};
4
5/// Centralized configuration for parallel processing behavior across the OCR pipeline.
6///
7/// This struct consolidates parallel processing configuration that was previously
8/// scattered across different components, providing a unified way to tune parallelism
9/// behavior throughout the OCR pipeline.
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ParallelPolicy {
12    /// Maximum number of threads to use for parallel processing.
13    /// If None, rayon will use the default thread pool size (typically number of CPU cores).
14    /// Default: None (use rayon's default)
15    #[serde(default)]
16    pub max_threads: Option<usize>,
17
18    /// Threshold for number of images to process sequentially (<= this uses sequential)
19    /// Default: 1 (process single images sequentially, use parallel for multiple images)
20    #[serde(default = "ParallelPolicy::default_image_threshold")]
21    pub image_threshold: usize,
22
23    /// Threshold for number of text boxes to crop sequentially (<= this uses sequential)
24    /// Default: 1 (process single text boxes sequentially, use parallel for multiple boxes)
25    #[serde(default = "ParallelPolicy::default_text_box_threshold")]
26    pub text_box_threshold: usize,
27
28    /// Threshold for batch processing operations (<= this uses sequential)
29    /// Default: 10 (use sequential for small batches, parallel for larger ones)
30    #[serde(default = "ParallelPolicy::default_batch_threshold")]
31    pub batch_threshold: usize,
32
33    /// Threshold for general utility operations like image loading (<= this uses sequential)
34    /// Default: 4 (matches DEFAULT_PARALLEL_THRESHOLD constant)
35    #[serde(default = "ParallelPolicy::default_utility_threshold")]
36    pub utility_threshold: usize,
37
38    /// Threshold for postprocessing operations based on pixel area (<= this uses sequential)
39    /// Default: 8000 (use sequential for regions with <= 8000 pixels, parallel for larger)
40    #[serde(default = "ParallelPolicy::default_postprocess_pixel_threshold")]
41    pub postprocess_pixel_threshold: usize,
42
43    /// ONNX Runtime threading configuration
44    #[serde(default)]
45    pub onnx_threading: OnnxThreadingConfig,
46}
47
48/// ONNX Runtime threading configuration that's part of the centralized parallel policy.
49#[derive(Debug, Clone, Serialize, Deserialize, Default)]
50pub struct OnnxThreadingConfig {
51    /// Number of threads used to parallelize execution within nodes.
52    /// If None, uses ONNX Runtime default.
53    #[serde(default)]
54    pub intra_threads: Option<usize>,
55
56    /// Number of threads used to parallelize execution across nodes.
57    /// If None, uses ONNX Runtime default.
58    #[serde(default)]
59    pub inter_threads: Option<usize>,
60
61    /// Enable parallel execution mode.
62    /// If None, uses ONNX Runtime default.
63    #[serde(default)]
64    pub parallel_execution: Option<bool>,
65}
66
67impl OnnxThreadingConfig {
68    /// Create a new OnnxThreadingConfig with default values.
69    pub fn new() -> Self {
70        Self::default()
71    }
72
73    /// Set the intra-op threads.
74    pub fn with_intra_threads(mut self, threads: Option<usize>) -> Self {
75        self.intra_threads = threads;
76        self
77    }
78
79    /// Set the inter-op threads.
80    pub fn with_inter_threads(mut self, threads: Option<usize>) -> Self {
81        self.inter_threads = threads;
82        self
83    }
84
85    /// Set parallel execution mode.
86    pub fn with_parallel_execution(mut self, enabled: Option<bool>) -> Self {
87        self.parallel_execution = enabled;
88        self
89    }
90
91    /// Convert to OrtSessionConfig for use with ONNX Runtime.
92    pub fn to_ort_session_config(&self) -> crate::core::config::OrtSessionConfig {
93        let mut config = crate::core::config::OrtSessionConfig::new();
94
95        if let Some(intra) = self.intra_threads {
96            config = config.with_intra_threads(intra);
97        }
98
99        if let Some(inter) = self.inter_threads {
100            config = config.with_inter_threads(inter);
101        }
102
103        if let Some(parallel) = self.parallel_execution {
104            config = config.with_parallel_execution(parallel);
105        }
106
107        config
108    }
109}
110
111impl ParallelPolicy {
112    /// Create a new ParallelPolicy with default values.
113    pub fn new() -> Self {
114        Self::default()
115    }
116
117    /// Set the maximum number of threads.
118    pub fn with_max_threads(mut self, max_threads: Option<usize>) -> Self {
119        self.max_threads = max_threads;
120        self
121    }
122
123    /// Set the image processing threshold.
124    pub fn with_image_threshold(mut self, threshold: usize) -> Self {
125        self.image_threshold = threshold;
126        self
127    }
128
129    /// Set the text box processing threshold.
130    pub fn with_text_box_threshold(mut self, threshold: usize) -> Self {
131        self.text_box_threshold = threshold;
132        self
133    }
134
135    /// Set the batch processing threshold.
136    pub fn with_batch_threshold(mut self, threshold: usize) -> Self {
137        self.batch_threshold = threshold;
138        self
139    }
140
141    /// Set the postprocessing pixel threshold.
142    pub fn with_postprocess_pixel_threshold(mut self, threshold: usize) -> Self {
143        self.postprocess_pixel_threshold = threshold;
144        self
145    }
146
147    /// Set the ONNX threading configuration.
148    pub fn with_onnx_threading(mut self, config: OnnxThreadingConfig) -> Self {
149        self.onnx_threading = config;
150        self
151    }
152
153    /// Set the utility operations threshold.
154    pub fn with_utility_threshold(mut self, threshold: usize) -> Self {
155        self.utility_threshold = threshold;
156        self
157    }
158
159    /// Default value for image threshold.
160    fn default_image_threshold() -> usize {
161        1
162    }
163
164    /// Default value for text box threshold.
165    fn default_text_box_threshold() -> usize {
166        1
167    }
168
169    /// Default value for batch threshold.
170    fn default_batch_threshold() -> usize {
171        10
172    }
173
174    /// Default value for utility threshold.
175    fn default_utility_threshold() -> usize {
176        4 // Matches DEFAULT_PARALLEL_THRESHOLD from constants.
177    }
178
179    /// Default postprocessing pixel threshold.
180    fn default_postprocess_pixel_threshold() -> usize {
181        8_000
182    }
183}
184
185impl Default for ParallelPolicy {
186    fn default() -> Self {
187        Self {
188            max_threads: None,
189            image_threshold: Self::default_image_threshold(),
190            text_box_threshold: Self::default_text_box_threshold(),
191            batch_threshold: Self::default_batch_threshold(),
192            utility_threshold: Self::default_utility_threshold(),
193            postprocess_pixel_threshold: Self::default_postprocess_pixel_threshold(),
194            onnx_threading: OnnxThreadingConfig::default(),
195        }
196    }
197}