import cffi import os import os.path RESULT_ERROR = 0 RESULT_EMPTY = 1 RESULT_STRING = 2 RESULT_HISTOGRAM = 3 def get_q1tsim_lib(ffi): if os.name == 'nt': paths = ( './q1tsim.dll', '../target/release/q1tsim.dll', '../target/debug/q1tsim.dll' ) else: paths = ( './libq1tsim.so', '../target/release/libq1tsim.so', '../target/debug/libq1tsim.so' ) for fname in paths: if os.path.exists(fname): try: return ffi.dlopen(fname) except OSError: pass raise Exception('Failed to open q1tsim library') ffi = cffi.FFI() ffi.cdef(""" typedef struct circuit circuit_t; typedef struct { const char* key; size_t count; } histelem_t; typedef struct { double value; double* value_ptr; } parameter_t; typedef struct { void* data; size_t length; size_t size; uint32_t restype; } result_t; void result_free(result_t res); circuit_t *circuit_new(size_t nr_qbits, size_t nr_cbits); void circuit_free(circuit_t *ptr); size_t circuit_nr_qbits(const circuit_t *ptr); size_t circuit_nr_cbits(const circuit_t *ptr); result_t circuit_add_gate(circuit_t *ptr, const char* gate, const size_t* qbits, size_t nr_qubits, const parameter_t* param_ptr, size_t nr_params); result_t circuit_add_conditional_gate(circuit_t *ptr, const size_t* control_ptr, size_t nr_control, uint64_t target, const char* gate, const size_t* qbits_ptr, size_t nr_qbits, const parameter_t* param_ptr, size_t nr_params); result_t circuit_measure(circuit_t *ptr, size_t qbit, size_t cbit, char dir, uint8_t collapse); result_t circuit_measure_all(circuit_t *ptr, const size_t* cbits, size_t nr_cbits, char dir, uint8_t collapse); result_t circuit_reset(circuit_t *ptr, size_t qbit); result_t circuit_reset_all(circuit_t *ptr); result_t circuit_execute(circuit_t *ptr, size_t nr_shots); result_t circuit_reexecute(circuit_t *ptr); result_t circuit_histogram(const circuit_t *ptr); result_t circuit_latex(const circuit_t *ptr); result_t circuit_open_qasm(const circuit_t *ptr); result_t circuit_c_qasm(const circuit_t *ptr); """) qsim_obj = get_q1tsim_lib(ffi) def unpack_result(res): restype = res.restype try: if restype == RESULT_ERROR: msg = ffi.string(ffi.cast("const char*", res.data)).decode('utf-8') raise Exception(msg) if res.restype == RESULT_EMPTY: return None elif res.restype == RESULT_STRING: msg = ffi.string(ffi.cast("const char*", res.data)).decode('utf-8') return msg elif res.restype == RESULT_HISTOGRAM: elems = ffi.cast("const histelem_t*", res.data) hist = dict((ffi.string(elems[i].key).decode('utf-8'), elems[i].count) for i in range(res.length)) return hist else: raise Exception("Unknown data type code: {}".format(res.restype)) finally: qsim_obj.result_free(res) def make_parameters(values): res = ffi.new('parameter_t[]', len(values)) for (i, val) in enumerate(values): if type(val) == float: res[i].value = val res[i].value_ptr = ffi.NULL else: res[i].value = 0.0 res[i].value_ptr = val.pointer() return res def q1tsim(): return qsim_obj