

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Esegui il codice locale come lavoro ibrido
<a name="braket-hybrid-job-decorator"></a>

Amazon Braket Hybrid Jobs fornisce un'orchestrazione completamente gestita di algoritmi ibridi quantistici classici, combinando le risorse di calcolo di Amazon EC2 con l'accesso ad Amazon Braket Quantum Processing Unit (QPU). Le attività quantistiche create in un processo ibrido hanno la priorità di essere messe in coda rispetto alle singole attività quantistiche, in modo che gli algoritmi non vengano interrotti dalle fluttuazioni nella coda delle attività quantistiche. Ogni QPU mantiene una coda di lavori ibridi separata, garantendo che sia possibile eseguire solo un processo ibrido alla volta.

**Topics**
+ [Crea un lavoro ibrido dal codice Python locale](#create-hybrid-job-from-local-python-code)
+ [Installa pacchetti Python e codice sorgente aggiuntivi](#install-python-packages-and-code)
+ [Salva e carica i dati in un'istanza di lavoro ibrida](#save-load-data-into-instance)
+ [Le migliori pratiche per arredatori di lavori ibridi](#best-practices)

## Crea un lavoro ibrido dal codice Python locale
<a name="create-hybrid-job-from-local-python-code"></a>

Puoi eseguire il codice Python locale come Amazon Braket Hybrid Job. Puoi farlo annotando il codice con un `@hybrid_job` decoratore, come mostrato nel seguente esempio di codice. Per gli ambienti personalizzati, puoi scegliere di [utilizzare un contenitore personalizzato](braket-jobs-byoc.md) da Amazon Elastic Container Registry (ECR). 

**Nota**  
Per impostazione predefinita, è supportato solo Python 3.12.

 È possibile utilizzare il `@hybrid_job` decoratore per annotare una funzione. [Braket trasforma il codice all'interno del decoratore in uno script di algoritmo di lavoro ibrido Braket.](braket-jobs-first.md) Il job ibrido richiama quindi la funzione all'interno del decoratore su un'istanza Amazon EC2. Puoi monitorare l'avanzamento del lavoro con `job.state()` o con la console Braket. Il seguente esempio di codice mostra come eseguire una sequenza di cinque stati su. 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}
```

Crei il lavoro ibrido invocando la funzione come faresti con le normali funzioni di Python. Tuttavia, la funzione decorator restituisce l'handle del lavoro ibrido anziché il risultato della funzione. Per recuperare i risultati dopo il completamento, usa. `job.result()` 

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

L'argomento device nel `@hybrid_job` decoratore specifica il dispositivo a cui il lavoro ibrido ha accesso prioritario, in questo caso, il simulatore. SV1 Per ottenere la priorità QPU, è necessario assicurarsi che l'ARN del dispositivo utilizzato all'interno della funzione corrisponda a quello specificato nel decoratore. Per comodità, è possibile utilizzare la funzione helper per `get_job_device_arn()` acquisire l'ARN del dispositivo dichiarato in. `@hybrid_job` 

**Nota**  
Ogni processo ibrido ha un tempo di avvio di almeno un minuto poiché crea un ambiente containerizzato su Amazon EC2. Quindi, per carichi di lavoro molto brevi, come un singolo circuito o un batch di circuiti, può essere sufficiente utilizzare attività quantistiche.

**Iperparametri** 

La `run_hybrid_job()` funzione utilizza l'argomento `num_tasks` per controllare il numero di attività quantistiche create. [Il processo ibrido lo acquisisce automaticamente come iperparametro.](braket-jobs-hyperparameters.md)

**Nota**  
Gli iperparametri vengono visualizzati nella console Braket come stringhe, limitate a 2500 caratteri. 

**Metriche e registrazione** 

All'interno della `run_hybrid_job()` funzione, vengono registrate le metriche degli algoritmi iterativi con. `log_metrics` Le metriche vengono tracciate automaticamente nella pagina della console Braket nella scheda del lavoro ibrido. [Puoi utilizzare le metriche per tracciare i costi quantistici delle attività in tempo quasi reale durante l'esecuzione del lavoro ibrido con il tracker dei costi di Braket.](braket-pricing.md) [L'esempio precedente utilizza il nome della metrica «probabilità» che registra la prima probabilità del tipo di risultato.](braket-result-types.md)

**Recupero dei risultati** 

Una volta completato il lavoro ibrido, si utilizza `job.result()` per recuperare i risultati dei lavori ibridi. Tutti gli oggetti nell'istruzione return vengono acquisiti automaticamente da Braket. Nota che gli oggetti restituiti dalla funzione devono essere una tupla con ogni elemento serializzabile. Ad esempio, il codice seguente mostra un esempio funzionante e uno non riuscito. 

```
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 del lavoro** 

Per impostazione predefinita, il nome di questo lavoro ibrido viene dedotto dal nome della funzione. È inoltre possibile specificare un nome personalizzato lungo fino a 50 caratteri. Ad esempio, nel codice seguente il nome del lavoro è "my-job-name».

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

**modalità locale** 

I [lavori locali](braket-jobs-local-mode.md) vengono creati aggiungendo l'argomento `local=True` al decoratore. Questo esegue il lavoro ibrido in un ambiente containerizzato sull'ambiente di elaborazione locale, ad esempio il laptop. I lavori locali **non** prevedono la priorità delle code per le attività quantistiche. Per casi avanzati come multi-nodo o MPI, i job locali possono avere accesso alle variabili di ambiente Braket richieste. Il codice seguente crea un processo ibrido locale con il dispositivo come simulatore. SV1 

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

Sono supportate tutte le altre opzioni di lavoro ibride. Per un elenco di opzioni, consultate il modulo [braket.jobs.quantum\$1job\$1creation](https://amazon-braket-sdk-python.readthedocs.io/en/stable/_apidoc/braket.jobs.quantum_job_creation.html). 

## Installa pacchetti Python e codice sorgente aggiuntivi
<a name="install-python-packages-and-code"></a>

Puoi personalizzare il tuo ambiente di runtime per usare i tuoi pacchetti Python preferiti. È possibile utilizzare un `requirements.txt` file, un elenco di nomi di pacchetti o [portare il proprio contenitore (BYOC)](braket-jobs-byoc.md). Ad esempio, il `requirements.txt` file può includere altri pacchetti da installare.

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

Per personalizzare un ambiente di runtime utilizzando un `requirements.txt` file, fate riferimento al seguente esempio di codice.

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

In alternativa, puoi fornire i nomi dei pacchetti come elenco Python come segue.

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

Il codice sorgente aggiuntivo può essere specificato come elenco di moduli o come singolo modulo come nel seguente esempio di codice. 

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

## Salva e carica i dati in un'istanza di lavoro ibrida
<a name="save-load-data-into-instance"></a>

**Specificazione dei dati di addestramento in ingresso**

Quando crei un lavoro ibrido, puoi fornire un set di dati di addestramento di input specificando un bucket Amazon Simple Storage Service (Amazon S3). Puoi anche specificare un percorso locale, quindi Braket carica automaticamente i dati su Amazon S3 all'indirizzo. `s3://<default_bucket_name>/jobs/<job_name>/<timestamp>/data/<channel_name>` Se specifichi un percorso locale, il nome del canale è predefinito su «input». Il codice seguente mostra un file numpy dal percorso locale. `data/file.npy` 

```
import numpy as np


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

Per S3, è necessario utilizzare la funzione di `get_input_data_dir()` supporto.

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

È possibile specificare più fonti di dati di input fornendo un dizionario dei valori dei canali e dei percorsi URIs S3 o locali. 

```
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 i dati di input sono di grandi dimensioni (>1 GB), c'è un lungo tempo di attesa prima che il lavoro venga creato. Ciò è dovuto ai dati di input locali che vengono caricati per la prima volta in un bucket S3, quindi il percorso S3 viene aggiunto alla richiesta di lavoro. Infine, la richiesta di lavoro viene inviata al servizio Braket.

**Salvataggio dei risultati su S3**

Per salvare i risultati non inclusi nell'istruzione return della funzione decorata, è necessario aggiungere la directory corretta a tutte le operazioni di scrittura dei file. L'esempio seguente mostra il salvataggio di un array numpy e di una 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 ...
```

Tutti i risultati vengono compressi in un file denominato. `model.tar.gz` Puoi scaricare i risultati con la funzione `job.result()` Python o accedendo alla cartella dei risultati dalla pagina del lavoro ibrido nella console di gestione Braket. 

**Salvataggio e ripresa dai checkpoint**

Per lavori ibridi di lunga durata, si consiglia di salvare periodicamente lo stato intermedio dell'algoritmo. È possibile utilizzare la funzione di `save_job_checkpoint()` supporto integrata o salvare i file nel percorso. `AMZN_BRAKET_JOB_RESULTS_DIR` Quest'ultima è disponibile con la funzione helper. `get_job_results_dir()`

Quello che segue è un esempio di funzionamento minimo per salvare e caricare i checkpoint con un Job Decorator ibrido:

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

Nel primo job ibrido, `save_job_checkpoint()` viene chiamato con un dizionario contenente i dati che vogliamo salvare. Per impostazione predefinita, ogni valore deve essere serializzabile come testo. Per controllare oggetti Python più complessi, come gli array numpy, puoi impostare. `data_format = PersistedJobDataFormat.PICKLED_V4` Questo codice crea e sovrascrive un file di checkpoint con nome predefinito negli artefatti del job ibrido `<jobname>.json` in una sottocartella chiamata «checkpoints».

Per creare un nuovo lavoro ibrido che prosegua dal checkpoint, dobbiamo indicare `copy_checkpoints_from_job=job_arn` `job_arn` dov'è l'ARN del lavoro ibrido del lavoro precedente. Quindi eseguiamo `load_job_checkpoint(job_name)` il caricamento dal checkpoint.

## Le migliori pratiche per arredatori di lavori ibridi
<a name="best-practices"></a>

**Abbraccia l'asincronicità**

I lavori ibridi creati con l'annotazione decorator sono asincroni: vengono eseguiti non appena le risorse classiche e quantistiche sono disponibili. Monitora l'avanzamento dell'algoritmo utilizzando Braket Management Console o Amazon CloudWatch. Quando invii l'algoritmo per l'esecuzione, Braket lo esegue in un ambiente containerizzato scalabile e i risultati vengono recuperati quando l'algoritmo è completo.

**Esegui algoritmi variazionali iterativi**

Hybrid jobs ti offre gli strumenti per eseguire algoritmi iterativi quantistici classici. [Per problemi puramente quantistici, utilizzate attività quantistiche o una serie di [attività quantistiche](braket-submit-tasks.md).](braket-batching-tasks.md) L'accesso prioritario a determinati QPUs è particolarmente vantaggioso per gli algoritmi variazionali di lunga durata che richiedono più chiamate iterative a o con l'elaborazione classica intermedia. QPUs 

**Esegui il debug utilizzando la modalità locale**

Prima di eseguire un job ibrido su una QPU, si consiglia di eseguirlo prima sul simulatore SV1 per confermare che funzioni come previsto. Per i test su piccola scala, puoi eseguirli in modalità locale per iterazioni e debug rapidi. 

**[Migliora la riproducibilità con Bring your own container (BYOC)](braket-jobs-byoc.md)**

Crea un esperimento riproducibile incapsulando il tuo software e le sue dipendenze in un ambiente containerizzato. Comprimendo tutto il codice, le dipendenze e le impostazioni in un contenitore, si evitano potenziali conflitti e problemi di versione. 

**Simulatori distribuiti a più istanze**

Per eseguire un gran numero di circuiti, prendi in considerazione l'utilizzo del supporto MPI integrato per eseguire simulatori locali su più istanze all'interno di un singolo processo ibrido. [Per ulteriori informazioni, consulta Simulatori incorporati.](pennylane-embedded-simulators.md)

**Usa circuiti parametrici**

I circuiti parametrici inviati da un processo ibrido vengono compilati automaticamente su determinati circuiti QPUs utilizzando la [compilazione parametrica](braket-jobs-parametric-compilation.md) per migliorare i tempi di esecuzione degli algoritmi. 

**Checkpoint periodicamente**

Per lavori ibridi di lunga durata, si consiglia di salvare periodicamente lo stato intermedio dell'algoritmo. 

**Per ulteriori esempi, casi d'uso e best practice, consulta gli esempi di [Amazon GitHub Braket](https://github.com/amazon-braket/amazon-braket-examples).**