Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cmake/prefix_defs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ QDMI_device_job_get_results
QDMI_device_session_query_device_property
QDMI_device_session_query_site_property
QDMI_device_session_query_operation_property
QDMI_device_session_query_pulse_parameter_property
QDMI_device_session_query_pulse_waveform_property
QDMI_device_session_query_pulse_implementation_property
QDMI_Device_Session
QDMI_Device_Session_impl_d
QDMI_Device_Job
Expand All @@ -24,3 +27,9 @@ QDMI_Site
QDMI_Site_impl_d
QDMI_Operation
QDMI_Operation_impl_d
QDMI_Pulse_Parameter
QDMI_Pulse_Parameter_impl_d
QDMI_Pulse_Waveform
QDMI_Pulse_Waveform_impl_d
QDMI_Pulse_Implementation
QDMI_Pulse_Implementation_impl_d
30 changes: 29 additions & 1 deletion examples/device/c/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "c_qdmi/device.h"

#include "c_qdmi/types.h"

Comment on lines +26 to +27
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "c_qdmi/types.h"

Iirc, this should not be necessary since the header above already re-exposes the types header.

#include <math.h>
#include <stddef.h>
#include <stdint.h>
Expand Down Expand Up @@ -727,7 +729,7 @@ int C_QDMI_device_session_query_device_property(C_QDMI_Device_Session session,

ADD_SINGLE_VALUE_PROPERTY(
QDMI_DEVICE_PROPERTY_PULSESUPPORT, QDMI_Device_Pulse_Support_Level,
QDMI_DEVICE_PULSE_SUPPORT_LEVEL_NONE, prop, size, value, size_ret)
QDMI_DEVICE_PULSE_SUPPORT_LEVEL_SITE, prop, size, value, size_ret)

return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]
Expand Down Expand Up @@ -846,3 +848,29 @@ int C_QDMI_device_session_query_operation_property(
}
return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]

struct C_QDMI_Pulse_Implementation_impl_d {};
struct C_QDMI_Pulse_Waveform_impl_t {};
struct C_QDMI_Pulse_Implementation_impl_t {};
Comment on lines +853 to +854
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The types, i.e., the structure names ending with _t should not needed to be redefined by the device, actually, this should lead to a compiler error because of redefinition. Am I overseeing something?


int C_QDMI_device_session_query_pulse_parameter_property(
C_QDMI_Device_Session session, C_QDMI_Pulse_Parameter param,
const QDMI_Pulse_Parameter_Property prop, const size_t size, void *value,
size_t *size_ret) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if no property is supported, the function is expected to validate its arguments and return QDMI_ERROR_INVALIDARGUMENT if necessary. That has higher priority than QDMI_ERROR_NOTSUPPORTED.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment also applies to the two subsequent functions.

return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]

int C_QDMI_device_session_query_pulse_waveform_property(
C_QDMI_Device_Session session, C_QDMI_Pulse_Waveform waveform,
const QDMI_Pulse_Waveform_Property prop, const size_t size, void *value,
size_t *size_ret) {
return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]

int C_QDMI_device_session_query_pulse_implementation_property(
C_QDMI_Device_Session session, C_QDMI_Pulse_Implementation impl,
const QDMI_Pulse_Implementation_Property prop, const size_t size,
void *value, size_t *size_ret) {
return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]
160 changes: 158 additions & 2 deletions examples/device/cxx/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "cxx_qdmi/device.h"

#include "cxx_qdmi/types.h"
#include "qdmi/constants.h"
Comment on lines +27 to +28
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those should all be re-exported by the device header and not needed here. In particular, including headers from the directory with the prefixed headers and from the main include directory does not seem clean to me.

Suggested change
#include "cxx_qdmi/types.h"
#include "qdmi/constants.h"


#include <algorithm>
#include <array>
#include <cmath>
Expand All @@ -36,6 +39,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include <map>
#include <random>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -78,6 +82,17 @@ struct CXX_QDMI_Operation_impl_d {
std::string name;
};

