@@ -8,7 +8,22 @@ use pecos_engines::{ClassicalControlEngineBuilder, MonteCarloEngine, SimBuilder,
88use pecos_programs:: Program ;
99use pecos_qasm:: qasm_engine;
1010#[ cfg( feature = "qis" ) ]
11- use pecos_qis:: qis_engine;
11+ use pecos_qis:: { IntoQisInterface , qis_engine} ;
12+
13+ /// Set up a QIS engine with Selene runtime and Helios interface for the given program.
14+ #[ cfg( feature = "qis" ) ]
15+ fn build_qis_engine < P : IntoQisInterface + ' static > (
16+ program : P ,
17+ ) -> Result < pecos_qis:: QisEngineBuilder , PecosError > {
18+ let selene_runtime = crate :: selene_simple_runtime ( )
19+ . map_err ( |e| PecosError :: Generic ( format ! ( "Failed to load Selene runtime: {e}" ) ) ) ?;
20+ let helios_builder = crate :: helios_interface_builder ( ) ;
21+ qis_engine ( )
22+ . runtime ( selene_runtime)
23+ . interface ( helios_builder)
24+ . try_program ( program)
25+ . map_err ( |e| PecosError :: Generic ( format ! ( "Failed to load program: {e}" ) ) )
26+ }
1227
1328/// Extension trait for `SimBuilder` to add program-based methods
1429pub trait SimBuilderExt {
@@ -43,184 +58,77 @@ pub struct ProgrammedSimBuilder {
4358}
4459
4560impl ProgrammedSimBuilder {
61+ /// Auto-select the classical engine based on program type, returning a configured `SimBuilder`.
62+ fn configure_engine ( self ) -> Result < SimBuilder , PecosError > {
63+ if self . override_classical {
64+ return Ok ( self . base_builder ) ;
65+ }
66+
67+ match self . program {
68+ Program :: Qasm ( qasm) => Ok ( self . base_builder . classical ( qasm_engine ( ) . program ( qasm) ) ) ,
69+ Program :: Qis ( qis) => {
70+ #[ cfg( feature = "qis" ) ]
71+ {
72+ let engine_builder = build_qis_engine ( qis) ?;
73+ Ok ( self . base_builder . classical ( engine_builder) )
74+ }
75+ #[ cfg( not( feature = "qis" ) ) ]
76+ {
77+ let _ = qis;
78+ Err ( PecosError :: Generic (
79+ "QIS programs require Selene and LLVM support. Please rebuild with --features selene,llvm" . to_string ( )
80+ ) )
81+ }
82+ }
83+ Program :: Hugr ( hugr) => {
84+ #[ cfg( feature = "qis" ) ]
85+ {
86+ let engine_builder = build_qis_engine ( hugr) ?;
87+ Ok ( self . base_builder . classical ( engine_builder) )
88+ }
89+ #[ cfg( not( feature = "qis" ) ) ]
90+ {
91+ let _ = hugr;
92+ Err ( PecosError :: Generic (
93+ "HUGR programs require Selene and LLVM support. Please rebuild with --features selene,llvm" . to_string ( )
94+ ) )
95+ }
96+ }
97+ Program :: Wasm ( _) => Err ( PecosError :: Input (
98+ "WASM programs are not yet supported in unified simulation" . to_string ( ) ,
99+ ) ) ,
100+ Program :: Wat ( _) => Err ( PecosError :: Input (
101+ "WAT programs are not yet supported in unified simulation" . to_string ( ) ,
102+ ) ) ,
103+ Program :: PhirJson ( _) => Err ( PecosError :: Input (
104+ "PHIR JSON programs are not yet supported in unified simulation" . to_string ( ) ,
105+ ) ) ,
106+ Program :: SeleneInterface ( _) => Err ( PecosError :: Input (
107+ "SeleneInterface programs are not yet supported in unified simulation" . to_string ( ) ,
108+ ) ) ,
109+ }
110+ }
111+
46112 /// Build the simulation with automatic engine selection
47113 ///
48- /// This selects an engine based on the program type and builds the simulation,
49- /// unless a classical engine was already explicitly set.
50- ///
51114 /// # Errors
52115 ///
53116 /// Returns an error if:
54117 /// - The program type is not yet supported (WASM, WAT, PHIR JSON, `SeleneInterface`)
55118 /// - Engine building fails
56119 pub fn build ( self ) -> Result < MonteCarloEngine , PecosError > {
57- if self . override_classical {
58- // Classical engine was already set, just build
59- self . base_builder . build ( )
60- } else {
61- // Auto-select engine based on program type
62- match self . program {
63- Program :: Qasm ( qasm) => self
64- . base_builder
65- . classical ( qasm_engine ( ) . program ( qasm) )
66- . build ( ) ,
67- Program :: Qis ( qis) => {
68- // Use Selene runtime and Helios interface
69- #[ cfg( feature = "qis" ) ]
70- {
71- let selene_runtime = crate :: selene_simple_runtime ( ) . map_err ( |e| {
72- PecosError :: Generic ( format ! ( "Failed to load Selene runtime: {e}" ) )
73- } ) ?;
74- let helios_builder = crate :: helios_interface_builder ( ) ;
75- let engine_builder = qis_engine ( )
76- . runtime ( selene_runtime)
77- . interface ( helios_builder)
78- . try_program ( qis)
79- . map_err ( |e| {
80- PecosError :: Generic ( format ! ( "Failed to load QIS program: {e}" ) )
81- } ) ?;
82-
83- self . base_builder . classical ( engine_builder) . build ( )
84- }
85- #[ cfg( not( feature = "qis" ) ) ]
86- {
87- let _ = qis; // Mark as used to avoid warning
88- Err ( PecosError :: Generic (
89- "QIS programs require Selene and LLVM support. Please rebuild with --features selene,llvm" . to_string ( )
90- ) )
91- }
92- }
93- Program :: Hugr ( hugr) => {
94- // Use Selene runtime and Helios interface for HUGR programs
95- #[ cfg( feature = "qis" ) ]
96- {
97- let selene_runtime = crate :: selene_simple_runtime ( ) . map_err ( |e| {
98- PecosError :: Generic ( format ! ( "Failed to load Selene runtime: {e}" ) )
99- } ) ?;
100- let helios_builder = crate :: helios_interface_builder ( ) ;
101- let engine_builder = qis_engine ( )
102- . runtime ( selene_runtime)
103- . interface ( helios_builder)
104- . try_program ( hugr)
105- . map_err ( |e| {
106- PecosError :: Generic ( format ! ( "Failed to load HUGR program: {e}" ) )
107- } ) ?;
108-
109- self . base_builder . classical ( engine_builder) . build ( )
110- }
111- #[ cfg( not( feature = "qis" ) ) ]
112- {
113- let _ = hugr; // Mark as used to avoid warning
114- Err ( PecosError :: Generic (
115- "HUGR programs require Selene and LLVM support. Please rebuild with --features selene,llvm" . to_string ( )
116- ) )
117- }
118- }
119- Program :: Wasm ( _) => Err ( PecosError :: Input (
120- "WASM programs are not yet supported in unified simulation" . to_string ( ) ,
121- ) ) ,
122- Program :: Wat ( _) => Err ( PecosError :: Input (
123- "WAT programs are not yet supported in unified simulation" . to_string ( ) ,
124- ) ) ,
125- Program :: PhirJson ( _) => Err ( PecosError :: Input (
126- "PHIR JSON programs are not yet supported in unified simulation" . to_string ( ) ,
127- ) ) ,
128- Program :: SeleneInterface ( _) => Err ( PecosError :: Input (
129- "SeleneInterface programs are not yet supported in unified simulation"
130- . to_string ( ) ,
131- ) ) ,
132- }
133- }
120+ self . configure_engine ( ) ?. build ( )
134121 }
135122
136123 /// Build and run the simulation with automatic engine selection
137124 ///
138- /// This selects an engine based on the program type and runs the simulation,
139- /// unless a classical engine was already explicitly set.
140- ///
141125 /// # Errors
142126 ///
143127 /// Returns an error if:
144128 /// - The program type is not yet supported (WASM, WAT, PHIR JSON, `SeleneInterface`)
145129 /// - Engine building or running fails
146130 pub fn run ( self , shots : usize ) -> Result < pecos_engines:: shot_results:: ShotVec , PecosError > {
147- if self . override_classical {
148- // Classical engine was already set, just run
149- self . base_builder . run ( shots)
150- } else {
151- // Auto-select engine based on program type
152- match self . program {
153- Program :: Qasm ( qasm) => self
154- . base_builder
155- . classical ( qasm_engine ( ) . program ( qasm) )
156- . run ( shots) ,
157- Program :: Qis ( qis) => {
158- // Use Selene runtime and Helios interface
159- #[ cfg( feature = "qis" ) ]
160- {
161- let selene_runtime = crate :: selene_simple_runtime ( ) . map_err ( |e| {
162- PecosError :: Generic ( format ! ( "Failed to load Selene runtime: {e}" ) )
163- } ) ?;
164- let helios_builder = crate :: helios_interface_builder ( ) ;
165- let engine_builder = qis_engine ( )
166- . runtime ( selene_runtime)
167- . interface ( helios_builder)
168- . try_program ( qis)
169- . map_err ( |e| {
170- PecosError :: Generic ( format ! ( "Failed to load QIS program: {e}" ) )
171- } ) ?;
172-
173- self . base_builder . classical ( engine_builder) . run ( shots)
174- }
175- #[ cfg( not( feature = "qis" ) ) ]
176- {
177- let _ = qis; // Mark as used to avoid warning
178- Err ( PecosError :: Generic (
179- "QIS programs require Selene and LLVM support. Please rebuild with --features selene,llvm" . to_string ( )
180- ) )
181- }
182- }
183- Program :: Hugr ( hugr) => {
184- // Use Selene runtime and Helios interface for HUGR programs
185- #[ cfg( feature = "qis" ) ]
186- {
187- let selene_runtime = crate :: selene_simple_runtime ( ) . map_err ( |e| {
188- PecosError :: Generic ( format ! ( "Failed to load Selene runtime: {e}" ) )
189- } ) ?;
190- let helios_builder = crate :: helios_interface_builder ( ) ;
191- let engine_builder = qis_engine ( )
192- . runtime ( selene_runtime)
193- . interface ( helios_builder)
194- . try_program ( hugr)
195- . map_err ( |e| {
196- PecosError :: Generic ( format ! ( "Failed to load HUGR program: {e}" ) )
197- } ) ?;
198-
199- self . base_builder . classical ( engine_builder) . run ( shots)
200- }
201- #[ cfg( not( feature = "qis" ) ) ]
202- {
203- let _ = hugr; // Mark as used to avoid warning
204- Err ( PecosError :: Generic (
205- "HUGR programs require Selene and LLVM support. Please rebuild with --features selene,llvm" . to_string ( )
206- ) )
207- }
208- }
209- Program :: Wasm ( _) => Err ( PecosError :: Input (
210- "WASM programs are not yet supported in unified simulation" . to_string ( ) ,
211- ) ) ,
212- Program :: Wat ( _) => Err ( PecosError :: Input (
213- "WAT programs are not yet supported in unified simulation" . to_string ( ) ,
214- ) ) ,
215- Program :: PhirJson ( _) => Err ( PecosError :: Input (
216- "PHIR JSON programs are not yet supported in unified simulation" . to_string ( ) ,
217- ) ) ,
218- Program :: SeleneInterface ( _) => Err ( PecosError :: Input (
219- "SeleneInterface programs are not yet supported in unified simulation"
220- . to_string ( ) ,
221- ) ) ,
222- }
223- }
131+ self . configure_engine ( ) ?. run ( shots)
224132 }
225133
226134 /// Override the classical engine selection
0 commit comments