Closed Durganshu closed 7 months ago
If the coupling maps for the CX gate is: [[0, 1], [1, 0],[1, 2], [2, 1], [2, 3], [3, 2], [3, 4], [4, 3]]
This will be saved: [[0, 1, -1], [1, 0, -1],[1, 2, -1], [2, 1, -1], [2, 3, -1], [3, 2, -1], [3, 4, -1], [4, 3, -1], NULL]
This is one of the safest methods to ensure that sys-sage
/ Fomac
gets the accurate value for the size of this map and the number of qubits involved. However, this requires storing one extra value per map. So, an alternative solution can also be implemented:
typedef struct QDMI_Gate_impl_d
{
const char *name;
QDMI_Gate_property** coupling_mapping;
char *unitary;
float fidelity;
size_t size_coupling_map; // New addition: 8 for the above example
size_t gate_size; // New addition: refers to the gate size (1-qubit, 2-qubits, 3-qubits, etc.)
} QDMI_Gate_impl_t;
If the coupling maps for the CX gate is: [[0, 1], [1, 0],[1, 2], [2, 1], [2, 3], [3, 2], [3, 4], [4, 3]]
This will be saved: [[0, 1, -1], [1, 0, -1],[1, 2, -1], [2, 1, -1], [2, 3, -1], [3, 2, -1], [3, 4, -1], [4, 3, -1], NULL]
This is one of the safest methods to ensure that
sys-sage
/Fomac
gets the accurate value for the size of this map and the number of qubits involved. However, this requires storing one extra value per map. So, an alternative solution can also be implemented:typedef struct QDMI_Gate_impl_d { const char *name; QDMI_Gate_property** coupling_mapping; char *unitary; float fidelity; size_t size_coupling_map; // New addition: 8 for the above example size_t gate_size; // New addition: refers to the gate size (1-qubit, 2-qubits, 3-qubits, etc.) } QDMI_Gate_impl_t;
Just a quick thought, but isn't the second solution here much more efficient?
Instead of adding |E|+1
64 bit values, it just adds 2, unconditionally. And these two perfectly describe how to interpret the int**
coupling map.
Hi @burgholzer
Yes, it is. But since all the QDMI backends follow the same standard, I didn't want to implement the second method without getting a confirmation from others, so that every backend will have same struct members. This will ensure consistency in what QDMI can provide. @echavarria-lrz @kayaercument @martin-knudsen What do you think about that?
Hi @burgholzer
Yes, it is. But since all the QDMI backends follow the same standard, I didn't want to implement the second method without getting a confirmation from others, so that every backend will have same struct members. This will ensure consistency in what QDMI can provide. @echavarria-lrz @kayaercument @martin-knudsen What do you think about that?
I see your concern. IMHO, at this moment in time, we should not be afraid to make breaking changes to the interface. Especially, if those changes allow for more efficient implementations of key characteristics and features. QDMI is in such an early stage that changes are almost inevitable.
Fair point. Let me modify the implementation to use the second method. Thanks!
Hi @burgholzer
Yes, it is. But since all the QDMI backends follow the same standard, I didn't want to implement the second method without getting a confirmation from others, so that every backend will have same struct members. This will ensure consistency in what QDMI can provide. @echavarria-lrz @kayaercument @martin-knudsen What do you think about that?
That's actually how we handle qubits' coupling mappings:
typedef struct QDMI_Qubit_impl_d
{
QDMI_qubit_index index;
QDMI_qubit_index* coupling_mapping;
int size_coupling_mapping;
} QDMI_Qubit_impl_t;
Yes, indeed. Thanks!
Some quantum backends provide coupling maps for gates as well. The coupling maps provide a list of qubits that the gate applies to, where each element of the list is an n-qubit list where n is the size of the gate (e.g. 1-qubit gate, 2-qubit gate). For example, the coupling map for a CX gate on a 5-qubit backend could be: [[0, 1], [1, 0],[1, 2], [2, 1], [2, 3], [3, 2], [3, 4], [4, 3]].
struct QDMI_Gate_impl_d
has acoupling_mapping
member: https://github.com/Munich-Quantum-Software-Stack/QDMI/blob/ea3c65888cae9ee995a477e787333d535bbe2eb5/include/qdmi_internal.h#L130If the backend doesn't provide a
coupling_mapping
for a particular gate, this must be set to NULL. If it does, this member stores the corresponding mapping as an int** (int [][]) as a typedefQDMI_Gate_property
. However, this raw pointer doesn't store any information regarding the size of the coupling mapping. Also, there's no member in theQDMI_Gate_impl_d
struct, which stores the gate size (1-qubit, 2-qubit, etc.). When a C++-based higher-level library like FoMac orsys-sage
tries to access this information, it'll be convenient to provide it.This PR presents one of the possible solutions: setting sentinel values at the end of the pointers pointed to by the coupling_mapping.
If the size of
gate->coupling_mapping
is N, memory for N+1 pointers to QDMI_Gate_property could be allocated to store an extra NULL value. Similarly, for everygate->coupling_mapping[i]
, where i = 0,1...N-1, i+N can store the value -1 (as qubit indices can never be negative). This will help higher-level libraries to get the count of the qubits involved and the size of the coupling mapping.The reference solution is implemented for the IBM backend