struct CXX_QDMI_Pulse_Parameter_impl_d {
std::string name;
};

struct CXX_QDMI_Pulse_Waveform_impl_d {
std::string name;
};

struct CXX_QDMI_Pulse_Implementation_impl_d {
std::string operation_name;
};
namespace {
/**
* @brief Static function to maintain the device state.
Expand Down Expand Up @@ -212,7 +227,57 @@ const std::unordered_map<
{{CXX_DEVICE_SITES[0], CXX_DEVICE_SITES[4]}, 0.95}}},
// No need to specify single-qubit fidelities here
};
} // namespace

const CXX_QDMI_Pulse_Parameter_impl_d AMPLITUDE{"A"};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand that correctly, than only "A" is transferred as the name of the parameter through QDMI. Is that standardized anywhere? If not, I propose to use a more comprehensive name, i.e., "amplitude". Similar reasoning applies to the next one.

const CXX_QDMI_Pulse_Parameter_impl_d TIME{"t"};
const CXX_QDMI_Pulse_Parameter_impl_d SIGMA{"sigma"};

const CXX_QDMI_Pulse_Waveform_impl_d GAUSSIAN{"gaussian"};

std::array<const CXX_QDMI_Pulse_Parameter_impl_d *, 3>
GAUSSIAN_PULSE_PARAMETERS = {&AMPLITUDE, &TIME, &SIGMA};

const std::unordered_map<const CXX_QDMI_Pulse_Parameter_impl_d *,
std::tuple<double, double, bool>>
GAUSSIAN_PULSE_PARAMETERS_PROPERTIES = {
{&AMPLITUDE, {0.3, 0.7, true}},
{&TIME,
{-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity(), true}},
{&SIGMA, {10.0, 20.0, true}},
Comment on lines +243 to +247
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though QDMI does not define it, I propose to define a struct containing the three respective properties for a parameter instead of a tuple. This give the code better clearity as the different entries are than accessed via a meaningful name.

};
const std::unordered_map<
const CXX_QDMI_Pulse_Waveform_impl_d *,
std::pair<std::string,
std::array<const CXX_QDMI_Pulse_Parameter_impl_d *, 3>>>
PULSE_WAVEFORMS = {
{&GAUSSIAN, {"A * e^(-(t / sigma)^2)", GAUSSIAN_PULSE_PARAMETERS}}};

const CXX_QDMI_Pulse_Implementation_impl_d RX_PULSE_IMPLEMENTATION = {"rx"};
const CXX_QDMI_Pulse_Implementation_impl_d RY_PULSE_IMPLEMENTATION = {"ry"};
const CXX_QDMI_Pulse_Implementation_impl_d RZ_PULSE_IMPLEMENTATION = {"rz"};
const CXX_QDMI_Pulse_Implementation_impl_d CX_PULSE_IMPLEMENTATION = {"cx"};

const std::unordered_map<const CXX_QDMI_Operation_impl_d *,
const CXX_QDMI_Pulse_Implementation_impl_d *>
OPERATION_PULSE_IMPLEMENTATIONS = {
{CXX_DEVICE_OPERATIONS[0], &RX_PULSE_IMPLEMENTATION},
{CXX_DEVICE_OPERATIONS[1], &RY_PULSE_IMPLEMENTATION},
{CXX_DEVICE_OPERATIONS[2], &RZ_PULSE_IMPLEMENTATION},
{CXX_DEVICE_OPERATIONS[3], &CX_PULSE_IMPLEMENTATION}};

const std::unordered_map<
const CXX_QDMI_Pulse_Implementation_impl_d *,
std::pair<const CXX_QDMI_Pulse_Waveform_impl_d *,
std::array<const CXX_QDMI_Pulse_Parameter_impl_d *, 3>>>
OPERATION_PULSE_IMPLEMENTATIONS_PROPERTIES = {
{&RX_PULSE_IMPLEMENTATION, {&GAUSSIAN, GAUSSIAN_PULSE_PARAMETERS}},
{&RY_PULSE_IMPLEMENTATION, {&GAUSSIAN, GAUSSIAN_PULSE_PARAMETERS}},
{&RZ_PULSE_IMPLEMENTATION, {&GAUSSIAN, GAUSSIAN_PULSE_PARAMETERS}},
{&CX_PULSE_IMPLEMENTATION, {&GAUSSIAN, GAUSSIAN_PULSE_PARAMETERS}},
};

}; // namespace

// NOLINTBEGIN(bugprone-macro-parentheses)
#define ADD_SINGLE_VALUE_PROPERTY(prop_name, prop_type, prop_value, prop, \
Expand Down Expand Up @@ -776,7 +841,7 @@ int CXX_QDMI_device_session_query_device_property(

ADD_SINGLE_VALUE_PROPERTY(
QDMI_DEVICE_PROPERTY_PULSESUPPORT, QDMI_Device_Pulse_Support_Level,
QDMI_DEVICE_PULSE_SUPPORT_LEVEL_NONE, prop, size, value, size_ret)
QDMI_DEVICE_PULSE_SUPPORT_LEVEL_SITE, prop, size, value, size_ret)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that I a rather random place for this comment but this just came to my mind: To align this enum value to the naming convention throughout QDMI, I propose QDMI_DEVICE_PULSESUPPORT_SITE.


return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]
Expand Down Expand Up @@ -821,10 +886,17 @@ int CXX_QDMI_device_session_query_operation_property(
prop != QDMI_OPERATION_PROPERTY_CUSTOM5)) {
return QDMI_ERROR_INVALIDARGUMENT;
}

// General properties
ADD_STRING_PROPERTY(QDMI_OPERATION_PROPERTY_NAME,
OPERATION_PROPERTIES.at(operation).first.c_str(), prop,
size, value, size_ret)
ADD_SINGLE_VALUE_PROPERTY(QDMI_OPERATION_PROPERTY_PULSEIMPLEMENTATION,
CXX_QDMI_Pulse_Implementation,
const_cast<CXX_QDMI_Pulse_Implementation>(
OPERATION_PULSE_IMPLEMENTATIONS.at(operation)),
prop, size, value, size_ret)

if (operation == CXX_DEVICE_OPERATIONS[3]) {
if (sites != nullptr && num_sites != 2) {
return QDMI_ERROR_INVALIDARGUMENT;
Expand Down Expand Up @@ -873,3 +945,87 @@ int CXX_QDMI_device_session_query_operation_property(
}
return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]

int CXX_QDMI_device_session_query_pulse_parameter_property(
CXX_QDMI_Device_Session session, CXX_QDMI_Pulse_Parameter param,
const QDMI_Pulse_Parameter_Property prop, const size_t size, void *value,
size_t *size_ret) {
if (session == nullptr || (value != nullptr && size == 0) ||
(prop >= QDMI_PULSE_PARAMETER_PROPERTY_MAX &&
prop != QDMI_PULSE_PARAMETER_PROPERTY_CUSTOM1 &&
prop != QDMI_PULSE_PARAMETER_PROPERTY_CUSTOM2 &&
prop != QDMI_PULSE_PARAMETER_PROPERTY_CUSTOM3 &&
prop != QDMI_PULSE_PARAMETER_PROPERTY_CUSTOM4 &&
prop != QDMI_PULSE_PARAMETER_PROPERTY_CUSTOM5)) {
return QDMI_ERROR_INVALIDARGUMENT;
}

auto [range_min, range_max, is_mutable] =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto [range_min, range_max, is_mutable] =
const auto& [range_min, range_max, is_mutable] =

Saves some copies.

GAUSSIAN_PULSE_PARAMETERS_PROPERTIES.at(param);

ADD_STRING_PROPERTY(QDMI_PULSE_PARAMETER_PROPERTY_NAME, param->name.c_str(),
prop, size, value, size_ret)
ADD_SINGLE_VALUE_PROPERTY(QDMI_PULSE_PARAMETER_PROPERTY_RANGEMIN, double,
range_min, prop, size, value, size_ret)
ADD_SINGLE_VALUE_PROPERTY(QDMI_PULSE_PARAMETER_PROPERTY_RANGEMAX, double,
range_max, prop, size, value, size_ret)
ADD_SINGLE_VALUE_PROPERTY(QDMI_PULSE_PARAMETER_PROPERTY_MUTABLE, bool,
is_mutable, prop, size, value, size_ret)

return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]

int CXX_QDMI_device_session_query_pulse_waveform_property(
CXX_QDMI_Device_Session session, CXX_QDMI_Pulse_Waveform waveform,
const QDMI_Pulse_Waveform_Property prop, const size_t size, void *value,
size_t *size_ret) {
if (session == nullptr || waveform == nullptr ||
(value != nullptr && size == 0) ||
(prop >= QDMI_PULSE_WAVEFORM_PROPERTY_MAX &&
prop != QDMI_PULSE_WAVEFORM_PROPERTY_CUSTOM1 &&
prop != QDMI_PULSE_WAVEFORM_PROPERTY_CUSTOM2 &&
prop != QDMI_PULSE_WAVEFORM_PROPERTY_CUSTOM3 &&
prop != QDMI_PULSE_WAVEFORM_PROPERTY_CUSTOM4 &&
prop != QDMI_PULSE_WAVEFORM_PROPERTY_CUSTOM5)) {
return QDMI_ERROR_INVALIDARGUMENT;
}

ADD_STRING_PROPERTY(QDMI_PULSE_WAVEFORM_PROPERTY_NAME, waveform->name.c_str(),
prop, size, value, size_ret)
ADD_STRING_PROPERTY(QDMI_PULSE_WAVEFORM_PROPERTY_FORMULA,
PULSE_WAVEFORMS.at(waveform).first.c_str(), prop, size,
value, size_ret)
ADD_LIST_PROPERTY(
QDMI_PULSE_WAVEFORM_PROPERTY_PARAMETERS, CXX_QDMI_Pulse_Parameter,
PULSE_WAVEFORMS.at(waveform).second, prop, size, value, size_ret)

return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]

int CXX_QDMI_device_session_query_pulse_implementation_property(
CXX_QDMI_Device_Session session, CXX_QDMI_Pulse_Implementation impl,
const QDMI_Pulse_Implementation_Property prop, const size_t size,
void *value, size_t *size_ret) {
if (session == nullptr || impl == nullptr ||
(value != nullptr && size == 0) ||
(prop >= QDMI_PULSE_IMPLEMENTATION_PROPERTY_MAX &&
prop != QDMI_PULSE_IMPLEMENTATION_PROPERTY_CUSTOM1 &&
prop != QDMI_PULSE_IMPLEMENTATION_PROPERTY_CUSTOM2 &&
prop != QDMI_PULSE_IMPLEMENTATION_PROPERTY_CUSTOM3 &&
prop != QDMI_PULSE_IMPLEMENTATION_PROPERTY_CUSTOM4 &&
prop != QDMI_PULSE_IMPLEMENTATION_PROPERTY_CUSTOM5)) {
return QDMI_ERROR_INVALIDARGUMENT;
}
ADD_SINGLE_VALUE_PROPERTY(
QDMI_PULSE_IMPLEMENTATION_PROPERTY_PULSEWAVEFORM, CXX_QDMI_Pulse_Waveform,
const_cast<CXX_QDMI_Pulse_Waveform>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this const_cast is necessary, right? Just to double-check that it is not superfluous. Feel free to resolve immediately.

OPERATION_PULSE_IMPLEMENTATIONS_PROPERTIES.at(impl).first),
prop, size, value, size_ret)

ADD_LIST_PROPERTY(QDMI_PULSE_IMPLEMENTATION_PROPERTY_PULSEPARAMETERS,
CXX_QDMI_Pulse_Parameter,
OPERATION_PULSE_IMPLEMENTATIONS_PROPERTIES.at(impl).second,
prop, size, value, size_ret)

return QDMI_ERROR_NOTSUPPORTED;
} /// [DOXYGEN FUNCTION END]
52 changes: 51 additions & 1 deletion examples/driver/qdmi_example_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "qdmi/client.h"
#include "qdmi/device.h"
#include "qdmi/types.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "qdmi/types.h"

Same reason as above.


#include <algorithm>
#include <cstdint>
Expand Down Expand Up @@ -102,7 +103,18 @@ struct QDMI_Library {
/// Function pointer to @ref QDMI_device_session_query_operation_property.
decltype(QDMI_device_session_query_operation_property)
*device_session_query_operation_property{};

/// Function pointer to @ref
/// QDMI_device_session_query_pulse_parameter_property.
decltype(QDMI_device_session_query_pulse_parameter_property)
*device_session_query_pulse_parameter_property{};
/// Function pointer to @ref
/// QDMI_device_session_query_pulse_waveform_property.
decltype(QDMI_device_session_query_pulse_waveform_property)
*device_session_query_pulse_waveform_property{};
/// Function pointer to @ref
/// QDMI_device_session_query_pulse_implementation_property.
decltype(QDMI_device_session_query_pulse_implementation_property)
*device_session_query_pulse_implementation_property{};
// default constructor
QDMI_Library() = default;

Expand Down Expand Up @@ -219,6 +231,10 @@ void QDMI_library_load(const std::string &lib_name, const std::string &prefix) {
LOAD_SYMBOL(library, prefix, device_session_query_device_property)
LOAD_SYMBOL(library, prefix, device_session_query_site_property)
LOAD_SYMBOL(library, prefix, device_session_query_operation_property)
LOAD_SYMBOL(library, prefix, device_session_query_pulse_parameter_property)
LOAD_SYMBOL(library, prefix, device_session_query_pulse_waveform_property)
LOAD_SYMBOL(library, prefix,
device_session_query_pulse_implementation_property)

// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
} catch (const std::exception &) {
Expand Down Expand Up @@ -528,3 +544,37 @@ int QDMI_device_query_operation_property(
device->device_session, operation, num_sites, sites, num_params, params,
prop, size, value, size_ret);
}

int QDMI_device_query_pulse_parameter_property(
QDMI_Device device, QDMI_Pulse_Parameter parameter,
QDMI_Pulse_Parameter_Property prop, const size_t size, void *value,
size_t *size_ret) {
if (device == nullptr) {
return QDMI_ERROR_INVALIDARGUMENT;
}
return device->library->device_session_query_pulse_parameter_property(
device->device_session, parameter, prop, size, value, size_ret);
}

int QDMI_device_query_pulse_waveform_property(QDMI_Device device,
QDMI_Pulse_Waveform waveform,
QDMI_Pulse_Waveform_Property prop,
const size_t size, void *value,
size_t *size_ret) {
if (device == nullptr) {
return QDMI_ERROR_INVALIDARGUMENT;
}
return device->library->device_session_query_pulse_waveform_property(
device->device_session, waveform, prop, size, value, size_ret);
}

int QDMI_device_query_pulse_implementation_property(
QDMI_Device device, QDMI_Pulse_Implementation implementation,
QDMI_Pulse_Implementation_Property prop, const size_t size, void *value,
size_t *size_ret) {
if (device == nullptr) {
return QDMI_ERROR_INVALIDARGUMENT;
}
return device->library->device_session_query_pulse_implementation_property(
device->device_session, implementation, prop, size, value, size_ret);
}
Loading