Administración de sesiones

En este artículo, aprenderá a trabajar con sesiones. Con las sesiones, puede agrupar uno o varios trabajos en un solo target, lo que le permite administrar los trabajos de forma eficaz. Para más información, consulte Computación cuántica interactiva: sesiones.

Nota

Las sesiones se administran con Python, incluso cuando se ejecuta Q# código insertado. Para obtener más información, consulte la sección "Q# + Python" de Introducción a las sesiones.

Recuperar sesiones, enumerar sesiones y enumerar trabajos de sesiones

En la tabla siguiente se muestran los comandos de Python para obtener la lista de todas las sesiones y todos los trabajos de una sesión determinada.

Get-Help Descripción
workspace.list_sessions() o session.list_sessions() Recupere una lista de todas las sesiones de un área de trabajo de Quantum.
workspace.get_session(sessionId) o session.get_session(sessionId) Recupere la sesión con el identificador sessionId. Cada sesión tiene un identificador único.
workspace.list_session_jobs(sessionId) o session.list_session_jobs(sessionId) Recupere una lista de todos los trabajos de la sesión con el identificador sessionId. Cada sesión tiene un identificador único.

Por ejemplo, el código siguiente define una función que obtiene una sesión con un número mínimo de trabajos. A continuación, para esa sesión, enumera todos los trabajos, el número total de trabajos y los primeros 10 trabajos.

def get_a_session_with_jobs(min_jobs):
    all_sessions = workspace.list_sessions() # list of all sessions
    for session in all_sessions:
        if len(workspace.list_session_jobs(session.id)) >= min_jobs:
            return session

session = get_a_session_with_jobs(min_jobs=3) # Get a Session with at least 3 jobs

session_jobs = workspace.list_session_jobs(session.id) # List of all jobs within Session ID

print(f"Job count: {len(session_jobs)} \n")
print(f"First 10 jobs for session {session.id}:")
for job in session_jobs[0:10]:
    print(f"Id: {job.id}, Name={job.details.name}")

Métodos manuales de apertura y cierre de sesiones

Se recomienda seguir los pasos descritos en Introducción a las sesiones para crear una nueva sesión. Sin embargo, puede crear manualmente sesiones.

  1. En primer lugar, cree un objeto Session.

    from azure.quantum.job.session import Session, SessionDetails, SessionJobFailurePolicy
    import uuid
    
    session = Session(
        workspace=workspace, # required
        id=f"{uuid.uuid1()}", # optional, if not passed will use uuid.uuid1()
        name="", # optional, will be blank if not passed
        provider_id="ionq", # optional, if not passed will try to parse from the target
        target="ionq.simulator", # required
        job_failure_policy=SessionJobFailurePolicy.ABORT # optional, defaults to abort
        )
    
    print(f"Session status: {session.details.status}")
    

    Nota

    En este momento, la sesión solo existe en el cliente y puede ver que el estado es Ninguno. Para ver el estado de la sesión, también debe crear la sesión en el servicio.

  2. Para crear una sesión en el servicio, puede usar workspace.open_session(session) o session.open().

  3. Puede actualizar el estado y los detalles de la sesión con session.refresh()o obteniendo un nuevo objeto de sesión a partir de un identificador de sesión.

    same_session = workspace.get_session(session.id) 
    print(f"Session: {session.details} \n")
    print(f"Session: {same_session.details} \n")
    
  4. Puede cerrar una sesión con session.close() o workspace.close_session(session).

  5. Para adjuntar la sesión a , targetpuede usar target.latest_session.

  6. Puede esperar a que se complete una sesión:

    session_jobs = session.list_jobs()
    [session_job.id for session_job in session_jobs]
    
    import time
    while (session.details.status != "Succeeded" and session.details.status != "Failed" and session.details.status != "TimedOut"):
      session.refresh()
      time.sleep(5)
    

Pasar argumentos en Q#

Si la Q# operación toma argumentos de entrada, esos argumentos se pasan durante el envío del trabajo, que es código de Python. Esto significa que debe tener cuidado de dar formato a los argumentos como Q# objetos.

Al pasar argumentos como parámetros al trabajo, se les da formato de Q# código al llamar a qsharp.compile, por lo que los valores de Python deben tener formato en una cadena como sintaxis válida Q# .

Considere el siguiente Q# programa, que toma un entero, ny una matriz de ángulos, angle, como entrada.

open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Arrays;

