CUDA-QX Namespaces and Core Library C++ API

Namespaces

namespace cudaqx
namespace cudaq
namespace qec
namespace steane
namespace repetition
namespace solvers
namespace stateprep
namespace adapt
namespace optim

Core

template<typename T, typename ...CtorArgs>
class extension_point

A template class for implementing an extension point mechanism.

This class provides a framework for registering and retrieving plugin-like extensions. It allows dynamic creation of objects based on registered types.

How to use the extension_point class

The extension_point class provides a mechanism for creating extensible frameworks with plugin-like functionality. Here’s how to use it:

  1. Define your extension point: Create a new class that inherits from cudaq::extension_point<YourClass>. This class should declare pure virtual methods that extensions will implement.

class MyExtensionPoint : public cudaq::extension_point<MyExtensionPoint> {
public:
  virtual std::string parrotBack(const std::string &msg) const = 0;
};

  1. Implement concrete extensions: Create classes that inherit from your extension point and implement its methods. Use the CUDAQ_EXTENSION_CREATOR_FUNCTION macro to define a creator function.

class RepeatBackOne : public MyExtensionPoint {
public:
  std::string parrotBack(const std::string &msg) const override {
    return msg + " from RepeatBackOne.";
  }

  CUDAQ_EXTENSION_CREATOR_FUNCTION(MyExtensionPoint, RepeatBackOne)
};

  1. Register your extensions: Use the CUDAQ_REGISTER_TYPE macro to register each extension.

CUDAQ_REGISTER_TYPE(RepeatBackOne)

  1. Use your extensions: You can now create instances of your extensions, check registrations, and more.

auto extension = MyExtensionPoint::get("RepeatBackOne");
std::cout << extension->parrotBack("Hello") << std::endl;

auto registeredTypes = MyExtensionPoint::get_registered();
bool isRegistered = MyExtensionPoint::is_registered("RepeatBackOne");

This approach allows for a flexible, extensible design where new functionality can be added without modifying existing code.

Template Parameters:
  • T – The base type of the extensions.

  • CtorArgs – Variadic template parameters for constructor arguments.

Subclassed by cudaqx::details::tensor_impl< Scalar >

Public Static Functions

static inline std::unique_ptr<T> get(const std::string &name, CtorArgs... args)

Create an instance of a registered extension.

Parameters:
  • name – The identifier of the registered extension.

  • args – Constructor arguments for the extension.

Throws:

std::runtime_error – if the extension is not found.

Returns:

A unique pointer to the created instance.

static inline std::vector<std::string> get_registered()

Get a list of all registered extension names.

Returns:

A vector of registered extension names.

static inline bool is_registered(const std::string &name)

Check if an extension is registered.

Parameters:

name – The identifier of the extension to check.

Returns:

True if the extension is registered, false otherwise.

class heterogeneous_map

A class that implements a heterogeneous map allowing string keys to be mapped to any value type.

Public Functions

heterogeneous_map() = default

Default constructor.

inline heterogeneous_map(const heterogeneous_map &_other)

Copy constructor.

Parameters:

_other – The map to copy from

inline heterogeneous_map(heterogeneous_map &_other)

Move constructor.

Parameters:

_other – The map to move from

inline heterogeneous_map(const std::initializer_list<std::pair<std::string, std::any>> &list)

Constructor from initializer list.

Parameters:

list – The initializer list of key-value pairs

inline void clear()

Clear the map.

inline heterogeneous_map &operator=(const heterogeneous_map &_other)

Assignment operator.

Parameters:

_other – The map to assign from

Returns:

Reference to this map

template<typename T>
inline void insert(const std::string &key, const T &value)

Insert a key-value pair into the map.

Template Parameters:

T – The type of the value

Parameters:
  • key – The key

  • value – The value

template<typename T, typename KeyT, std::enable_if_t<std::is_convertible_v<KeyT, std::string>, int> = 0>
inline const T get(const KeyT &key) const

Get a value from the map.

Template Parameters:

T – The type of the value to retrieve

Parameters:

key – The key of the value to retrieve

Throws:

std::runtime_error – if the key is invalid or the type doesn’t match

Returns:

The value associated with the key

template<typename T>
inline const T get(const std::vector<std::string> &keys) const

Get a value from the map, search for the value from any of the provided string keys.

Template Parameters:

T – The type of the value to retrieve

Parameters:

keys – The keys to search for the desired value.

Throws:

std::runtime_error – if the key is invalid or the type doesn’t match

Returns:

The value associated with the key

template<typename T>
inline const T get(const std::string key, const T &defaultValue) const

Get a value from the map with a default value.

Template Parameters:

