Class busclique::coordinate_converter#

class coordinate_converter#

An arena to perform arithmetic that does not respect the unit system defined in coordinate_base<T>.

This class is not a friend of coordinate_base<T> so so that we can do all of our bounds-checking here, with full type-safety. The generic pattern is that bounds-checking is done inside a public method, respecting the unit systems, and then we explicitly convert coordinates and dimensions to size_t, to be combined in a private method with the _impl suffix.

Public Static Functions

static inline size_t cell_index(size_y y, size_x x, bool u, size_y dim_y, size_x dim_x)#

This computes compute the index of A[u][y][x] in an array A of dimension [2][dim_y][dim_x]

static inline size_t cell_index(bool u, size_w w, size_z z, size_y dim_y, size_x dim_x)#

This computes compute the index of A[u][y][x] in an array A of dimension [2][dim_y][dim_x]; where y and x are determined from w and z, depending on the orientation u.

template<typename shore_t>
static inline size_t chimera_linear(size_y y, size_x x, bool u, shore_t k, size_y dim_y, size_x dim_x, shore_t shore)#

given a chimera coordinate (y, x, u, k) with chimera dimensions (m, n, t) = (dim_y, dim_x, shore), compute the linear index.

template<typename shore_t>
static inline void linear_chimera(size_t q0, size_y &y, size_x &x, bool &u, shore_t &k, size_y dim_y, size_x dim_x, shore_t shore)#

given a linear index q0 in a chimera graph with dimensions (m, n, t) = (dim_y, dim_x, shore), compute the coordinate (y, x, u, k)

template<typename shore_t>
static inline size_t linemajor_linear(bool u, size_w w, shore_t k, size_z z, size_w dim_w, shore_t shore, size_z dim_z)#

Pegasus and Zephyr coordinates exist in relative coordinate systems.

We note that our implementation of Zephyr coordinates differs from the one used other places &#8212; we’ve merged the k and j indices into one. The name ‘linemajor’ indicates that the (u, w, k) parameters specify a line of colinear qubits. This function is used to pack a Zephyr or Pegasus coordinate address (u, w, k, z) into a linear index. The interpretation of dim_w, shore, and dim_z is determined by the relevant topology, and we expect callers to know what they’re doing. Specifically, for pegasus_graph(m), dim_w = 6*m, shore = 2, dim_z = m-1 and for zephyr_graph(m), dim_w = 2*m+1, shore=2*t, dim_z = m

template<typename shore_t>
static inline void linear_linemajor(size_t q0, bool &u, size_w &w, shore_t &k, size_z &z, size_w dim_w, shore_t shore, size_z dim_z)#

Pegasus and Zephyr coordinates exist in relative coordinate systems.

We note that our implementation of Zephyr coordinates differs from the one used other places &#8212; we’ve merged the k and j indices into one. The name ‘linemajor’ indicates that the (u, w, k) parameters specify a line of colinear qubits. This function is used to unpack a Zephyr or Pegasus linear index to a coordinate address (u, w, k, z). The interpretation of dim_w, shore, and dim_z is determined by the relevant topology, and we expect callers to know what they’re doing. Specifically, for pegasus_graph(m), dim_w = 6*m, shore = 2, dim_z = m-1 and for zephyr_graph(m), dim_w = 2*m+1, shore=2*t, dim_z = m

template<typename T, typename ...Args>
static inline size_t product(T t, Args... args)#

explicitly convert all arguments into a size_t and return the product of them all.

template<typename T, typename ...Args>
static inline size_t sum(T t, Args... args)#

explicitly convert all arguments into a size_t and return the product of them all.

template<typename S, typename T>
static inline size_t min(S s, T t)#

explicitly convert both arguments into a size_t and return the minimum

template<typename S, typename T>
static inline size_t max(S s, T t)#

explicitly convert both arguments into a size_t and return the maximum

static inline size_t grid_index(size_y y, size_x x, size_y dim_y, size_x dim_x)#

Implements addressing into a 2-dimensional array T[dim_y][dim_x].

static inline size_t bundle_cache_index(bool u, size_w w, size_z z0, size_z z1, size_t stride_u, size_t stride_w)#

This addressing scheme is wikkid complicated.

The majority of the logic is contained in bundle_cache.hpp. We store line masks (that is, sets of k-indices) corresponding to the line segment (u, w, z0, z1). That is, if the bit i is set in line_mask[bundle_cache_index(u, w, z0, z1)], then line of qubits [(u, w, i, z) for z in range(z0, z1+1)] and the necessary external couplers are present in the linemajor representation of the topology. We assume that the caller knows what it’s doing with stride_u and stride_w. We do belts-and-suspenders assertion testing in bundle_cache::compute_line_masks for added confidence that the caller actually knows what it’s doing.