

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Trabalhando com o Amazon Braket Hybrid Jobs
<a name="braket-jobs"></a>

O Amazon Braket Hybrid Jobs oferece uma maneira de você executar algoritmos clássicos quânticos híbridos que exigem recursos AWS clássicos e unidades de processamento quântico (). QPUs O Hybrid Jobs foi projetado para ativar os recursos clássicos solicitados, executar seu algoritmo e liberar as instâncias após a conclusão, para que você *pague apenas pelo que usar*. 

O Hybrid Jobs é ideal para algoritmos iterativos de longa duração que envolvem o uso de recursos de computação clássica e recursos de computação quântica. Com o Hybrid Jobs, depois de enviar seu algoritmo para execução, o Braket executará seu algoritmo em um ambiente escalável e em contêineres. Depois que o algoritmo for concluído, você poderá recuperar os resultados.

Além disso, as tarefas quânticas criadas a partir de um trabalho híbrido se beneficiam do enfileiramento de maior prioridade no dispositivo QPU de destino. Essa priorização garante que seus cálculos quânticos sejam processados e executados antes de outras tarefas que aguardam na fila. Isso é particularmente vantajoso para algoritmos híbridos iterativos, nos quais os resultados de uma tarefa quântica dependem dos resultados de tarefas quânticas anteriores. Exemplos desses algoritmos incluem o [Algoritmo de Otimização Aproximada Quântica (QAOA)](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_quantum_algorithms/QAOA/QAOA_braket.ipynb), o [autosolucionador quântico variacional](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_quantum_algorithms/VQE_Chemistry/VQE_chemistry_braket.ipynb) ou o [machine learning quântico](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). Você também pode monitorar o progresso do algoritmo quase em tempo real, permitindo que você acompanhe os custos, o orçamento ou as métricas personalizadas, como perda de treinamento ou valores esperados. 

