

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Trabajar con trabajos híbridos de Amazon Braket
<a name="braket-jobs"></a>

Amazon Braket Hybrid Jobs le ofrece una forma de ejecutar algoritmos híbridos cuántico-clásicos que requieren tanto AWS recursos clásicos como unidades de procesamiento cuántico (). QPUs Los trabajos híbridos están diseñados para activar los recursos clásicos solicitados, ejecutar su algoritmo y liberar las instancias una vez completados, de modo que solo pague por *lo que use*. 

Los trabajos híbridos son ideales para algoritmos iterativos de larga duración que implican el uso tanto de recursos de computación clásica como de recursos de computación cuántica. Con los trabajos híbridos, después de enviar su algoritmo para su ejecución, Braket lo ejecutará en un entorno escalable y en contenedor. Una vez que el algoritmo se haya completado, puede recuperar los resultados.

Además, las tareas cuánticas que se crean a partir de un trabajo híbrido se benefician de una mayor prioridad al hacer cola en el dispositivo de QPU de destino. Esta priorización garantiza que sus cálculos cuánticos se procesen y ejecuten antes que otras tareas que esperan en la cola. Esto resulta especialmente ventajoso para los algoritmos híbridos iterativos, en los que los resultados de una tarea cuántica dependen de los resultados de tareas cuánticas anteriores. Algunos ejemplos de estos algoritmos incluyen el [algoritmo de optimización cuántica aproximada (QAOA)](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_quantum_algorithms/QAOA/QAOA_braket.ipynb), el [solucionador de problemas de autovalores cuánticos variacionales](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_quantum_algorithms/VQE_Chemistry/VQE_chemistry_braket.ipynb) o la [ machine learning cuántica](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs.ipynb). También puede supervisar el progreso de su algoritmo casi en tiempo real, lo que le permite realizar un seguimiento de los costos, el presupuesto o métricas personalizadas, como la pérdida de entrenamiento o los valores esperados. 