T – The type of the value to retrieve

Parameters:
  • key – The key of the value to retrieve

  • defaultValue – The default value to return if the key is not found

Returns:

The value associated with the key or the default value

inline std::size_t size() const

Get the size of the map.

Returns:

The number of key-value pairs in the map

inline bool contains(const std::string &key) const

Check if the map contains a key.

Parameters:

key – The key to check

Returns:

true if the key exists, false otherwise

class tear_down

A base class for tear down services to be run at application shutdown.

This class is designed to be subclassed with concrete tear down routines. Instances of subclasses should be submitted to a global registry which will be run at application shutdown.

Public Functions

virtual void runTearDown() const = 0

Pure virtual function to be implemented by derived classes.

This function should contain the specific tear down logic for each service.

template<typename Scalar = std::complex<double>>
class tensor_impl : public cudaqx::extension_point<tensor_impl<std::complex<double>>, const std::complex<double>*, const std::vector<std::size_t>>

Implementation class for tensor operations following the PIMPL idiom.

Public Types

using scalar_type = Scalar

Type alias for the scalar type used in the tensor.

Public Functions

virtual std::size_t rank() const = 0

Get the rank of the tensor.

Returns:

The rank of the tensor

virtual std::size_t size() const = 0

Get the total size of the tensor.

Returns:

The total number of elements in the tensor

virtual std::vector<std::size_t> shape() const = 0

Get the shape of the tensor.

Returns:

A vector containing the dimensions of the tensor

virtual scalar_type &at(const std::vector<size_t> &indices) = 0

Access a mutable element of the tensor.

Parameters:

indices – The indices of the element to access

Returns:

A reference to the element at the specified indices

virtual const scalar_type &at(const std::vector<size_t> &indices) const = 0

Access a const element of the tensor.

Parameters:

indices – The indices of the element to access

Returns:

A const reference to the element at the specified indices

virtual void copy(const scalar_type *data, const std::vector<std::size_t> &shape) = 0

Copy data into the tensor.

Parameters:
  • data – Pointer to the source data

  • shape – The shape of the source data

virtual void take(const scalar_type *data, const std::vector<std::size_t> &shape) = 0

Take ownership of the given data.

Parameters:
  • data – Pointer to the source data

  • shape – The shape of the source data

virtual void borrow(const scalar_type *data, const std::vector<std::size_t> &shape) = 0

Borrow the given data without taking ownership.

Parameters:
  • data – Pointer to the source data

  • shape – The shape of the source data

virtual scalar_type *data() = 0

Get a pointer to the raw data of the tensor. This method provides direct access to the underlying data storage of the tensor. It returns a pointer to the first element of the data array.

Note

Care should be taken when directly manipulating the raw data to avoid invalidating the tensor’s internal state or violating its invariants.

Returns:

scalar_type* A pointer to the mutable data of the tensor.

virtual const scalar_type *data() const = 0

Get a const pointer to the raw data of the tensor. This method provides read-only access to the underlying data storage of the tensor. It returns a const pointer to the first element of the data array.

Note

This const version ensures that the tensor’s data cannot be modified through the returned pointer, preserving const correctness.

Returns:

const scalar_type * A const pointer to the immutable data of the tensor.

Public Static Functions

static inline std::unique_ptr<tensor_impl<Scalar>> get(const std::string &name, const std::vector<std::size_t> &shape)

Create a tensor implementation with the given name and shape.

Parameters:
  • name – The name of the tensor implementation

  • shape – The shape of the tensor

Throws:

std::runtime_error – if the requested tensor implementation is invalid

Returns:

A unique pointer to the created tensor implementation

static inline std::unique_ptr<tensor_impl<Scalar>> get(const std::string &name, const scalar_type *data, const std::vector<std::size_t> &shape)

Create a tensor implementation with the given name, data, and shape.

Parameters:
  • name – The name of the tensor implementation

  • data – Pointer to the tensor data

  • shape – The shape of the tensor

Throws:

std::runtime_error – if the requested tensor implementation is invalid

Returns:

A unique pointer to the created tensor implementation

template<typename Scalar = std::complex<double>>
class tensor

A tensor class implementing the PIMPL idiom.

Public Types

using scalar_type = details::tensor_impl<Scalar>::scalar_type

Type alias for the scalar type used in the tensor.

Public Functions

inline tensor()

Construct an empty tensor.

inline tensor(const std::vector<std::size_t> &shape)

Construct a tensor with the given shape.

Parameters:

shape – The shape of the tensor

inline tensor(const scalar_type *data, const std::vector<std::size_t> &shape)

Construct a tensor with the given data and shape.

