1- from typing import Any , Dict , List
1+ import httpx
2+ import time
3+
4+ from typing import List , Union
5+
6+ from qami import (
7+ QuantumProgram ,
8+ QuantumProgramResult ,
9+ QuantumComputationModel ,
10+ QuantumComputationParameters ,
11+ )
212
313from yardstiq .core import (
414 provider ,
515 Provider ,
616 Backend ,
7- BackendRunResult ,
817 BackendAvailability ,
9- ComputationalModel ,
1018)
1119
1220from scaleway_qaas_client .v1alpha1 import (
1321 QaaSClient ,
1422 QaaSPlatform ,
1523 QaaSPlatformAvailability ,
16- QaaSJobBackendData ,
17- QaaSJobRunData ,
18- QaaSJobData ,
19- QaaSCircuitData
24+ QaaSJobResult ,
2025)
2126
2227
2328class ScalewayBackend (Backend ):
2429 def __init__ (
2530 self , provider : "ScalewayProvider" , platform : QaaSPlatform , client : QaaSClient
2631 ):
27- super ().__init__ (provider = provider , name = platform .name )
32+ super ().__init__ (
33+ provider = provider , name = platform .name , version = platform .version
34+ )
2835
2936 self .__platform : QaaSPlatform = platform
3037 self .__client : QaaSClient = client
@@ -35,9 +42,11 @@ def allocate(self, **kwargs) -> None:
3542 return
3643
3744 deduplication_id = kwargs .get ("deduplication_id" , None )
45+
3846 session = self .__client .create_session (
3947 self .__platform .id , deduplication_id = deduplication_id
4048 )
49+
4150 self .__session_id = session .id
4251
4352 def deallocate (self , ** kwargs ) -> None :
@@ -46,42 +55,73 @@ def deallocate(self, **kwargs) -> None:
4655
4756 self .__client .terminate_session (self .__session_id )
4857
49- def run (self , model : ComputationalModel , shots : int , ** kwargs ) -> BackendRunResult :
50- run_data = QaaSJobRunData (
51- options = {
52- "shots" : shots ,
53- },
54- circuits = list (
55- map (
56- lambda c : QaaSCircuitData (
57- serialization_format = model .serialization_format ,
58- circuit_serialization = model .serialization ,
59- ),
60- self ._circuits ,
61- )
62- ),
63- )
58+ def run (
59+ self ,
60+ program : Union [QuantumProgram , List [QuantumProgram ]],
61+ shots : int ,
62+ wait : bool ,
63+ ** kwargs ,
64+ ) -> List [QuantumProgramResult ]:
65+ if not isinstance (program , list ):
66+ program = [program ]
6467
65- backend_data = QaaSJobBackendData (
66- name = self .backend ().name ,
67- version = self .backend ().version ,
68- )
68+ computation_model = QuantumComputationModel (
69+ programs = program ,
70+ backend = None ,
71+ client = None ,
72+ ).to_dict ()
6973
70- data = QaaSJobData .schema ().dumps (
71- QaaSJobData (
72- backend = backend_data ,
73- run = run_data ,
74- client = None ,
75- )
76- )
74+ computation_parameters = QuantumComputationParameters (
75+ shots = shots ,
76+ ).to_dict ()
7777
78- model = self .__client .create_model (model )
78+ model = self .__client .create_model (computation_model )
7979
8080 if not model :
81- raise RuntimeError ("Failed to push circuit data" )
81+ raise RuntimeError ("Failed to push model data" )
8282
8383 job = self .__client .create_job (self .__session_id , model_id = model .id )
8484
85+ if wait :
86+ while job .status in ["waiting" , "running" ]:
87+ time .sleep (2 )
88+ job = self .__client .get_job (job .id )
89+
90+ if job .status == "error" :
91+ raise RuntimeError (f"Job failed with error: { job .progress_message } " )
92+
93+ raw_results = self .__client .list_job_results (job .id )
94+
95+ program_results = list (
96+ map (
97+ lambda r : QuantumProgramResult .from_json (
98+ self ._extract_payload_from_response (r )
99+ ),
100+ raw_results ,
101+ )
102+ )
103+
104+ if len (program_results ) == 1 :
105+ return program_results [0 ]
106+
107+ return program_results
108+
109+ def _extract_payload_from_response (self , job_result : QaaSJobResult ) -> str :
110+ result = job_result .result
111+
112+ if result is None or result == "" :
113+ url = job_result .url
114+
115+ if url is not None :
116+ resp = httpx .get (url )
117+ resp .raise_for_status ()
118+
119+ return resp .text
120+ else :
121+ raise RuntimeError ("Got result with empty data and url fields" )
122+ else :
123+ return result
124+
85125 @property
86126 def max_qubit_count (self ) -> int :
87127 return self .__platform .max_qubit_count
@@ -98,7 +138,7 @@ def availability(self) -> BackendAvailability:
98138 QaaSPlatformAvailability .MAINTENANCE : BackendAvailability .MAINTENANCE ,
99139 }
100140 return availability_map .get (
101- self .__platform .availability , BackendAvailability .UNKOWN_AVAILABILITY
141+ self .__platform .availability , BackendAvailability .UNKNOWN_AVAILABILITY
102142 )
103143
104144
0 commit comments