Puede acceder a los trabajos híbridos en Braket mediante:
+ el [SDK de Python de Amazon Braket](https://github.com/aws/amazon-braket-sdk-python);
+ la [consola de Amazon Braket](https://console.aws.amazon.com/braket/home); o
+ la API de Amazon Braket.

**Topics**
+ [Cuándo utilizar los trabajos híbridos de Amazon Braket](#braket-jobs-use)
+ [Ejecución de un trabajo híbrido con los trabajos híbridos de Amazon Braket](#braket-jobs-works)
+ [Conceptos clave de los trabajos híbridos](braket-jobs-concepts.md)
+ [Requisitos previos](braket-jobs-prerequisites.md)
+ [Creación de un trabajo híbrido](braket-jobs-first.md)
+ [Cancelación de un trabajo híbrido](braket-jobs-cancel.md)
+ [Personalización del trabajo híbrido](braket-jobs-customize.md)
+ [Uso PennyLane con Amazon Braket](hybrid.md)
+ [Uso de CUDA-Q con Amazon Braket](braket-using-cuda-q.md)

## Cuándo utilizar los trabajos híbridos de Amazon Braket
<a name="braket-jobs-use"></a>

 Los trabajos híbridos de Amazon Braket le permiten ejecutar algoritmos híbridos cuánticos-clásicos, como el solucionador de problemas de autovalores cuánticos variacionales (VQE) y el algoritmo de optimización cuántica aproximada (QAOA), que combinan recursos de computación clásica con dispositivos de computación cuántica para optimizar el rendimiento de los sistemas cuánticos actuales. Los trabajos híbridos de Amazon Braket ofrecen tres ventajas principales:

1.  **Rendimiento**: los trabajos híbridos de Amazon Braket ofrecen un mejor rendimiento que la ejecución de algoritmos híbridos desde su propio entorno. Mientras se ejecuta su trabajo, tiene acceso prioritario a la QPU de destino seleccionada. Las tareas de tu trabajo se ejecutan antes que las demás tareas que están en cola en el dispositivo. Esto se traduce en tiempos de ejecución más cortos y predecibles para los algoritmos híbridos. Los trabajos híbridos de Amazon Braket también admiten la compilación paramétrica. Puede enviar un circuito utilizando parámetros libres y Braket compila el circuito una vez, sin necesidad de recompilarlo para posteriores actualizaciones de parámetros en el mismo circuito, lo que se traduce en tiempos de ejecución aún más rápidos.

1.  **Comodidad**: los trabajos híbridos de Amazon Braket simplifican la configuración y la gestión de su entorno de computación, y mantienen su funcionamiento mientras se ejecuta su algoritmo híbrido. Solo tiene que proporcionar el script de algoritmo y seleccionar un dispositivo cuántico (ya sea una unidad de procesamiento cuántico o un simulador) en el que ejecutarlo. Amazon Braket espera a que el dispositivo de destino esté disponible, activa los recursos clásicos, ejecuta la carga de trabajo en entornos de contenedores preconstruidos, devuelve los resultados a Amazon Simple Storage Service (Amazon S3) y libera los recursos de computación.

1.  **Métricas**: Amazon Braket Hybrid Jobs proporciona on-the-fly información sobre la ejecución de los algoritmos y proporciona métricas de algoritmos personalizables prácticamente en tiempo real a Amazon CloudWatch y a la consola Amazon Braket para que pueda realizar un seguimiento del progreso de sus algoritmos.

## Ejecución de un trabajo híbrido con los trabajos híbridos de Amazon Braket
<a name="braket-jobs-works"></a>

Para ejecutar un trabajo híbrido con los trabajos híbridos de Amazon Braket, primero debe definir su algoritmo. Puede definirlo escribiendo el *script del algoritmo* y, si lo desea, otros archivos de dependencia mediante el [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python) o. [PennyLane](https://pennylane.ai) Si desea utilizar otras bibliotecas (de código abierto o patentadas), puede definir su propia imagen de contenedor personalizada mediante Docker, que incluye estas bibliotecas. Para obtener más información, consulte [Utilice su propio contenedor (BYOC)](braket-jobs-byoc.md).

En cualquier caso, a continuación, cree un trabajo híbrido utilizando la API de Amazon Braket, donde proporcionará el contenedor o el script de algoritmo, seleccionará el dispositivo cuántico de destino que utilizará el trabajo híbrido y, a continuación, elegirá entre una serie de configuraciones opcionales. Los valores predeterminados proporcionados para estas configuraciones opcionales funcionan para la mayoría de los casos de uso. Para que el dispositivo de destino ejecute su trabajo híbrido, puede elegir entre una QPU, un simulador bajo demanda (como SV1, DM1 o TN1) o la propia instancia de trabajo híbrida clásica. Con un simulador bajo demanda o una QPU, su contenedor de trabajos híbridos realiza llamadas a la API a un dispositivo remoto. Con los simuladores integrados, el simulador se integra en el mismo contenedor que el script de algoritmo. Los [simuladores Lightning](https://github.com/PennyLaneAI/pennylane-lightning) de PennyLane vienen integrados en el contenedor de trabajos híbridos prediseñado por defecto para su uso. Si ejecuta el código con un PennyLane simulador integrado o un simulador personalizado, puede especificar un tipo de instancia, así como el número de instancias que desea utilizar. Consulte la [página de precios de Amazon Braket](https://aws.amazon.com/braket/pricing/) para conocer los costos asociados a cada opción.

![\[Diagrama de flujo que muestra las interacciones de los usuarios con los componentes de Amazon Braket, la API, la instancia de trabajos y los simuladores para tareas híbridas, de QPU, bajo demanda e integradas. Los resultados se almacenan en el bucket de Amazon Simple Storage Service y se analizan con Amazon CloudWatch en la consola Amazon Braket.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-hybrid-job-run.png)


Si el dispositivo de destino es un simulador bajo demanda integrado, Amazon Braket comienza a ejecutar el trabajo híbrido de inmediato. Inicia la instancia de trabajo híbrido (puede personalizar el tipo de instancia en la llamada a la API), ejecuta su algoritmo, escribe los resultados en Amazon S3 y libera sus recursos. Esta liberación de recursos garantiza que solo pague por lo que usa.

El número total de trabajos híbridos simultáneos por unidad de procesamiento cuántico (QPU) está restringido. En la actualidad, solo se puede ejecutar un trabajo híbrido en una QPU en un momento determinado. Las colas se utilizan para controlar la cantidad de trabajos híbridos que se pueden ejecutar a fin de no superar el límite permitido. Si el dispositivo de destino es una QPU, el trabajo híbrido entra primero en la *cola de trabajos* de la QPU seleccionada. Amazon Braket activa la instancia de trabajo híbrido necesaria y ejecuta su trabajo híbrido en el dispositivo. Durante la duración de su algoritmo, su trabajo híbrido tiene acceso prioritario, lo que significa que las tareas cuánticas de su trabajo híbrido se ejecutan antes que otras tareas cuánticas de Braket en cola en el dispositivo, siempre que las tareas cuánticas del trabajo se envíen a la QPU una vez cada pocos minutos. Una vez completado el trabajo híbrido, los recursos se liberan, lo que significa que solo pagará por lo que utilice.

**nota**  
Los dispositivos son regionales y su trabajo híbrido se ejecuta de la Región de AWS misma manera que su dispositivo principal.

Tanto en los escenarios de destino del simulador como de la QPU, tiene la opción de definir métricas de algoritmo personalizadas, como la energía de su hamiltoniano, como parte de su algoritmo. Estas métricas se notifican automáticamente a Amazon CloudWatch y, desde allí, se muestran casi en tiempo real en la consola Amazon Braket.

**nota**  
Si desea utilizar una instancia basada en GPU, asegúrese de utilizar uno de los simuladores basados en GPU disponibles con los simuladores integrados en Braket (por ejemplo, `lightning.gpu`). Si elige uno de los simuladores integrados basados en CPU (por ejemplo, `lightning.qubit` o `braket:default-simulator`), la GPU no se utilizará y usted podría incurrir en gastos innecesarios.

# Conceptos clave de los trabajos híbridos
<a name="braket-jobs-concepts"></a>

En esta sección se explican los conceptos clave de la función `AwsQuantumJob.create` proporcionada por el SDK de Python de Amazon Braket y su asignación a la estructura del archivo contenedor.

Además del archivo o los archivos que componen el script completo del algoritmo, el trabajo híbrido puede tener entradas y salidas adicionales. Cuando se inicia el trabajo híbrido, Amazon Braket copia las entradas proporcionadas como parte de la creación del trabajo híbrido en el contenedor que ejecuta el script de algoritmo. Cuando se completa el trabajo híbrido, todos los resultados definidos durante el algoritmo se copian en la ubicación de Amazon S3 especificada.

**nota**  
 Las *métricas del algoritmo* se notifican en tiempo real y no siguen este procedimiento de salida.

Amazon Braket también proporciona varias variables de entorno y funciones auxiliares para simplificar las interacciones con las entradas y salidas de los contenedores. Para obtener más información, consulte el [paquete braket.jobs](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.jobs.html) del SDK de Amazon Braket. 

**Topics**
+ [Entradas](#braket-jobs-inputs)
+ [Outputs](#braket-jobs-outputs)
+ [Variables de entorno](#braket-jobs-environmental-variables)
+ [Funciones auxiliares](#braket-jobs-helper-functions)

## Entradas
<a name="braket-jobs-inputs"></a>

 **Datos de entrada**: los datos de entrada se pueden proporcionar al algoritmo híbrido especificando el archivo de datos de entrada, que está configurado como un diccionario, con el argumento `input_data`. El usuario define el argumento `input_data` dentro de la función `AwsQuantumJob.create` en el SDK. Esto copia los datos de entrada al sistema de archivo contenedor en la ubicación indicada por la variable de entorno `"AMZN_BRAKET_INPUT_DIR"`. Para ver un par de ejemplos de cómo se utilizan los datos de entrada en un algoritmo híbrido, consulte la [QAOA con Amazon Braket Hybrid Jobs PennyLane y el aprendizaje automático cuántico en los cuadernos Amazon Braket Hybrid](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs/Using_PennyLane_with_Braket_Hybrid_Jobs.ipynb) [Jobs Jupyter](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs.ipynb).

**nota**  
Si los datos de entrada son grandes (>1 GB), habrá un largo tiempo de espera antes de que se envíe el trabajo híbrido. Esto se debe a que los datos de entrada locales se cargarán primero en un bucket S3, luego se añadirá la ruta S3 a la solicitud de trabajo híbrido y, por último, la solicitud de trabajo híbrido se enviará al servicio de Braket.

 **Hiperparámetros**: si transfiere`hyperparameters`, estarán disponibles en la variable de entorno `"AMZN_BRAKET_HP_FILE"`.

**nota**  
Para obtener más información sobre cómo crear hiperparámetros y datos de entrada y, a continuación, pasar esta información al script de trabajo híbrido, consulte la sección [Uso de hiperparámetros](braket-jobs-hyperparameters.md) en esta [página](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/qcbm/qcbm.py) de GitHub.

 **Puntos de control**: para especificar un `job-arn` cuyo punto de control desea utilizar en un nuevo trabajo híbrido, utilice el comando `copy_checkpoints_from_job`. Este comando copia los datos del punto de control al `checkpoint_configs3Uri` del nuevo trabajo híbrido, de forma que estén disponibles en la ruta indicada por la variable de entorno `AMZN_BRAKET_CHECKPOINT_DIR` mientras se ejecuta el trabajo. El valor predeterminado es `None`, lo que significa que los datos del punto de control de otro trabajo híbrido no se utilizarán en el nuevo trabajo híbrido.

## Outputs
<a name="braket-jobs-outputs"></a>

 **Tareas cuánticas**: los resultados de las tareas cuánticas se almacenan en la ubicación `s3://amazon-braket-<region>-<accountID>/jobs/<job-name>/tasks` de S3.

 **Resultados del trabajo**: todo lo que el script de algoritmo guarda en el directorio indicado por la variable de entorno `"AMZN_BRAKET_JOB_RESULTS_DIR"` se copia en la ubicación de S3 especificada en `output_data_config`. Si no se especifica el valor, el valor predeterminado es. `s3://amazon-braket-<region>-<accountID>/jobs/<job-name>/<timestamp>/data` Proporcionamos la función auxiliar del SDK ** `save_job_result` **, que puede utilizar para almacenar los resultados cómodamente en forma de diccionario cuando se llame desde el script de algoritmo.

 **Puntos de control**: si desea utilizar puntos de control, puede guardarlos en el directorio indicado por la variable de entorno `"AMZN_BRAKET_CHECKPOINT_DIR"`. También puede usar la función auxiliar del SDK `save_job_checkpoint` en su lugar.

 **Métricas de algoritmos**: puedes definir las métricas de los algoritmos como parte del script de tu algoritmo que se emiten a Amazon CloudWatch y se muestran en tiempo real en la consola de Amazon Braket mientras se ejecuta tu trabajo híbrido. Para ver un ejemplo de cómo utilizar las métricas de algoritmo, consulte [Uso de los trabajos híbridos de Amazon Braket para ejecutar un algoritmo QAOA](braket-jobs-run-qaoa-algorithm.md).

Para obtener más información sobre cómo guardar los resultados de sus trabajos, consulte [Guardar los resultados](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-first.html#braket-jobs-save-results) en la documentación de trabajos híbridos. 

## Variables de entorno
<a name="braket-jobs-environmental-variables"></a>

Amazon Braket proporciona varias variables de entorno para simplificar las interacciones con las entradas y salidas del contenedor. En el siguiente código se enumeran las variables de entorno que utiliza Braket.
+ `AMZN_BRAKET_INPUT_DIR`— El directorio opt/braket/input/data de datos de entrada.
+ `AMZN_BRAKET_JOB_RESULTS_DIR`— El directorio de salida en el opt/braket/model que se escriben los resultados del trabajo.
+ `AMZN_BRAKET_JOB_NAME`: el nombre del trabajo.
+ `AMZN_BRAKET_CHECKPOINT_DIR`: el directorio de puntos de control.
+ `AMZN_BRAKET_HP_FILE`: el archivo que contiene los hiperparámetros.
+ `AMZN_BRAKET_DEVICE_ARN`— El ARN (nombre del AWS recurso) del dispositivo.
+ `AMZN_BRAKET_OUT_S3_BUCKET`: el bucket de Amazon S3 de salida, tal como se especifica en la `OutputDataConfig` de la solicitud de `CreateJob`.
+ `AMZN_BRAKET_SCRIPT_ENTRY_POINT`: el punto de entrada, tal como se especifica en la `ScriptModeConfig` de la solicitud de `CreateJob`.
+ `AMZN_BRAKET_SCRIPT_COMPRESSION_TYPE`: el tipo de compresión, tal como se especifica en la `ScriptModeConfig` de la solicitud de `CreateJob`.
+ `AMZN_BRAKET_SCRIPT_S3_URI`: la ubicación en Amazon S3 del script del usuario, tal como se especifica en la `ScriptModeConfig` de la solicitud de `CreateJob`.
+ `AMZN_BRAKET_TASK_RESULTS_S3_URI`: la ubicación de Amazon S3 en la que el SDK almacenaría los resultados de las tareas cuánticas de forma predeterminada.
+ `AMZN_BRAKET_JOB_RESULTS_S3_PATH`: la ubicación de Amazon S3 en la que se almacenarían los resultados del trabajo, tal como se especifica en la `OutputDataConfig` de la solicitud de `CreateJob`.
+ `AMZN_BRAKET_JOB_TOKEN`: la cadena que se debe pasar al parámetro `jobToken` de `CreateQuantumTask` correspondiente a las tareas cuánticas creadas en el contenedor de tareas.

## Funciones auxiliares
<a name="braket-jobs-helper-functions"></a>

Amazon Braket proporciona varias funciones auxiliares para simplificar las interacciones con las entradas y salidas del contenedor. Estas funciones auxiliares se llamarían desde dentro del script de algoritmo que se utiliza para ejecutar su trabajo híbrido. En el siguiente ejemplo se muestra cómo utilizarlas.

```
from braket.jobs import get_checkpoint_dir, get_hyperparameters, get_input_data_dir, get_job_device_arn, get_job_name, get_results_dir, save_job_result, save_job_checkpoint, load_job_checkpoint

get_checkpoint_dir() # Get the checkpoint directory
get_hyperparameters() # Get the hyperparameters as strings
get_input_data_dir() # Get the input data directory
get_job_device_arn() # Get the device specified by the hybrid job
get_job_name() # Get the name of the hybrid job.
get_results_dir() # Get the path to a results directory
save_job_result(result_data='data') # Save hybrid job results
save_job_checkpoint(checkpoint_data={'key': 'value'}) # Save a checkpoint
load_job_checkpoint() # Load a previously saved checkpoint
```

# Requisitos previos
<a name="braket-jobs-prerequisites"></a>

Antes de ejecutar su primer trabajo híbrido, debe asegurarse de que tiene permisos suficientes para continuar con esta tarea. Para determinar si tiene los permisos correctos, seleccione **Permisos** en el menú de la parte izquierda de la consola de Braket. La página **Permisos de administración para Amazon Braket ** le ayuda a verificar si alguno de sus roles existentes tiene permisos suficientes para ejecutar su trabajo híbrido o le guía a través de la creación de un rol predeterminado que se puede utilizar para ejecutar su trabajo híbrido si aún no dispone de dicho rol.

![\[Página de permisos y configuración del servicio de Amazon Braket que muestra un rol vinculado a servicios y la opción de verificar los roles existentes para la función de ejecución de trabajos híbridos.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-permissions.png)


Para comprobar que tiene roles con permisos suficientes para ejecutar un trabajo híbrido, seleccione el botón **Verificar el rol existente**. Al hacerlo, obtendrá un mensaje que indica que se encontraron los roles. Para ver los nombres de las funciones y su función ARNs, seleccione el botón **Mostrar funciones**.

![\[Pantalla de permisos y configuración de Amazon Braket que muestra un rol vinculado a servicios encontrado y los roles existentes con permisos suficientes para ejecutar trabajos híbridos.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-yes.png)


Si no tiene un rol con los permisos suficientes para ejecutar un trabajo híbrido, recibirá un mensaje en el que se indica que no se ha encontrado dicho rol. Seleccione el botón **Crear rol predeterminado** para obtener un rol con permisos suficientes.

![\[Página de permisos y configuración de Amazon Braket que muestra el rol vinculado a servicios encontrado y ningún rol de ejecución de trabajos híbridos encontrado.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-no.png)


Si el rol se creó correctamente, recibirá un mensaje que lo confirma.

![\[Página de permisos y configuración de Amazon Braket que muestra un rol vinculado a servicios encontrado y un rol de ejecución de trabajos híbridos creado correctamente.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-created.png)


Si no tiene permisos para realizar esta consulta, se le denegará el acceso. En este caso, póngase en contacto con su AWS administrador interno.

![\[AccessDenied mensaje de error que indica que el usuario no está autorizado a ejecutar el comando iam: ListAttachedRolePolicies en caso contrario, AmazonBraketJobsExecutionRole con una denegación explícita.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-permissions-access-denied.png)


# Creación de un trabajo híbrido
<a name="braket-jobs-first"></a>

 En esta sección se muestra cómo crear un trabajo híbrido usando un script de Python. Como alternativa, para crear un trabajo híbrido a partir de código Python local, como su entorno de desarrollo integrado (IDE) preferido o un cuaderno de Braket, consulte [Ejecución del código local como un trabajo híbrido](braket-hybrid-job-decorator.md).

**Topics**
+ [Creación y ejecución](#braket-jobs-first-create)
+ [Supervisión de los resultados](#braket-jobs-first-monitor-results)
+ [Guardar los resultados](#braket-jobs-save-results)
+ [Uso de puntos de comprobación](#braket-jobs-checkpoints)
+ [Ejecución del código local como un trabajo híbrido](braket-hybrid-job-decorator.md)
+ [Uso de la API con trabajos híbridos](braket-jobs-api.md)
+ [Creación y depuración de un trabajo híbrido con modo local](braket-jobs-local-mode.md)

## Creación y ejecución
<a name="braket-jobs-first-create"></a>

Una vez que tenga un rol con permisos para ejecutar un trabajo híbrido, estará listo para proceder. La pieza clave de su primer trabajo híbrido de Braket es el *script de algoritmo*. Define el algoritmo que desea ejecutar y contiene las tareas lógicas clásicas y cuánticas que forman parte de su algoritmo. Además del script de algoritmo, puede proporcionar otros archivos de dependencia. El script de algoritmo, junto con sus dependencias, se denomina *módulo fuente*. El *punto de entrada* define el primer archivo o función que se ejecutará en el módulo fuente cuando se inicie el trabajo híbrido.

![\[Diagrama que muestra el flujo de trabajo consistente en crear un trabajo cuántico con una consola o un cuaderno, ejecutar el script de algoritmo en un dispositivo cuántico y analizar los resultados.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-workflow.jpg)


En primer lugar, consideremos el siguiente ejemplo básico de un script de algoritmo que crea cinco estados Bell e imprime los resultados de medición correspondientes.

```
import os

from braket.aws import AwsDevice
from braket.circuits import Circuit


def start_here():

    print("Test job started!")

    # Use the device declared in the job script
    device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"])

    bell = Circuit().h(0).cnot(0, 1)
    for count in range(5):
        task = device.run(bell, shots=100)
        print(task.result().measurement_counts)

    print("Test job completed!")
```

Guarde este archivo con el nombre *algorithm\$1script.py* en el directorio de trabajo actual de su cuaderno de Braket o en su entorno local. El fichero algorithm\$1script.py tiene `start_here()` como punto de entrada previsto.

A continuación, cree un archivo de Python o un cuaderno de Python en el mismo directorio que el archivo algorithm\$1script.py. Este script inicia el trabajo híbrido y gestiona cualquier procesamiento asíncrono, como imprimir el estado o los resultados clave que nos interesen. Como mínimo, este script debe especificar su script de trabajo híbrido y su dispositivo principal.

**nota**  
Para obtener más información sobre cómo crear un cuaderno de Braket o cargar un archivo, como el archivo *algorithm\$1script.py*, en el mismo directorio que los cuadernos, consulte [Ejecución de su primer circuito utilizando el SDK de Python de Amazon Braket](braket-get-started-run-circuit.md). 

Para este primer caso básico, se utiliza un simulador de destino. Independientemente del tipo de dispositivo cuántico de destino, ya sea un simulador o una unidad de procesamiento cuántico (QPU) real, el dispositivo que especifique con `device` en el siguiente script se utilizará para programar el trabajo híbrido y estará disponible para los scripts del algoritmo como variable de entorno `AMZN_BRAKET_DEVICE_ARN`.

**nota**  
Solo puede usar los dispositivos que estén disponibles en Región de AWS su trabajo híbrido. El SDK de Amazon Braket selecciona automáticamente esta Región de AWS. Por ejemplo, un trabajo híbrido en us-east-1 puede utilizar dispositivos IonQ, SV1, DM1 y TN1, pero no dispositivos Rigetti.

Si elige una computadora cuántica en lugar de un simulador, Braket programa sus trabajos híbridos para ejecutar todas sus tareas cuánticas con acceso prioritario.

```
from braket.aws import AwsQuantumJob
from braket.devices import Devices

job = AwsQuantumJob.create(
    Devices.Amazon.SV1,
    source_module="algorithm_script.py",
    entry_point="algorithm_script:start_here",
    wait_until_complete=True
)
```

El parámetro `wait_until_complete=True` establece un modo detallado para que su trabajo imprima la salida del trabajo real mientras se está ejecutando. Debería ver un resultado similar al del siguiente ejemplo.

```
Initializing Braket Job: arn:aws:braket:us-west-2:111122223333:job/braket-job-default-123456789012
Job queue position: 1
Job queue position: 1
Job queue position: 1
..............
.
.
.
Beginning Setup
Checking for Additional Requirements
Additional Requirements Check Finished
Running Code As Process
Test job started!
Counter({'00': 58, '11': 42})
Counter({'00': 55, '11': 45})
Counter({'11': 51, '00': 49})
Counter({'00': 56, '11': 44})
Counter({'11': 56, '00': 44})
Test job completed!
Code Run Finished
2025-09-24 23:13:40,962 sagemaker-training-toolkit INFO     Reporting training SUCCESS
```

**nota**  
También puedes usar tu módulo personalizado con el método [AwsQuantumJob.create](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.aws.aws_quantum_job.html#braket.aws.aws_quantum_job.AwsQuantumJob.create) pasando su ubicación (ya sea la ruta a un directorio o archivo local, o el URI de S3 de un archivo tar.gz). Para ver un ejemplo de trabajo, consulte el archivo [Parallelize\$1training\$1for\$1QML.ipynb](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/5_Parallelize_training_for_QML/Parallelize_training_for_QML.ipynb) en la carpeta de trabajos híbridos en el [repositorio de GitHub de ejemplos de Amazon Braket](https://github.com/amazon-braket/amazon-braket-examples/tree/main).

## Supervisión de los resultados
<a name="braket-jobs-first-monitor-results"></a>

Como alternativa, puedes acceder a la salida del registro desde Amazon CloudWatch. Para ello, vaya a la pestaña **Grupos de registro** en el menú izquierdo de la página de detalles del trabajo, seleccione el grupo de registro `aws/braket/jobs` y, a continuación, elija el flujo de registro que contiene el nombre del trabajo. En el ejemplo anterior, es `braket-job-default-1631915042705/algo-1-1631915190`.

![\[CloudWatch grupo de registros que muestra una lista de eventos de registro con rutas de archivo y marcas de tiempo para las pruebas de Python del SDK de Amazon Braket.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-cw-log.png)


También puede ver el estado del trabajo híbrido en la consola seleccionando la página **Trabajos híbridos** y, a continuación, **Configuración**.

![\[Detalles del trabajo híbrido de Amazon Braket que muestran un resumen, las horas de los eventos, el código fuente y la configuración de la instancia, y las condiciones de parada.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-jobs-first-console-status.png)


Su trabajo híbrido produce algunos artefactos en Amazon S3 mientras se ejecuta. El nombre predeterminado del bucket de S3 es `amazon-braket-<region>-<accountid>` y el contenido está en el `jobs/<jobname>/<timestamp>` directorio. Puede configurar las ubicaciones de S3 en las que se almacenan estos artefactos especificando una `code_location` diferente al crear el trabajo híbrido con el SDK de Python de Braket.

**nota**  
Este depósito de S3 debe estar ubicado en el mismo lugar que su script de Región de AWS trabajo.

El directorio `jobs/<jobname>/<timestamp>` contiene una subcarpeta con la salida del script del punto de entrada en un archivo `model.tar.gz`. También hay un directorio denominado `script` que contiene los artefactos del script de algoritmo en un archivo `source.tar.gz`. Los resultados de sus tareas cuánticas reales se encuentran en el directorio denominado `jobs/<jobname>/tasks`.

## Guardar los resultados
<a name="braket-jobs-save-results"></a>

Puede guardar los resultados generados por el script de algoritmo para que estén disponibles en el objeto de trabajo híbrido del script de trabajo híbrido, así como en la carpeta de salida de Amazon S3 (en un archivo comprimido con tar denominado model.tar.gz).

El resultado debe guardarse en un archivo con un formato de notación de JavaScript objetos (JSON). Si los datos no se pueden serializar fácilmente en texto, como en el caso de una matriz numpy, puede pasar una opción para serializar utilizando un formato de datos pickled. Consulte el [módulo braket.jobs.data\$1persistence](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.jobs.data_persistence.html#braket.jobs.data_persistence.save_job_result) para obtener más información.

Para guardar los resultados de los trabajos híbridos, añada las siguientes líneas comentadas con \$1ADD al archivo algorithm\$1script.py.

```
import os

from braket.aws import AwsDevice
from braket.circuits import Circuit
from braket.jobs import save_job_result  # ADD


def start_here():

    print("Test job started!")

    device = AwsDevice(os.environ['AMZN_BRAKET_DEVICE_ARN'])

    results = []  # ADD

    bell = Circuit().h(0).cnot(0, 1)
    for count in range(5):
        task = device.run(bell, shots=100)
        print(task.result().measurement_counts)
        results.append(task.result().measurement_counts)  # ADD

        save_job_result({"measurement_counts": results})  # ADD

    print("Test job completed!")
```

A continuación, puede mostrar los resultados del trabajo desde su script de trabajo añadiendo la línea ** `print(job.result())` ** comentada con \$1ADD.

```
import time
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    source_module="algorithm_script.py",
    entry_point="algorithm_script:start_here",
    device="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
)

print(job.arn)
while job.state() not in AwsQuantumJob.TERMINAL_STATES:
    print(job.state())
    time.sleep(10)

print(job.state())
print(job.result())   # ADD
```

En este ejemplo, hemos eliminado `wait_until_complete=True` para suprimir la salida detallada. Puedes volver a añadirlo para su depuración. Cuando ejecuta este trabajo híbrido, se muestra el identificador y el `job-arn`, seguido del estado del trabajo híbrido cada 10 segundos hasta que el trabajo híbrido esté `COMPLETED`, después de lo cual le muestra los resultados del circuito Bell. Consulte el siguiente ejemplo.

```
arn:aws:braket:us-west-2:111122223333:job/braket-job-default-123456789012
INITIALIZED
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
RUNNING
...
RUNNING
RUNNING
COMPLETED
{'measurement_counts': [{'11': 53, '00': 47},..., {'00': 51, '11': 49}]}
```

## Uso de puntos de comprobación
<a name="braket-jobs-checkpoints"></a>

Puede guardar las iteraciones intermedias de sus trabajos híbridos mediante puntos de control. En el ejemplo de script de algoritmo de la sección anterior, añadiría las siguientes líneas comentadas con \$1ADD para crear archivos de punto de control.

```
from braket.aws import AwsDevice
from braket.circuits import Circuit
from braket.jobs import save_job_checkpoint  # ADD
import os


def start_here():

    print("Test job starts!")

    device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"])

    # ADD the following code
    job_name = os.environ["AMZN_BRAKET_JOB_NAME"]
    save_job_checkpoint(checkpoint_data={"data": f"data for checkpoint from {job_name}"}, checkpoint_file_suffix="checkpoint-1")  # End of ADD

    bell = Circuit().h(0).cnot(0, 1)
    for count in range(5):
        task = device.run(bell, shots=100)
        print(task.result().measurement_counts)

    print("Test hybrid job completed!")
```

Cuando ejecuta el trabajo híbrido, se crea el archivo *<jobname>-checkpoint-1.json* en sus artefactos de trabajo híbrido en el directorio de puntos de control con una ruta de `/opt/jobs/checkpoints` predeterminada. El script del trabajo híbrido permanece inalterado a menos que desee cambiar esta ruta predeterminada.

Si desea cargar un trabajo híbrido desde un punto de control generado por un trabajo híbrido anterior, el script de algoritmo utiliza `from braket.jobs import load_job_checkpoint`. La lógica que se debe cargar en el script de algoritmo es la siguiente.

```
from braket.jobs import load_job_checkpoint

checkpoint_1 = load_job_checkpoint(
    "previous_job_name",
    checkpoint_file_suffix="checkpoint-1",
)
```

Después de cargar este punto de control, puede continuar con su lógica basándose en el contenido cargado en el `checkpoint-1`.

**nota**  
El *checkpoint\$1file\$1suffix* debe coincidir con el sufijo especificado previamente al crear el punto de control.

Su script de orquestación debe especificar el `job-arn` del trabajo híbrido anterior con la línea comentada con \$1ADD.

```
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    source_module="source_dir",
    entry_point="source_dir.algorithm_script:start_here",
    device="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
    copy_checkpoints_from_job="<previous-job-ARN>", #ADD
    )
```

# Ejecución del código local como un trabajo híbrido
<a name="braket-hybrid-job-decorator"></a>

Los trabajos híbridos de Amazon Braket proporcionan una orquestación totalmente administrada de algoritmos híbridos cuánticos-clásicos, combinando los recursos de computación de Amazon EC2 con el acceso a la unidad de procesamiento cuántico (QPU) de Amazon Braket. Las tareas cuánticas creadas en un trabajo híbrido tienen prioridad en la cola sobre las tareas cuánticas individuales, de modo que sus algoritmos no se verán interrumpidos por las fluctuaciones en la cola de tareas cuánticas. Cada QPU mantiene una cola de trabajos híbridos independiente, lo que garantiza que solo se pueda ejecutar un trabajo híbrido en un momento dado.

**Topics**
+ [Creación de un trabajo híbrido a partir de código de Python local](#create-hybrid-job-from-local-python-code)
+ [Instalación de paquetes y código fuente de Python adicionales](#install-python-packages-and-code)
+ [Guardar y cargar datos en una instancia de trabajo híbrido](#save-load-data-into-instance)
+ [Prácticas recomendadas para decoradores de trabajos híbridos](#best-practices)

## Creación de un trabajo híbrido a partir de código de Python local
<a name="create-hybrid-job-from-local-python-code"></a>

Puede ejecutar su código de Python local como un trabajo híbrido de Amazon Braket. Puede hacerlo anotando su código con un decorador `@hybrid_job`, como se muestra en el siguiente ejemplo de código. Para los entornos personalizados, puede optar por [utilizar un contenedor personalizado](braket-jobs-byoc.md) de Amazon Elastic Container Registry (ECR). 

**nota**  
De forma predeterminada, solo se admite Python 3.12.

 Puede usar el decorador `@hybrid_job` para anotar una función. Braket transforma el código dentro del decorador en un [script de algoritmo](braket-jobs-first.md) de trabajo híbrido de Braket. A continuación, el trabajo híbrido invoca la función dentro del decorador en una instancia de Amazon EC2. Puede supervisar el progreso del trabajo con `job.state()` o con la consola de Braket. El siguiente ejemplo de código muestra cómo ejecutar una secuencia de cinco estados en el State Vector Simulator (SV1) device. 

```
from braket.aws import AwsDevice
from braket.circuits import Circuit, FreeParameter, Observable
from braket.devices import Devices
from braket.jobs.hybrid_job import hybrid_job
from braket.jobs.metrics import log_metric

device_arn = Devices.Amazon.SV1


@hybrid_job(device=device_arn)  # Choose priority device
def run_hybrid_job(num_tasks=1):
    device = AwsDevice(device_arn)  # Declare AwsDevice within the hybrid job

    # Create a parametric circuit
    circ = Circuit()
    circ.rx(0, FreeParameter("theta"))
    circ.cnot(0, 1)
    circ.expectation(observable=Observable.X(), target=0)

    theta = 0.0  # Initial parameter

    for i in range(num_tasks):
        task = device.run(circ, shots=100, inputs={"theta": theta})  # Input parameters
        exp_val = task.result().values[0]

        theta += exp_val  # Modify the parameter (possibly gradient descent)

        log_metric(metric_name="exp_val", value=exp_val, iteration_number=i)

    return {"final_theta": theta, "final_exp_val": exp_val}
```

El trabajo híbrido se crea invocando la función como lo haría con las funciones normales de Python. Sin embargo, la función de decorador devuelve el identificador del trabajo híbrido en lugar del resultado de la función. Para recuperar los resultados una vez que se haya completado, utilice `job.result()`. 

```
job = run_hybrid_job(num_tasks=1)
result = job.result()
```

El argumento del dispositivo en el decorador `@hybrid_job` especifica el dispositivo al que el trabajo híbrido tiene acceso prioritario, en este caso, el simulador SV1. Para obtener la prioridad de la QPU, debe asegurarse de que el ARN del dispositivo utilizado en la función coincida con el especificado en el decorador. Para mayor comodidad, puede utilizar la función auxiliar `get_job_device_arn()` para capturar el ARN del dispositivo declarado en `@hybrid_job`. 

**nota**  
Cada trabajo híbrido tiene un tiempo de inicio de al menos un minuto, ya que crea un entorno en contenedor en Amazon EC2. Por lo tanto, para cargas de trabajo muy cortas, como un circuito único o un lote de circuitos, puede bastar con utilizar tareas cuánticas.

**Hiperparámetros** 

La función `run_hybrid_job()` utiliza el argumento `num_tasks` para controlar el número de tareas cuánticas creadas. El trabajo híbrido captura esto automáticamente como un [hiperparámetro](braket-jobs-hyperparameters.md).

**nota**  
Los hiperparámetros se muestran en la consola de Braket como cadenas, que tienen un límite de 2500 caracteres. 

**Métricas y registro** 

En la función `run_hybrid_job()`, las métricas de los algoritmos iterativos se registran con `log_metrics`. Las métricas se representan automáticamente en la página de la consola de Braket, en la pestaña de trabajos híbridos. Puede utilizar las métricas para realizar un seguimiento de los costos de las tareas cuánticas prácticamente en tiempo real durante la ejecución de un trabajo híbrido con el [Rastreador de costos de Braket](braket-pricing.md). En el ejemplo anterior, se utiliza el nombre de métrica «probabilidad», que registra la primera probabilidad del [tipo de resultado](braket-result-types.md).

**Recuperación de resultados** 

Una vez finalizado el trabajo híbrido, se utiliza `job.result()` para recuperar los resultados del trabajo híbrido. Braket captura automáticamente todos los objetos de la declaración de devolución. Tenga en cuenta que los objetos devueltos por la función deben ser una tupla y cada elemento debe ser serializable. Por ejemplo, el código siguiente muestra un ejemplo de funcionamiento correcto y otro incorrecto. 

```
import numpy as np


# Working example
@hybrid_job(device=Devices.Amazon.SV1)
def passing():
    np_array = np.random.rand(5)
    return np_array  # Serializable

# # Failing example
# @hybrid_job(device=Devices.Amazon.SV1)
# def failing():
#     return MyObject() # Not serializable
```

**Nombre del trabajo** 

De forma predeterminada, el nombre de este trabajo híbrido se deduce del nombre de la función. Puede especificar un nombre personalizado que tenga un máximo de 50 caracteres. Por ejemplo, en el código siguiente, el nombre del trabajo es "my-job-name».

```
@hybrid_job(device=Devices.Amazon.SV1, job_name="my-job-name")
def function():
    pass
```

**Modo local** 

Los [trabajos locales](braket-jobs-local-mode.md) se crean añadiendo el argumento `local=True` al decorador. Esto ejecuta el trabajo híbrido en un entorno en contenedor en su entorno de computación local, como un portátil. Los trabajos locales **no** tienen prioridad en las colas para las tareas cuánticas. En casos avanzados, como los de varios nodos o MPI, los trabajos locales pueden tener acceso a las variables de entorno de Braket requeridas. El código siguiente crea un trabajo híbrido local con el dispositivo como SV1 simulador. 

```
@hybrid_job(device=Devices.Amazon.SV1, local=True)
def run_hybrid_job(num_tasks=1):
    return ...
```

Todas las demás opciones de trabajo híbrido son compatibles. Para ver una lista de opciones, consulte el [módulo braket.jobs.quantum\$1job\$1creation](https://amazon-braket-sdk-python.readthedocs.io/en/stable/_apidoc/braket.jobs.quantum_job_creation.html). 

## Instalación de paquetes y código fuente de Python adicionales
<a name="install-python-packages-and-code"></a>

Puede personalizar su entorno de tiempo de ejecución para usar sus paquetes de Python preferidos. Puede usar un archivo `requirements.txt`, una lista de nombres de paquetes o [utilizar su propio contenedor (BYOC)](braket-jobs-byoc.md). Por ejemplo, el archivo `requirements.txt` puede incluir otros paquetes para instalar.

```
qiskit 
pennylane >= 0.31
mitiq == 0.29
```

Para personalizar un entorno de tiempo de ejecución utilizando un archivo `requirements.txt`, consulte el siguiente ejemplo de código.

```
@hybrid_job(device=Devices.Amazon.SV1, dependencies="requirements.txt")
def run_hybrid_job(num_tasks=1):
    return ...
```

Como alternativa, puede proporcionar los nombres de los paquetes como una lista de Python de la siguiente manera.

```
@hybrid_job(device=Devices.Amazon.SV1, dependencies=["qiskit", "pennylane>=0.31", "mitiq==0.29"])
def run_hybrid_job(num_tasks=1):
    return ...
```

El código fuente adicional se puede especificar como una lista de módulos o como un solo módulo, como en el siguiente ejemplo de código. 

```
@hybrid_job(device=Devices.Amazon.SV1, include_modules=["my_module1", "my_module2"])
def run_hybrid_job(num_tasks=1):
    return ...
```

## Guardar y cargar datos en una instancia de trabajo híbrido
<a name="save-load-data-into-instance"></a>

**Especificación de los datos de entrenamiento de entrada**

Al crear un trabajo híbrido, puede proporcionar conjuntos de datos de entrenamiento de entrada especificando un bucket de Amazon Simple Storage Service (Amazon S3). También puede especificar una ruta local y, a continuación, Braket carga automáticamente los datos en Amazon S3 en `s3://<default_bucket_name>/jobs/<job_name>/<timestamp>/data/<channel_name>`. Si especifica una ruta local, el nombre del canal predeterminado será «entrada». El siguiente código muestra un archivo numpy de la ruta local `data/file.npy`. 

```
import numpy as np


@hybrid_job(device=Devices.Amazon.SV1, input_data="data/file.npy")
def run_hybrid_job(num_tasks=1):
    data = np.load("data/file.npy")
    return ...
```

Para S3, debe usar la función auxiliar `get_input_data_dir()`.

```
import numpy as np
from braket.jobs import get_input_data_dir

s3_path = "s3://amazon-braket-us-east-1-123456789012/job-data/file.npy"


@hybrid_job(device=None, input_data=s3_path)
def job_s3_input():
    np.load(get_input_data_dir() + "/file.npy")


@hybrid_job(device=None, input_data={"channel": s3_path})
def job_s3_input_channel():
    np.load(get_input_data_dir("channel") + "/file.npy")
```

Puede especificar varias fuentes de datos de entrada proporcionando un diccionario de valores de canal y rutas S3 URIs o locales. 

```
import numpy as np
from braket.jobs import get_input_data_dir

input_data = {
    "input": "data/file.npy",
    "input_2": "s3://amzn-s3-demo-bucket/data.json"
}


@hybrid_job(device=None, input_data=input_data)
def multiple_input_job():
    np.load(get_input_data_dir("input") + "/file.npy")
    np.load(get_input_data_dir("input_2") + "/data.json")
```

**nota**  
Si los datos de entrada son grandes (>1 GB), habrá un largo tiempo de espera antes de que se cree el trabajo. Esto se debe a que los datos de entrada locales se cargan por primera vez en un bucket de S3 y, a continuación, se añade la ruta de S3 a la solicitud de trabajo. Por último, la solicitud de trabajo se envía al servicio de Braket.

**Guardar los resultados en S3**

Para guardar los resultados no incluidos en la declaración de devolución de la función decorada, debe añadir el directorio correcto a todas las operaciones de escritura de archivos. En el siguiente ejemplo, se muestra cómo guardar una matriz numpy y una figura de matplotlib.

```
import matplotlib.pyplot as plt
import numpy as np


@hybrid_job(device=Devices.Amazon.SV1)
def run_hybrid_job(num_tasks=1):
    result = np.random.rand(5)

    # Save a numpy array
    np.save("result.npy", result)

    # Save a matplotlib figure
    plt.plot(result)
    plt.savefig("fig.png")
    return ...
```

Todos los resultados se comprimen en un archivo denominado `model.tar.gz`. Puede descargar los resultados con la función `job.result()` de Python o yendo a la carpeta de resultados desde la página de trabajos híbridos de la consola de administración de Braket. 

**Guardar y reanudar desde los puntos de control**

Para trabajos híbridos de larga duración, se recomienda guardar periódicamente el estado intermedio del algoritmo. Puede utilizar la función auxiliar `save_job_checkpoint()` integrada o guardar los archivos en la ruta `AMZN_BRAKET_JOB_RESULTS_DIR`. Esta última opción está disponible con la función auxiliar `get_job_results_dir()`.

El siguiente es un ejemplo práctico mínimo para guardar y cargar puntos de control con un decorador de trabajo híbrido:

```
from braket.jobs import save_job_checkpoint, load_job_checkpoint, hybrid_job


@hybrid_job(device=None, wait_until_complete=True)
def function():
    save_job_checkpoint({"a": 1})


job = function()
job_name = job.name
job_arn = job.arn


@hybrid_job(device=None, wait_until_complete=True, copy_checkpoints_from_job=job_arn)
def continued_function():
    load_job_checkpoint(job_name)


continued_job = continued_function()
```

En el primer trabajo híbrido, `save_job_checkpoint()` se llama con un diccionario que contiene los datos que queremos guardar. De forma predeterminada, todos los valores deben poder serializarse como texto. Para comprobar objetos de Python más complejos, como matrices numpy, puede configurar `data_format = PersistedJobDataFormat.PICKLED_V4`. Este código crea y sobrescribe un archivo de puntos de control con el nombre predeterminado `<jobname>.json` en sus artefactos de trabajo híbrido, en una subcarpeta denominada «puntos de control».

Para crear un nuevo trabajo híbrido para continuar desde el punto de control, debemos pasar `copy_checkpoints_from_job=job_arn` dónde `job_arn` es el ARN del trabajo híbrido del trabajo anterior. A continuación, usamos `load_job_checkpoint(job_name)` para realizar la carga desde el punto de control.

## Prácticas recomendadas para decoradores de trabajos híbridos
<a name="best-practices"></a>

**Uso de la asincronicidad**

Los trabajos híbridos creados con la anotación de decorador son asíncronos: se ejecutan una vez que los recursos clásicos y cuánticos están disponibles. Usted monitorea el progreso del algoritmo utilizando Amazon Braket Management Console o Amazon CloudWatch. Cuando envía el algoritmo para su ejecución, Braket lo ejecuta en un entorno en contenedor escalable y los resultados se recuperan cuando se completa el algoritmo.

**Ejecución de algoritmos variacionales iterativos**

Los trabajos híbridos le proporcionan las herramientas necesarias para ejecutar algoritmos cuánticos-clásicos iterativos. Para problemas puramente cuánticos, utilice [tareas cuánticas](braket-submit-tasks.md) o un [lote de tareas cuánticas](braket-batching-tasks.md). El acceso prioritario a ciertos QPUs es más beneficioso para los algoritmos variacionales de larga duración que requieren múltiples llamadas iterativas QPUs con el procesamiento clásico en el medio. 

**Depuración utilizando el modo local**

Antes de ejecutar un trabajo híbrido en una QPU, se recomienda ejecutarlo primero en el simulador para confirmar SV1 que se ejecuta según lo esperado. En el caso de pruebas a pequeña escala, puede ejecutarlas con el modo local para una iteración y depuración rápidas. 

**Mejora de la reproducibilidad [utilizando su propio contenedor (BYOC)](braket-jobs-byoc.md)**

Cree un experimento reproducible encapsulando su software y sus dependencias en un entorno en contenedor. Al empaquetar todo su código, dependencias y configuración en un contenedor, evitará posibles conflictos y problemas de control de versiones. 

**Simuladores distribuidos multiinstancia**

Para ejecutar una gran cantidad de circuitos, considere la posibilidad de utilizar el soporte de MPI integrado para ejecutar simuladores locales en varias instancias en un solo trabajo híbrido. Para obtener más información, consulte [simuladores integrados](pennylane-embedded-simulators.md).

**Uso de circuitos paramétricos**

Los circuitos paramétricos que se envían a partir de un trabajo híbrido se compilan automáticamente en algunos casos QPUs mediante la [compilación paramétrica](braket-jobs-parametric-compilation.md) para mejorar los tiempos de ejecución de los algoritmos. 

**Punto de control periódico**

Para trabajos híbridos de larga duración, se recomienda guardar periódicamente el estado intermedio del algoritmo. 

**Para ver más ejemplos, casos de uso y mejores prácticas, consulta los ejemplos de [Amazon GitHub Braket](https://github.com/amazon-braket/amazon-braket-examples).**

# Uso de la API con trabajos híbridos
<a name="braket-jobs-api"></a>

Puede acceder e interactuar con los trabajos híbridos de Amazon Braket directamente utilizando la API. Sin embargo, los métodos predeterminados y prácticos no están disponibles cuando se utiliza la API directamente.

**nota**  
Le recomendamos encarecidamente que interactúe con los trabajos híbridos de Amazon Braket mediante el [SDK de Python de Amazon Braket](https://github.com/aws/amazon-braket-sdk-python). Ofrece prácticos valores predeterminados y protecciones que ayudan a que sus trabajos híbridos se ejecuten correctamente.

En este tema se describen los aspectos básicos del uso de la API. Si decide utilizar la API, tenga en cuenta que este enfoque puede ser más complejo, por lo que debe prepararse para varias iteraciones hasta que su trabajo híbrido se ejecute.

Para usar la API, tu cuenta debe tener un rol con la política administrada `AmazonBraketFullAccess`.

**nota**  
Para obtener más información sobre cómo obtener un rol con la política administrada `AmazonBraketFullAccess`, consulte la página [Activación de Amazon Braket](braket-enable-overview.md).

Además, necesita un **rol de ejecución**. Esta función se transferirá al servicio. Puede crear el rol utilizando la **consola de Amazon Braket**. Utilice la pestaña **Roles de ejecución** en la página **Permisos y configuración** para crear un rol predeterminado para los trabajos híbridos.

La API de `CreateJob` requiere que especifique todos los parámetros necesarios para el trabajo híbrido. Para utilizar Python, comprima los archivos del script de algoritmo en un paquete tar, como un archivo input.tar.gz, y ejecute el siguiente script. Actualice las partes del código entre corchetes angulares (`<>`) para que coincidan con la información de su cuenta y el punto de entrada que especifican la ruta, el archivo y el método en los que comienza su trabajo híbrido.

```
from braket.aws import AwsDevice, AwsSession
import boto3
from datetime import datetime

s3_client = boto3.client("s3")
client = boto3.client("braket")

project_name = "job-test"
job_name = project_name + "-" + datetime.strftime(datetime.now(), "%Y%m%d%H%M%S")
bucket = "amazon-braket-<your_bucket>"
s3_prefix = job_name

job_script = "input.tar.gz"
job_object = f"{s3_prefix}/script/{job_script}"
s3_client.upload_file(job_script, bucket, job_object)

input_data = "inputdata.csv"
input_object = f"{s3_prefix}/input/{input_data}"
s3_client.upload_file(input_data, bucket, input_object)

job = client.create_job(
    jobName=job_name,
    roleArn="arn:aws:iam::<your_account>:role/service-role/AmazonBraketJobsExecutionRole",  # https://docs.aws.amazon.com/braket/latest/developerguide/braket-manage-access.html#about-amazonbraketjobsexecution
    algorithmSpecification={
        "scriptModeConfig": {
            "entryPoint": "<your_execution_module>:<your_execution_method>",
            "containerImage": {"uri": "292282985366.dkr.ecr.us-west-1.amazonaws.com/amazon-braket-base-jobs:1.0-cpu-py37-ubuntu18.04"},   # Change to the specific region you are using
            "s3Uri": f"s3://{bucket}/{job_object}",
            "compressionType": "GZIP"
        }
    },
    inputDataConfig=[
        {
            "channelName": "hellothere",
            "compressionType": "NONE",
            "dataSource": {
                "s3DataSource": {
                    "s3Uri": f"s3://{bucket}/{s3_prefix}/input",
                    "s3DataType": "S3_PREFIX"
                }
            }
        }
    ],
    outputDataConfig={
        "s3Path": f"s3://{bucket}/{s3_prefix}/output"
    },
    instanceConfig={
        "instanceType": "ml.m5.large",
        "instanceCount": 1,
        "volumeSizeInGb": 1
    },
    checkpointConfig={
        "s3Uri":  f"s3://{bucket}/{s3_prefix}/checkpoints",
        "localPath": "/opt/omega/checkpoints"
    },
    deviceConfig={
        "priorityAccess": {
            "devices": [
                "arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3"
            ]
        }
    },
    hyperParameters={
        "hyperparameter key you wish to pass": "<hyperparameter value you wish to pass>",
    },
    stoppingCondition={
        "maxRuntimeInSeconds": 1200,
        "maximumTaskLimit": 10
    },
)
```

Una vez que haya creado su trabajo híbrido, podrá acceder a los detalles de este a través de la API de `GetJob` o de la consola. Para obtener los detalles del trabajo híbrido de la sesión de Python en la que ejecutó el código `createJob`, como en el ejemplo anterior, utilice el siguiente comando de Python.

```
getJob = client.get_job(jobArn=job["jobArn"])
```

Para cancelar un trabajo híbrido, llame a la API de `CancelJob` con el Amazon Resource Name del trabajo ('JobArn').

```
cancelJob = client.cancel_job(jobArn=job["jobArn"])
```

Puede especificar puntos de control como parte de la API de `createJob` usando el parámetro `checkpointConfig`.

```
    checkpointConfig = {
        "localPath" : "/opt/omega/checkpoints",
        "s3Uri": f"s3://{bucket}/{s3_prefix}/checkpoints"
    },
```

**nota**  
La localPath de `checkpointConfig` no puede comenzar con ninguna de las siguientes rutas reservadas: `/opt/ml`, `/opt/braket`, `/tmp` ni `/usr/local/nvidia`.

# Creación y depuración de un trabajo híbrido con modo local
<a name="braket-jobs-local-mode"></a>

Cuando crea un nuevo algoritmo híbrido, el modo local le ayuda a depurar y probar el script de algoritmo. El modo local es una característica que le permite ejecutar código que tiene previsto utilizar en trabajos híbridos de Amazon Braket, pero sin necesidad de que Braket gestione la infraestructura para ejecutar el trabajo híbrido. En su lugar, ejecute trabajos híbridos localmente en su instancia de cuaderno de Amazon Braket o en un cliente preferido, como una computadora portátil o de sobremesa. 

En el modo local, aún puede enviar tareas cuánticas a dispositivos reales, pero no obtiene las ventajas de rendimiento que ofrece el uso de una unidad de procesamiento cuántico (QPU) real mientras se encuentra en el modo local.

Para utilizar el modo local, cambie `AwsQuantumJob` a `LocalQuantumJob` donde sea que aparezca en su programa. Por ejemplo, para ejecutar el ejemplo de [Creación de su primer trabajo híbrido](braket-jobs-first.md), edite el script del trabajo híbrido en el código de la siguiente manera.

```
from braket.jobs.local import LocalQuantumJob

job = LocalQuantumJob.create(
    device="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
    source_module="algorithm_script.py",
    entry_point="algorithm_script:start_here",
)
```

**nota**  
Docker, que ya viene preinstalado en los cuadernos de Amazon Braket, debe instalarse en su entorno local para poder utilizar esta característica. Las instrucciones para instalar Docker se pueden encontrar en la página [Get Docker](https://docs.docker.com/get-started/get-docker/). Además, no todos los parámetros son compatibles en el modo local.

# Cancelación de un trabajo híbrido
<a name="braket-jobs-cancel"></a>

Es posible que tenga que cancelar un trabajo híbrido en un estado no terminal. Esto se puede hacer en la consola o mediante código.

Para cancelar el trabajo híbrido en la consola, seleccione el trabajo híbrido que desee cancelar en la página **Trabajos híbridos** y, a continuación, seleccione **Cancelar trabajo híbrido** en el menú desplegable **Acciones**.

![\[Tabla de trabajos híbridos de Amazon Braket con 4 trabajos que muestran sus nombres, estado, información del dispositivo y marcas de tiempo. El menú desplegable Acciones contiene opciones para ver los nuevos trabajos híbridos, cancelarlos o administrar las etiquetas.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-hybrid-cancel-job.png)


Para confirmar la cancelación, introduzca *cancelar* en el campo de entrada cuando se le solicite y, a continuación, seleccione **Aceptar**.

![\[Cuadro de diálogo para cancelar un trabajo específico con advertencias sobre el proceso de cancelación y un campo de entrada de texto para confirmarlo introduciendo «cancelar».\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/braket-hybrid-cancel-job-confirm.png)


Para cancelar su trabajo híbrido mediante código desde el SDK de Python de Braket, utilice `job_arn` para identificar el trabajo híbrido y, a continuación, llame al comando `cancel` que contiene, como se muestra en el código siguiente.

```
job = AwsQuantumJob(arn=job_arn)
job.cancel()
```

El comando `cancel` cierra inmediatamente el contenedor de trabajo híbrido clásico y hace todo lo posible por cancelar todas las tareas cuánticas relacionadas que aún se encuentran en un estado no terminal.

# Personalización del trabajo híbrido
<a name="braket-jobs-customize"></a>

Amazon Braket ofrece varias formas de personalizar la forma en que se ejecutan sus trabajos híbridos, lo que le permite adaptar el entorno a sus necesidades específicas. En esta sección se exploran las opciones para personalizar los trabajos híbridos, desde definir el entorno del script de algoritmo hasta utilizar su propio contenedor. Aprenderá a optimizar su flujo de trabajo utilizando hiperparámetros, configurar instancias de trabajo y utilizar la compilación paramétrica para mejorar el rendimiento. Estas técnicas de personalización le ayudan a maximizar el potencial de sus cómputos cuánticos híbridos en Amazon Braket.

**Topics**
+ [Definición del entorno para el script de algoritmo](braket-jobs-script-environment.md)
+ [Uso de hiperparámetros](braket-jobs-hyperparameters.md)
+ [Configuración de su instancia de trabajo híbrido](braket-jobs-configure-job-instance-for-script.md)
+ [Uso de la compilación paramétrica para acelerar los trabajos híbridos](braket-jobs-parametric-compilation.md)

# Definición del entorno para el script de algoritmo
<a name="braket-jobs-script-environment"></a>

Amazon Braket admite entornos definidos por contenedores para el script de algoritmo:
+ Un contenedor base (el predeterminado, si no se especifica un `image_uri`)
+ Un contenedor con CUDA-Q
+ Un contenedor con Tensorflow y PennyLane
+ Un contenedor con PyTorch, y PennyLane CUDA-Q

En la tabla siguiente, se proporcionan detalles sobre los contenedores y las bibliotecas que incluyen.


**Contenedores de Amazon Braket**  

| Tipo | Base | CUDA-Q | TensorFlow | PyTorch | 
| --- | --- | --- | --- | --- | 
|   **URI de imagen**   |  292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest amazon-braket-base-jobs  |  292282985366.dkr. ecr.us-west-2.amazonaws.com /:último amazon-braket-cudaq-jobs  |  292282985366.dkr. ecr.us-east-1.amazonaws.com /:último amazon-braket-tensorflow-jobs  |  292282985366.dkr. ecr.us-west-2.amazonaws.com /:último amazon-braket-pytorch-jobs  | 
|   **Bibliotecas heredadas**   |  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/braket-jobs-script-environment.html)  | 
|   **Bibliotecas adicionales**   |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/braket-jobs-script-environment.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/braket-jobs-script-environment.html)  | 

[Puede ver y acceder a las definiciones de contenedores de código abierto en aws/. amazon-braket-containers](https://github.com/aws/amazon-braket-containers) Elija el contenedor que mejor se adapte a su caso de uso. Puedes usar cualquiera de las AWS regiones disponibles en Braket (us-east-1, us-west-1, us-west-2, eu-north-1, eu-west-2), pero la región contenedora debe coincidir con la región de tu trabajo híbrido. Especifique la imagen del contenedor al crear un trabajo híbrido añadiendo uno de los tres argumentos siguientes a su llamada a `create(…​)` en el script del trabajo híbrido. Puede instalar dependencias adicionales en el contenedor que elija en el tiempo de ejecución (al costo del inicio o el tiempo de ejecución), ya que los contenedores de Amazon Braket tienen conectividad a Internet. En el siguiente ejemplo es para la región us-west-2.
+  **Imagen** base: amazon-braket-base-jobs image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest»
+  **Imagen CUDA-Q:** image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest» amazon-braket-cudaq-jobs
+  **Imagen de Tensorflow:** image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest» amazon-braket-tensorflow-jobs
+  **PyTorch imagen**: image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest» amazon-braket-pytorch-jobs

Los `image-uris` también se pueden recuperar usando la función `retrieve_image()` en el SDK de Amazon Braket. El siguiente ejemplo muestra cómo recuperarlos del us-west-2 Región de AWS.

```
from braket.jobs.image_uris import retrieve_image, Framework

image_uri_base = retrieve_image(Framework.BASE, "us-west-2")
image_uri_cudaq = retrieve_image(Framework.CUDAQ, "us-west-2")
image_uri_tf = retrieve_image(Framework.PL_TENSORFLOW, "us-west-2")
image_uri_pytorch = retrieve_image(Framework.PL_PYTORCH, "us-west-2")
```

# Utilice su propio contenedor (BYOC)
<a name="braket-jobs-byoc"></a>

Los trabajos híbridos de Amazon Braket proporcionan tres contenedores preconstruidos para ejecutar código en diferentes entornos. Si uno de estos contenedores es compatible con su caso de uso, solo tiene que proporcionar el script de algoritmo cuando cree un trabajo híbrido. Las pequeñas dependencias que falten se pueden añadir desde el script de algoritmo o desde un archivo `requirements.txt` utilizando `pip`.

Si ninguno de estos contenedores se adapta a su caso de uso, o si desea ampliarlos, los trabajos híbridos de Braket admiten la ejecución de trabajos híbridos con su propia imagen de contenedor de Docker personalizada, o que utilice su propio contenedor (BYOC). Asegúrese de que sea la característica adecuada para su caso de uso. 

**Topics**
+ [¿Cuándo es conveniente utilizar su propio contenedor?](#bring-own-container-decision)
+ [Fórmula para utilizar su propio contenedor](bring-own-container-recipe.md)
+ [Ejecución de trabajos híbridos de Braket en su propio contenedor](running-hybrid-jobs-in-own-container.md)

## ¿Cuándo es conveniente utilizar su propio contenedor?
<a name="bring-own-container-decision"></a>

Utilizar su propio contenedor (BYOC) en los trabajos híbridos de Braket le ofrece la flexibilidad de utilizar su propio software instalándolo en un entorno empaquetado. Dependiendo de sus necesidades específicas, puede haber formas de lograr la misma flexibilidad sin tener que pasar por todo el ciclo completo de construcción de BYOC Docker, carga en Amazon ECR y URI de imagen personalizada.

**nota**  
BYOC puede no ser la opción adecuada si desea añadir un pequeño número de paquetes de Python adicionales (generalmente menos de 10) que están disponibles públicamente. Por ejemplo, si estás usando. PyPi

En este caso, puede utilizar una de las imágenes de Braket preconstruidas y, a continuación, incluir un archivo `requirements.txt` en su directorio de origen al enviar el trabajo. El archivo se lee automáticamente y `pip` instalará los paquetes con las versiones especificadas de forma normal. Si va a instalar una gran cantidad de paquetes, es posible que el tiempo de ejecución de sus trabajos aumente considerablemente. Compruebe la versión de Python y, si corresponde, la de CUDA del contenedor preconstruido que desee utilizar para comprobar si el software funciona.

BYOC es necesario cuando desea utilizar un lenguaje que no sea Python (como C\$1\$1 o Rust) para su script de trabajo, o si desea utilizar una versión de Python que no está disponible a través de los contenedores preconstruidos de Braket. También es una buena opción en los siguientes casos:
+ Está utilizando un software con una clave de licencia y necesita autenticar esa clave en un servidor de licencias para ejecutar el software. Con la opción de BYOC, puede incrustar la clave de licencia en su imagen de Docker e incluir un código para autenticarla.
+ Está utilizando un software que no es de acceso público. Por ejemplo, el software está alojado en un GitHub repositorio privado GitLab o al que se necesita una clave SSH específica para acceder.
+ Necesita instalar un gran conjunto de software que no está incluido en los contenedores proporcionados por Braket. BYOC le permitirá eliminar los largos tiempos de inicio de sus contenedores de trabajos híbridos debido a la instalación de software.

BYOC también le permite poner su SDK o algoritmo personalizado a disposición de los clientes al crear un contenedor de Docker con su software y ponerlo a disposición de sus usuarios. Puede hacerlo configurando los permisos adecuados en Amazon ECR.

**nota**  
Debe cumplir con todas las licencias de software aplicables.

# Fórmula para utilizar su propio contenedor
<a name="bring-own-container-recipe"></a>

En esta sección, le ofrecemos una step-by-step guía sobre lo que necesita bring your own container (BYOC) para hacer Braket Hybrid Jobs: los scripts, los archivos y los pasos para combinarlos y ponerlos en marcha con sus imágenes personalizadasDocker. Las fórmulas para dos casos comunes:

1. Instale software adicional en una imagen de Docker y utilice únicamente scripts de algoritmo de Python en sus trabajos.

1. Utilice scripts de algoritmo escritos en un lenguaje que no sea Python con los trabajos híbridos o una arquitectura de CPU distinta de x86.

Definir el *script de entrada de contenedor* es más complejo en el caso 2.

Cuando Braket ejecuta su trabajo híbrido, inicia el número y tipo de instancias de Amazon EC2 solicitados y, a continuación, ejecuta la imagen de Docker especificada por la entrada de URI de imagen en la creación del trabajo. Al utilizar la característica BYOC, debe especificar un URI de imagen alojado en un [repositorio privado de Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html) al que tenga acceso de lectura. Los trabajos híbridos de Braket utilizan esa imagen personalizada para ejecutar el trabajo.

Los componentes específicos que necesita para crear una imagen de Docker que se pueda utilizar con trabajos híbridos. Si no está familiarizado con la escritura y la creación de `Dockerfiles`, consulte la [documentación de Dockerfile](https://docs.docker.com/reference/dockerfile/) y la [documentación de Amazon ECR CLI](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html).

**Topics**
+ [Una imagen base para su Dockerfile](#base-image-dockerfile)
+ [(Opcional) Un script de punto de entrada de contenedor modificado](#modified-container-entry-point)
+ [Instalación del software y el script de contenedor necesarios con `Dockerfile`](#install-docketfile)

## Una imagen base para su Dockerfile
<a name="base-image-dockerfile"></a>

Si está utilizando Python y desea instalar software sobre lo que se proporciona en los contenedores proporcionados por Braket, una opción para una imagen base es una de las imágenes del contenedor de Braket, alojada en nuestro [GitHub repositorio](https://github.com/amazon-braket/amazon-braket-containers) y en Amazon ECR. Tendrá que [autenticarse en Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-authenticate-registry) para extraer la imagen y construir sobre ella. Por ejemplo, la primera línea del archivo de Docker de BYOC podría ser: `FROM [IMAGE_URI_HERE]`

A continuación, rellene el resto del Dockerfile para instalar y configurar el software que desea añadir al contenedor. Las imágenes de Braket preconstruidas ya contienen el script de punto de entrada de contenedor adecuado, por lo que no tiene que preocuparse por incluirlo.

Si desea utilizar un lenguaje que no sea Python, como C\$1\$1, Rust o Julia, o si desea crear una imagen para una arquitectura de CPU que no sea x86, como ARM, es posible que tenga que crear una imagen pública básica. Puede encontrar muchas de estas imágenes en la [galería pública de Amazon Elastic Container Registry](https://gallery.ecr.aws/). Asegúrese de elegir una que sea adecuada para la arquitectura de la CPU y, si es necesario, para la GPU que desee utilizar.

## (Opcional) Un script de punto de entrada de contenedor modificado
<a name="modified-container-entry-point"></a>

**nota**  
Si solo va a añadir software adicional a una imagen de Braket preconstruida, puede omitir esta sección.

Para ejecutar código que no sea Python como parte de su trabajo híbrido, modifique el script de Python que define el punto de entrada del contenedor. Por ejemplo, el [script de Python `braket_container.py` en el GitHub de Amazon Braket](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py). Este es el script que utilizan las imágenes preconstruidas por Braket para ejecutar el script de algoritmo y establecer las variables de entorno adecuadas. El propio script del punto de entrada del contenedor **debe** estar en Python, pero puede lanzar scripts que no sean de Python. En el ejemplo preconstruido, puede ver que los scripts de algoritmos de Python se lanzan como un [subproceso de Python](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L274) o como un [proceso completamente nuevo](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L257). Al modificar esta lógica, puede habilitar el script de punto de entrada para lanzar scripts de algoritmos que no sean de Python. Por ejemplo, puede modificar la función [https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L139](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L139) para lanzar procesos de Rust dependientes del final de la extensión del archivo.

También puede elegir escribir un `braket_container.py` completamente nuevo. Debería copiar los datos de entrada, los archivos fuente y otros archivos necesarios de Amazon S3 en el contenedor y definir las variables de entorno adecuadas.

## Instalación del software y el script de contenedor necesarios con `Dockerfile`
<a name="install-docketfile"></a>

**nota**  
Si utiliza una imagen de Braket preconstruida como imagen base de Docker, el script de contenedor ya está presente.

Si ha creado un script de contenedor modificado en el paso anterior, deberá copiarlo en el contenedor **y** definir la variable de entorno `SAGEMAKER_PROGRAM` como `braket_container.py`, o como haya llamado al script del nuevo punto de entrada del contenedor.

El siguiente es un ejemplo de un `Dockerfile` que le permite usar Julia en instancias de trabajos aceleradas por GPU:

```
FROM nvidia/cuda:12.2.0-devel-ubuntu22.04

    
 ARG DEBIAN_FRONTEND=noninteractive
 ARG JULIA_RELEASE=1.8
 ARG JULIA_VERSION=1.8.3


 ARG PYTHON=python3.11 
 ARG PYTHON_PIP=python3-pip
 ARG PIP=pip


 ARG JULIA_URL = https://julialang-s3.julialang.org/bin/linux/x64/${JULIA_RELEASE}/
 ARG TAR_NAME = julia-${JULIA_VERSION}-linux-x86_64.tar.gz


 ARG PYTHON_PKGS = # list your Python packages and versions here


 RUN curl -s -L ${JULIA_URL}/${TAR_NAME} | tar -C /usr/local -x -z --strip-components=1 -f -


 RUN apt-get update \

    && apt-get install -y --no-install-recommends \

    build-essential \

    tzdata \

    openssh-client \

    openssh-server \

    ca-certificates \

    curl \

    git \

    libtemplate-perl \

    libssl1.1 \

    openssl \

    unzip \ 

    wget \

    zlib1g-dev \

    ${PYTHON_PIP} \

    ${PYTHON}-dev \




 RUN ${PIP} install --no-cache --upgrade ${PYTHON_PKGS}


 RUN ${PIP} install --no-cache --upgrade sagemaker-training==4.1.3


 # Add EFA and SMDDP to LD library path
 ENV LD_LIBRARY_PATH="/opt/conda/lib/python${PYTHON_SHORT_VERSION}/site-packages/smdistributed/dataparallel/lib:$LD_LIBRARY_PATH"
 ENV LD_LIBRARY_PATH=/opt/amazon/efa/lib/:$LD_LIBRARY_PATH


 # Julia specific installation instructions
 COPY Project.toml /usr/local/share/julia/environments/v${JULIA_RELEASE}/
 RUN JULIA_DEPOT_PATH=/usr/local/share/julia \

    julia -e 'using Pkg; Pkg.instantiate(); Pkg.API.precompile()'
 # generate the device runtime library for all known and supported devices
 RUN JULIA_DEPOT_PATH=/usr/local/share/julia \

    julia -e 'using CUDA; CUDA.precompile_runtime()'


 # Open source compliance scripts
 RUN HOME_DIR=/root \

 && curl -o ${HOME_DIR}/oss_compliance.zip https://aws-dlinfra-utilities.s3.amazonaws.com/oss_compliance.zip \

 && unzip ${HOME_DIR}/oss_compliance.zip -d ${HOME_DIR}/ \

 && cp ${HOME_DIR}/oss_compliance/test/testOSSCompliance /usr/local/bin/testOSSCompliance \

 && chmod +x /usr/local/bin/testOSSCompliance \

 && chmod +x ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh \

 && ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh ${HOME_DIR} ${PYTHON} \

 && rm -rf ${HOME_DIR}/oss_compliance*


 # Copying the container entry point script
 COPY braket_container.py /opt/ml/code/braket_container.py
 ENV SAGEMAKER_PROGRAM braket_container.py
```

En este ejemplo, se descargan y ejecutan los scripts proporcionados por AWS para garantizar el cumplimiento de todas las licencias de código abierto pertinentes. Por ejemplo, atribuyendo correctamente cualquier código instalado que se rija por una MIT license.

Si necesitas incluir código no público, por ejemplo, código alojado en un repositorio privado GitHub o en un GitLab repositorio, **no** insertes claves SSH en la Docker imagen para acceder a él. En su lugar, utilice Docker Compose en la creación para permitir el acceso de Docker a SSH en la máquina host en la que está integrado. Para obtener más información, consulte la guía [Uso seguro de claves SSH en Docker para acceder a repositorios privados de GitHub](https://www.fastruby.io/blog/docker/docker-ssh-keys.html).

**Cómo crear y subir su imagen de Docker**

Una vez definido`Dockerfile` correctamente, ya puede seguir los pasos para [crear un repositorio privado de Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html), si aún no existe. También puede crear, etiquetar y cargar su imagen de contenedor en el repositorio.

Ya puede crear, etiquetar y enviar la imagen. Consulte la [documentación de compilación de Docker](https://docs.docker.com/reference/cli/docker/buildx/build/) para obtener una explicación completa de las opciones para `docker build` y algunos ejemplos.

Para el archivo de muestra definido anteriormente, puede ejecutar lo siguiente:

```
aws ecr get-login-password --region ${your_region} | docker login --username AWS --password-stdin ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com
 docker build -t braket-julia .
 docker tag braket-julia:latest ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com/braket-julia:latest
 docker push ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com/braket-julia:latest
```

**Asignación de los permisos de Amazon ECR adecuados**

Las imágenes de Braket Hybrid Jobs Docker deben estar alojadas en repositorios privados de Amazon ECR. De forma predeterminada, un repositorio privado de Amazon ECR **no** proporciona acceso de lectura al Braket Hybrid Jobs IAM role ni a ningún otro usuario que quiera usar su imagen, como un colaborador o un estudiante. Debe [establecer una política de repositorio](https://docs.aws.amazon.com/AmazonECR/latest/userguide/set-repository-policy.html) para conceder los permisos adecuados. En general, conceda permiso únicamente a los usuarios y roles de IAM específicos a los que quiera que accedan a sus imágenes, en lugar de permitir que cualquier persona con el image URI acceda.

# Ejecución de trabajos híbridos de Braket en su propio contenedor
<a name="running-hybrid-jobs-in-own-container"></a>

Para crear un trabajo híbrido con su propio contenedor, llame a `AwsQuantumJob.create()` con el argumento de `image_uri` especificado. Puede utilizar una QPU, un simulador bajo demanda o ejecutar su código localmente en el procesador clásico disponible con los trabajos híbridos de Braket. Te recomendamos que pruebes tu código en un simulador o TN1 antes de ejecutarlo en una QPU real. SV1 DM1

Para ejecutar el código en el procesador clásico, especifique el `instanceType` y el `instanceCount` que utiliza actualizando la `InstanceConfig`. Tenga en cuenta que si especifica un `instance_count` > 1, debe asegurarse de que el código puede ejecutarse en varios hosts. El límite máximo de instancias que puede elegir es de 5. Por ejemplo:

```
job = AwsQuantumJob.create(
    source_module="source_dir",
    entry_point="source_dir.algorithm_script:start_here",
    image_uri="111122223333.dkr.ecr.us-west-2.amazonaws.com/my-byoc-container:latest",
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge", instanceCount=3),
    device="local:braket/braket.local.qubit",
    # ...)
```

**nota**  
Utilice el ARN del dispositivo para realizar un seguimiento del simulador que utilizó como metadatos del trabajo híbrido. Los valores aceptables deben seguir el formato `device = "local:<provider>/<simulator_name>"`. Recuerde que `<provider>` y `<simulator_name>` debe constar únicamente de letras, números, `_`, `-` y `.` El tamaño de la cadena se limita a 256 caracteres.  
Si planea BYOC y no usa el SDK de Braket para crear tareas cuánticas, debe pasar el valor de la variable de entorno `AMZN_BRAKET_JOB_TOKEN` al parámetro `jobToken` en la solicitud `CreateQuantumTask`. De lo contrario, las tareas cuánticas no tienen prioridad y se consideran tareas cuánticas normales e independientes.

# Uso de hiperparámetros
<a name="braket-jobs-hyperparameters"></a>

Puede definir los hiperparámetros que necesita su algoritmo, como la tasa de aprendizaje o el tamaño del paso, al crear un trabajo híbrido. Los valores de los hiperparámetros se utilizan normalmente para controlar diversos aspectos del algoritmo y, a menudo, pueden ajustarse para optimizar el rendimiento del algoritmo. Para utilizar los hiperparámetros en un trabajo híbrido de Braket, es necesario especificar sus nombres y valores de forma explícita en un diccionario. Especifique los valores de los hiperparámetros que se van a probar al buscar el conjunto de valores óptimo. El primer paso para utilizar los hiperparámetros es configurar y definir los hiperparámetros como un diccionario, como se puede ver en el siguiente código.

```
from braket.devices import Devices

device_arn = Devices.Amazon.SV1

hyperparameters = {"shots": 1_000}
```

A continuación, pase los hiperparámetros definidos en el fragmento de código indicado anteriormente para utilizarlos en el algoritmo que elija. Para ejecutar el siguiente ejemplo de código, cree un directorio denominado «src» en la misma ruta que el archivo de hiperparámetros. Dentro del directorio «src», añada los archivos de código 0[\$1Getting\$1started\$1papermill.ipynb](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/0_Getting_started_papermill.ipynb), [notebook\$1runner.py](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/notebook_runner.py) y [requirements.txt](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/requirements.txt). 

```
import time
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    device=device_arn,
    source_module="src",
    entry_point="src.notebook_runner:run_notebook",
    input_data="src/0_Getting_started_papermill.ipynb",
    hyperparameters=hyperparameters,
    job_name=f"papermill-job-demo-{int(time.time())}",
)

# Print job to record the ARN
print(job)
```

Para acceder a sus hiperparámetros desde *dentro* de su script de trabajo híbrido, consulte la función `load_jobs_hyperparams()` en el archivo de python [notebook\$1runner.py](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/7_Running_notebooks_as_hybrid_jobs/src/notebook_runner.py). Para acceder a los hiperparámetros desde *fuera* de su script de trabajo híbrido, ejecute el siguiente código. 

```
from braket.aws import AwsQuantumJob

# Get the job using the ARN
job_arn = "arn:aws:braket:us-east-1:111122223333:job/5eabb790-d3ff-47cc-98ed-b4025e9e296f"  # Replace with your job ARN
job = AwsQuantumJob(arn=job_arn)

# Access the hyperparameters
job_metadata = job.metadata()
hyperparameters = job_metadata.get("hyperParameters", {})
print(hyperparameters)
```

Para obtener más información sobre cómo usar los hiperparámetros, consulte los tutoriales de [QAOA con Amazon Braket Hybrid Jobs PennyLane y Quantum Machine [Learning en Amazon Braket](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/1_Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs/Quantum_machine_learning_in_Amazon_Braket_Hybrid_Jobs.ipynb) Hybrid Jobs](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs/Using_PennyLane_with_Braket_Hybrid_Jobs.ipynb).

# Configuración de su instancia de trabajo híbrido
<a name="braket-jobs-configure-job-instance-for-script"></a>

Dependiendo de tu algoritmo, es posible que tengas diferente requisitos. De forma predeterminada, Amazon Braket ejecuta el script de algoritmo en una instancia de `ml.m5.large`. Sin embargo, puede personalizar este tipo de instancia al crear un trabajo híbrido mediante el siguiente argumento de importación y configuración.

```
from braket.jobs.config import InstanceConfig

job = AwsQuantumJob.create(
    ...
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge"), # Use NVIDIA T4 instance with 4 GPUs.
    ...
    ),
```

Si está ejecutando una simulación integrada y ha especificado un dispositivo local en la configuración del dispositivo, también puede solicitar más de una instancia en la `InstanceConfig` especificando el `instanceCount` y configurándolo para que sea mayor que uno. El límite superior es 5. Por ejemplo, puede elegir 3 instancias de la siguiente manera.

```
from braket.jobs.config import InstanceConfig
job = AwsQuantumJob.create(
    ...
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge", instanceCount=3), # Use 3 NVIDIA T4 instances
    ...
    ),
```

Cuando utilice varias instancias, considere la posibilidad de distribuir su trabajo híbrido mediante la característica de paralelismo de datos. Consulte el siguiente cuaderno de ejemplo para obtener más información sobre cómo ver este ejemplo de [paralelizar el entrenamiento para QML](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/5_Parallelize_training_for_QML/Parallelize_training_for_QML.ipynb).

Las tres tablas siguientes enumeran los tipos de instancias disponibles y las especificaciones para instancias estándar, de alto rendimiento y aceleradas por GPU.

**nota**  
Para ver las cuotas de instancias de cómputo clásicas predeterminadas para trabajos híbridos, consulte la página [Cuotas de Amazon Braket](braket-quotas.md).


| Instancia estándar | vCPU | Memoria (GiB) | 
| --- | --- | --- | 
|  ml.m5.large (predeterminado)  |  4  |  16  | 
|  ml.m5.xlarge  |  4  |  16  | 
|  ml.m5.2xlarge  |  8  |  32  | 
|  ml.m5.4xlarge  |  16  |  64  | 
|  ml.m5.12xlarge  |  48  |  192  | 
|  ml.m5.24xlarge  |  96  |  384  | 


| Instancias de alto rendimiento | vCPU | Memoria (GiB) | 
| --- | --- | --- | 
|  ml.c5.xlarge  |  4  |  8  | 
|  ml.c5.2xlarge  |  8  |  16  | 
|  ml.c5.4xlarge  |  16  |  32  | 
|  ml.c5.9xlarge  |  36  |  72  | 
|  ml.c5.18xlarge  |  72  |  144  | 
|  ml.c5n.xlarge  |  4  |  10.5  | 
|  ml.c5n.2xlarge  |  8  |  21  | 
|  ml.c5n.4xlarge  |  16  |  32  | 
|  ml.c5n.9xlarge  |  36  |  72  | 
|  ml.c5n.18xlarge  |  72  |  192  | 


| Instancias aceleradas por GPU | GPUs | vCPU | Memoria (GiB) | Memoria de GPU (GiB) | 
| --- | --- | --- | --- | --- | 
|  ml.p4d.24xlarge  |  8  |  96  |  1152  |  320  | 
|  ml.g4dn.xlarge  |  1  |  4  |  16  |  16  | 
|  ml.g4dn.2xlarge  |  1  |  8  |  32  |  16  | 
|  ml.g4dn.4xlarge  |  1  |  16  |  64  |  16  | 
|  ml.g4dn.8xlarge  |  1  |  32  |  128  |  16  | 
|  ml.g4dn.12xlarge  |  4  |  48  |  192  |  64  | 
|  ml.g4dn.16xlarge  |  1  |  64  |  256  |  16  | 

Cada instancia usa una configuración predeterminada de almacenamiento de datos (SSD) de 30 GB. Sin embargo, puede ajustar el almacenamiento de la misma manera que configure el `instanceType`. El siguiente ejemplo muestra cómo aumentar el almacenamiento total a 50 GB.

```
from braket.jobs.config import InstanceConfig

job = AwsQuantumJob.create(
    ...
    instance_config=InstanceConfig(
        instanceType="ml.g4dn.xlarge",
        volumeSizeInGb=50,
    ),
    ...
    ),
```

## Configuración de bucket predeterminado en `AwsSession`
<a name="braket-jobs-configure-default-bucket"></a>

El uso de su propia instancia de `AwsSession` le proporciona una mayor flexibilidad, como la posibilidad de especificar una ubicación personalizada para su bucket de Amazon S3 predeterminado. De forma predeterminada, un `AwsSession` tiene una ubicación de bucket de Amazon S3 preconfigurada de `"amazon-braket-{id}-{region}"`. Sin embargo, tiene la opción de anular la ubicación de bucket de Amazon S3 predeterminada al crear un `AwsSession`. Los usuarios pueden pasar opcionalmente un objeto de `AwsSession` al método `AwsQuantumJob.create()` proporcionando el parámetro `aws_session` como se muestra en el siguiente ejemplo de código.

```
aws_session = AwsSession(default_bucket="amazon-braket-s3-demo-bucket")

# Then you can use that AwsSession when creating a hybrid job
job = AwsQuantumJob.create(
    ...
    aws_session=aws_session
)
```

# Uso de la compilación paramétrica para acelerar los trabajos híbridos
<a name="braket-jobs-parametric-compilation"></a>

 Amazon Braket admite la compilación paramétrica en algunos casos. QPUs Esto le permite reducir la sobrecarga asociada con el costoso paso de compilación computacional, ya que solo es necesario compilar un circuito una vez y no para cada iteración en su algoritmo híbrido. Esto puede mejorar considerablemente los tiempos de ejecución de los trabajos híbridos, ya que evita la necesidad de recompilar el circuito en cada paso. Simplemente envíe los circuitos parametrizados a uno de nuestros trabajos compatibles QPUs como Braket Hybrid. Para trabajos híbridos de larga duración, Braket utiliza automáticamente los datos de calibración actualizados del proveedor de hardware al compilar su circuito para garantizar resultados de la máxima calidad.

Para crear un circuito paramétrico, primero debe proporcionar los parámetros como entradas en el script de algoritmo. En este ejemplo, utilizamos un circuito paramétrico pequeño e ignoramos cualquier procesamiento clásico entre cada iteración. Para las cargas de trabajo típicas, debe enviar muchos circuitos por lotes y realizar el procesamiento clásico, como la actualización de los parámetros en cada iteración.

```
import os

from braket.aws import AwsDevice
from braket.circuits import Circuit, FreeParameter

def start_here():

    print("Test job started.")

    # Use the device declared in the job script
    device = AwsDevice(os.environ["AMZN_BRAKET_DEVICE_ARN"])

    circuit = Circuit().rx(0, FreeParameter("theta"))
    parameter_list = [0.1, 0.2, 0.3]
    
    for parameter in parameter_list:
        result = device.run(circuit, shots=1000, inputs={"theta": parameter})

    print("Test job completed.")
```

Puede enviar el script de algoritmo para que se ejecute como un trabajo híbrido con el siguiente script de trabajo. Al ejecutar el trabajo híbrido en una QPU que admite la compilación paramétrica, el circuito se compila solo en la primera ejecución. En las siguientes ejecuciones, el circuito compilado se reutiliza, lo que aumenta el rendimiento en el tiempo de ejecución del trabajo híbrido sin líneas de código adicionales. 

```
from braket.aws import AwsQuantumJob

job = AwsQuantumJob.create(
    device=device_arn,
    source_module="algorithm_script.py",
)
```

**nota**  
La compilación paramétrica es compatible con todos los sistemas superconductores basados en compuertas, Rigetti Computing con la excepción de los programas QPUs de nivel de pulso.

# Uso PennyLane con Amazon Braket
<a name="hybrid"></a>

Los algoritmos híbridos son algoritmos que contienen instrucciones clásicas y cuánticas. Las instrucciones clásicas se ejecutan en un hardware clásico (una instancia de EC2 o su portátil) y las instrucciones cuánticas se ejecutan en un simulador o en una computadora cuántica. Se recomienda ejecutar algoritmos híbridos mediante la característica de trabajos híbridos. Para obtener más información, consulte [Cuándo utilizar los trabajos de Amazon Braket](braket-jobs.md#braket-jobs-use).

Amazon Braket le permite configurar y ejecutar algoritmos cuánticos híbridos con la ayuda del complemento Amazon **Braket o con el SDK de Python de Amazon PennyLane Braket** **y repositorios de cuadernos** de ejemplo. Los cuadernos de ejemplo de Amazon Braket, basados en el SDK, permiten configurar y ejecutar determinados algoritmos híbridos sin el complemento. PennyLane Sin embargo, lo recomendamos PennyLane porque proporciona una experiencia más rica.

 **Acerca de los algoritmos cuánticos híbridos** 

Los algoritmos cuánticos híbridos son importantes para la industria actual porque los dispositivos de computación cuántica contemporáneos generalmente producen ruido y, por lo tanto, errores. Cada puerta cuántica que se añade a un cómputo aumenta la probabilidad de añadir ruido; por lo tanto, los algoritmos de larga duración pueden verse abrumados por el ruido, lo que da lugar a cómputos erróneos.

Los algoritmos cuánticos puros como el de Shor [(ejemplo de estimación de fase cuántica)](https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/advanced_circuits_algorithms/Quantum_Phase_Estimation) o el de Grover [(ejemplo de Grover)](https://github.com/aws/amazon-braket-examples/tree/main/examples/advanced_circuits_algorithms/Grover) requieren miles o millones de operaciones. Por este motivo, pueden resultar poco prácticos para los dispositivos cuánticos existentes, que generalmente se denominan *dispositivos cuánticos ruidosos de escala intermedia* (NISQ).

En los algoritmos cuánticos híbridos, las unidades de procesamiento cuántico (QPUs) funcionan como coprocesadores en los algoritmos clásicos CPUs, específicamente para acelerar ciertos cálculos en un algoritmo clásico. Las ejecuciones de circuitos se vuelven mucho más cortas, al alcance de las capacidades de los dispositivos actuales.

**Topics**
+ [Amazon Braket con PennyLane](#pennylane-option)
+ [Algoritmos híbridos en cuadernos de ejemplo de Amazon Braket](#braket-hybrid-workflow)
+ [Algoritmos híbridos con simuladores integrados PennyLane](#hybrid-alorithms-pennylane)
+ [Activa el gradiente adjunto PennyLane con los simuladores Amazon Braket](#adjoint-gradient-pennylane)
+ [Utilizar Hybrid Jobs y ejecutar un algoritmo de QAOA PennyLane](braket-jobs-run-qaoa-algorithm.md)
+ [Ejecute cargas de trabajo híbridas con simuladores integrados PennyLane](pennylane-embedded-simulators.md)

## Amazon Braket con PennyLane
<a name="pennylane-option"></a>

Amazon Braket ofrece soporte para [PennyLane](https://pennylane.ai)un marco de software de código abierto creado en torno al concepto de programación *cuántica* diferenciable. Puede utilizar este marco para entrenar circuitos cuánticos de la misma manera que entrenaría una red neuronal para encontrar soluciones a problemas computacionales en química cuántica, machine learning cuántico y optimización.

La PennyLane biblioteca proporciona interfaces a herramientas conocidas de aprendizaje automático, que incluyen PyTorch y TensorFlow permiten que el entrenamiento de los circuitos cuánticos sea rápido e intuitivo.
+  **La PennyLane biblioteca**: PennyLane viene preinstalada en los cuadernos Amazon Braket. Para acceder a los dispositivos Amazon Braket desde PennyLane, abra un cuaderno e importe la PennyLane biblioteca con el siguiente comando.

```
import pennylane as qml
```

Los cuadernos de tutoriales lo ayudan a empezar rápidamente. Como alternativa, puede utilizarla PennyLane en Amazon Braket desde el IDE que prefiera.
+  **El PennyLane complemento Amazon Braket**: para usar su propio IDE, puede instalar el complemento Amazon Braket manualmente PennyLane . El complemento se conecta PennyLane con el [SDK de Python de Amazon Braket](https://github.com/aws/amazon-braket-sdk-python), por lo que puede ejecutar circuitos PennyLane en dispositivos Amazon Braket. Para instalar el PennyLane complemento, utilice el siguiente comando.

```
pip install amazon-braket-pennylane-plugin
```

El siguiente ejemplo muestra cómo configurar el acceso a los dispositivos Amazon Braket en PennyLane:

```
# to use SV1
import pennylane as qml
sv1 = qml.device("braket.aws.qubit", device_arn="arn:aws:braket:::device/quantum-simulator/amazon/sv1", wires=2)

# to run a circuit:
@qml.qnode(sv1)
def circuit(x):
    qml.RZ(x, wires=0)
    qml.CNOT(wires=[0,1])
    qml.RY(x, wires=1)
    return qml.expval(qml.PauliZ(1))

result = circuit(0.543)


#To use the local sim:
local = qml.device("braket.local.qubit", wires=2)
```

Para ver ejemplos de tutoriales y más información al respecto PennyLane, consulte el repositorio de [ejemplos de Amazon Braket](https://github.com/aws/amazon-braket-examples/tree/main/examples/pennylane).

El PennyLane complemento Amazon Braket le permite cambiar entre la QPU de Amazon Braket y los dispositivos simuladores integrados PennyLane con una sola línea de código. Ofrece dos dispositivos cuánticos Amazon Braket con los que trabajar: PennyLane
+  `braket.aws.qubit`para funcionar con los dispositivos cuánticos del servicio Amazon Braket, incluidos QPUs los simuladores
+  `braket.local.qubit` para ejecutarse con el simulador local del SDK de Amazon Braket.

El PennyLane plugin Amazon Braket es de código abierto. Puedes instalarlo desde el [ GitHub repositorio de PennyLane complementos](https://github.com/aws/amazon-braket-pennylane-plugin-python).

Para obtener más información al respecto PennyLane, consulte la documentación del sitio [PennyLane web](https://pennylane.ai).

## Algoritmos híbridos en cuadernos de ejemplo de Amazon Braket
<a name="braket-hybrid-workflow"></a>

Amazon Braket proporciona una variedad de cuadernos de ejemplo que no dependen del PennyLane complemento para ejecutar algoritmos híbridos. Puede empezar con cualquiera de estos [cuadernos de ejemplos híbridos de Amazon Braket](https://github.com/aws/amazon-braket-examples/tree/main/examples/hybrid_quantum_algorithms) que ilustran *métodos variacionales*, como el algoritmo de optimización cuántica aproximada (QAOA) o el solucionador de problemas de autovalores cuánticos variacionales (VQE).

Los cuadernos de ejemplo de Amazon Braket se basan en el [SDK de Python de Amazon Braket](https://github.com/aws/amazon-braket-sdk-python). El SDK proporciona un marco para interactuar con los dispositivos de hardware de computación cuántica a través de Amazon Braket. Se trata de una biblioteca de código abierto diseñada para ayudarle con la parte cuántica de su flujo de trabajo híbrido.

Puede explorar Amazon Braket más a fondo con nuestros [cuadernos de ejemplo](https://github.com/aws/amazon-braket-examples).

## Algoritmos híbridos con simuladores integrados PennyLane
<a name="hybrid-alorithms-pennylane"></a>

Amazon Braket Hybrid Jobs ahora incluye simuladores integrados de alto rendimiento basados en CPU y GPU de. [PennyLane](https://github.com/PennyLaneAI/pennylane-lightning) Esta familia de simuladores integrados se puede incorporar directamente en su contenedor de trabajos híbridos e incluye el simulador rápido de vectores de estado `lightning.qubit`, el simulador `lightning.gpu` acelerado mediante la [biblioteca cuQuantum](https://developer.nvidia.com/cuquantum-sdk) de NVIDIA y otros. Estos simuladores integrados son ideales para algoritmos variacionales, como el machine learning cuántico, que pueden beneficiarse de métodos avanzados como el [método de diferenciación adjunta](https://docs.pennylane.ai/en/stable/introduction/interfaces.html#simulation-based-differentiation). Puede ejecutar estos simuladores integrados en una o varias instancias de CPU o GPU.

Con Hybrid Jobs, ahora puede ejecutar el código de su algoritmo variacional utilizando una combinación de un coprocesador clásico y una QPU, un simulador Amazon Braket bajo demanda como, por ejemploSV1, o directamente utilizando el simulador integrado desde. PennyLane

El simulador integrado ya está disponible con el contenedor de trabajos híbridos y usted debe decorar su función principal de Python con el decorador `@hybrid_job`. Para usar el PennyLane `lightning.gpu` simulador, también debe especificar una instancia de GPU, `InstanceConfig` tal como se muestra en el siguiente fragmento de código:

```
import pennylane as qml
from braket.jobs import hybrid_job
from braket.jobs.config import InstanceConfig


@hybrid_job(device="local:pennylane/lightning.gpu", instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge"))
def function(wires):
    dev = qml.device("lightning.gpu", wires=wires)
    ...
```

Consulta el [cuaderno de ejemplo](https://github.com/aws/amazon-braket-examples/blob/main/examples/hybrid_jobs/4_Embedded_simulators_in_Braket_Hybrid_Jobs/Embedded_simulators_in_Braket_Hybrid_Jobs.ipynb) para empezar a usar un simulador PennyLane integrado con Hybrid Jobs.

## Activa el gradiente adjunto PennyLane con los simuladores Amazon Braket
<a name="adjoint-gradient-pennylane"></a>

Con el PennyLane complemento para Amazon Braket, puede calcular gradientes mediante el método de diferenciación adjunto cuando se ejecuta en el simulador vectorial de estado local o. SV1

 **Note:** Para utilizar el método de diferenciación adjunta, debe especificar `diff_method='device'` en su `qnode`, y **no** `diff_method='adjoint'`. Consulte el siguiente ejemplo.

```
device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1"
dev = qml.device("braket.aws.qubit", wires=wires, shots=0, device_arn=device_arn)
                
@qml.qnode(dev, diff_method="device")
def cost_function(params):
    circuit(params)
    return qml.expval(cost_h)

gradient = qml.grad(circuit)
initial_gradient = gradient(params0)
```

**nota**  
Actualmente, PennyLane computará los índices de agrupación para los hamiltonianos de QAOA y los utilizará para dividir el hamiltoniano en diversos valores esperados. Si quiere utilizar SV1 la función de diferenciación adjunta al ejecutar la QAOAPennyLane, necesitará reconstruir el coste hamiltoniano eliminando los índices de agrupamiento, de la siguiente manera: `cost_h, mixer_h = qml.qaoa.max_clique(g, constrained=False) cost_h = qml.Hamiltonian(cost_h.coeffs, cost_h.ops)` 

# Utilizar Hybrid Jobs y ejecutar un algoritmo de QAOA PennyLane
<a name="braket-jobs-run-qaoa-algorithm"></a>

En esta sección, utilizará lo que ha aprendido para escribir un programa híbrido real utilizando la compilación PennyLane paramétrica. Utilizará el script del algoritmo para abordar un problema de algoritmo de optimización cuántica aproximada (QAOA). El programa crea una función de costo correspondiente a un problema clásico de optimización Max Cut, especifica un circuito cuántico parametrizado y utiliza un método de descenso de gradiente para optimizar los parámetros de manera que se minimice la función de costo. En este ejemplo, generamos el gráfico del problema en el script del algoritmo para simplificar, pero para casos de uso más habituales, la mejor práctica es proporcionar la especificación del problema a través de un canal dedicado en la configuración de los datos de entrada. El indicador se establece de `parametrize_differentiable` forma predeterminada para `True` que pueda disfrutar automáticamente de las ventajas de un mejor rendimiento en tiempo de ejecución gracias a la compilación paramétrica si es compatible. QPUs

```
import os
import json
import time

from braket.jobs import save_job_result
from braket.jobs.metrics import log_metric

import networkx as nx
import pennylane as qml
from pennylane import numpy as np
from matplotlib import pyplot as plt

def init_pl_device(device_arn, num_nodes, shots, max_parallel):
    return qml.device(
        "braket.aws.qubit",
        device_arn=device_arn,
        wires=num_nodes,
        shots=shots,
        # Set s3_destination_folder=None to output task results to a default folder
        s3_destination_folder=None,
        parallel=True,
        max_parallel=max_parallel,
        parametrize_differentiable=True, # This flag is True by default.
    )

def start_here():
    input_dir = os.environ["AMZN_BRAKET_INPUT_DIR"]
    output_dir = os.environ["AMZN_BRAKET_JOB_RESULTS_DIR"]
    job_name = os.environ["AMZN_BRAKET_JOB_NAME"]
    checkpoint_dir = os.environ["AMZN_BRAKET_CHECKPOINT_DIR"]
    hp_file = os.environ["AMZN_BRAKET_HP_FILE"]
    device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"]

    # Read the hyperparameters
    with open(hp_file, "r") as f:
        hyperparams = json.load(f)

    p = int(hyperparams["p"])
    seed = int(hyperparams["seed"])
    max_parallel = int(hyperparams["max_parallel"])
    num_iterations = int(hyperparams["num_iterations"])
    stepsize = float(hyperparams["stepsize"])
    shots = int(hyperparams["shots"])

    # Generate random graph
    num_nodes = 6
    num_edges = 8
    graph_seed = 1967
    g = nx.gnm_random_graph(num_nodes, num_edges, seed=graph_seed)

    # Output figure to file
    positions = nx.spring_layout(g, seed=seed)
    nx.draw(g, with_labels=True, pos=positions, node_size=600)
    plt.savefig(f"{output_dir}/graph.png")

    # Set up the QAOA problem
    cost_h, mixer_h = qml.qaoa.maxcut(g)

    def qaoa_layer(gamma, alpha):
        qml.qaoa.cost_layer(gamma, cost_h)
        qml.qaoa.mixer_layer(alpha, mixer_h)

    def circuit(params, **kwargs):
        for i in range(num_nodes):
            qml.Hadamard(wires=i)
        qml.layer(qaoa_layer, p, params[0], params[1])

    dev = init_pl_device(device_arn, num_nodes, shots, max_parallel)

    np.random.seed(seed)
    cost_function = qml.ExpvalCost(circuit, cost_h, dev, optimize=True)
    params = 0.01 * np.random.uniform(size=[2, p])

    optimizer = qml.GradientDescentOptimizer(stepsize=stepsize)
    print("Optimization start")

    for iteration in range(num_iterations):
        t0 = time.time()

        # Evaluates the cost, then does a gradient step to new params
        params, cost_before = optimizer.step_and_cost(cost_function, params)
        # Convert cost_before to a float so it's easier to handle
        cost_before = float(cost_before)

        t1 = time.time()

        if iteration == 0:
            print("Initial cost:", cost_before)
        else:
            print(f"Cost at step {iteration}:", cost_before)

        # Log the current loss as a metric
        log_metric(
            metric_name="Cost",
            value=cost_before,
            iteration_number=iteration,
        )

        print(f"Completed iteration {iteration + 1}")
        print(f"Time to complete iteration: {t1 - t0} seconds")

    final_cost = float(cost_function(params))
    log_metric(
        metric_name="Cost",
        value=final_cost,
        iteration_number=num_iterations,
    )

    # We're done with the hybrid job, so save the result.
    # This will be returned in job.result()
    save_job_result({"params": params.numpy().tolist(), "cost": final_cost})
```

**nota**  
La compilación paramétrica es compatible con todos los programas superconductores basados en compuertas, Rigetti Computing con la excepción de los QPUs programas de nivel de pulso.

# Ejecute cargas de trabajo híbridas con simuladores integrados PennyLane
<a name="pennylane-embedded-simulators"></a>

Veamos cómo puede utilizar los simuladores integrados de PennyLane Amazon Braket Hybrid Jobs para ejecutar cargas de trabajo híbridas. El simulador integrado basado en GPU de PennyLane, `lightning.gpu`, usa la [biblioteca de Nvidia cuQuantum](https://developer.nvidia.com/cuquantum-sdk) para acelerar las simulaciones de circuitos. El simulador de GPU integrado viene preconfigurado en todos los [contenedores de trabajos](https://github.com/amazon-braket/amazon-braket-containers) de Braket, que los usuarios pueden utilizar de forma inmediata. En esta página, le mostramos cómo usar `lightning.gpu` para acelerar las cargas de trabajo híbridas.

## Uso de `lightning.gpu` para cargas de trabajo de QAOA
<a name="lightning-gpu-qaoa"></a>

Considere los ejemplos del algoritmo de optimización cuántica aproximada (QAOA) de este [cuaderno](https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs). Para seleccionar un simulador integrado, debe especificar que el argumento `device` sea una cadena con la forma: `"local:<provider>/<simulator_name>"`. Por ejemplo, configuraría `"local:pennylane/lightning.gpu"` para `lightning.gpu`. La cadena de dispositivo que proporciona al trabajo híbrido al iniciarlo se pasa al trabajo como el `"AMZN_BRAKET_DEVICE_ARN"` de la variable de entorno.

```
device_string = os.environ["AMZN_BRAKET_DEVICE_ARN"]
prefix, device_name = device_string.split("/")
device = qml.device(simulator_name, wires=n_wires)
```

En esta página, compare los dos simuladores vectoriales de PennyLane estado integrados (que están basados en la CPU) y `lightning.qubit` `lightning.gpu` (que están basados en la GPU). Proporcione a los simuladores descomposiciones de puertas personalizadas para calcular varios gradientes.

Ahora ya puede preparar el script de lanzamiento del trabajo híbrido. Ejecute el algoritmo QAOA mediante dos tipos de instancias: `ml.m5.2xlarge` y `ml.g4dn.xlarge`. El tipo de instancia `ml.m5.2xlarge` es equiparable al de un portátil de desarrollador estándar. `ml.g4dn.xlarge`Se trata de una instancia de computación acelerada que tiene una sola GPU NVIDIA T4 con 16 GB de memoria.

Para ejecutar la GPU, primero debemos especificar una imagen compatible y la instancia correcta (que por defecto es una `ml.m5.2xlarge` instancia).

```
from braket.aws import AwsSession
from braket.jobs.image_uris import Framework, retrieve_image

image_uri = retrieve_image(Framework.PL_PYTORCH, AwsSession().region)
instance_config = InstanceConfig(instanceType="ml.g4dn.xlarge")
```

A continuación, debemos introducirlos en el decorador de tareas híbridas, junto con los parámetros actualizados del dispositivo, tanto en el sistema como en los argumentos de los trabajos híbridos.

```
@hybrid_job(
        device="local:pennylane/lightning.gpu",
        input_data=input_file_path,
        image_uri=image_uri,
        instance_config=instance_config)
def run_qaoa_hybrid_job_gpu(p=1, steps=10):
    params = np.random.rand(2, p)

    braket_task_tracker = Tracker()

    graph = nx.read_adjlist(input_file_path, nodetype=int)
    wires = list(graph.nodes)
    cost_h, _mixer_h = qaoa.maxcut(graph)

    device_string = os.environ["AMZN_BRAKET_DEVICE_ARN"]
    prefix, device_name = device_string.split("/")
    dev= qml.device(simulator_name, wires=len(wires))
    ...
```

**nota**  
Si especificas el `instance_config` como mediante una instancia basada en la GPU, pero eliges `device` que sea el simulador integrado basado en la CPU (`lightning.qubit`), no se utilizará la GPU. Asegúrese de utilizar el simulador integrado basado en GPU si desea utilizar la GPU como destino.

El tiempo medio de iteración de la `m5.2xlarge` instancia es de unos 73 segundos, mientras que el de la `ml.g4dn.xlarge` instancia es de unos 0,6 segundos. Para este flujo de trabajo de 21 qubits, la instancia de GPU nos proporciona una aceleración de 100 veces. Si consulta la [página de precios](https://aws.amazon.com/braket/pricing/) de Amazon Braket Hybrid Jobs, verá que el coste por minuto de una `m5.2xlarge` instancia es de 0,00768\$1, mientras que para la `ml.g4dn.xlarge` instancia es de 0,01227\$1. En este caso, es más rápido y económico ejecutarlo en la instancia de GPU.

## Machine learning cuántico y paralelismo de datos
<a name="quantumML-data-parallelism"></a>

Si su tipo de carga de trabajo es el machine learning cuántico (QML) que se entrena con conjuntos de datos, puede acelerar aún más su carga de trabajo utilizando el paralelismo de datos. En QML, el modelo contiene uno o más circuitos cuánticos. El modelo puede o no contener también redes neuronales clásicas. Al entrenar el modelo con el conjunto de datos, los parámetros del modelo se actualizan para minimizar la función de pérdida. Por lo general, se define una función de pérdida para un único punto de datos y la pérdida total para la pérdida media de todo el conjunto de datos. En QML, las pérdidas generalmente se calculan en serie antes de promediar la pérdida total para los cómputos de gradientes. Este procedimiento lleva mucho tiempo, especialmente cuando hay cientos de puntos de datos.

Como la pérdida de un punto de datos no depende de otros puntos de datos, las pérdidas se pueden evaluar en paralelo. Las pérdidas y los gradientes asociados a diferentes puntos de datos se pueden evaluar al mismo tiempo. Esto se conoce como paralelismo de datos. Con SageMaker la biblioteca paralela de datos distribuida, Amazon Braket Hybrid Jobs le facilita el uso del paralelismo de datos para acelerar su entrenamiento.

Considere la siguiente carga de trabajo de QML para el paralelismo de datos, que utiliza el [conjunto de datos Sonar](https://archive.ics.uci.edu/dataset/151/connectionist+bench+sonar+mines+vs+rocks) del conocido repositorio de UCI como ejemplo para la clasificación binaria. El conjunto de datos de Sonar tiene 208 puntos de datos, cada uno con 60 características que se recopilan a partir de señales de Sonar que rebotan en los materiales. Cada punto de datos se etiqueta con una «M» para las minas o con una «R» para las rocas. Nuestro modelo QML consta de una capa de entrada, un circuito cuántico como capa oculta y una capa de salida. Las capas de entrada y salida son redes neuronales clásicas implementadas en. PyTorch El circuito cuántico se integra con las redes PyTorch neuronales mediante PennyLane el módulo qml.qnn. Consulte nuestros [cuadernos de ejemplo](https://github.com/aws/amazon-braket-examples) para obtener más detalles sobre la carga de trabajo. Al igual que en el ejemplo anterior de QAOA, puede aprovechar la potencia de la GPU mediante el uso de simuladores integrados basados en la GPU, como PennyLane los que se utilizan para mejorar el rendimiento en comparación con los simuladores basados en la CPU integrada. `lightning.gpu`

Para crear un trabajo híbrido, puede llamar a `AwsQuantumJob.create` y especificar el script del algoritmo, el dispositivo y otras configuraciones a través de sus argumentos de palabra clave.

```
instance_config = InstanceConfig(instanceType='ml.g4dn.xlarge')

hyperparameters={"nwires": "10",
                 "ndata": "32",
                 ...
}

job = AwsQuantumJob.create(
    device="local:pennylane/lightning.gpu",
    source_module="qml_source",
    entry_point="qml_source.train_single",
    hyperparameters=hyperparameters,
    instance_config=instance_config,
    ...
)
```

Para utilizar el paralelismo de datos, es necesario modificar algunas líneas de código en el script del algoritmo para que la biblioteca distribuida paralelice correctamente el entrenamiento. SageMaker En primer lugar, importa el `smdistributed` paquete que se encarga de la mayor parte del trabajo pesado de distribuir las cargas de trabajo en varias y múltiples instancias. GPUs Este paquete viene preconfigurado en Braket y en los contenedores. PyTorch TensorFlow El `dist` módulo indica a nuestro script de algoritmo cuál es el número total de núcleos GPUs para el entrenamiento (`world_size`) `rank` y el núcleo `local_rank` de la GPU. `rank`es el índice absoluto de una GPU en todas las instancias, mientras que `local_rank` es el índice de una GPU dentro de una instancia. Por ejemplo, si hay cuatro instancias, cada una con ocho GPUs asignadas para el entrenamiento, los `rank` rangos van de 0 a 31 y los `local_rank` rangos de 0 a 7.

```
import smdistributed.dataparallel.torch.distributed as dist

dp_info = {
    "world_size": dist.get_world_size(),
    "rank": dist.get_rank(),
    "local_rank": dist.get_local_rank(),
}
batch_size //= dp_info["world_size"] // 8
batch_size = max(batch_size, 1)
```

A continuación, se define un `DistributedSampler` según el `world_size` y `rank` y, después, se pasa al cargador de datos. Este muestreador evita GPUs acceder a la misma porción de un conjunto de datos.

```
train_sampler = torch.utils.data.distributed.DistributedSampler(
    train_dataset,
    num_replicas=dp_info["world_size"],
    rank=dp_info["rank"]
)
train_loader = torch.utils.data.DataLoader(
    train_dataset,
    batch_size=batch_size,
    shuffle=False,
    num_workers=0,
    pin_memory=True,
    sampler=train_sampler,
)
```

A continuación, use la clase `DistributedDataParallel` para habilitar el paralelismo de datos.

```
from smdistributed.dataparallel.torch.parallel.distributed import DistributedDataParallel as DDP

model = DressedQNN(qc_dev).to(device)
model = DDP(model)
torch.cuda.set_device(dp_info["local_rank"])
model.cuda(dp_info["local_rank"])
```

Los cambios anteriores son los que necesita para usar el paralelismo de datos. Generalmente, en QML es conveniente guardar los resultados e imprimir el progreso del entrenamiento. Si cada GPU ejecuta el comando de guardar e imprimir, el registro se saturará con información repetida y los resultados se sobrescribirán entre sí. Para evitarlo, solo puede guardar e imprimir desde la GPU que tiene `rank` 0.

```
if dp_info["rank"]==0:
    print('elapsed time: ', elapsed)
    torch.save(model.state_dict(), f"{output_dir}/test_local.pt")
    save_job_result({"last loss": loss_before})
```

 Amazon Braket Hybrid Jobs admite tipos de `ml.g4dn.12xlarge` instancias para la biblioteca paralela de datos SageMaker distribuidos. El tipo de instancia se configura mediante el argumento `InstanceConfig` en los trabajos híbridos. Para que la biblioteca paralela de datos SageMaker distribuidos sepa que el paralelismo de datos está habilitado, debe agregar dos hiperparámetros adicionales: configurar `"true"` y `"sagemaker_distributed_dataparallel_enabled"` `"sagemaker_instance_type"` configurar el tipo de instancia que está utilizando. El paquete de `smdistributed` utiliza estos dos hiperparámetros. El script de algoritmo no necesita usarlos de forma explícita. En el SDK de Amazon Braket, proporciona un práctico argumento de palabra clave `distribution`. Con el `distribution="data_parallel"` en la creación de trabajos híbridos, el SDK de Amazon Braket inserta automáticamente los dos hiperparámetros por usted. Si utiliza la API de Amazon Braket, debe incluir estos dos hiperparámetros.

Una vez configurados el paralelismo de datos y la instancia, ya puede enviar su trabajo híbrido. Hay 4 GPUs en una instancia. `ml.g4dn.12xlarge` Cuando lo configuras`instanceCount=1`, la carga de trabajo se distribuye entre las 8 GPUs de la instancia. Si configuras `instanceCount` más de uno, la carga de trabajo se distribuye entre las GPUs disponibles en todas las instancias. Al usar varias instancias, cada instancia conlleva un cargo en función del tiempo que la utilice. Por ejemplo, cuando utiliza cuatro instancias, el tiempo facturable es cuatro veces el tiempo de ejecución por instancia, ya que hay cuatro instancias ejecutando sus cargas de trabajo al mismo tiempo.

```
instance_config = InstanceConfig(instanceType='ml.g4dn.12xlarge',
                                 instanceCount=1,
)

hyperparameters={"nwires": "10",
                 "ndata": "32",
                 ...,
}

job = AwsQuantumJob.create(
    device="local:pennylane/lightning.gpu",
    source_module="qml_source",
    entry_point="qml_source.train_dp",
    hyperparameters=hyperparameters,
    instance_config=instance_config,
    distribution="data_parallel",
    ...
)
```

**nota**  
En la creación del trabajo híbrido anterior, `train_dp.py` es el script del algoritmo modificado para utilizar el paralelismo de datos. Tenga en cuenta que el paralelismo de datos solo funciona correctamente cuando modifica el script de algoritmo según lo indicado en la sección anterior. Si se habilita la opción de paralelismo de datos sin un script de algoritmo modificado correctamente, el trabajo híbrido puede generar errores, o cada GPU puede procesar repetidamente la misma porción de datos, lo cual es ineficiente.

Si se utiliza correctamente, el uso de varias instancias puede suponer una reducción de varios órdenes de magnitud tanto en tiempo como en costes. Consulte el [cuaderno de ejemplo para obtener más información](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/5_Parallelize_training_for_QML/Parallelize_training_for_QML.ipynb).

# Uso de CUDA-Q con Amazon Braket
<a name="braket-using-cuda-q"></a>

NVIDIA's CUDA-Qes una biblioteca de software diseñada para programar algoritmos cuánticos híbridos que combinan CPUs GPUs, y unidades de procesamiento cuántico (QPUs). Proporciona un modelo de programación unificado que permite a los desarrolladores expresar instrucciones clásicas y cuánticas en un solo programa, lo que agiliza los flujos de trabajo. CUDA-Qacelera la simulación cuántica y el tiempo de ejecución de los programas con sus simuladores de CPU y GPU integrados. CUDA-Qestá disponible con instancias de notebook Braket nativas (NBIs) y Amazon Braket Hybrid Jobs.

**Topics**
+ [CUDA-Q en NBIs](#braket-cuda-q-nbis)
+ [CUDA-Q en trabajos híbridos](#braket-cuda-q-hybrid-jobs)

## CUDA-Q en NBIs
<a name="braket-cuda-q-nbis"></a>

CUDA-Q está instalado de forma predeterminada en el entorno de NBI de Braket. Para abrir un cuaderno de CUDA-Q ejemplo, vaya a la página del lanzador de Jupyter y seleccione el mosaico de CUDA-Q y Braket. Esto abre el cuaderno de ejemplo `0_Getting_started_with_CUDA-Q.ipynb` en la ventana principal. Para ver más ejemplos de CUDA-Q, consulte el panel izquierdo en el directorio de `nvidia_cuda_q/`.

También puede comprobar la versión de CUDA-Q o cualquier otro paquete de terceros instalado en su NBI. Por ejemplo, puede ejecutar el siguiente comando en una celda de código de un bloc de notas para comprobar las versiones de CUDA-Q los paquetes Qiskit y Braket que están instaladas en el entorno. PennyLane

```
%pip freeze | grep -i -e cudaq -e qiskit -e pennylane -e braket
```

## CUDA-Q en trabajos híbridos
<a name="braket-cuda-q-hybrid-jobs"></a>

El uso de CUDA-Q en [trabajos híbridos de Amazon Braket](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html) ofrece un entorno de computación flexible y bajo demanda. Las instancias computacionales solo se ejecutan durante el tiempo que dura su carga de trabajo, lo que garantiza que solo pague por lo que utiliza. Los trabajos híbridos de Amazon Braket también proporcionan una experiencia escalable. Los usuarios pueden comenzar con instancias más pequeñas para crear prototipos y realizar pruebas, y luego escalar verticalmente a instancias más grandes capaces de manejar mayores cargas de trabajo para realizar experimentos completos.

Amazon Braket Hybrid Jobs apoya, GPUs que es esencial para maximizar su potencial. CUDA-Q GPUs acelera considerablemente las simulaciones de programas cuánticos en comparación con los simuladores basados en CPU, especialmente cuando se trabaja con circuitos con un alto número de cúbits. La paralelización se simplifica cuando se utiliza CUDA-Q en los trabajos híbridos de Amazon Braket. Los trabajos híbridos simplifican la distribución del muestreo de circuitos y las evaluaciones observables entre varios nodos computacionales. Esta paralelización fluida de las cargas de trabajo de CUDA-Q permite a los usuarios centrarse más en desarrollar sus cargas de trabajo en lugar de configurar la infraestructura para experimentos a gran escala.

Para empezar, consulte el [ejemplo para empezar con CUDA-Q](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/nvidia_cuda_q/0_Getting_started_with_CUDA-Q.ipynb) en el GitHub de ejemplos de Amazon Braket para utilizar un contenedor de trabajos híbridos de CUDA-Q proporcionado por Braket.

El siguiente fragmento de código es un ejemplo de `hello-world` para ejecutar un programa de CUDA-Q con los trabajos híbridos de Amazon Braket.

```
image_uri = retrieve_image(Framework.CUDAQ, AwsSession().region)

@hybrid_job(device='local:nvidia/qpp-cpu', image_uri=image_uri)
def hello_quantum():
    import cudaq

    # define the backend
    device=get_job_device_arn()
    cudaq.set_target(device.split('/')[-1])

    # define the Bell circuit
    kernel = cudaq.make_kernel()
    qubits = kernel.qalloc(2)
    kernel.h(qubits[0])
    kernel.cx(qubits[0], qubits[1])

    # sample the Bell circuit
    result = cudaq.sample(kernel, shots_count=1000)
    measurement_probabilities = dict(result.items())
    
    return measurement_probabilities
```

El ejemplo anterior simula un circuito Bell en un simulador de CPU. Este ejemplo se ejecuta localmente en su portátil o en el cuaderno de Jupyter de Braket. Debido a esta configuración de `local=True`, cuando ejecute este script, se iniciará un contenedor en su entorno local para ejecutar el programa CUDA-Q con fines de prueba y depuración. Cuando termine de realizar las pruebas, puede quitar el indicador `local=True` y continuar con su trabajo en AWS. Para obtener más información, consulte [Trabajar con trabajos híbridos de Amazon Braket](braket-jobs.md).

Si sus cargas de trabajo tienen un recuento elevado de qubits, un gran número de circuitos o un gran número de iteraciones, puede utilizar recursos de computación de CPU más potentes especificando la configuración `instance_config`. El siguiente fragmento de código muestra cómo configurar el ajuste `instance_config` en el decorador de `hybrid_job`. Para obtener más información sobre los tipos de instancias compatibles, consulte [Configuración de su instancia de trabajo híbrido](braket-jobs-configure-job-instance-for-script.md). Para obtener la lista de los tipos de instancia, consulte [Tipos de instancias de Amazon EC2](https://aws.amazon.com/ec2/instance-types/).

```
@hybrid_job(
    device="local:nvidia/qpp-cpu",
    image_uri=image_uri,
    instance_config=InstanceConfig(instanceType="ml.c5.2xlarge"),
)
def my_job_script():
    ...
```

Para cargas de trabajo más exigentes, puede ejecutar sus cargas de trabajo en un simulador de GPU de CUDA-Q. Para habilitar un simulador de GPU, use el nombre de backend `nvidia`. El backend `nvidia` funciona como un simulador GPU de CUDA-Q. A continuación, seleccione un tipo de instancia de Amazon EC2 que sea compatible con una GPU de NVIDIA. El siguiente fragmento de código muestra el decorador de `hybrid_job` configurado para la GPU.

```
@hybrid_job(
    device="local:nvidia/nvidia",
    image_uri=image_uri,
    instance_config=InstanceConfig(instanceType="ml.g4dn.xlarge"),
)
def my_job_script():
    ...
```

Amazon Braket Hybrid Jobs y admite simulaciones de GPU NBIs paralelas con. CUDA-Q Puede paralelizar la evaluación de varias observables o varios circuitos para mejorar el rendimiento de su carga de trabajo. Para paralelizar varios observables, realice los siguientes cambios en el script de algoritmo.

Configura la opción `mgpu` del backend `nvidia`. Esto es necesario para paralelizar los observables. La paralelización utiliza el MPI para la comunicación entre ellas GPUs, por lo que el MPI debe inicializarse antes de la ejecución y finalizarse después de la ejecución.

A continuación, especifique el modo de ejecución mediante la configuración de `execution=cudaq.parallel.mpi`. El siguiente fragmento de código muestra estos cambios.

```
cudaq.set_target("nvidia", option="mqpu")
cudaq.mpi.initialize()
result = cudaq.observe(
    kernel, hamiltonian, shots_count=n_shots, execution=cudaq.parallel.mpi
)
cudaq.mpi.finalize()
```

En el `hybrid_job` decorador, especifique un tipo de instancia que aloje múltiples GPUs , como se muestra en el siguiente fragmento de código.

```
@hybrid_job(
    device="local:nvidia/nvidia-mqpu",
    instance_config=InstanceConfig(instanceType="ml.g4dn.12xlarge", instanceCount=1),
    image_uri=image_uri,
)
def parallel_observables_gpu_job(sagemaker_mpi_enabled=True):
    ...
```

El [cuaderno de simulaciones paralelas](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/nvidia_cuda_q/5_Multiple_GPU_simulations.ipynb) de Amazon Braket, Github, proporciona end-to-end ejemplos que demuestran cómo ejecutar simulaciones de programas cuánticos en backends de GPU y realizar simulaciones paralelas de observables y lotes de circuitos.

### Ejecución de sus cargas de trabajo en computadoras cuánticas
<a name="braket-using-cuda-q-quantum"></a>

Tras completar las pruebas con el simulador, puede pasar a la ejecución de experimentos en él QPUs. Simplemente cambie el destino a una QPU de Amazon Braket, como los dispositivos IQM, IonQ o Rigetti. El siguiente fragmento de código ilustra cómo establecer el objetivo en el dispositivo IQM Garnet. Para ver una lista de las disponibles QPUs, consulta la [consola Amazon Braket](https://console.aws.amazon.com/braket/home).

```
device_arn = "arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet"
cudaq.set_target("braket", machine=device_arn)
```

Para obtener más información sobre trabajos híbridos, consulte [Trabajar con trabajos híbridos de Amazon Braket](braket-jobs.md) en la guía para desarrolladores. Para obtener más información sobre CUDA-Q, consulte la [documentación de NVIDIA CUDA-Q](https://nvidia.github.io/cuda-quantum/latest/index.html).