Você pode acessar trabalhos híbridos no Braket usando:
+ O [SDK Amazon Braket Python](https://github.com/aws/amazon-braket-sdk-python).
+ O [console Amazon Braket](https://console.aws.amazon.com/braket/home).
+ O Amazon Braket API.

**Topics**
+ [Quando usar o Amazon Braket Hybrid Jobs](#braket-jobs-use)
+ [Executando um trabalho híbrido com o Amazon Braket Hybrid Jobs](#braket-jobs-works)
+ [Conceitos principais do Hybrid Jobs](braket-jobs-concepts.md)
+ [Pré-requisitos](braket-jobs-prerequisites.md)
+ [Criar um trabalho híbrido](braket-jobs-first.md)
+ [Cancelar um Hybrid Job](braket-jobs-cancel.md)
+ [Personalizar seu Hybrid Job](braket-jobs-customize.md)
+ [Usando PennyLane com o Amazon Braket](hybrid.md)
+ [Usando o CUDA-Q com o Amazon Braket](braket-using-cuda-q.md)

## Quando usar o Amazon Braket Hybrid Jobs
<a name="braket-jobs-use"></a>

 O Amazon Braket Hybrid Jobs permite que você execute algoritmos clássicos quânticos híbridos, como o Variational Quantum Eigensolver (VQE) e o Quantum Approximate Optimization Algorithm (QAOA), que combinam recursos computacionais clássicos com dispositivos de computação quântica para otimizar o desempenho dos sistemas quânticos atuais. O Amazon Braket Hybrid Jobs oferece três benefícios principais:

1.  **Desempenho**: o Amazon Braket Hybrid Jobs oferece melhor desempenho do que executar algoritmos híbridos em seu próprio ambiente. Enquanto seu trabalho está em execução, ele tem acesso prioritário à QPU de destino selecionada. As tarefas do seu trabalho são executadas antes de outras tarefas enfileiradas no dispositivo. Isso resulta em runtimes mais curtos e previsíveis para algoritmos híbridos. O Amazon Braket Hybrid Jobs também oferece suporte à compilação paramétrica. Você pode enviar um circuito usando parâmetros livres e o Braket compila o circuito uma vez, sem a necessidade de recompilar para atualizações subsequentes de parâmetros no mesmo circuito, resultando em runtimes ainda mais rápidos.

1.  **Conveniência**: o Amazon Braket Hybrid Jobs simplifica a configuração e o gerenciamento do seu ambiente computacional e o mantém em execução enquanto seu algoritmo híbrido é executado. Basta fornecer seu script de algoritmo e selecionar um dispositivo quântico (uma unidade de processamento quântico ou um simulador) no qual executar. O Amazon Braket espera que o dispositivo de destino fique disponível, acelera os recursos clássicos, executa a workload em ambientes de contêineres pré-criados, retorna os resultados para o Amazon Simple Storage Service (Amazon S3) e libera os recursos computacionais.

1.  **Métricas**: o Amazon Braket Hybrid Jobs on-the-fly fornece informações sobre a execução de algoritmos e fornece métricas de algoritmo personalizáveis quase em tempo real para a Amazon e para CloudWatch o console Amazon Braket, para que você possa acompanhar o progresso de seus algoritmos.

## Executando um trabalho híbrido com o Amazon Braket Hybrid Jobs
<a name="braket-jobs-works"></a>

Para executar um trabalho híbrido com o Amazon Braket Hybrid Jobs, primeiro você precisa definir seu algoritmo. Você pode defini-lo escrevendo o *script do algoritmo* e, opcionalmente, outros arquivos de dependência usando o [Amazon Braket](https://github.com/aws/amazon-braket-sdk-python) Python SDK ou. [PennyLane](https://pennylane.ai) Se quiser usar outras bibliotecas (de código aberto ou proprietárias), você pode definir sua própria imagem de contêiner personalizada usando o Docker, que inclui essas bibliotecas. Para obter mais informações, consulte [Trazer seu próprio contêiner (BYOC)](braket-jobs-byoc.md).

Em ambos os casos, em seguida, você cria um trabalho híbrido usando o Amazon Braket API, onde você fornece seu script ou contêiner de algoritmo, seleciona o dispositivo quântico de destino que o trabalho híbrido deve usar e, em seguida, escolhe entre uma variedade de configurações opcionais. Os valores padrão fornecidos para essas configurações opcionais funcionam na maioria dos casos de uso. Para que o dispositivo de destino execute seu Hybrid Job, você pode escolher entre uma QPU, um simulador sob demanda (como SV1, DM1 ou TN1) ou a própria instância de trabalho híbrida clássica. Com um simulador sob demanda ou QPU, seu contêiner de tarefas híbrido faz chamadas de API para um dispositivo remoto. Com os simuladores incorporados, o simulador é incorporado no mesmo contêiner do seu script de algoritmo. Os [simuladores de relâmpagos](https://github.com/PennyLaneAI/pennylane-lightning) do PennyLane são incorporados ao contêiner de trabalhos híbrido pré-construído padrão para você usar. Se você executar seu código usando um PennyLane simulador incorporado ou personalizado, poderá especificar um tipo de instância e quantas instâncias deseja usar. Consulte a página de [Preços do Amazon Braket](https://aws.amazon.com/braket/pricing/) para ver os custos associados a cada opção.

![\[Diagrama de fluxograma mostrando as interações do usuário com componentes, API, instância de trabalho e simuladores do Amazon Braket para tarefas híbridas, de QPU, sob demanda e incorporadas. Os resultados são armazenados no bucket do Amazon Simple Storage Service e analisados usando a Amazon CloudWatch no console Amazon Braket.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-hybrid-job-run.png)


Se seu dispositivo de destino for um simulador sob demanda ou incorporado, o Amazon Braket começará a executar a tarefa híbrida imediatamente. Ele ativa a instância de trabalho híbrida (você pode personalizar o tipo de instância na chamada API), executa seu algoritmo, grava os resultados no Amazon S3 e libera seus recursos. Essa liberação de recursos garante que você pague apenas pelo que usar.

O número total de trabalhos híbridos simultâneos por unidade de processamento quântico (QPU) é restrito. Atualmente, somente uma tarefa híbrida pode ser executada em uma QPU a qualquer momento. As filas são usadas para controlar o número de trabalhos híbridos que podem ser executados de forma a não exceder o limite permitido. Se o dispositivo de destino for uma QPU, sua tarefa híbrida primeiro entrará na *fila de tarefas* da QPU selecionada. O Amazon Braket cria a instância de trabalho híbrida necessária e executa sua tarefa híbrida no dispositivo. Durante a duração do seu algoritmo, sua tarefa híbrida tem acesso prioritário, o que significa que as tarefas quânticas de sua tarefa híbrida são executadas antes de outras tarefas quânticas do Braket enfileiradas no dispositivo, desde que as tarefas quânticas da tarefa sejam enviadas à QPU uma vez a cada poucos minutos. Quando o trabalho híbrido é concluído, os recursos são liberados, o que significa que você paga apenas pelo que usa.

**nota**  
Os dispositivos são regionais e sua tarefa híbrida é executada da Região da AWS mesma forma que seu dispositivo principal.

Tanto no simulador quanto nos cenários de destino da QPU, você tem a opção de definir métricas personalizadas do algoritmo, como a energia do seu hamiltoniano, como parte do seu algoritmo. Essas métricas são automaticamente reportadas à Amazon CloudWatch e, a partir daí, são exibidas quase em tempo real no console do Amazon Braket.

**nota**  
Se você quiser usar uma instância baseada em GPU, certifique-se de usar um dos simuladores baseados em GPU disponíveis com os simuladores incorporados no Braket (por exemplo, `lightning.gpu`). Se você escolher um dos simuladores incorporados baseados em CPU (por exemplo, `lightning.qubit` ou `braket:default-simulator`), a GPU não será usada e você poderá incorrer em custos desnecessários.

# Conceitos principais do Hybrid Jobs
<a name="braket-jobs-concepts"></a>

Esta seção explica os principais conceitos da função `AwsQuantumJob.create` fornecida pelo SDK do Amazon Braket Python e o mapeamento para a estrutura do arquivo de contêiner.

Além do arquivo ou arquivos que compõem seu script de algoritmo completo, sua tarefa híbrida pode ter entradas e saídas adicionais. Quando sua tarefa híbrida é iniciada, o Amazon Braket copia as entradas fornecidas como parte da criação da tarefa híbrida no contêiner que executa o script do algoritmo. Quando o trabalho híbrido é concluído, todas as saídas definidas durante o algoritmo são copiadas para o local especificado no Amazon S3.

**nota**  
 As *métricas do algoritmo* são relatadas em tempo real e não seguem esse procedimento de saída.

O Amazon Braket também fornece várias variáveis de ambiente e funções auxiliares para simplificar as interações com entradas e saídas de contêineres. Para obter mais informações, consulte o [pacote braket.jobs](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.jobs.html) no *Amazon Braket SDK*. 

**Topics**
+ [Entradas](#braket-jobs-inputs)
+ [Saídas](#braket-jobs-outputs)
+ [Variáveis de ambiente](#braket-jobs-environmental-variables)
+ [funções auxiliares](#braket-jobs-helper-functions)

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

 **Dados de entrada**: os dados de entrada podem ser fornecidos ao algoritmo híbrido especificando o arquivo de dados de entrada, que é configurado como um dicionário, com o argumento `input_data`. O usuário define o argumento `input_data` dentro da função `AwsQuantumJob.create` no SDK. Isso copia os dados de entrada para o sistema de arquivos do contêiner no local fornecido pela variável de ambiente `"AMZN_BRAKET_INPUT_DIR"`. Para ver alguns exemplos de como os dados de entrada são usados em um algoritmo híbrido, consulte [QAOA com Amazon Braket Hybrid Jobs PennyLane [e Quantum machine learning nos notebooks Amazon Braket Hybrid 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)](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).

**nota**  
Quando os dados de entrada forem grandes (>1 GB), haverá um longo tempo de espera até que o trabalho híbrido seja enviado. Isso se deve ao fato de que os dados de entrada locais serão primeiro carregados em um bucket do S3, depois o caminho do S3 será adicionado à solicitação de trabalho híbrida e, por fim, a solicitação de trabalho híbrida será enviada ao serviço Braket.

 **Hiperparâmetros**: se você passar os `hyperparameters`, eles estarão disponíveis na variável de ambiente `"AMZN_BRAKET_HP_FILE"`.

**nota**  
Para obter mais informações sobre como criar hiperparâmetros e dados de entrada e, em seguida, passar essas informações para o script de trabalho híbrido, consulte a seção [Usar hiperparâmetros](braket-jobs-hyperparameters.md) e esta [página do GitHub](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).

 **Pontos de verificação**: Para especificar um ponto de verificação `job-arn` cujo você deseja usar em um novo trabalho híbrido, use o comando `copy_checkpoints_from_job`. Esse comando copia os dados do ponto de verificação `checkpoint_configs3Uri` para o novo trabalho híbrido, disponibilizando-os no caminho fornecido pela variável de ambiente `AMZN_BRAKET_CHECKPOINT_DIR` enquanto o trabalho é executado. O padrão é `None`, o que significa que os dados do ponto de verificação de outro trabalho híbrido não serão usados no novo trabalho híbrido.

## Saídas
<a name="braket-jobs-outputs"></a>

 **Tarefas quânticas**: os resultados das tarefas quânticas são armazenados no local `s3://amazon-braket-<region>-<accountID>/jobs/<job-name>/tasks` do S3.

 **Resultados do trabalho**: tudo o que seu script de algoritmo salva no diretório fornecido pela variável de ambiente `"AMZN_BRAKET_JOB_RESULTS_DIR"` é copiado para o local do S3 especificado em `output_data_config`. Se o valor não for especificado, o padrão será. `s3://amazon-braket-<region>-<accountID>/jobs/<job-name>/<timestamp>/data` Fornecemos a função auxiliar do SDK **`save_job_result`**, que você pode usar para armazenar resultados convenientemente na forma de um dicionário quando chamada a partir do seu script de algoritmo.

 **Pontos de verificação**: Se você quiser usar pontos de verificação, poderá salvá-los no diretório fornecido pela variável de ambiente `"AMZN_BRAKET_CHECKPOINT_DIR"`. Você também pode usar `save_job_checkpoint` para invocar a função.

 **Métricas de algoritmo**: você pode definir métricas de algoritmo como parte do seu script de algoritmo que são emitidas para a Amazon CloudWatch e exibidas em tempo real no console do Amazon Braket enquanto sua tarefa híbrida está em execução. Para obter um exemplo de como usar métricas de algoritmo, consulte [Usar Amazon Braket Hybrid Jobs para executar um algoritmo QAOA](braket-jobs-run-qaoa-algorithm.md).

Para obter mais informações sobre como salvar suas saídas de trabalho, consulte [Salvar seus resultados](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-first.html#braket-jobs-save-results) na documentação do Hybrid Jobs. 

## Variáveis de ambiente
<a name="braket-jobs-environmental-variables"></a>

O Amazon Braket fornece várias variáveis de ambiente para simplificar as interações com entradas e saídas de contêineres. O código a seguir lista as variáveis ambientais que Braket usa.
+ `AMZN_BRAKET_INPUT_DIR`— O diretório de dados de entradaopt/braket/input/data.
+ `AMZN_BRAKET_JOB_RESULTS_DIR`— O diretório de saída no opt/braket/model qual gravar os resultados do trabalho.
+ `AMZN_BRAKET_JOB_NAME`: o nome do trabalho.
+ `AMZN_BRAKET_CHECKPOINT_DIR`— O diretório do ponto de verificação.
+ `AMZN_BRAKET_HP_FILE`— O arquivo contendo os hiperparâmetros.
+ `AMZN_BRAKET_DEVICE_ARN`— O ARN (nome do AWS recurso) do dispositivo.
+ `AMZN_BRAKET_OUT_S3_BUCKET`— O bucket de saída do Amazon S3, conforme especificado na solicitação `CreateJob` do `OutputDataConfig`.
+ `AMZN_BRAKET_SCRIPT_ENTRY_POINT`— O ponto de entrada, conforme especificado na solicitação `CreateJob` do `ScriptModeConfig`.
+ `AMZN_BRAKET_SCRIPT_COMPRESSION_TYPE`— O tipo de compressão conforme especificado na solicitação `CreateJob` do `ScriptModeConfig`.
+ `AMZN_BRAKET_SCRIPT_S3_URI`— A localização do script do usuário no Amazon S3, conforme especificado na solicitação `CreateJob` do `ScriptModeConfig`.
+ `AMZN_BRAKET_TASK_RESULTS_S3_URI`— O local do Amazon S3 em que o SDK armazenaria os resultados da tarefa quântica por padrão para o trabalho.
+ `AMZN_BRAKET_JOB_RESULTS_S3_PATH`— O local do Amazon S3 onde os resultados do trabalho seriam armazenados, conforme especificado na solicitação `CreateJob` do `OutputDataConfig`.
+ `AMZN_BRAKET_JOB_TOKEN`— A string que deve ser passada para o parâmetro `jobToken` do `CreateQuantumTask` para tarefas quânticas criadas no contêiner de tarefas.

## funções auxiliares
<a name="braket-jobs-helper-functions"></a>

O Amazon Braket fornece várias funções auxiliares para simplificar as interações com entradas e saídas de contêineres. Essas funções auxiliares seriam chamadas de dentro do script de algoritmo usado para executar seu Hybrid Job. O exemplo a seguir demonstra como utilizá-las.

```
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
```

# Pré-requisitos
<a name="braket-jobs-prerequisites"></a>

Antes de executar a primeira tarefa híbrida, você deverá garantir que tenha permissões suficientes para realizar essa tarefa. Para determinar se você tem as permissões corretas, selecione **Permissões** no menu à esquerda do console Braket. A página **Gerenciamento de permissões para Amazon Braket** ajuda você a verificar se uma de suas funções existentes tem permissões suficientes para executar seu trabalho híbrido ou orienta você na criação de uma função padrão que pode ser usada para executar seu trabalho híbrido, caso você ainda não tenha essa função.

![\[Página de permissões e configurações do serviço Amazon Braket mostrando uma função vinculada ao serviço e a opção de verificar funções existentes para a função de execução de trabalhos híbridos.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-permissions.png)


Para verificar se você tem funções com permissões suficientes para executar um trabalho híbrido, selecione o botão **Verificar função existente**. Quando usa, você obtém uma mensagem de que as funções foram encontradas. Para ver os nomes das funções e suas funções ARNs, selecione o botão **Mostrar funções**.

![\[Tela de permissões e configurações do Amazon Braket mostrando uma função vinculada ao serviço encontrada e funções existentes com permissões suficientes para executar trabalhos híbridos.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-yes.png)


Se você não tiver uma função com permissões suficientes para executar uma tarefa híbrida, você receberá uma mensagem informando que essa função não foi encontrada. Selecione o botão **Criar função padrão** para obter uma função com permissões suficientes.

![\[Página de permissões e configurações do Amazon Braket mostrando a função vinculada ao serviço encontrada e nenhuma função de execução de trabalhos híbridos encontrada.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-no.png)


Se a função foi criada com sucesso, você receberá uma mensagem confirmando isso.

![\[Página de permissões e configurações do Amazon Braket mostrando uma função vinculada ao serviço encontrada e uma função de execução de trabalhos híbridos criada com sucesso.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-permissions-verify-created.png)


Se você não tiver permissão para fazer essa consulta, seu acesso será negado. Nesse caso, entre em contato com seu AWS administrador interno.

![\[AccessDenied mensagem de erro indicando que o usuário não está autorizado a realizar iam: ListAttachedRolePolicies on an AmazonBraketJobsExecutionRole com uma negação explícita.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-permissions-access-denied.png)


# Criar um trabalho híbrido
<a name="braket-jobs-first"></a>

 Esta seção mostra como criar um Hybrid Job usando um script do Python. Como alternativa, para criar um trabalho híbrido a partir do código Python local, como seu ambiente de desenvolvimento integrado (IDE) preferido ou um caderno do Braket, consulte [Execute seu código local como um trabalho híbrido](braket-hybrid-job-decorator.md).

**Topics**
+ [Criar e executar](#braket-jobs-first-create)
+ [Monitorar resultados](#braket-jobs-first-monitor-results)
+ [Salve seus resultados](#braket-jobs-save-results)
+ [Usando pontos de verificação](#braket-jobs-checkpoints)
+ [Execute seu código local como um trabalho híbrido](braket-hybrid-job-decorator.md)
+ [Usando a API com trabalhos híbridos](braket-jobs-api.md)
+ [Crie e depure uma tarefa híbrida com o modo local](braket-jobs-local-mode.md)

## Criar e executar
<a name="braket-jobs-first-create"></a>

Depois de ter um perfil com permissões para executar um trabalho híbrido, você estará pronto para continuar. A peça-chave do seu primeiro trabalho híbrido do Braket é o *script do algoritmo*. Ele define o algoritmo que você deseja executar e contém a lógica clássica e as tarefas quânticas que fazem parte do seu algoritmo. Além do script do algoritmo, você pode fornecer outros arquivos de dependência. O script do algoritmo, junto com suas dependências, é chamado de *módulo de origem*. O *ponto de entrada* define o primeiro arquivo ou função a ser executado em seu módulo de origem quando o trabalho híbrido é iniciado.

![\[Diagrama mostrando o fluxo de trabalho de criar um trabalho quântico usando um console ou notebook, executando o script do algoritmo em um dispositivo quântico e analisando os resultados.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-workflow.jpg)


Primeiro, considere o seguinte exemplo básico de um script de algoritmo que cria cinco estados de sino e imprime os resultados de medição correspondentes.

```
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!")
```

Salve esse arquivo com o nome *algorithm\$1script.py* em seu diretório de trabalho atual no notebook Braket ou no ambiente local. O arquivo algorithm\$1script.py tem `start_here()` como ponto de entrada planejado.

Em seguida, crie um arquivo Python ou um caderno Python no mesmo diretório do arquivo algorithm\$1script.py. Esse script inicia o trabalho híbrido e processa qualquer processamento assíncrono, como imprimir o status ou os principais resultados nos quais estamos interessados. No mínimo, esse script precisa especificar seu script de trabalho híbrido e seu dispositivo principal.

**nota**  
Para obter mais informações sobre como criar um caderno Braket ou fazer upload de um arquivo, como o arquivo *algorithm\$1script.py*, no mesmo diretório dos cadernos, consulte [Executar seu primeiro circuito usando o Amazon Braket Python SDK](braket-get-started-run-circuit.md). 

Para esse primeiro caso básico, você escolhe um simulador. Qualquer que seja o tipo de dispositivo quântico que você almeje, um simulador ou uma unidade de processamento quântico (QPU) real, o dispositivo especificado com `device` no script a seguir é usado para agendar a tarefa híbrida e está disponível para os scripts do algoritmo como a variável de ambiente `AMZN_BRAKET_DEVICE_ARN`.

**nota**  
Você só pode usar dispositivos que estejam disponíveis no Região da AWS seu trabalho híbrido. O Amazon Braket SDK seleciona automaticamente a Região da AWS. Por exemplo, uma tarefa híbrida em us-east-1 pode usar dispositivos IonQ, SV1, DM1, e TN1, mas não Rigetti.

Se você escolher um computador quântico em vez de um simulador, o Braket agenda seus trabalhos híbridos para executar todas as tarefas quânticas com acesso prioritário.

```
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
)
```

O parâmetro `wait_until_complete=True` define um modo detalhado para que seu trabalho imprima a saída do trabalho real enquanto ele está sendo executado. Você deverá ver uma saída semelhante ao exemplo a seguir.

```
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**  
Você também pode usar seu módulo personalizado com o [AwsQuantumJobmétodo.create](https://amazon-braket-sdk-python.readthedocs.io/en/latest/_apidoc/braket.aws.aws_quantum_job.html#braket.aws.aws_quantum_job.AwsQuantumJob.create) passando sua localização (o caminho para um diretório ou arquivo local ou um URI do S3 de um arquivo tar.gz). Para um exemplo prático, consulte o arquivo [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) na pasta hybrid jobs do [repositório de exemplos do Amazon Braket no Github](https://github.com/amazon-braket/amazon-braket-examples/tree/main).

## Monitorar resultados
<a name="braket-jobs-first-monitor-results"></a>

Como alternativa, você pode acessar a saída do log da Amazon CloudWatch. Para fazer isso, acesse a guia **Grupos de logs** no menu esquerdo da página de detalhes do trabalho, selecione o grupo de logs `aws/braket/jobs` e escolha o fluxo de logs que contém o nome do trabalho. No exemplo acima, ele é `braket-job-default-1631915042705/algo-1-1631915190`.

![\[CloudWatch grupo de registros mostrando uma lista de eventos de log com caminhos de arquivo e registros de data e hora para testes do SDK Python do Amazon Braket.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-cw-log.png)


Você também pode visualizar o status do trabalho híbrido no console selecionando a página **Trabalhos híbridos** e, em seguida, escolhendo **Configurações**.

![\[Detalhes do trabalho híbrido do Amazon Braket, incluindo resumo, horários dos eventos, código-fonte, configuração da instância e condições de parada.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-jobs-first-console-status.png)


Seu trabalho híbrido produz alguns artefatos no Amazon S3 enquanto é executado. O nome padrão do bucket do S3 é `amazon-braket-<region>-<accountid>` e o conteúdo está no diretório `jobs/<jobname>/<timestamp>`. Você pode configurar os locais do S3 em que esses artefatos são armazenados especificando um `code_location` diferente quando a tarefa híbrida é criada com o SDK Braket Python.

**nota**  
Esse bucket do S3 deve estar localizado da Região da AWS mesma forma que seu script de trabalho.

O diretório `jobs/<jobname>/<timestamp>` contém uma subpasta com a saída do script do ponto de entrada em um arquivo `model.tar.gz`. Também há um diretório chamado `script` que contém os artefatos do script do algoritmo em um `source.tar.gz` arquivo. Os resultados de suas tarefas quânticas reais estão no diretório nomeado `jobs/<jobname>/tasks`.

## Salve seus resultados
<a name="braket-jobs-save-results"></a>

Você pode salvar os resultados gerados pelo script do algoritmo para que estejam disponíveis no objeto de trabalho híbrido no script de trabalho híbrido, bem como na pasta de saída no Amazon S3 (em um arquivo compactado em tar chamado model.tar.gz).

A saída deve ser salva em um arquivo usando o formato JavaScript Object Notation (JSON). Se os dados não puderem ser prontamente serializados em texto, como no caso de uma matriz numérica, você poderá passar uma opção para serializar usando um formato de dados em conserva. Consulte o 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 obter mais detalhes.

Para salvar os resultados das tarefas híbridas, adicione as seguintes linhas comentadas com \$1ADD ao arquivo 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!")
```

Em seguida, você pode exibir os resultados do trabalho a partir do seu script de trabalho anexando a linha ** `print(job.result())` ** comentada com \$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
```

Neste exemplo, removemos `wait_until_complete=True` para suprimir a saída detalhada. Você pode adicioná-lo novamente para depuração. Quando você executa essa tarefa híbrida, ela gera o identificador e o `job-arn`, seguidos pelo estado da tarefa híbrida a cada 10 segundos até que a tarefa híbrida chegue a `COMPLETED`, após o qual mostra os resultados do circuito da campainha. Veja o exemplo a seguir.

```
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}]}
```

## Usando pontos de verificação
<a name="braket-jobs-checkpoints"></a>

Você pode salvar iterações intermediárias de seus trabalhos híbridos usando pontos de verificação. No exemplo de script de algoritmo da seção anterior, você adicionaria as seguintes linhas comentadas com \$1ADD para criar arquivos de ponto de verificação.

```
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!")
```

Ao executar o trabalho híbrido, o arquivo *<jobname>-checkpoint-1.json* é criado nos artefatos do trabalho híbrido, no diretório de checkpoints, com um caminho padrão `/opt/jobs/checkpoints`. O script de trabalho híbrido permanece inalterado, a menos que você queira alterar esse caminho padrão.

Se você quiser carregar uma tarefa híbrida a partir de um ponto de verificação gerado por uma tarefa híbrida anterior, o script do algoritmo usa `from braket.jobs import load_job_checkpoint`. A lógica a ser carregada em seu script de algoritmo é a seguinte.

```
from braket.jobs import load_job_checkpoint

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

Depois de carregar esse ponto de verificação, você pode continuar sua lógica com base no conteúdo carregado no `checkpoint-1`.

**nota**  
O *checkpoint\$1file\$1suffix* deve corresponder ao sufixo especificado anteriormente ao criar o ponto de verificação.

Seu script de orquestração precisa especificar o `job-arn` do trabalho híbrido anterior com a linha comentada com \$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
    )
```

# Execute seu código local como um trabalho híbrido
<a name="braket-hybrid-job-decorator"></a>

O Amazon Braket Hybrid Jobs fornece uma orquestração totalmente gerenciada de algoritmos clássicos quânticos híbridos, combinando recursos computacionais do Amazon EC2 com o acesso à Amazon Braket Quantum Processing Unit (QPU). As tarefas quânticas criadas em um trabalho híbrido têm prioridade na fila em relação às tarefas quânticas individuais, para que seus algoritmos não sejam interrompidos por flutuações na fila de tarefas quânticas. Cada QPU mantém uma fila de trabalhos híbridos separada, garantindo que somente um trabalho híbrido possa ser executado a qualquer momento.

**Topics**
+ [Crie um trabalho híbrido a partir do código Python local](#create-hybrid-job-from-local-python-code)
+ [Instale pacotes e código-fonte adicionais do Python](#install-python-packages-and-code)
+ [Salvar e carregar dados em uma instância de trabalho híbrida](#save-load-data-into-instance)
+ [Práticas recomendadas para decoradores de trabalhos híbridos](#best-practices)

## Crie um trabalho híbrido a partir do código Python local
<a name="create-hybrid-job-from-local-python-code"></a>

Você pode executar seu código Python local como um Amazon Braket Hybrid Job. Você pode fazer isso anotando seu código com um decorador `@hybrid_job`, como mostrado no exemplo de código a seguir. Para ambientes personalizados, você pode optar por [usar um contêiner personalizado](braket-jobs-byoc.md) do Amazon Elastic Container Registry (ECR). 

**nota**  
Somente o Python 3.12 é suportado por padrão.

 Você pode usar o decorador `@hybrid_job` para anotar uma função. O Braket transforma o código dentro do decorador em um [script de algoritmo](braket-jobs-first.md) de trabalho híbrido do Braket. O trabalho híbrido então invoca a função dentro do decorador em uma instância do Amazon EC2. É possível monitorar o progresso do trabalho com `job.state()` ou com o console Braket. O exemplo de código a seguir mostra como executar uma sequência de cinco estados no 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}
```

Você cria o trabalho híbrido invocando a função como faria com as funções normais do Python. No entanto, a função decoradora retorna o identificador de trabalho híbrido em vez do resultado da função. Para recuperar os resultados após a conclusão, use `job.result()`. 

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

O argumento do dispositivo no `@hybrid_job` decorador especifica o dispositivo ao qual a tarefa híbrida tem acesso prioritário - nesse caso, o simulador SV1. Para obter prioridade de QPU, você deve garantir que o ARN do dispositivo usado na função corresponda ao especificado no decorador. Por conveniência, você pode usar a função auxiliar `get_job_device_arn()` para capturar o ARN do dispositivo declarado em `@hybrid_job`. 

**nota**  
Cada trabalho híbrido tem um tempo de inicialização de pelo menos um minuto, pois cria um ambiente em contêineres no Amazon EC2. Portanto, para workloads muito curtas, como um único circuito ou um lote de circuitos, pode ser suficiente usar tarefas quânticas.

**Hiperparâmetros** 

A função `run_hybrid_job()` usa o argumento `num_tasks` para controlar o número de tarefas quânticas criadas. A tarefa híbrida captura isso automaticamente como um [hiperparâmetro](braket-jobs-hyperparameters.md).

**nota**  
Os hiperparâmetros são exibidos no console do Braket como sequências de caracteres, limitadas a 2500 caracteres. 

**Métricas e log** 

Dentro da função `run_hybrid_job()`, métricas de algoritmos iterativos são registradas com `log_metrics`. As métricas são plotadas automaticamente na página do console do Braket, na guia de tarefas híbridas. Você pode usar métricas para rastrear os custos quânticos da tarefa quase em tempo real durante a execução do trabalho híbrido com o rastreador de custos [Braket](braket-pricing.md). O exemplo acima usa o nome da métrica “probabilidade” que registra a primeira probabilidade do [tipo de resultado](braket-result-types.md).

**Recuperando resultados** 

Depois que a tarefa híbrida for concluída, você usará `job.result()` para recuperar os resultados da tarefa híbrida. Todos os objetos na declaração de retorno são automaticamente capturados pelo Braket. Observe que os objetos retornados pela função devem ser uma tupla com cada elemento sendo serializável. Por exemplo, o código a seguir mostra um exemplo de funcionamento e um de falha. 

```
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
```

**Nome do trabalho** 

Por padrão, o nome desse trabalho híbrido é inferido do nome da função. Você também pode especificar um nome personalizado com até 50 caracteres. Por exemplo, no código a seguir, o nome do trabalho é "my-job-name”.

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

**Modo local** 

Os [trabalhos locais](braket-jobs-local-mode.md) são criados adicionando o argumento `local=True` ao decorador. Isso executa a tarefa híbrida em um ambiente conteinerizado em seu ambiente de computação local, como seu laptop. Os trabalhos locais **não têm** fila prioritária para tarefas quânticas. Para casos avançados, como vários nós ou MPI, as tarefas locais podem ter acesso às variáveis de ambiente Braket necessárias. O código a seguir cria uma tarefa híbrida local com o dispositivo como SV1 simulador. 

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

Todas as outras opções de trabalhos híbrida são compatíveis. Para obter uma lista de opções, consulte o módulo [braket.jobs.quantum\$1job\$1creation](https://amazon-braket-sdk-python.readthedocs.io/en/stable/_apidoc/braket.jobs.quantum_job_creation.html). 

## Instale pacotes e código-fonte adicionais do Python
<a name="install-python-packages-and-code"></a>

Você pode personalizar seu ambiente de runtime para usar seus pacotes Python preferidos. Você pode usar um arquivo `requirements.txt`, uma lista de nomes de pacotes ou [trazer seu próprio contêiner (BYOC)](braket-jobs-byoc.md). Por exemplo, o arquivo `requirements.txt` pode incluir outros pacotes para instalação.

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

Para personalizar um ambiente de runtime usando um arquivo `requirements.txt`, consulte o exemplo de código a seguir.

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

Como alternativa, você pode fornecer os nomes dos pacotes como uma lista do Python da seguinte maneira.

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

O código-fonte adicional pode ser especificado como uma lista de módulos ou como um único módulo, como no exemplo de código a seguir. 

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

## Salvar e carregar dados em uma instância de trabalho híbrida
<a name="save-load-data-into-instance"></a>

**Especificando dados de treinamento de entrada**

Ao criar um trabalho híbrido, será possível fornecer uma entrada de conjuntos de dados de treinamento especificando um bucket do Amazon Simple Storage Service (Amazon S3). Você também pode especificar um caminho local e, em seguida, o Braket carrega automaticamente os dados para o Amazon S3 em `s3://<default_bucket_name>/jobs/<job_name>/<timestamp>/data/<channel_name>`. Se você especificar um caminho local, o nome do canal será padronizado como “entrada”. O código a seguir mostra um arquivo numpy do caminho `data/file.npy` local. 

```
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 o S3, você deve usar a função 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")
```

Você pode especificar várias fontes de dados de entrada fornecendo um dicionário de valores de canais e caminhos S3 URIs ou locais. 

```
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**  
Quando os dados de entrada são grandes (>1 GB), há um longo tempo de espera até que a tarefa seja criada. Isso se deve aos dados de entrada locais quando eles são carregados pela primeira vez em um bucket do S3 e, em seguida, o caminho do S3 é adicionado à solicitação de trabalho. Finalmente, a solicitação de trabalho é enviada ao serviço Braket.

**Salvando resultados no S3**

Para salvar resultados não incluídos na instrução de retorno da função decorada, você deve acrescentar o diretório correto a todas as operações de gravação de arquivos. O exemplo a seguir mostra como salvar uma matriz numérica e uma figura 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 os resultados são compactados em um arquivo chamado `model.tar.gz`. Você pode baixar os resultados com a função `job.result()` do Python ou navegando até a pasta de resultados na página de trabalhos híbridos no console de gerenciamento do Braket. 

**Salvando e retomando a partir dos pontos de verificação**

Para trabalhos híbridos de longa duração, é recomendável salvar periodicamente o estado intermediário do algoritmo. Você pode usar a função auxiliar `save_job_checkpoint()` integrada ou salvar arquivos no caminho `AMZN_BRAKET_JOB_RESULTS_DIR`. O último está disponível com a função auxiliar `get_job_results_dir()`.

Veja a seguir um exemplo prático mínimo para salvar e carregar pontos de verificação com um decorador de tarefas 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()
```

No primeiro trabalho híbrido, `save_job_checkpoint()` é chamado com um dicionário contendo os dados que queremos salvar. Por padrão, cada valor deve ser serializável como texto. Para verificar objetos Python mais complexos, como matrizes numpy, você pode definir `data_format = PersistedJobDataFormat.PICKLED_V4`. Esse código cria e sobrescreve um arquivo de ponto de verificação com nome padrão `<jobname>.json` em seus artefatos de trabalho híbridos em uma subpasta chamada “pontos de verificação”.

Para criar um novo trabalho híbrido para continuar a partir do posto de controle, precisamos informar `copy_checkpoints_from_job=job_arn` onde `job_arn` é o ARN do trabalho híbrido do trabalho anterior. Em seguida, usamos `load_job_checkpoint(job_name)` para carregar a partir do ponto de verificação.

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

**Adote a assincronicidade**

As tarefas híbridas criadas com a anotação do decorador são assíncronas — elas são executadas quando os recursos clássicos e quânticos estão disponíveis. Você monitora o progresso do algoritmo usando o Braket Management Console ou Amazon CloudWatch. Quando você envia seu algoritmo para execução, o Braket executa seu algoritmo em um ambiente escalável em contêineres e os resultados são recuperados quando o algoritmo é concluído.

**Execute algoritmos variacionais iterativos**

Os trabalhos híbridos oferecem as ferramentas para executar algoritmos clássicos quânticos iterativos. Para problemas puramente quânticos, use [tarefas quânticas](braket-submit-tasks.md) ou um [lote de tarefas quânticas](braket-batching-tasks.md). O acesso prioritário a determinados QPUs é mais benéfico para algoritmos variacionais de longa execução que exigem várias chamadas iterativas para o QPUs com processamento clássico intermediário. 

**Depurar usando o modo local**

Antes de executar uma tarefa híbrida em uma QPU, é recomendável executá-la primeiro no simulador SV1 para confirmar se ela é executada conforme o esperado. Para testes de pequena escala, você pode executar com o modo local para iteração e depuração rápidas. 

**Melhore a reprodutibilidade com [Bring your own container (BYOC)](braket-jobs-byoc.md)**

Crie um experimento reproduzível encapsulando seu software e suas dependências em um ambiente em contêineres. Ao empacotar todo o seu código, dependências e configurações em um contêiner, você evita possíveis conflitos e problemas de versão. 

**Simuladores distribuídos de várias instâncias**

Para executar um grande número de circuitos, considere usar o suporte MPI integrado para executar simuladores locais em várias instâncias em uma única tarefa híbrida. Para obter mais informações, consulte [simuladores incorporados](pennylane-embedded-simulators.md).

**Use circuitos paramétricos**

Os circuitos paramétricos que você envia a partir de um trabalho híbrido são compilados automaticamente em determinados, QPUs usando a [compilação paramétrica](braket-jobs-parametric-compilation.md) para melhorar os tempos de execução de seus algoritmos. 

**Ponto de verificação periódico**

Para trabalhos híbridos de longa duração, é recomendável salvar periodicamente o estado intermediário do algoritmo. 

**Para mais exemplos, casos de uso e melhores práticas, consulte exemplos do [Amazon Braket](https://github.com/amazon-braket/amazon-braket-examples). GitHub**

# Usando a API com trabalhos híbridos
<a name="braket-jobs-api"></a>

Você pode acessar e interagir com o Amazon Braket Hybrid Jobs diretamente usando o API. No entanto, os padrões e os métodos de conveniência não estão disponíveis ao usar o API diretamente.

**nota**  
É altamente recomendável que você interaja com o Amazon Braket Hybrid Jobs usando o [SDK Amazon Braket Python.](https://github.com/aws/amazon-braket-sdk-python) Ele oferece padrões e proteções convenientes que ajudam seus trabalhos híbridos a serem executados com êxito.

Este tópico aborda os conceitos básicos do uso do API. Se você optar por usar a API, lembre-se de que essa abordagem pode ser mais complexa e estar preparada para várias iterações para que seu trabalho híbrido seja executado.

Para usar a API, sua conta deve ter um papel na política gerenciada `AmazonBraketFullAccess`.

**nota**  
Para obter mais informações sobre como obter uma função com a política gerenciada `AmazonBraketFullAccess`, consulte a página [Habilitar o Amazon Braket](braket-enable-overview.md).

Além disso, você precisa de um **perfil de execução**. Esse perfil será passado para o serviço. Você pode criar o perfil usando o **console do Amazon Braket**. Use a guia **Perfis de execução** na página **Permissões e configurações** para criar um perfil padrão para trabalhos híbridos.

O `CreateJob` API exige que você especifique todos os parâmetros necessários para a tarefa híbrida. Para usar o Python, compacte seus arquivos de script de algoritmo em um pacote tar, como um arquivo input.tar.gz, e execute o script a seguir. Atualize as partes do código entre colchetes angulares (`<>`) para corresponder às informações da sua conta e ao ponto de entrada que especificam o caminho, o arquivo e o método em que seu trabalho híbrido começa.

```
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
    },
)
```

Depois de criar seu trabalho híbrido, você pode acessar os detalhes do trabalho híbrido por meio do `GetJob` API ou do console. Para obter os detalhes do trabalho híbrido da sessão do Python na qual você executou o código `createJob`, como no exemplo anterior, use o comando Python a seguir.

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

Para cancelar um trabalho híbrido, chame o `CancelJob` API com o Amazon Resource Name do trabalho ('JobArn').

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

Você pode especificar pontos de verificação como parte do `createJob` API usando o `checkpointConfig` parâmetro.

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

**nota**  
O localPath de `checkpointConfig` não pode começar com nenhum dos seguintes caminhos reservados: `/opt/ml`, `/opt/braket`, `/tmp`, ou `/usr/local/nvidia`.

# Crie e depure uma tarefa híbrida com o modo local
<a name="braket-jobs-local-mode"></a>

Quando você está criando um novo algoritmo híbrido, o modo local ajuda você a depurar e testar seu script de algoritmo. O modo local é um recurso que permite executar o código que você planeja usar no Amazon Braket Hybrid Jobs, mas sem precisar que o Braket gerencie a infraestrutura para executar o trabalho híbrido. Em vez disso, execute trabalhos híbridos localmente em sua instância do Amazon Braket Notebook ou em um cliente preferencial, como um laptop ou computador desktop. 

No modo local, você ainda pode enviar tarefas quânticas para dispositivos reais, mas não obtém os benefícios de desempenho ao executar em uma unidade de processamento quântico (QPU) real no modo local.

Para usar o modo local, modifique `AwsQuantumJob` para `LocalQuantumJob` onde quer que ele ocorra dentro do seu programa. Por exemplo, para executar o exemplo de [Criar seu primeiro trabalho híbrido](braket-jobs-first.md), edite o script de trabalho híbrido no código da seguinte forma.

```
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**  
O Docker, que já vem pré-instalado nos cadernos Amazon Braket, precisa ser instalado em seu ambiente local para usar esse recurso. As instruções para instalar o Docker podem ser encontradas na página [Obter Docker](https://docs.docker.com/get-started/get-docker/). Além disso, nem todos os parâmetros são compatíveis com o modo local.

# Cancelar um Hybrid Job
<a name="braket-jobs-cancel"></a>

Talvez seja necessário cancelar um trabalho híbrido em um estado não terminal. Isso pode ser feito no console ou com código.

Para cancelar seu trabalho híbrido no console, selecione o trabalho híbrido a ser cancelado na página **Trabalhos híbridos** e, em seguida, selecione **Cancelar trabalho híbrido** no menu suspenso **Ações**.

![\[Tabela de trabalhos híbridos do Amazon Braket com 4 trabalhos mostrando seus nomes, status, informações do dispositivo e logs de data e hora. O menu suspenso Ações contém opções para visualizar o novo trabalho híbrido, cancelar ou gerenciar tags.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-hybrid-cancel-job.png)


Para confirmar o cancelamento, insira *cancelar* no campo de entrada quando solicitado e selecione **OK**.

![\[Caixa de diálogo para cancelar um trabalho específico com avisos sobre o processo de cancelamento e um campo de entrada de texto para confirmar digitando “cancelar”.\]](http://docs.aws.amazon.com/pt_br/braket/latest/developerguide/images/braket-hybrid-cancel-job-confirm.png)


Para cancelar seu trabalho híbrido usando o código do SDK do Braket Python, use o `job_arn` para identificar o trabalho híbrido e, em seguida, chame o comando `cancel` nele, conforme mostrado no código a seguir.

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

O comando `cancel` encerra imediatamente o contêiner de trabalho híbrido clássico e faz o possível para cancelar todas as tarefas quânticas relacionadas que ainda estão em um estado não terminal.

# Personalizar seu Hybrid Job
<a name="braket-jobs-customize"></a>

O Amazon Braket fornece várias maneiras de personalizar a execução de seus trabalhos híbridos, permitindo que você adapte o ambiente às suas necessidades específicas. Esta seção explora as opções para personalizar trabalhos híbridos, desde a definição do ambiente de script de algoritmo até a criação de seu próprio contêiner. Você aprenderá a otimizar seu fluxo de trabalho usando hiperparâmetros, configurar instâncias de trabalho e aproveitar a compilação paramétrica para melhorar o desempenho. Essas técnicas de personalização ajudam você a maximizar o potencial de suas computações quânticas híbridas no Amazon Braket.

**Topics**
+ [Defina o ambiente para seu script de algoritmo](braket-jobs-script-environment.md)
+ [Usando hiperparâmetros](braket-jobs-hyperparameters.md)
+ [Configure sua instância de trabalho híbrida](braket-jobs-configure-job-instance-for-script.md)
+ [Usar compilação paramétrica para acelerar trabalhos híbridos](braket-jobs-parametric-compilation.md)

# Defina o ambiente para seu script de algoritmo
<a name="braket-jobs-script-environment"></a>

O Amazon Braket oferece suporte a ambientes definidos por contêineres para seu script de algoritmo:
+ Um contêiner base (o padrão, se nenhum `image_uri` for especificado)
+ Um contêiner com CUDA-Q
+ Um contêiner com Tensorflow e PennyLane
+ Um contêiner com PyTorch PennyLane, e CUDA-Q

A tabela a seguir fornece detalhes sobre os contêineres e as bibliotecas que eles incluem.


**Contêineres Amazon Braket**  

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

Você pode visualizar e acessar as definições de contêiner de código aberto em [aws/ amazon-braket-containers](https://github.com/aws/amazon-braket-containers). Escolha o contêiner que corresponde ao seu caso de uso. Você pode usar qualquer uma das AWS regiões disponíveis no Braket (us-east-1, us-west-1, us-west-2, eu-north-1, eu-west-2), mas a região do contêiner deve corresponder à região do seu trabalho híbrido. Especifique a imagem do contêiner ao criar um trabalho híbrido adicionando um dos três argumentos a seguir à sua chamada `create(…​)` no script de trabalho híbrido. Você pode instalar dependências adicionais no contêiner escolhido em runtime (ao custo da inicialização ou do runtime) porque os contêineres do Amazon Braket têm conectividade com a internet. O exemplo a seguir refere-se à região us-west-2.
+  **Imagem base:** image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest” amazon-braket-base-jobs
+  **Imagem CUDA-Q:** image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest” amazon-braket-cudaq-jobs
+  **Imagem do Tensorflow:** image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest” amazon-braket-tensorflow-jobs
+  **PyTorch imagem:** image\$1uri="292282985366.dkr. ecr.us-west-2.amazonaws.com /:latest” amazon-braket-pytorch-jobs

A `image-uris` pode ser recuperada usando a função `retrieve_image()` no SDK do Amazon Braket. O exemplo a seguir mostra como recuperá-los do Região da AWS us-west-2.

```
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")
```

# Traga seu próprio contêiner (BYOC)
<a name="braket-jobs-byoc"></a>

O Amazon Braket Hybrid Jobs fornece três contêineres pré-criados para execução de código em ambientes diferentes. Se um desses contêineres oferecer suporte ao seu caso de uso, você só precisará fornecer seu script de algoritmo ao criar um trabalho híbrido. Pequenas dependências ausentes podem ser adicionadas a partir do seu script de algoritmo ou de um arquivo `requirements.txt` usando `pip`.

Se nenhum desses contêineres oferecer suporte ao seu caso de uso, ou se você quiser expandi-los, o Braket Hybrid Jobs suporta a execução de trabalhos híbridos com sua própria imagem de Docker contêiner personalizada ou traga seu próprio contêiner (BYOC). Certifique-se que esse é o recurso certo para o seu caso de uso. 

**Topics**
+ [Quando trazer meu próprio contêiner é a decisão certa?](#bring-own-container-decision)
+ [Como trazer seu próprio contêiner](bring-own-container-recipe.md)
+ [Executando trabalhos híbridos do Braket em seu próprio contêiner](running-hybrid-jobs-in-own-container.md)

## Quando trazer meu próprio contêiner é a decisão certa?
<a name="bring-own-container-decision"></a>

Trazer seu próprio contêiner (BYOC) para o Braket Hybrid Jobs oferece a flexibilidade de usar seu próprio software instalando-o em um ambiente empacotado. Dependendo de suas necessidades específicas, pode haver maneiras de obter a mesma flexibilidade sem precisar passar pelo ciclo completo de criação do BYOC Docker - upload do Amazon ECR - URI de imagem personalizada.

**nota**  
O BYOC pode não ser a escolha certa se você quiser adicionar um pequeno número de pacotes Python adicionais (geralmente menos de 10) que estão disponíveis publicamente. Por exemplo, se você estiver usando PyPi.

Nesse caso, você pode usar uma das imagens pré-criadas do Braket e, em seguida, incluir um arquivo `requirements.txt` no diretório de origem no envio do trabalho. O arquivo é lido automaticamente e o `pip` instalará os pacotes com as versões especificadas normalmente. Se você estiver instalando um grande número de pacotes, o runtime de seus trabalhos poderá ser substancialmente aumentado. Verifique a versão Python e, se aplicável, CUDA do contêiner pré-construído que você deseja usar para testar se seu software funcionará.

O BYOC é necessário quando você deseja usar uma linguagem não Python (como C\$1\$1 ou Rust) para seu script de trabalho ou se quiser usar uma versão em Python não disponível nos contêineres pré-construídos do Braket. Essa também é uma boa escolha se:
+ Você está usando um software com uma chave de licença e precisa autenticar essa chave em um servidor de licenciamento para executar o software. Com o BYOC, você pode incorporar a chave de licença em sua imagem Docker e incluir um código para autenticá-la.
+ Você está usando um software que não está disponível ao público. Por exemplo, o software está hospedado em um repositório privado GitLab ou GitHub repositório que você precisa de uma chave SSH específica para acessar.
+ Você precisa instalar um grande pacote de software que não esteja empacotado nos contêineres fornecidos pelo Braket. O BYOC permitirá que você elimine longos tempos de inicialização de seus contêineres de trabalhos híbridos devido à instalação do software.

O BYOC também permite que você disponibilize seu SDK ou algoritmo personalizado aos clientes criando um contêiner Docker com seu software e disponibilizando-o para seus usuários. Você pode fazer isso definindo as permissões apropriadas no Amazon ECR.

**nota**  
Você deve estar em conformidade com todas as licenças de software aplicáveis.

# Como trazer seu próprio contêiner
<a name="bring-own-container-recipe"></a>

Nesta seção, fornecemos um step-by-step guia do que você precisa fazer bring your own container (BYOC) para Braket Hybrid Jobs — os scripts, arquivos e etapas para combiná-los para começar a trabalhar com suas imagens personalizadasDocker. As receitas para dois casos comuns:

1. Instale software adicional em uma imagem Docker e use somente scripts de algoritmo Python em seus trabalhos.

1. Use scripts de algoritmo escritos em uma linguagem não Python com trabalhos híbridos ou uma arquitetura de CPU além de x86.

Definir o *script de entrada do contêiner* é mais complexo para o caso 2.

Quando o Braket executa seu Hybrid Job, ele inicia o número e o tipo solicitados de instâncias do Amazon EC2 e, em seguida, Docker executa a imagem especificada pela entrada do URI da imagem para a criação do trabalho nelas. Ao usar o recurso BYOC, você especifica um URI de imagem hospedado em um [repositório privado do Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html) ao qual você tem acesso de leitura. O Braket Hybrid Jobs usa essa imagem personalizada para executar o trabalho.

Os componentes específicos necessários para criar uma imagem Docker que possa ser usada com trabalhos híbridos. Se você não estiver familiarizado com escrever e criar`Dockerfiles`, consulte a [documentação do Dockerfile](https://docs.docker.com/reference/dockerfile/) e a [documentação Amazon ECR CLI](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html).

**Topics**
+ [Uma imagem base para seu Dockerfile](#base-image-dockerfile)
+ [(Opcional) Um script de ponto de entrada de contêiner modificado](#modified-container-entry-point)
+ [Instale o software e o script de contêiner necessários com `Dockerfile`](#install-docketfile)

## Uma imagem base para seu Dockerfile
<a name="base-image-dockerfile"></a>

[Se você estiver usando Python e quiser instalar software além do que é fornecido nos contêineres fornecidos pelo Braket, uma opção para uma imagem base é uma das imagens do contêiner do Braket, hospedada em nosso GitHub repositório e no Amazon ECR.](https://github.com/amazon-braket/amazon-braket-containers) Você precisará se [autenticar no Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-authenticate-registry) para extrair a imagem e criar em cima dela. Por exemplo, a primeira linha do seu arquivo Docker BYOC pode ser: `FROM [IMAGE_URI_HERE]`

Em seguida, preencha o restante do Dockerfile para instalar e configurar o software que você deseja adicionar ao contêiner. As imagens pré-criadas do Braket já conterão o script de ponto de entrada do contêiner apropriado, então você não precisa se preocupar em incluí-lo.

Se você quiser usar uma linguagem não Python, como C\$1\$1, Rust ou Julia, ou se quiser criar uma imagem para uma arquitetura de CPU não x86, como ARM, talvez seja necessário criar com base em uma imagem pública básica. Você pode encontrar muitas dessas imagens na [Galeria Pública do Amazon Elastic Container Registry](https://gallery.ecr.aws/). Certifique-se de escolher uma que seja apropriada para a arquitetura da CPU e, se necessário, para a GPU que você deseja usar.

## (Opcional) Um script de ponto de entrada de contêiner modificado
<a name="modified-container-entry-point"></a>

**nota**  
Se você só estiver adicionando mais software a uma imagem de Braket pré-criada, ignore esta seção.

Para executar código não Python como parte de seu trabalho híbrido, modifique o script Python que define o ponto de entrada do contêiner. Por exemplo, o [script `braket_container.py` python no Amazon Braket Github](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py). Esse é o script que as imagens pré-construídas pelo Braket usam para iniciar seu script de algoritmo e definir as variáveis de ambiente apropriadas. O script de ponto de entrada do contêiner em si **deve** estar em Python, mas pode iniciar scripts que não sejam Python. No exemplo pré-construído, você pode ver que os scripts do algoritmo Python são lançados como um [subprocesso do Python](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L274) ou [como um processo totalmente novo.](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L257) Ao modificar essa lógica, você pode habilitar o script de ponto de entrada para iniciar scripts de algoritmo não Python. Por exemplo, você pode modificar a [função `thekick_off_customer_script()`](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L139) para iniciar processos Rust dependendo do final da extensão do arquivo.

Você também pode escrever um `braket_container.py` completamente novo. Ele deve copiar dados de entrada, arquivos de origem e outros arquivos necessários do Amazon S3 para o contêiner e definir as variáveis de ambiente apropriadas.

## Instale o software e o script de contêiner necessários com `Dockerfile`
<a name="install-docketfile"></a>

**nota**  
Se você usar uma imagem Braket pré-criada como imagem Docker base, o script do contêiner já estará presente.

Se você criou um script de contêiner modificado na etapa anterior, precisará copiá-lo para o contêiner **e** definir a variável de ambiente de `SAGEMAKER_PROGRAM` para `braket_container.py`, ou para o nome que você deu ao seu novo script de ponto de entrada do contêiner.

Veja a seguir um exemplo de um `Dockerfile` que permite que você use Julia em instâncias de Jobs 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
```

Este exemplo baixa e executa scripts fornecidos por AWS para garantir a conformidade com todas as licenças de código aberto relevantes. Por exemplo, atribuindo adequadamente qualquer código instalado governado por um MIT license.

Se você precisar incluir código não público, por exemplo, código hospedado em um GitLab repositório GitHub ou privado, **não** incorpore chaves SSH na Docker imagem para acessá-la. Em vez disso, use o Docker Compose ao criar para permitir ao Docker o acesso ao SSH na máquina host em que ele foi criado. Para obter mais informações, consulte o guia [Como usar chaves SSH com segurança no Docker para acessar repositórios privados do Github](https://www.fastruby.io/blog/docker/docker-ssh-keys.html).

**Criando e enviando sua imagem Docker**

Com um repositório Amazon ECR devidamente definido`Dockerfile`, agora você está pronto para seguir as etapas para [criar um repositório privado do Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html), caso ainda não exista um. Você também pode criar, marcar e carregar sua imagem de contêiner no repositório.

Você está pronto para criar, marcar e enviar a imagem. Consulte a [documentação de compilação do Docker](https://docs.docker.com/reference/cli/docker/buildx/build/) para obter uma explicação completa das opções para o `docker build` e alguns exemplos.

Para o arquivo de amostra definido acima, você pode executar:

```
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
```

**Atribuição de permissões apropriadas do Amazon ECR**

As imagens do Braket Hybrid Jobs Docker devem ser hospedadas em repositórios privados do Amazon ECR. Por padrão, um repositório privado do Amazon ECR **não** fornece acesso de leitura ao Braket Hybrid Jobs IAM role ou a nenhum outro usuário que queira usar sua imagem, como um colaborador ou estudante. Você precisa [definir uma política de repositório](https://docs.aws.amazon.com/AmazonECR/latest/userguide/set-repository-policy.html) para conceder as permissões apropriadas. Em geral, dê permissão apenas aos usuários e perfis do IAM específicos aos quais você deseja acessar suas imagens, em vez de permitir que qualquer pessoa com a image URI as extraia.

# Executando trabalhos híbridos do Braket em seu próprio contêiner
<a name="running-hybrid-jobs-in-own-container"></a>

Para criar um trabalho híbrido com seu próprio contêiner, chame `AwsQuantumJob.create()` com o argumento `image_uri` especificado. Você pode usar uma QPU, um simulador sob demanda ou executar seu código localmente no processador clássico disponível com o Braket Hybrid Jobs. Recomendamos testar seu código em um simulador como SV1 DM1, ou TN1 antes de executar em uma QPU real.

Para executar seu código no processador clássico, especifique o `instanceType` e o `instanceCount` que você usa atualizando o `InstanceConfig`. Observe que, se você especificar um `instance_count` > 1, precisará garantir que seu código possa ser executado em vários hosts. O limite superior para o número de instâncias que você pode escolher é 5. Por exemplo:

```
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**  
Use o ARN do dispositivo para rastrear o simulador que você usou como metadados do trabalho híbrido. Os valores aceitáveis devem seguir o formato `device = "local:<provider>/<simulator_name>"`. Lembre-se que `<provider>` e `<simulator_name>` deve consistir apenas em letras, números, `_`, `-`, e `.`. O tamanho máximo da string é 256 caracteres.  
Se você planeja usar o BYOC e não está usando o SDK do Braket para criar tarefas quânticas, deve passar o valor da variável ambiental `AMZN_BRAKET_JOB_TOKEN` para o parâmetro `jobToken` na solicitação `CreateQuantumTask`. Caso contrário, as tarefas quânticas não têm prioridade e são cobradas como tarefas quânticas autônomas regulares.

# Usando hiperparâmetros
<a name="braket-jobs-hyperparameters"></a>

Você pode definir os hiperparâmetros necessários ao seu algoritmo, como a taxa de aprendizado ou o tamanho da etapa, ao criar um trabalho híbrido. Os valores dos hiperparâmetros são normalmente usados para controlar vários aspectos do algoritmo e geralmente podem ser ajustados para otimizar o desempenho do algoritmo. Para usar hiperparâmetros em uma tarefa híbrida do Braket, você precisa especificar seus nomes e valores explicitamente como um dicionário. Especifique os valores dos hiperparâmetros a serem testados ao pesquisar o conjunto ideal de valores. A primeira etapa para usar hiperparâmetros é configurar e definir os hiperparâmetros como um dicionário, que pode ser visto no código a seguir.

```
from braket.devices import Devices

device_arn = Devices.Amazon.SV1

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

Em seguida, passe os hiperparâmetros definidos no trecho de código fornecido acima para serem usados no algoritmo de sua escolha. Para executar o exemplo de código a seguir, crie um diretório chamado “src” no mesmo caminho do seu arquivo de hiperparâmetros. Dentro do diretório "src", adicione os arquivos 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), e [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 acessar seus hiperparâmetros de *dentro* do seu script de trabalho híbrido, consulte a função `load_jobs_hyperparams()` no arquivo [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 acessar seus hiperparâmetros *fora* do script de trabalho híbrido, execute o código a seguir. 

```
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 obter mais informações sobre como aprender a usar hiperparâmetros, consulte os tutoriais [QAOA com Amazon Braket Hybrid Jobs e Quantum PennyLane machine [learning nos](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) Amazon Braket 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).

# Configure sua instância de trabalho híbrida
<a name="braket-jobs-configure-job-instance-for-script"></a>

Dependendo do seu algoritmo, você pode ter requisitos diferentes. Por padrão, o Amazon Braket executa seu script de algoritmo em uma instância `ml.m5.large`. No entanto, você pode personalizar esse tipo de instância ao criar um trabalho híbrido usando o seguinte argumento de importação e configuração.

```
from braket.jobs.config import InstanceConfig

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

Se você estiver executando uma simulação incorporada e tiver especificado um dispositivo local na configuração do dispositivo, também poderá solicitar mais de uma instância no `InstanceConfig` especificando `instanceCount` e definindo que seja maior que um. O limite superior é 5. Por exemplo, você pode escolher 3 instâncias da seguinte maneira.

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

Ao usar várias instâncias, considere distribuir seu trabalho híbrido usando o recurso de data parallel. Consulte o exemplo de caderno a seguir para obter mais detalhes sobre como ver esse exemplo de [treinamento do Parallelize 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).

As três tabelas a seguir listam os tipos e especificações de instância disponíveis para instâncias padrão, de alto desempenho e aceleradas por GPU.

**nota**  
Para ver as cotas padrão de instância de computação clássica para trabalhos híbridos, consulte a página [Cotas do Amazon Braket](braket-quotas.md).


| Instâncias padrão | vCPU | Memória (GiB) | 
| --- | --- | --- | 
|  ml.m5.large (padrão)  |  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  | 


| Instâncias de alta performance | vCPU | Memória (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  | 


| Inferência acelerada por GPU | GPUs | vCPU | Memória (GiB) | Memória 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 instância usa uma configuração padrão de armazenamento de dados (SSD) de 30 GB. Mas você pode ajustar o armazenamento da mesma forma que configura o `instanceType`. O exemplo a seguir mostra como aumentar o armazenamento total para 50 GB.

```
from braket.jobs.config import InstanceConfig

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

## Configure o bucket padrão em `AwsSession`
<a name="braket-jobs-configure-default-bucket"></a>

A utilização de sua própria instância de `AwsSession` oferece maior flexibilidade, como a capacidade de especificar um local personalizado para seu bucket padrão do Amazon S3. Por padrão, uma `AwsSession` tem uma localização pré-configurada de bucket do Amazon S3 do `"amazon-braket-{id}-{region}"`. No entanto, você tem a opção de substituir a localização padrão do bucket do Amazon S3 ao criar uma `AwsSession`. Opcionalmente, os usuários podem passar um objeto `AwsSession` para o método `AwsQuantumJob.create()`, fornecendo o parâmetro `aws_session` conforme demonstrado no exemplo de código a seguir.

```
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
)
```

# Usar compilação paramétrica para acelerar trabalhos híbridos
<a name="braket-jobs-parametric-compilation"></a>

 O Amazon Braket oferece suporte à compilação paramétrica em alguns. QPUs Isso permite que você reduza a sobrecarga associada à etapa de compilação computacionalmente cara compilando um circuito apenas uma vez e não para cada iteração em seu algoritmo híbrido. Isso pode melhorar drasticamente os runtimes de trabalhos híbridos, já que você evita a necessidade de recompilar seu circuito em cada etapa. Basta enviar circuitos parametrizados para um dos nossos serviços suportados QPUs como Braket Hybrid Job. Para trabalhos híbridos de longa duração, o Braket usa automaticamente os dados de calibração atualizados do fornecedor de hardware ao compilar seu circuito para garantir resultados da mais alta qualidade.

Para criar um circuito paramétrico, primeiro você precisa fornecer parâmetros como entradas em seu script de algoritmo. Neste exemplo, usamos um pequeno circuito paramétrico e ignoramos qualquer processamento clássico entre cada iteração. Para workloads típicas, você enviaria vários circuitos em lote e executaria o processamento clássico, como atualizar os parâmetros em cada iteração.

```
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.")
```

Você pode enviar o script do algoritmo para ser executado como um Hybrid Job com o script de trabalho a seguir. Ao executar o Hybrid Job em uma QPU compatível com compilação paramétrica, o circuito é compilado somente na primeira execução. Nas execuções seguintes, o circuito compilado é reutilizado, aumentando o desempenho do runtime do Hybrid Job sem nenhuma linha adicional de código. 

```
from braket.aws import AwsQuantumJob

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

**nota**  
A compilação paramétrica é suportada em todos os formatos supercondutores baseados em portas, Rigetti Computing com exceção QPUs dos programas de nível de pulso.

# Usando PennyLane com o Amazon Braket
<a name="hybrid"></a>

Algoritmos híbridos são algoritmos que contêm instruções clássicas e quânticas. As instruções clássicas são executadas em hardware clássico (uma instância EC2 ou seu laptop), e as instruções quânticas são executadas em um simulador ou em um computador quântico. Recomendamos que você execute algoritmos híbridos usando o recurso Hybrid Jobs. Para obter mais informações, consulte [Quando usar o Amazon Braket Jobs](braket-jobs.md#braket-jobs-use).

**O Amazon Braket permite que você configure e execute algoritmos quânticos híbridos com a ajuda do plug-in Amazon **Braket ou com o SDK Amazon PennyLane Braket para Python** e exemplos de repositórios de notebooks.** Os notebooks de exemplo do Amazon Braket, baseados no SDK, permitem que você configure e execute determinados algoritmos híbridos sem o plug-in. PennyLane No entanto, recomendamos PennyLane porque proporciona uma experiência mais rica.

 **Sobre algoritmos quânticos híbridos** 

Os algoritmos quânticos híbridos são importantes para a indústria atual porque os dispositivos de computação quântica contemporâneos geralmente produzem ruído e, portanto, erros. Cada porta quântica adicionada a uma computação aumenta a chance de adicionar ruído; portanto, algoritmos de longa execução podem ser sobrecarregados pelo ruído, o que resulta em cálculos defeituosos.

Algoritmos quânticos puros, como o de Shor [(exemplo de estimativa de fase quântica)](https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/advanced_circuits_algorithms/Quantum_Phase_Estimation) ou o de [Grover (exemplo de Grover)](https://github.com/aws/amazon-braket-examples/tree/main/examples/advanced_circuits_algorithms/Grover), exigem milhares ou milhões de operações. Por esse motivo, eles podem ser impraticáveis para dispositivos quânticos existentes, geralmente chamados de *dispositivos quânticos ruidosos de escala intermediária (NISQ)*.

Em algoritmos quânticos híbridos, as unidades de processamento quântico (QPUs) funcionam como coprocessadores para o clássico CPUs, especificamente para acelerar certos cálculos em um algoritmo clássico. As execuções de circuitos se tornam muito mais curtas, ao alcance dos recursos dos dispositivos atuais.

**Topics**
+ [Amazon Braket com PennyLane](#pennylane-option)
+ [Algoritmos híbridos em cadernos de exemplo do Amazon Braket](#braket-hybrid-workflow)
+ [Algoritmos híbridos com PennyLane simuladores incorporados](#hybrid-alorithms-pennylane)
+ [Gradiente adjunto PennyLane com simuladores Amazon Braket](#adjoint-gradient-pennylane)
+ [Usando trabalhos híbridos e PennyLane para executar um algoritmo QAOA](braket-jobs-run-qaoa-algorithm.md)
+ [Execute cargas de trabalho híbridas com PennyLane simuladores incorporados](pennylane-embedded-simulators.md)

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

*O Amazon Braket fornece suporte [PennyLane](https://pennylane.ai)para uma estrutura de software de código aberto criada com base no conceito de programação quântica diferenciável.* Você pode usar essa estrutura para treinar circuitos quânticos da mesma forma que treinaria uma rede neural para encontrar soluções para problemas computacionais em química quântica, aprendizado de máquina quântica e otimização.

A PennyLane biblioteca fornece interfaces para ferramentas conhecidas de aprendizado de máquina, incluindo PyTorch e TensorFlow, para tornar o treinamento de circuitos quânticos rápido e intuitivo.
+  **A PennyLane Biblioteca** -— PennyLane está pré-instalada nos notebooks Amazon Braket. Para acessar os dispositivos Amazon Braket a partir de PennyLane, abra um notebook e importe a PennyLane biblioteca com o comando a seguir.

```
import pennylane as qml
```

Os cadernos tutoriais ajudam você a começar rapidamente. Como alternativa, você pode usar PennyLane no Amazon Braket a partir de um IDE de sua escolha.
+  **O PennyLane plug-in Amazon Braket** — Para usar seu próprio IDE, você pode instalar o plug-in Amazon PennyLane Braket manualmente. O plug-in se PennyLane conecta ao SDK [Amazon Braket Python](https://github.com/aws/amazon-braket-sdk-python), para que você possa executar circuitos em dispositivos Braket. PennyLane Amazon Para instalar o PennyLane plug-in, use o comando a seguir.

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

O exemplo a seguir demonstra como configurar o acesso aos dispositivos Amazon Braket em: 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 exemplos de tutoriais e mais informações sobre PennyLane, consulte o repositório de exemplos do [Amazon Braket](https://github.com/aws/amazon-braket-examples/tree/main/examples/pennylane).

O PennyLane plug-in Amazon Braket permite que você alterne entre o Amazon Braket QPU e dispositivos simuladores incorporados PennyLane com uma única linha de código. Ele oferece dois dispositivos quânticos Amazon Braket para trabalhar com: PennyLane
+  `braket.aws.qubit`para funcionar com os dispositivos quânticos do serviço Amazon Braket, inclusive simuladores QPUs 
+  `braket.local.qubit` para execução com o simulador local do SDK do Amazon Braket

O PennyLane plugin Amazon Braket é de código aberto. Você pode instalá-lo a partir do [ GitHub repositório de PennyLane plug-ins](https://github.com/aws/amazon-braket-pennylane-plugin-python).

Para obter mais informações sobre PennyLane, consulte a documentação no [PennyLane site](https://pennylane.ai).

## Algoritmos híbridos em cadernos de exemplo do Amazon Braket
<a name="braket-hybrid-workflow"></a>

O Amazon Braket fornece uma variedade de exemplos de notebooks que não dependem do plug-in para executar algoritmos PennyLane híbridos. Você pode começar com qualquer um destes [cadernos de exemplo híbridos do Amazon Braket](https://github.com/aws/amazon-braket-examples/tree/main/examples/hybrid_quantum_algorithms) que ilustram *métodos variacionais*, como o Algoritmo de Otimização Aproximada Quântica (QAOA) ou o Solucionador de Autovalores Quântico Variacional (VQE).

[Os cadernos de exemplo do Amazon Braket dependem do SDK Amazon Braket Python.](https://github.com/aws/amazon-braket-sdk-python) O SDK fornece uma estrutura para interagir com dispositivos de hardware de computação quântica por meio do Amazon Braket. É uma biblioteca de código aberto projetada para ajudá-lo com a parte quântica do seu fluxo de trabalho híbrido.

Você pode explorar ainda mais o Amazon Braket com nossos [exemplos de cadernos](https://github.com/aws/amazon-braket-examples).

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

O Amazon Braket Hybrid Jobs agora vem com simuladores incorporados de alto desempenho baseados em CPU e GPU da. [PennyLane](https://github.com/PennyLaneAI/pennylane-lightning) Essa família de simuladores integrados pode ser incorporada diretamente no seu contêiner de tarefas híbridas e inclui o simulador `lightning.qubit` de vetor de estado rápido, o simulador `lightning.gpu` acelerado usando a [biblioteca cuQuantum da NVIDIA](https://developer.nvidia.com/cuquantum-sdk), entre outros. Esses simuladores incorporados são ideais para algoritmos variacionais, como aprendizado de máquina quântico, que podem se beneficiar de métodos avançados, como o [método de diferenciação adjunta](https://docs.pennylane.ai/en/stable/introduction/interfaces.html#simulation-based-differentiation). Você pode executar esses simuladores incorporados em uma ou várias instâncias de CPU ou GPU.

Com o Hybrid Jobs, agora você pode executar seu código de algoritmo variacional usando uma combinação de um coprocessador clássico e uma QPU, um simulador sob demanda Amazon Braket, comoSV1, ou usando diretamente o simulador incorporado do. PennyLane

O simulador incorporado já está disponível com o contêiner Hybrid Jobs. Você precisa decorar sua função principal do Python com o decorador `@hybrid_job`. Para usar o PennyLane `lightning.gpu` simulador, você também precisa especificar uma instância de GPU no, `InstanceConfig` conforme mostrado no seguinte trecho 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)
    ...
```

Consulte o [exemplo de caderno](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 começar a usar um simulador PennyLane incorporado com o Hybrid Jobs.

## Gradiente adjunto PennyLane com simuladores Amazon Braket
<a name="adjoint-gradient-pennylane"></a>

Com o PennyLane plug-in do Amazon Braket, você pode calcular gradientes usando o método de diferenciação adjunta ao executar no simulador vetorial estadual local ou. SV1

 **Nota:** Para usar o método de diferenciação adjunta, você deve especificar `diff_method='device'` em seu `qnode`, e **não** `diff_method='adjoint'`. Veja o exemplo a seguir.

```
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**  
Atualmente, PennyLane calculará índices de agrupamento para hamiltonianos da QAOA e os usará para dividir o hamiltoniano em vários valores de expectativa. Se você quiser usar o recurso SV1 de diferenciação adjunta ao executar o QAOA a partir dePennyLane, precisará reconstruir o hamiltoniano de custo removendo os índices de agrupamento, da seguinte forma: `cost_h, mixer_h = qml.qaoa.max_clique(g, constrained=False) cost_h = qml.Hamiltonian(cost_h.coeffs, cost_h.ops)` 

# Usando trabalhos híbridos e PennyLane para executar um algoritmo QAOA
<a name="braket-jobs-run-qaoa-algorithm"></a>

Nesta seção, você usará o que aprendeu para escrever um programa híbrido real usando PennyLane a compilação paramétrica. Você usa o script do algoritmo para resolver um problema do Algoritmo de Otimização Aproximada Quântica (QAOA). O programa cria uma função de custo correspondente a um problema clássico de otimização do Max Cut, especifica um circuito quântico parametrizado e usa um método de gradiente descendente para otimizar os parâmetros para que a função de custo seja minimizada. Neste exemplo, geramos o gráfico do problema no script do algoritmo para simplificar, mas para casos de uso mais comuns, a melhor prática é fornecer a especificação do problema por meio de um canal dedicado na configuração dos dados de entrada. O `parametrize_differentiable` padrão do sinalizador é para que você `True` obtenha automaticamente os benefícios do desempenho aprimorado do tempo de execução a partir da compilação paramétrica, quando suportada. 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**  
A compilação paramétrica é suportada em todos os formatos supercondutores baseados em portas, Rigetti Computing com exceção QPUs dos programas de nível de pulso.

# Execute cargas de trabalho híbridas com PennyLane simuladores incorporados
<a name="pennylane-embedded-simulators"></a>

Vamos ver como você pode usar simuladores incorporados do PennyLane Amazon Braket Hybrid Jobs para executar cargas de trabalho híbridas. O simulador incorporado baseado em GPU da Pennylane, `lightning.gpu`, usa a biblioteca [Nvidia CuQuantum](https://developer.nvidia.com/cuquantum-sdk) para acelerar as simulações de circuitos. O simulador de GPU incorporado é pré-configurado em todos os [contêineres de trabalho](https://github.com/amazon-braket/amazon-braket-containers) do Braket que os usuários podem usar imediatamente. Nesta página, mostraremos como usar `lightning.gpu` para acelerar suas workloads híbrida.

## Usando `lightning.gpu` para workloads QAOA
<a name="lightning-gpu-qaoa"></a>

Considere os exemplos do Algoritmo de Otimização Aproximada Quântica (QAOA) deste [caderno](https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/hybrid_jobs/2_Using_PennyLane_with_Braket_Hybrid_Jobs). Para selecionar um simulador incorporado, você especifica o argumento `device` para ser uma string no formato: `"local:<provider>/<simulator_name>"`. Por exemplo, você definiria `"local:pennylane/lightning.gpu"` para `lightning.gpu`. A string do dispositivo que você fornece ao Hybrid Job ao iniciar é passada para o trabalho como a variável de ambiente `"AMZN_BRAKET_DEVICE_ARN"`.

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

Nesta página, compare os dois simuladores de vetores de PennyLane estado incorporados `lightning.qubit` (que são baseados em CPU) e `lightning.gpu` (que são baseados em GPU). Forneça aos simuladores decomposições de portas personalizadas para calcular vários gradientes.

Agora você está pronto para preparar o script híbrido de lançamento de tarefas. Execute o algoritmo QAOA usando dois tipos de instância: `ml.m5.2xlarge` e `ml.g4dn.xlarge`. O tipo `ml.m5.2xlarge` de instância é comparável a um laptop padrão para desenvolvedores. `ml.g4dn.xlarge`É uma instância de computação acelerada que tem uma única GPU NVIDIA T4 com 16 GB de memória.

Para executar a GPU, primeiro precisamos especificar uma imagem compatível e a instância correta (cujo padrão é uma `ml.m5.2xlarge` instância).

```
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")
```

Em seguida, precisamos inseri-los no decorador de trabalho híbrido, junto com os parâmetros atualizados do dispositivo nos argumentos do sistema e do trabalho híbrido.

```
@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**  
Se você especificar o `instance_config` como usando uma instância baseada em GPU, mas `device` escolher o como simulador baseado em CPU incorporado (`lightning.qubit`), a GPU não será usada. Certifique-se de usar o simulador incorporado baseado em GPU se quiser atingir a GPU\$1

O tempo médio de iteração para a `m5.2xlarge` instância é de cerca de 73 segundos, enquanto para a `ml.g4dn.xlarge` instância é de cerca de 0,6 segundos. Para esse fluxo de trabalho de 21 qubits, a instância da GPU nos dá uma aceleração de 100x. Se você olhar a página de [preços do Amazon Braket Hybrid Jobs](https://aws.amazon.com/braket/pricing/), verá que o custo por minuto para `m5.2xlarge` uma instância é de 0,00768 USD, enquanto para a instância é de 0,01227 USD. `ml.g4dn.xlarge` Nesse caso, é mais rápido e barato executar na instância da GPU.

## Aprendizado de máquina quântico e paralelismo de dados
<a name="quantumML-data-parallelism"></a>

Se seu tipo de workload for aprendizado de máquina quântico (QML) treinado em conjuntos de dados, você poderá acelerar ainda mais sua workload usando o paralelismo de dados. No QML, o modelo contém um ou mais circuitos quânticos. O modelo também pode ou não conter redes neurais clássicas. Ao treinar o modelo com o conjunto de dados, os parâmetros no modelo são atualizados para minimizar a função de perda. Uma função de perda geralmente é definida para um único ponto de dados e a perda total para a perda média em todo o conjunto de dados. Em QML, as perdas geralmente são calculadas em série antes da média da perda total para cálculos de gradiente. Esse procedimento é demorado, especialmente quando há centenas de pontos de dados.

Como a perda de um ponto de dados não depende de outros pontos de dados, as perdas podem ser avaliadas paralelamente\$1 Perdas e gradientes associados a diferentes pontos de dados podem ser avaliados ao mesmo tempo. Isso é conhecido como paralelismo de dados. Com SageMaker a biblioteca paralela de dados distribuídos, o Amazon Braket Hybrid Jobs facilita o uso do paralelismo de dados para acelerar seu treinamento.

Considere a seguinte workload QML para paralelismo de dados, que usa o [conjunto de dados Sonar](https://archive.ics.uci.edu/dataset/151/connectionist+bench+sonar+mines+vs+rocks) do conhecido repositório UCI como exemplo de classificação binária. O conjunto de dados Sonar tem 208 pontos de dados, cada um com 60 características que são coletadas de sinais de sonar refletidos em materiais. Cada ponto de dados é rotulado como “M” para minas ou “R” para rochas. Nosso modelo QML consiste em uma camada de entrada, um circuito quântico como camada oculta e uma camada de saída. As camadas de entrada e saída são redes neurais clássicas implementadas em PyTorch. O circuito quântico é integrado às PyTorch redes neurais usando PennyLane o módulo qml.qnn. Veja nossos [exemplos de cadernos](https://github.com/aws/amazon-braket-examples) para obter mais detalhes sobre a workload. Como no exemplo de QAOA acima, você pode aproveitar o poder da GPU usando simuladores incorporados baseados em GPU, como PennyLane os nossos, `lightning.gpu` para melhorar o desempenho em relação aos simuladores baseados em CPU incorporada.

Para criar uma tarefa híbrida, você pode chamar `AwsQuantumJob.create` e especificar o script do algoritmo, o dispositivo e outras configurações por meio de seus argumentos de palavra-chave.

```
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 usar o paralelismo de dados, você precisa modificar algumas linhas de código no script do algoritmo da biblioteca SageMaker distribuída para paralelizar corretamente o treinamento. Primeiro, você importa o `smdistributed` pacote que faz a maior parte do trabalho pesado para distribuir suas cargas de trabalho em várias e várias GPUs instâncias. Este pacote é pré-configurado no Braket PyTorch e nos contêineres. TensorFlow O `dist` módulo informa ao nosso script de algoritmo qual é o número total de GPUs para o treinamento (`world_size`), bem como o final `rank` `local_rank` de um núcleo de GPU. `rank`é o índice absoluto de uma GPU em todas as instâncias, enquanto `local_rank` é o índice de uma GPU dentro de uma instância. Por exemplo, se houver quatro instâncias, cada uma com oito GPUs alocadas para o treinamento, `rank` elas variam de 0 a 31 e as `local_rank` 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)
```

Em seguida, você define um `DistributedSampler` de acordo com `world_size` e `rank` e, em seguida, o passa para o carregador de dados. Esse amostrador evita GPUs acessar a mesma fatia de um conjunto de dados.

```
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,
)
```

Em seguida, você usa a classe `DistributedDataParallel` para ativar o paralelismo de dados.

```
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"])
```

As alterações acima são necessárias para usar o paralelismo de dados. Em QML, você geralmente deseja salvar os resultados e imprimir o progresso do treinamento. Se cada GPU executar o comando de salvar e imprimir, o log será inundado com as informações repetidas e os resultados se substituirão. Para evitar isso, você só pode salvar e imprimir a partir da GPU que tenha `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})
```

 O Amazon Braket Hybrid Jobs `ml.g4dn.12xlarge` oferece suporte a tipos de instância para a biblioteca paralela de dados SageMaker distribuídos. Você configura o tipo de instância por meio do argumento `InstanceConfig` em Hybrid Jobs. Para que a biblioteca paralela de dados SageMaker distribuídos saiba que o paralelismo de dados está ativado, você precisa adicionar dois hiperparâmetros adicionais, `"sagemaker_distributed_dataparallel_enabled"` configurando `"true"` e `"sagemaker_instance_type"` configurando o tipo de instância que você está usando. Esses dois hiperparâmetros são usados por pacote `smdistributed`. Seu script de algoritmo não precisa usá-los explicitamente. No Amazon Braket SDK, ele fornece um argumento `distribution` de palavra-chave conveniente. Com `distribution="data_parallel"` de empregos híbridos, o Amazon Braket SDK insere automaticamente os dois hiperparâmetros para você. Se você usa a API Amazon Braket, precisa incluir esses dois hiperparâmetros.

Com o paralelismo de instâncias e dados configurados, agora você pode enviar seu trabalho híbrido. Há 4 GPUs em uma `ml.g4dn.12xlarge` instância. Quando você define`instanceCount=1`, a carga de trabalho é distribuída entre os 8 GPUs na instância. Quando você define `instanceCount` mais de um, a carga de trabalho é distribuída entre os GPUs disponíveis em todas as instâncias. Ao usar várias instâncias, cada instância incorre em uma cobrança com base no tempo de uso. Por exemplo, quando você usa quatro instâncias, o tempo faturável é quatro vezes o tempo de execução por instância, pois há quatro instâncias executando suas workloads ao mesmo tempo.

```
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**  
Na criação de empregos híbridos acima, `train_dp.py` é o script de algoritmo modificado para usar o paralelismo de dados. Lembre-se de que o paralelismo de dados só funciona corretamente quando você modifica seu script de algoritmo de acordo com a seção acima. Se a opção de paralelismo de dados for ativada sem um script de algoritmo modificado corretamente, a tarefa híbrida poderá gerar erros ou cada GPU poderá processar repetidamente a mesma fatia de dados, o que é ineficiente.

Se usado corretamente, o uso de várias instâncias pode levar a uma redução de ordens de magnitude no tempo e no custo. Consulte o [exemplo de caderno para obter mais detalhes](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/hybrid_jobs/5_Parallelize_training_for_QML/Parallelize_training_for_QML.ipynb).

# Usando o CUDA-Q com o Amazon Braket
<a name="braket-using-cuda-q"></a>

NVIDIA's CUDA-Qé uma biblioteca de software projetada para programar algoritmos quânticos híbridos que combinam CPUs GPUs, e unidades de processamento quântico (QPUs). Ele fornece um modelo de programação unificado, permitindo que os desenvolvedores expressem instruções clássicas e quânticas em um único programa, simplificando os fluxos de trabalho. CUDA-Qacelera a simulação e o tempo de execução de programas quânticos com seus simuladores integrados de CPU e GPU. CUDA-Qestá disponível com instâncias nativas do notebook Braket (NBIs) e Amazon Braket Hybrid Jobs.

**Topics**
+ [CUDA-Q em NBIs](#braket-cuda-q-nbis)
+ [CUDA-Q no Hybrid Jobs](#braket-cuda-q-hybrid-jobs)

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

CUDA-Q é instalado por padrão no ambiente Braket NBI. Você pode abrir um caderno de exemplo CUDA-Q acessando a página inicial do Jupyter e selecionando o bloco CUDA-Q e Braket. Isso abre o caderno `0_Getting_started_with_CUDA-Q.ipynb` de exemplo na janela principal. Para obter mais exemplos CUDA-Q, consulte o painel esquerdo no `nvidia_cuda_q/` diretório.

Você também pode verificar a versão CUDA-Q ou qualquer outro pacote de terceiros instalado em seu NBI. Por exemplo, você pode executar o comando a seguir em uma célula de código do notebook para verificar as versões dos CUDA-Q pacotes Qiskit e Braket que estão instalados no ambiente. PennyLane

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

## CUDA-Q no Hybrid Jobs
<a name="braket-cuda-q-hybrid-jobs"></a>

Usar CUDA-Q no [Amazon Braket Hybrid Jobs](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html) oferece um ambiente de computação flexível e sob demanda. As instâncias computacionais são executadas somente durante a duração da workload, garantindo que você pague somente pelo que usar. O Amazon Braket Hybrid Jobs também oferece uma experiência escalável. Os usuários podem começar com instâncias menores para prototipagem e teste e, em seguida, escalar para instâncias maiores, capazes de lidar com workloads maiores para experimentos completos.

O Amazon Braket Hybrid Jobs GPUs oferece suporte essencial para CUDA-Q maximizar o potencial da Amazon Braket. GPUs aceleram significativamente as simulações de programas quânticos em comparação com simuladores baseados em CPU, especialmente ao trabalhar com circuitos de alta contagem de qubits. A paralelização se torna simples quando usada no Amazon Braket Hybrid Jobs CUDA-Q. O Hybrid Jobs simplifica a distribuição da amostragem do circuito e das avaliações observáveis em vários nós computacionais. Essa paralelização perfeita das workloads CUDA-Q permite que os usuários se concentrem mais no desenvolvimento de suas workloads em vez de configurar a infraestrutura para experimentos em grande escala.

Para começar, veja o [exemplo inicial CUDA-Q](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/nvidia_cuda_q/0_Getting_started_with_CUDA-Q.ipynb) no Github de exemplos do Amazon Braket para CUDA-Q usar um contêiner de trabalhos híbrido fornecido pela Braket.

O trecho de código a seguir é um exemplo `hello-world` de execução de um programa CUDA-Q com o Amazon Braket Hybrid Jobs.

```
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
```

O exemplo acima simula um circuito Bell em um simulador de CPU. Este exemplo é executado localmente em seu laptop ou notebook Braket Jupyter. Por causa da configuração `local=True` , ao executar esse script, um contêiner será iniciado em seu ambiente local para executar o programa CUDA-Q para teste e depuração. Depois de concluir o teste, você pode remover o sinalizador `local=True` e continuar executando seu trabalho AWS. Para saber mais, consulte [Trabalhando com o Amazon Braket Hybrid Jobs](braket-jobs.md).

Se suas workloads tiverem uma alta contagem de qubits, um grande número de circuitos ou um grande número de iterações, você poderá usar recursos de computação de CPU mais poderosos especificando a configuração `instance_config`. O trecho de código a seguir mostra como configurar a configuração `instance_config` no decorador `hybrid_job`. Para obter mais informações sobre os tipos de instância compatíveis, consulte [Configurar sua instância de trabalho híbrida](braket-jobs-configure-job-instance-for-script.md). Para obter uma lista dos tipos de instância , consulte [Tipos de instância do 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 workloads mais exigentes, você pode executar suas workloads em um simulador de GPU CUDA-Q. Para habilitar um simulador de GPU, use o nome do back-end `nvidia`. O back-end `nvidia` funciona como um simulador de GPU CUDA-Q. Em seguida, selecione um tipo de instância do Amazon EC2 que ofereça suporte a uma GPU NVIDIA. O seguinte trecho de código mostra o decorador configurado em GPU `hybrid_job` configurado.

```
@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 e NBIs suporte simulações paralelas de GPU com. CUDA-Q Você pode paralelizar a avaliação de vários observáveis ou vários circuitos para aumentar o desempenho de sua workload. Para paralelizar vários observáveis, faça as seguintes alterações em seu script de algoritmo.

Defina a opção `mgpu` do back-end `nvidia`. Isso é necessário para paralelizar os observáveis. A paralelização usa MPI para comunicação entre eles GPUs, portanto, o MPI precisa ser inicializado antes da execução e finalizado depois dela.

Em seguida, especifique o modo de execução por meio da configuração `execution=cudaq.parallel.mpi`. O seguinte trecho de código mostra essas alterações.

```
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()
```

No `hybrid_job` decorador, especifique um tipo de instância que hospede várias, GPUs conforme mostrado no trecho de código a seguir.

```
@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):
    ...
```

O [caderno de simulações paralelas](https://github.com/amazon-braket/amazon-braket-examples/blob/main/examples/nvidia_cuda_q/5_Multiple_GPU_simulations.ipynb) no Amazon Braket Examples end-to-end Github fornece exemplos que demonstram como executar simulações de programas quânticos em back-ends de GPU e realizar simulações paralelas de observáveis e lotes de circuitos.

### Executando suas workloads em computadores quânticos
<a name="braket-using-cuda-q-quantum"></a>

Depois de concluir o teste do simulador, você pode fazer a transição para a execução de experimentos no QPUs. Basta mudar o alvo para uma QPU Amazon Braket, como o IQM, os dispositivos IonQ, ou Rigetti. O trecho de código a seguir ilustra como definir o destino para o dispositivo IQM Garnet. Para obter uma lista dos disponíveis QPUs, consulte o [console 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 obter mais informações sobre trabalhos híbridos, consulte [Trabalhando com o Amazon Braket Hybrid Jobs](braket-jobs.md) no guia do desenvolvedor. Para saber mais sobre o CUDA-Q, consulte a [documentação NVIDIA CUDA-Q](https://nvidia.github.io/cuda-quantum/latest/index.html).