Skip to content
Pasqal Documentation

Tutorial 1: using a Quantum Device to extract machine-learning features

As in any machine learning task, we first need to load and prepare data. QEK can work with many types of graphs, including molecular graphs. For this tutorial, we will use the PTC-FM dataset, which contains such molecular graphs, labeled with their toxicity.

import torch_geometric.datasets as pyg_dataset
from qek.shared.retrier import PygRetrier
# Load the original PTC-FM dataset.
# We use PygRetrier to retry the download if it fails.
og_ptcfm = PygRetrier().insist(pyg_dataset.TUDataset, root="dataset", name="PTC_FM")
display("Loaded %s samples" % (len(og_ptcfm), ))
import qek.data.graphs as qek_graphs
compiler = qek_graphs.PTCFMCompiler()

Creating and executing a feature extractor from an emulator

Section titled “Creating and executing a feature extractor from an emulator”

The easiest way to process a graph is to compile and execute it for an emulator. QEK is built on top of Pulser, which provides several emulators. The simplest of these emulators is the QutipEmulator, which QEK uses for the QutipExtractor:

from pathlib import Path
import qek.data.extractors as qek_extractors
# Use the Qutip Extractor.
extractor = qek_extractors.QutipExtractor(
# Once computing is complete, data will be saved in this file.
path=Path("saved_data.json"),
compiler=compiler
)
# Add the graphs using the compiler we've picked previously.
extractor.add_graphs(graphs=og_ptcfm)
# We may now compile them.
compiled = extractor.compile()
display("Compiled %s sequences" % (len(compiled), ))
# Limit the number of qubits for this run, for performance reasons.
# You can increase this value to higher number of qubits, but this
# notebook will take longer to execute and may run out of memory.
#
# On our test computer, the practical limit is around 10 qubits.
max_qubits = 5
processed_dataset = extractor.run(max_qubits=max_qubits).processed_data
display("Extracted features from %s samples"% (len(processed_dataset), ))

Creating and executing a feature extractor on a physical QPU

Section titled “Creating and executing a feature extractor on a physical QPU”

Once you have checked that low qubit sequences provide the results you expect on an emulator, you will generally want to move to a QPU. For this, you will need either physical access to a QPU, or an account with PASQAL Cloud (external), which provides you remote access to QPUs built and hosted by Pasqal. In this section, we'll see how to use the latter.

If you don't have an account, just skip to the next section!

from pathlib import Path
HAVE_PASQAL_ACCOUNT = False # If you have a PASQAL Cloud account, fill in the details and set this to `True`.
if HAVE_PASQAL_ACCOUNT:
# Use the QPU Extractor.
extractor = qek_extractors.RemoteQPUExtractor(
# Once computing is complete, data will be saved in this file.
path=Path("saved_data.json"),
compiler = compiler,
project_id = "XXXX", # Replace this with your project id on the PASQAL Cloud
username = "XXX", # Replace this with your username on PASQAL Cloud
password = None, # Replace this with your password on PASQAL Cloud or enter it on the command-line
)
# Add the graphs, exactly as above.
extractor.add_graphs(graphs=og_ptcfm)
# We may now compile, exactly as above.
compiled = extractor.compile()
display("Compiled %s sequences" % (len(compiled), ))
# Launch the execution.
extracted = extractor.run()
display("Work enqueued with ids %s" % (extractor.batch_ids, ))
# ...and wait for the results.
await extracted
processed_data = extracted.processed_data
display("Extracted features from %s samples"% (len(processed_data), ))

For this notebook, instead of spending hours running the simulator on your computer, we're going to skip this step and load on we're going to cheat and load the results, which are conveniently stored in ptcfm_processed_dataset.json.

import qek.data.processed_data as qek_dataset
processed_dataset = qek_dataset.load_dataset(file_path="ptcfm_processed_dataset.json")
print(f"Size of the quantum compatible dataset = {len(processed_dataset)}")
dataset_example = processed_dataset[64]
dataset_example.draw_register()
dataset_example.draw_pulse()
display(dataset_example.state_dict)
print(f"Total number of samples: {sum(dataset_example.state_dict.values())}")

From the state dictionary, we derive as machine-learning feature the distribution of excitation. We'll use this in a second to define our kernel.

dataset_example.draw_excitation()

What we have seen so far covers the use of a Quantum Device to extract machine-learning features.

For the next step, we'll see how to use these features for actual machine learning.