Parameters:
  • data – Pointer to the tensor data

  • shape – The shape of the tensor

inline std::size_t rank() const

Get the rank of the tensor.

Returns:

The rank of the tensor

inline std::size_t size() const

Get the total size of the tensor.

Returns:

The total number of elements in the tensor

inline std::vector<std::size_t> shape() const

Get the shape of the tensor.

Returns:

A vector containing the dimensions of the tensor

inline scalar_type &at(const std::vector<size_t> &indices)

Access a mutable element of the tensor.

Parameters:

indices – The indices of the element to access

Returns:

A reference to the element at the specified indices

inline const scalar_type &at(const std::vector<size_t> &indices) const

Access a const element of the tensor.

Parameters:

indices – The indices of the element to access

Returns:

A const reference to the element at the specified indices

inline void copy(const scalar_type *data, const std::vector<std::size_t> shape = {})

Copy data into the tensor.

Parameters:
  • data – Pointer to the source data

  • shape – The shape of the source data

inline void take(const scalar_type *data, const std::vector<std::size_t> shape = {})

Take ownership of the given data.

Parameters:
  • data – Pointer to the source data

  • shape – The shape of the source data

inline void borrow(const scalar_type *data, const std::vector<std::size_t> shape = {})

Borrow the given data without taking ownership.

Parameters:
  • data – Pointer to the source data

  • shape – The shape of the source data

inline scalar_type *data()

Get a pointer to the raw data of the tensor.

This method provides direct access to the underlying data storage of the tensor. It returns a pointer to the first element of the data array.

Note

Care should be taken when directly manipulating the raw data to avoid invalidating the tensor’s internal state or violating its invariants.

Returns:

scalar_type* A pointer to the mutable data of the tensor.

inline const scalar_type *data() const

Get a const pointer to the raw data of the tensor.

This method provides read-only access to the underlying data storage of the tensor. It returns a const pointer to the first element of the data array.

Note

This const version ensures that the tensor’s data cannot be modified through the returned pointer, preserving const correctness.

Returns:

const scalar_type * A const pointer to the immutable data of the tensor.

class graph

A class representing an undirected weighted graph.

Public Functions

void add_edge(int u, int v, double weight = 1.0)

Add a weighted edge between two nodes.

Parameters:
  • u – First node

  • v – Second node

  • weight – Edge weight

void add_node(int node, double weight = 1.0)

Add a node to the graph.

Parameters:

node – The node to add

bool edge_exists(int i, int j) const

Check if an edge exists between two nodes.

Parameters:
  • i – First node

  • j – Second node

Returns:

True if edge exists, false otherwise

void set_node_weight(int node, double weight)

Set the weight of a node.

Parameters:
  • node – The node to set weight for

  • weight – The weight value

double get_node_weight(int node) const

Get the weight of a node.

Parameters:

node – The node to get weight for

Returns:

Node weight, or 0.0 if node doesn’t exist

void remove_edge(int u, int v)

Remove an edge between two nodes.

Parameters:
  • u – First node

  • v – Second node

void remove_node(int node)

Remove a node and all its incident edges from the graph.

Parameters:

node – The node to remove

std::vector<int> get_neighbors(int node) const

Get the neighbors of a node.

Parameters:

node – The node to get neighbors for

Returns:

Vector of neighboring node IDs

std::vector<std::pair<int, double>> get_weighted_neighbors(int node) const

Get the neighbors of a node with their weights.

Parameters:

node – The node to get neighbors for

Returns:

Vector of pairs containing (neighbor_id, weight)

std::vector<std::pair<int, int>> get_disconnected_vertices() const

Get all pairs of vertices that are not connected.

Returns:

Vector of pairs representing disconnected vertices

std::vector<int> get_nodes() const

Get all nodes in the graph.

Returns:

Vector of all nodes

int num_nodes() const

Get the number of nodes in the graph.

Returns:

Number of nodes

int num_edges() const

Get the number of edges in the graph.

Returns:

Number of edges

bool is_connected() const

Check if the graph is connected.

Returns:

True if the graph is connected, false otherwise

int get_degree(int node) const

Get the degree of a node.

Parameters:

node – The node to get the degree for

Returns:

Degree of the node

double get_edge_weight(int u, int v) const

Get the weight of an edge between two nodes.

Parameters:
  • u – First node

  • v – Second node

Returns:

Edge weight, or -1 if edge doesn’t exist

bool update_edge_weight(int u, int v, double weight)

Update the weight of an existing edge.

Parameters:
  • u – First node

  • v – Second node

  • weight – New edge weight

Returns:

True if edge exists and weight was updated, false otherwise

void clear()

Clear all nodes and edges from the graph.