operation GenerateRandomBits(n: Int, angle: Double[]) : Result[] {
   use qubits = Qubit[n]; // n parameter as the size of the qubit array
   for q in qubits {
       H(q);
   }
   R(PauliZ, angle[0], qubits[0]); // arrays as entry-points parameters
   R(PauliZ, angle[1], qubits[1]);
   let results = MeasureEachZ(qubits);
   ResetAll(qubits);
   return results;
}

Quiere ejecutar GenerateRandomBits la operación tres veces con n=2 y diferentes ángulos. Puede usar el siguiente código de Python para enviar tres trabajos con distintos ángulos.

angle = [0.0, 0.0]
with target.open_session(name="Q# session of three jobs") as session:
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 1", shots=100) # First job submission
    angle[0] += 1
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 2", shots=100) # Second job submission
    angle[1] += 1
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 3", shots=100) # Third job submission

session_jobs = session.list_jobs()
[session_job.details.name for session_job in session_jobs]

En este ejemplo, dado que las matrices de Python ya se imprimen como [item0, item1, ...], los argumentos de entrada coinciden con el Q# formato. En el caso de otras estructuras de datos de Python, es posible que necesite más control para obtener los valores de cadena insertados de Q# forma compatible. Por ejemplo, una Q# tupla debe estar entre paréntesis con valores separados por comas.

Tiempos de espera de sesión

Una sesión agota el tiempo de espera si no se envía ningún trabajo nuevo dentro de la sesión durante 10 minutos. La sesión notifica un estado de TimedOut. Para evitar esta situación, agregue un with bloque mediante backend.open_session(name="Name"), por lo que el servicio invoca la sesión close() al final del bloque de código.

Nota

Si hay errores o errores en el programa, puede tardar más de 10 minutos en enviar un nuevo trabajo después de que se hayan completado todos los trabajos anteriores de la sesión.

Los fragmentos de código siguientes muestran un ejemplo de tiempo de espera de una sesión después de 10 minutos porque no se envían nuevos trabajos. Para evitarlo, el siguiente fragmento de código muestra cómo usar un with bloque para crear una sesión.

#Example of a session that times out 

session = backend.open_session(name="Qiskit circuit session") # Session times out because only contains one job
backend.run(circuit=circuit, shots=100, job_name="Job 1")
#Example of a session that includes a with block to avoid timeout

with backend.open_session(name="Qiskit circuit session") as session:  # Use a with block to submit multiple jobs within a session
    job1 = backend.run(circuit=circuit, shots=100, job_name="Job 1") # First job submission
    job1.wait_for_final_state()
    job2 = backend.run(circuit=circuit, shots=100, job_name="Job 2") # Second job submission
    job2.wait_for_final_state()
    job3 = backend.run(circuit=circuit, shots=100, job_name="Job 3") # Third job submission
    job3.wait_for_final_state()

Directiva de error de trabajo en sesiones

La directiva predeterminada para una sesión cuando se produce un error en un trabajo es finalizar esa sesión. Si envía un trabajo adicional dentro de la misma sesión, el servicio lo rechaza y la sesión notifica un estado de Error. Los trabajos en curso se cancelan.

Sin embargo, este comportamiento se puede cambiar especificando una directiva de error de trabajo de job_failure_policy=SessionJobFailurePolicy.CONTINUE, en lugar del valor predeterminado SessionJobFailurePolicy.ABORT, al crear la sesión. Cuando la directiva de error del trabajo es CONTINUE, el servicio continúa aceptando trabajos. La sesión notifica un estado de Errores en este caso, que cambiará a Error una vez cerrada la sesión.

Si la sesión nunca se cierra y agota el tiempo de espera, el estado es TimedOut aunque se hayan producido errores en los trabajos.

Por ejemplo, el siguiente programa crea una sesión con tres trabajos. Se produce un error en el primer trabajo porque especifica "garbage" como datos de entrada. Para evitar el final de la sesión en este momento, el programa muestra cómo agregar job_failure_policy=SessionJobFailurePolicy.CONTINUE al crear la sesión.

#Example of a session that does not close but reports Failure(s) when a jobs fails

with target.open_session(name="JobFailurePolicy Continue", job_failure_policy=SessionJobFailurePolicy.CONTINUE) as session:
    target.submit(input_data="garbage", name="Job 1") #Input data is missing, this job fails
    target.submit(input_data=quil_program, name="Job 2") #Subsequent jobs are accepted beacuse of CONTINUE policy
    target.submit(input_data=quil_program, name="Job 3")

Paso siguiente