Skip to content

Commit

Permalink
Connect to OQD device runtime from Python layer (#1420)
Browse files Browse the repository at this point in the history
**Context:**
A boilerplate Python OQD device was added in PR #1355. We want to verify
that the infrastructure introduced in that PR is sufficient to generate
OpenAPL in the runtime.

**Description of the Change:**
Added get_c_interface method for the OQD device to be able to point to
the c++ implementation of the device in python.
This makes qjit to accept an instance of the OQD device and be able to
connect to its runtime.

**Benefits:**
This allows for OQD runtime to be exposed to python, unlocking the next
steps which are implementing the llvm lowering and the runtime methods.

**Possible Drawbacks:**

**Related GitHub Issues:**
[sc-73709]

---------

Co-authored-by: Joey Carter <[email protected]>
  • Loading branch information
mehrdad2m and joeycarter authored Jan 9, 2025
1 parent 15030f4 commit fa72766
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 2 deletions.
9 changes: 8 additions & 1 deletion doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

<h3>Internal changes ⚙️</h3>

* The `get_c_interface` method has been added to the OQD device, which enables retrieval of the C++
implementation of the device from Python. This allows `qjit` to accept an instance of the device
and connect to its runtime.
[(#1420)](https://github.com/PennyLaneAI/catalyst/pull/1420)

* `from_plxpr` now uses the `qml.capture.PlxprInterpreter` class for reduced code duplication.
[(#1398)](https://github.com/PennyLaneAI/catalyst/pull/1398)

Expand All @@ -21,4 +26,6 @@

This release contains contributions from (in alphabetical order):

Christina Lee
Christina Lee
Mehrdad Malekmohammadi

14 changes: 13 additions & 1 deletion frontend/catalyst/third_party/oqd/oqd_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
trapped-ion quantum computer device.
"""
from typing import Optional
import platform

from pennylane.devices import Device, ExecutionConfig
from pennylane.transforms.core import TransformProgram
Expand All @@ -33,7 +34,18 @@ class OQDDevice(Device):

config_filepath = get_lib_path("oqd_runtime", "OQD_LIB_DIR") + "/backend" + "/oqd.toml"

def __init__(self, wires, backend, shots, **kwargs):
@staticmethod
def get_c_interface():
"""Returns a tuple consisting of the device name, and
the location to the shared object with the C/C++ device implementation.
"""

system_extension = ".dylib" if platform.system() == "Darwin" else ".so"
lib_path = get_lib_path("oqd_runtime", "OQD_LIB_DIR") + "/librtd_oqd" + system_extension

return "oqd", lib_path

def __init__(self, wires, shots, backend="default", **kwargs):
self._backend = backend
_check_backend(backend=backend)
super().__init__(wires=wires, shots=shots, **kwargs)
Expand Down
69 changes: 69 additions & 0 deletions frontend/test/test_oqd/oqd/test_oqd_device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright 2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for the OQD device.
"""

import pennylane as qml
import pytest

from catalyst.third_party.oqd import OQDDevice


class TestOQDDevice:
"""Test the OQD device python layer for Catalyst."""

def test_initialization(self):
"""Test the initialization."""

device = OQDDevice(backend="default", shots=1000, wires=8)

assert device.backend == "default"
assert device.shots == qml.measurements.Shots(1000)
assert device.wires == qml.wires.Wires(range(0, 8))

def test_wrong_backend(self):
"""Test the backend check."""
with pytest.raises(ValueError, match="The backend random_backend is not supported."):
OQDDevice(backend="random_backend", shots=1000, wires=8)

def test_execute_not_implemented(self):
"""Test the python execute is not implemented."""
with pytest.raises(NotImplementedError, match="The OQD device only supports Catalyst."):
dev = OQDDevice(backend="default", shots=1000, wires=8)
dev.execute([], [])

def test_preprocess(self):
"""Test the device preprocessing"""
dev = OQDDevice(backend="default", shots=1000, wires=8)
tranform_program, _ = dev.preprocess()
assert tranform_program == qml.transforms.core.TransformProgram()

def test_preprocess_with_config(self):
"""Test the device preprocessing by explicitly passing an execution config"""
dev = OQDDevice(backend="default", shots=1000, wires=8)
execution_config = qml.devices.ExecutionConfig()
tranform_program, config = dev.preprocess(execution_config)
assert tranform_program == qml.transforms.core.TransformProgram()
assert config == execution_config

def test_get_c_interface(self):
"""Test the device get_c_interface method."""
dev = OQDDevice(backend="default", shots=1000, wires=8)
name, _ = dev.get_c_interface()
assert name == "oqd"


if __name__ == "__main__":
pytest.main(["-x", __file__])

0 comments on commit fa72766

Please sign in to comment.