
    iR                    F   S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
Jr  SSKJrJrJrJrJrJrJr  SSKJr  SSKJr  SSKrSSKrSS	KJr  SS
KJr  SSKJ r J!r!J"r"J#r#  SSK$J%r%  SSK&J'r'  SSK(J)r)J*r*J+r+  SSK,J-r-  SSK.J/r/  SSK0J1r1  SSK2J3r3  S,S jr4S-S jr5S.S jr6S/S jr7S0S jr8S1S2S jjr9S3S jr:S4S jr;S4S jr<S4S jr=S4S jr>S5S jr?S6S jr@ S7         S8S  jjrAS9S! jrBS:S" jrCS:S# jrDS;S$ jrES<S% jrFS=S& jrGS>S' jrH " S( S)\	5      rI " S* S+\J5      rKg)?zGeneral utility functions.    )annotationsN)Queue)	Condition)ListOptionalAnyDictUnionTupleSet)urlparse)chain)IAMAuthenticator)ResourceControllerV2)QuantumCircuitControlFlowOpParameterExpression	Parameter)Delay)Instruction)RZGateU1Gate	PhaseGate)Target)	BackendV2)EstimatorPub)
SamplerPubc                t    [        U S5      (       a  [        U R                  5       SS5      $ [        U SS5      $ )zReturn true if the backend is a simulator.

Args:
    backend: Backend to check.

Returns:
    True if backend is a simulator.
configuration	simulatorF)hasattrgetattrr   )backends    X/home/james-whalen/.local/lib/python3.13/site-packages/qiskit_ibm_runtime/utils/utils.pyis_simulatorr%   /   s8     w((w,,.UCC7K//    c           	       ^ U R                    GH?  nUR                  nUR                  n[        U4S jUR                   5       5      nUR                  XV5      (       d  US:w  a  SU SU S3s  $ US:X  a\  [        UR                  R                  S   =n[        5      (       d.  US:  d  U[        R                  S	-  S
-   :  a  SU SU SU S3s  $ [        U[        5      (       d  M  UR                   HT  n[        UR                  UR                  5       V	V
s0 s H  u  pU
TU	   _M     nn	n
[        XU5      nU(       d  MP  Us  s  $    GMB     gs  sn
n	f )zj
A section of is_isa_circuit, separated to allow recursive calls
within blocks of conditional operations.
c              3  .   >#    U  H
  nTU   v   M     g 7fN ).0bit	qubit_maps     r$   	<genexpr>)_is_isa_circuit_helper.<locals>.<genexpr>F   s     C0Bin0Bs   barrierzThe instruction z on qubits z' is not supported by the target system.rzzr              绽|=zD is supported only for angles in the range [0, pi/2], but an angle (+) outside of this range has been requested. )data	operationnametuplequbitsinstruction_supported
isinstanceparamsr   nppir   blockszip_is_isa_circuit_helper)circuittargetr-   instructionr8   r9   qargsparamsub_circouterinner	inner_map
sub_strings     `          r$   rC   rC   =   s^   
 ||))	~~C0B0BCC++D88TY=N"4&E7:ab EM)>)>)E)Ea)H HK^__	E(9 9 #4&E7 ;2278ce
 i//%,, ),K,>,>(P(P 9U++(P   4HiP
:%% -3 $D s   E
c                    U R                   UR                   :  a  SU R                    SUR                    S3$ [        U R                  5       VVs0 s H  u  p#X2_M	     nnn[        XU5      $ s  snnf )a  Checks if the circuit is an ISA circuit, meaning that it has a layout and that it
only uses instructions that exist in the target.

Args:
    circuit: A single QuantumCircuit
    target: The backend target

Returns:
    Message on why the circuit is not an ISA circuit, if applicable.
zThe circuit has z' qubits but the target system requires z qubits.)
num_qubits	enumerater;   rC   )rD   rE   indexqubitr-   s        r$   is_isa_circuitrS   g   s|     F---w112 3..4.?.?-@J	

 3<GNN2KL2K,%2KIL!'9== Ms   A-c                
   [        5       nU R                   H  nUR                  nUR                  S:X  ah  UR                  R                  S   n[        U[        5      (       a  UR                  U5        O(US:  d  U[        R                  S-  S-   :  a  SU S3s  $ [        U[        5      (       d  M  UR                   H:  n[        U5      n[        U[        5      (       a  Us  s  $ UR                  U5        M<     M     U$ )a  
For rzz gates:
- Verify that numeric angles are in the range [0, pi/2]
- Collect parameterized angles

Returns one of the following:
- A string, containing an error message, if a numeric angle is outside of the range [0, pi/2]
- A list of names of all the parameters that participate in an rzz gate

Note: we check for parametrized rzz gates inside control flow operation, although fractional
gates are actually impossible in combination with dynamic circuits. This is in order to remain
correct if this restriction is removed at some point.
r1   r   r2   r3   r4   WThe instruction rzz is supported only for angles in the range [0, pi/2], but an angle (r5   )setr7   r8   r9   r>   r=   r   addr?   r@   r   rA   _is_valid_rzz_pub_helperstrupdate)rD   angle_paramsrF   r8   anglerI   body_results          r$   rX   rX   |   s     5L||))	 >>U"))003E%!455  '	E(9 966;W =00 i//%,,6x@k3//&&##K0	 -' $2 r&   c                   [        U R                  5      n[        U[        5      (       a  U$ [	        U5      S:X  a  g[        U5      n[        R                  " [        [        R                  " U R                  R                  5      5      5      nU R                  R                  5       R                  5       nU GH  nUR                   Vs/ s H  ofR                  PM     nnU Vs/ s H!  n[        R                   " X8:H  5      S   S   PM#     n	nUSS2U	4   n
U
 H  n[#        UR%                  ['        [)        UR                  U5      5      5      5      nUS:  d  U[        R*                  S-  S-   :  d  M\  SR-                  [)        X{5       VVs/ s H  u  pU SU 3PM     snn5      nS	U S
U SU S3s  s  $    GM     gs  snf s  snf s  snnf )zVerify that all rzz angles are in the range [0, pi/2].

Args:
    pub: A pub to be checked

Returns:
    An empty string if all angles are valid, otherwise an error message.
r   r6   Nr2   r3   r4   z, =rU   zC) outside of this range has been requested; via parameter value(s) z&, substituted in parameter expression .)rX   rD   r=   rY   lenlistr?   arrayr   from_iterableparameter_valuesr7   ravelas_array
parametersr9   wherefloatbinddictrB   r@   join)pubhelper_result
rzz_params
pub_paramsarr	param_exprH   param_names
param_namecol_indicesprojected_arrrowr\   	param_valvals_msgs                  r$   is_valid_rzz_pubr{      s    -S[[9M-%%
=Q m$J $u2233G3G3L3LMNOJ 


$
$
&
/
/
1C	/8/C/CD/Cezz/CDR]^R]Jrxx
 89!<Q?R]^ A{N+ C)..c)2F2F.L)MNOEs{ebeeai%&7799NQR]NcdNc5JZ
|1YK0Ncd66;W =99A
 C""+A/ !  , + E^ es   G&(GGc                    U  H_  n[        U[        5      (       a  Us  $ U H=  n[        UR                  [        5      (       d  [	        UR                  SS5      c  M<      g   Ma     g)z)Checks if the input circuits are dynamic.	conditionNTF)r=   rY   r8   r   r"   )circuitsqasm_defaultrD   insts       r$   are_circuits_dynamicr      sU    gs##D4>>=994>>;=I   r&   c                    [         [        [        [        4n[	        U R
                  5      S:  =(       a    [        X5      (       + $ )a  Test if a gate is considered fractional by IBM

Fractional gates produce a rotation based on a continuous input parameter
and require a non-zero gate duration. The latter distinction excludes gates
like ``RZGate`` which can be implemented in software with no duration. The
fractional gate definition is based on the current IBM compiler system
which currently can not use fractional gates and dynamic circuit
instructions in the same job. In that sense, this function is really
testing if a gate is currently incompatible with dynamic circuit
instructions for IBM's compiler.

Args:
    gate: The instruction to test for status as a fractional gate

Returns:
    True if the gate is a fractional gate
r   )r   r   r   r   ra   r>   r=   )gateexclude_lists     r$   is_fractional_gater      s3    ( Ivu5Lt{{aF
4(F$FFr&   c                N    [        U 5      nUR                   SUR                   3$ )z5Computes the IAM API URL for the given IBM Cloud URL.z://iam.r   schemehostname	cloud_url
parsed_urls     r$   get_iam_api_urlr     s+    )$J 
(;(;'<==r&   c                N    [        U 5      nUR                   SUR                   3$ )z#Compute the GlobalSearchV2 API URL.z://api.global-search-tagging.r   r   s     r$   get_global_search_api_urlr     s,    )$J  =j>Q>Q=RSSr&   c                P    [        U 5      nUR                   SUR                   S3$ )z$Compute the GlobalCatalogV1 API URL.z://globalcatalog./api/v1r   r   s     r$   get_global_catalog_api_urlr     s.    )$J  1*2E2E1FgNNr&   c                N    [        U 5      nUR                   SUR                   3$ )zEComputes the Resource Controller API URL for the given IBM Cloud URL.z://resource-controller.r   r   s     r$   get_resource_controller_api_urlr     s,    )$J  7
8K8K7LMMr&   c                   U S;  a  [        S5      e[        U5      (       a  U/$ [        R                  " 5        n[	        U[        U5      S9n[        US9nUR                  [        U5      5        UR                  U5        UR                  US9nUR                  5       nUS   n	U	S:X  a  / sSSS5        $ [        [        S	 US
   5      5      sSSS5        $ ! , (       d  f       g= f)zCResolves the Cloud Resource Name (CRN) for the given cloud account.)	ibm_cloudibm_quantum_platformz2CRN value can only be resolved for cloud accounts.url)authenticator)r9   
rows_countr   Nc                    U S   $ )Ncrnr*   )resources    r$   <lambda>resolve_crn.<locals>.<lambda>.  s    %r&   	resources)
ValueErroris_crnrequestsSessionr   r   r   set_service_urlr   set_http_clientlist_resource_instances
get_resultrb   map)
channelr   instancetokensessionr   clientlist_responseresult	row_counts
             r$   resolve_crnr     s    ;;MNNhz7,U8LMM)FF""#B3#GH""7+":::IM"--/F|,IA~   C @&BUVW  s   A3C7C
C'c                R    [        U [        5      =(       a    U R                  S5      $ )zCheck if a given value is a CRN (Cloud Resource Name).

Args:
    locator: The value to check.

Returns:
    Whether the input is a CRN.
zcrn:)r=   rY   
startswith)locators    r$   r   r   1  s!     gs#B(:(:6(BBr&   c                   U n[        U5      (       a  [        U 5      (       d  [        U 5      nU(       a*  UR                   S[	        U5       SUR
                   S3nU$ US:X  a9  [	        U5      nUS:X  a  SOU S3nUR                   SU S	UR
                   S3nU$ UR                   S[	        U5       S
UR
                   3nU$ )zComputes the Runtime API base URL based on the provided input parameters.

Args:
    url: The URL.
    instance: The instance.
    private_endpoint: Connect to private API URL.

Returns:
    Runtime API base URL
z://private.z	.quantum.r   r   zus-eastr6   r`   z://zquantum.z.quantum-computing.)r   _is_experimental_runtime_urlr   r   _location_from_crnr   )r   r   private_endpointr   api_hostr   regionregion_prefixs           r$   default_runtime_url_resolverr   =  s     H h <S A Ac]
$$%[1CH1M0NJ//09 $ O ..'1F"(I"5BfXQ<M$$%S8JDWDWCXX_`  O	 $$%S);H)E(F%j&9&9%:< 
 Or&   c                :    [        U [        5      =(       a    SU ;   $ )zChecks if the provided url points to an experimental runtime cluster.
This type of URLs is used for internal development purposes only.

Args:
    url: The URL.
experimental)r=   rY   r   s    r$   r   r   g  s     c39Nc$99r&   c                P    Sn[         R                  " X5      R                  S5      $ )zComputes the location from a given CRN.

Args:
    crn: A CRN (format: https://cloud.ibm.com/docs/account?topic=account-crn#format-crn)

Returns:
    The location.
&(.*?):(.*?):(.*?):(.*?):(.*?):(.*?):.*   )researchgroupr   patterns     r$   r   r   q  s#     7G99W"((++r&   c                r    [        U 5      (       a'  Sn[        R                  " X5      R                  S5      $ g)zComputes the CNAME ('bluemix' or 'staging') from a given CRN.

Args:
    crn: A CRN (format: https://cloud.ibm.com/docs/account?topic=account-crn#format-crn)

Returns:
    The location.
r      N)r   r   r   r   r   s     r$   cname_from_crnr   ~  s/     c{{:yy&,,Q//r&   c                p   [         R                  " S[         R                  5      nU R                  5       (       d  [         R                  " USU 5      n [         R                  " SSU 5      R                  5       n [        R                  " U 5      (       a"  U S-  n [        R                  " U 5      (       a  M"  U $ )zConvert a name to a valid Python identifier.

Args:
    name: Name to be converted.

Returns:
    Name that is a valid Python identifier.
z
\W|^(?=\d)_z.((?<=[a-z0-9])[A-Z]|(?!^)(?<!_)[A-Z](?=[a-z]))z_\1)r   compileASCIIisidentifiersublowerkeyword	iskeyword)r9   r   s     r$   to_python_identifierr     s     jj1GvvgsD) 66BFDQWWYD


D
!
! 

D
!
! Kr&   c                   [         R                  " SS5      n[         R                  " SS5      nSn[        R                  " U5      nSU l        U(       a9  [        R
                  " U5      nUR                  U5        U R                  U5        O7[        R                  " 5       nUR                  U5        U R                  U5        U(       a  [        R                  " UR                  5       5      n[        U[        5      (       d"  U R                  SU5        [        R                  nU R                  SU5        U R!                  U5        gg)	aL  Setup the logger for the runtime modules with the appropriate level.

It involves:
    * Use the `QISKIT_IBM_RUNTIME_LOG_LEVEL` environment variable to
      determine the log level to use for the runtime modules. If an invalid
      level is set, the log level defaults to ``WARNING``. The valid log levels
      are ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``, and ``CRITICAL``
      (case-insensitive). If the environment variable is not set, then the parent
      logger's level is used, which also defaults to `WARNING`.
    * Use the `QISKIT_IBM_RUNTIME_LOG_FILE` environment variable to specify the
      filename to use when logging messages. If a log file is specified, the log
      messages will not be logged to the screen. If a log file is not specified,
      the log messages will only be logged to the screen and not to a file.
QISKIT_IBM_RUNTIME_LOG_LEVELr6   QISKIT_IBM_RUNTIME_LOG_FILEz>%(module)s.%(funcName)s:%(levelname)s:%(asctime)s: %(message)sFzm"%s" is not a valid log level. The valid log levels are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, and `CRITICAL`.z%The logger is being set to level "%s"N)osgetenvlogging	Formatter	propagateFileHandlersetFormatter
addHandlerStreamHandlergetLevelNameupperr=   intwarningWARNINGdebugsetLevel)logger	log_levellog_filelog_fmt	formatterfile_handlerstream_handlerlevels           r$   setup_loggerr     s    		8"=Iyy6;H OG!!'*I F **84!!),,' !..0##I..) $$Y__%67%%%NNG
 OOE<eD r&   c                |    [        U [        5      (       d  U $ [        R                  " U 5      nS/n[	        X5        U$ )zReturn the data with certain fields filtered.

Data to be filtered out includes hub/group/project information.

Args:
    data: Original data to be filtered.

Returns:
    Filtered data.
hubInfo)r=   rl   copydeepcopy_filter_value)r7   data_to_filterkeys_to_filters      r$   filter_datar     s9     dD!!]]4(N[N.1r&   c                   U R                  5        Hp  u  p#U He  n[        U[        5      (       a  X$:X  a  SX'   M#  X$S   :X  a  US   U;   a  SXS      US   '   MC  [        U[        5      (       d  MZ  [	        X15        Mg     Mr     g)aV  Recursive function to filter out the values of the input keys.

Args:
    data: Data to be filtered
    filter_keys: A list of keys whose values are to be filtered out. Each
        item in the list can be a string or a tuple. A tuple indicates nested
        keys, such as ``{'backend': {'name': ...}}`` and must have a length
        of 2.
z...r      N)itemsr=   rY   rl   r   )r7   filter_keyskeyvalue
filter_keys        r$   r   r     sx     jjl
%J*c**s/@!	1%*Q-5*@5:]#JqM2E4((e1 & #r&   c                  ^   ^  \ rS rSrSrSU 4S jjrS	U 4S jjrS
SU 4S jjjrSS jrSr	U =r
$ )RefreshQueuei  zA queue that replaces the oldest item with the new item being added when full.

A FIFO queue with a bounded size. Once the queue is full, when a new item
is being added, the oldest item on the queue is discarded to make space for
the new item.
c                >   > [        5       U l        [        TU ]  US9  g)zIRefreshQueue constructor.

Args:
    maxsize: Maximum size of the queue.
)maxsizeN)r   r}   super__init__)selfr  	__class__s     r$   r  RefreshQueue.__init__	  s     #)r&   c                   > U R                      U R                  5       (       a  [        TU ]  SS9  [        TU ]  USS9  U R                   R                  5         SSS5        g! , (       d  f       g= f)zPut `item` into the queue.

If the queue is full, the oldest item is replaced by `item`.

Args:
    item: Item to put into the queue.
FblockN)r}   fullr  getputnotify)r  itemr  s     r$   r  RefreshQueue.put  sO     ^^yy{{%(GKEK*NN!!#	 ^^s   AA""
A0c                   > U R                      U(       a0  U R                  5       (       a  U R                   R                  U5        [        TU ]  SS9sSSS5        $ ! , (       d  f       g= f)a
  Remove and return an item from the queue.

Args:
    block: If ``True``, block if necessary until an item is available.
    timeout: Block at most `timeout` seconds before raising the
        ``queue.Empty`` exception if no item was available. If
        ``None``, block indefinitely until an item is available.

Returns:
    An item from the queue.

Raises:
    queue.Empty: If `block` is ``False`` and no item is available, or
        if `block` is ``True`` and no item is available before `timeout`
        is reached.
Fr  N)r}   emptywaitr  r  )r  r  timeoutr  s      r$   r  RefreshQueue.get"  sC    " ^^##G,7;U;+ ^^s   AA
A*c                    U R                      U R                   R                  5         SSS5        g! , (       d  f       g= f)z4Wake up all threads waiting for items on the queued.N)r}   
notify_allr  s    r$   r  RefreshQueue.notify_all8  s#    ^^NN%%' ^^s   1
?)r}   )r  r   )r  r   returnNone)TN)r  boolr  zOptional[float]r  r   )r  r  )__name__
__module____qualname____firstlineno____doc__r  r  r  r  __static_attributes____classcell__)r  s   @r$   r  r    s&    *$ , ,,( (r&   r  c                  "    \ rS rSrSrSS jrSrg)CallableStri>  zA callable string.c                    U $ r)   r*   r  s    r$   __call__CallableStr.__call__A  s    r&   r*   N)r  rY   )r  r   r!  r"  r#  r)  r$  r*   r&   r$   r'  r'  >  s
    r&   r'  )r#   r   r  r  )rD   r   rE   r   r-   r	   r  rY   )rD   r   rE   r   r  rY   )rD   r   r  zUnion[str, Set[Parameter]])rn   zUnion[EstimatorPub, SamplerPub]r  rY   )T)r~   zList[QuantumCircuit]r   r  r  r  )r   r   r  r  )r   rY   r  rY   )
r   rY   r   rY   r   rY   r   rY   r  z	List[str])r   rY   r  r  )Fr   )
r   rY   r   rY   r   r  r   rY   r  rY   )r   rY   r  r  )r   rY   r  rY   )r9   rY   r  rY   )r   zlogging.Loggerr  r  )r7   Dict[str, Any]r  r+  )r7   r+  r   z!List[Union[str, Tuple[str, str]]]r  r  )Lr#  
__future__r   r   r   r   r   r   queuer   	threadingr   typingr   r   r   r	   r
   r   r   urllib.parser   	itertoolsr   numpyr?   r   !ibm_cloud_sdk_core.authenticatorsr   ibm_platform_servicesr   qiskit.circuitr   r   r   r   qiskit.circuit.delayr   qiskit.circuit.gater   %qiskit.circuit.library.standard_gatesr   r   r   qiskit.transpilerr   qiskit.providers.backendr   *qiskit.primitives.containers.estimator_pubr   (qiskit.primitives.containers.sampler_pubr   r%   rC   rS   rX   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  rY   r'  r*   r&   r$   <module>r=     s!   ! "    	 	   ? ? ? !    7 X X & + 
 % . C ?0'T>*)X0fG0>TONX0	C Mc'	''/3'FI''T:
,01h(2(:(5 :(z# r&   