11"""
22qector_decoder_v3.backend — Workload-Aware AutoDecoder with Self-Auto-Debug & Multi-Tier Fallback.
33
4- Provides automatic hardware routing, real-time performance calibration, and a
4+ Provides automatic hardware routing, real-time performance calibration, and a
557-tier fault-tolerant self-debugging fallback engine for quantum error correction decoding.
66"""
77
2020 CPUBatchDecoder ,
2121 CUDABatchDecoder ,
2222 FastUnionFindDecoder ,
23- UnionFindDecoder ,
2423 BlossomDecoder ,
2524 SparseBlossomDecoder ,
2625 LookupTableDecoder ,
@@ -128,7 +127,7 @@ def __init__(self, check_to_qubits, n_qubits=None, config: Optional[BackendConfi
128127 self ._cuda_ok = bool (self .config .allow_gpu and cuda_is_available ())
129128 opencl_auto = os .environ .get ("QECTOR_ENABLE_OPENCL_AUTO" , "" ).lower () in {"1" , "true" , "yes" , "on" }
130129 self ._opencl_ok = bool (self .config .allow_gpu and opencl_auto and opencl_is_available ())
131-
130+
132131 if self .config .allow_gpu and not opencl_auto and opencl_is_available ():
133132 self ._diag .warnings .append ("OpenCL auto-routing disabled; set QECTOR_ENABLE_OPENCL_AUTO=1 to enable it" )
134133
@@ -173,7 +172,11 @@ def _get_decoder(self, backend: str) -> Any:
173172 if backend in self ._decoders :
174173 return self ._decoders [backend ]
175174
176- dec = None
175+ # `dec` holds a heterogeneous set of decoder types (one per backend
176+ # branch below). Typing it as Any avoids mypy flagging every elif
177+ # branch as a type-incompatible assignment while remaining accurate
178+ # at runtime.
179+ dec : Any = None
177180 if backend == Backend .CPU_SINGLE :
178181 dec = FastUnionFindDecoder (self ._c2q , self ._nq )
179182 elif backend == Backend .CPU_RAYON :
@@ -211,16 +214,16 @@ def _get_decoder(self, backend: str) -> Any:
211214 return dec
212215
213216 def _get_cpu_single (self ) -> FastUnionFindDecoder :
214- return self ._get_decoder (Backend .CPU_SINGLE )
217+ return cast ( FastUnionFindDecoder , self ._get_decoder (Backend .CPU_SINGLE ) )
215218
216219 def _get_cpu_rayon (self ) -> BatchDecoder :
217- return self ._get_decoder (Backend .CPU_RAYON )
220+ return cast ( BatchDecoder , self ._get_decoder (Backend .CPU_RAYON ) )
218221
219222 def _get_cuda (self ) -> Optional [CUDABatchDecoder ]:
220- return self ._get_decoder (Backend .CUDA )
223+ return cast ( Optional [ CUDABatchDecoder ], self ._get_decoder (Backend .CUDA ) )
221224
222225 def _get_opencl (self ) -> Optional [OpenCLBatchDecoder ]:
223- return self ._get_decoder (Backend .OPENCL )
226+ return cast ( Optional [ OpenCLBatchDecoder ], self ._get_decoder (Backend .OPENCL ) )
224227
225228 # -- selection ---------------------------------------------------------
226229 def select (self , batch_size : int ) -> str :
@@ -229,7 +232,11 @@ def select(self, batch_size: int) -> str:
229232 return self .config .force
230233
231234 if self .config .allow_gpu and batch_size >= self .config .gpu_threshold :
232- if self .config .prefer == Backend .OPENCL and self ._opencl_ok and self ._diag .backend_health .get (Backend .OPENCL , True ):
235+ if (
236+ self .config .prefer == Backend .OPENCL
237+ and self ._opencl_ok
238+ and self ._diag .backend_health .get (Backend .OPENCL , True )
239+ ):
233240 return Backend .OPENCL
234241 if self ._cuda_ok and self ._diag .backend_health .get (Backend .CUDA , True ):
235242 return Backend .CUDA
@@ -283,7 +290,14 @@ def batch_decode(self, syndromes) -> np.ndarray:
283290
284291 # Robust multi-tier self-debugging execution chain
285292 fallback_chain = [chosen ]
286- for t in [Backend .CUDA , Backend .OPENCL , Backend .CPU_RAYON , Backend .CPU_BATCH , Backend .CPU_SINGLE , Backend .BLOSSOM ]:
293+ for t in [
294+ Backend .CUDA ,
295+ Backend .OPENCL ,
296+ Backend .CPU_RAYON ,
297+ Backend .CPU_BATCH ,
298+ Backend .CPU_SINGLE ,
299+ Backend .BLOSSOM ,
300+ ]:
287301 if t not in fallback_chain :
288302 fallback_chain .append (t )
289303
@@ -362,12 +376,14 @@ def _record_auto_debug_failure(self, backend: str, exc: Exception, context: str)
362376 self ._diag .backend_health [backend ] = False
363377 msg = f"AutoDebug caught error on { backend } [{ context } ]: { exc } "
364378 self ._diag .warnings .append (msg )
365- self ._diag .debug_log .append ({
366- "timestamp" : time .time (),
367- "backend" : backend ,
368- "context" : context ,
369- "error" : str (exc ),
370- })
379+ self ._diag .debug_log .append (
380+ {
381+ "timestamp" : time .time (),
382+ "backend" : backend ,
383+ "context" : context ,
384+ "error" : str (exc ),
385+ }
386+ )
371387 logger .warning (msg )
372388
373389 def _python_fallback_decode (self , syndrome : np .ndarray ) -> np .ndarray :
0 commit comments