diff --git a/examples/analog/qaa.c b/examples/analog/qaa.c index a167a77..309990c 100644 --- a/examples/analog/qaa.c +++ b/examples/analog/qaa.c @@ -18,15 +18,18 @@ #include #include +#define CQ_ADDR_GLOBAL 0 +#define CQ_ADDR_LOCAL 1 + cq_status quantum_adiabatic_algo(const size_t NQUBITS, qubit *qr, cstate * cr, qkern_map * reg) { CQ_REGISTER_KERNEL(reg); set_qureg(qr, 0, NQUBITS); int qreg_id = 0; - HANDLE_CQ_ERROR(cq_enable_analog_qreg(qreg_id, NQUBITS)); + HANDLE_CQ_ERROR(cq_enable_analog_qreg(qr)); channel ch0 = {0}; - HANDLE_CQ_ERROR(cq_get_global_channel(&ch0, 0, qreg_id)); + HANDLE_CQ_ERROR(cq_get_channel(&ch0, CQ_ADDR_GLOBAL, qr, NULL)); pulse pulse = {0}; double duration = 4000.0; @@ -42,23 +45,23 @@ cq_status quantum_adiabatic_algo(const size_t NQUBITS, qubit *qr, cstate * cr, q HANDLE_CQ_ERROR(cq_interpolated_wf(pulse.detuning, duration, data_points, num_points)); - qpos positions[5] = { - { 5.53855359, 1.7891413 , 0.0}, - { 5.48899179, -6.27296412, 0.0}, - {-1.43242244, -2.26122822, 0.0}, - { 1.62594084, 10.99193777, 0.0}, - {15.4687696 , 2.96846731, 0.0}}; + double positions[15] = { + 5.53855359, 1.7891413 , 0.0, + 5.48899179, -6.27296412, 0.0, + -1.43242244, -2.26122822, 0.0, + 1.62594084, 10.99193777, 0.0, + 15.4687696 , 2.96846731, 0.0 + }; - HANDLE_CQ_ERROR(cq_update_qreg_pos(positions, NQUBITS, qreg_id)); + HANDLE_CQ_ERROR(cq_set_qubit_pos(positions, qr)); HANDLE_CQ_ERROR(cq_play(&ch0, &pulse)); measure_qureg(qr, NQUBITS, cr); - HANDLE_CQ_ERROR(cq_disable_analog_qreg(qreg_id)); + HANDLE_CQ_ERROR(cq_free_pulse(&pulse)); + HANDLE_CQ_ERROR(cq_disable_analog_qreg(qr)); return CQ_SUCCESS; }; -#undef HANDLE_CQ_ERROR - int main (void) { const size_t NQUBITS = 5; @@ -69,7 +72,7 @@ int main (void) cq_init(0); - cq_enable_analog_mode(RYDBERG); + cq_enable_analog_mode(ISING); qubit * qr = NULL; alloc_qureg(&qr, NQUBITS); diff --git a/include/analog.h b/include/analog.h index 2aca4eb..f3cfdc7 100644 --- a/include/analog.h +++ b/include/analog.h @@ -14,61 +14,49 @@ #include typedef enum device_mode { - RYDBERG, + ISING, XY } device_mode; -typedef struct qpos { - double x; - double y; - double z; -} qpos; - typedef struct channel { int id; int type; - int target; + ptrdiff_t target; double time; void* params; } channel; #define __CQ_ANALOG_MAX_NUM_SAMPLES__ 4096 typedef struct pulse { - double freq[__CQ_ANALOG_MAX_NUM_SAMPLES__]; - double phase[__CQ_ANALOG_MAX_NUM_SAMPLES__]; - double detuning[__CQ_ANALOG_MAX_NUM_SAMPLES__]; + double *freq; + double *phase; + double *detuning; + double duration; ptrdiff_t num_samples; } pulse; -cq_status cq_print_analog_device(void); -cq_status cq_print_avail_channels(void); -cq_status cq_print_channel(channel *ch); -cq_status cq_print_qpos(int qreg_id); -// TODO: cq_status cq_retarget_channel(channel *ch, int new_target); -ptrdiff_t cq_duration_to_samples(double duration); -double cq_samples_to_duration(ptrdiff_t num_samples); - -cq_status cq_enable_analog_mode(device_mode mode); -cq_status cq_enable_analog_qreg(int qreg_id, int num_qubits); -cq_status cq_disable_analog_qreg(int qreg_id); -cq_status cq_get_global_channel(channel *ch, int type, int qreg_id); -cq_status cq_get_local_channel(channel *ch, int type, int target, int qreg_id); +cq_status cq_enable_analog_mode(int mode); +cq_status cq_enable_analog_qreg(qubit *qr); +cq_status cq_disable_analog_qreg(qubit *qr); -cq_status cq_update_qreg_pos(const qpos *new_positions, int num_qubits, int qreg_id); +cq_status cq_get_channel(channel *ch, int type, qubit *qr, qubit *target); +cq_status cq_retarget_channel(channel *ch, qubit *new_target); +cq_status cq_set_qubit_pos(const double *new_positions, qubit *qr); cq_status cq_init_pulse(pulse *pulse, double duration); +cq_status cq_free_pulse(pulse *pulse); + cq_status cq_play(channel *ch, pulse *pulse); cq_status cq_capture(channel *ch, pulse *pulse, int *result, int shots); cq_status cq_delay(channel *ch, double dt); cq_status cq_barrier(channel **ch, int num_channels); +// =============================== Waveforms ================================== cq_status cq_gaussian_wf(double *samples, double duration, double amp, double sigma); - // TODO: consider removing as it has limited applicability cq_status cq_gaussian_sqr_wf(double *samples, double duration, double amp, double sigma, double width); - cq_status cq_interpolated_wf(double *samples, double duration, double *points, int num_points); cq_status cq_sech_wf(double *samples, double duration, double amp, double sigma); @@ -84,4 +72,22 @@ cq_status cq_composite_wf(double *samples, double **waveforms, ptrdiff_t *num_samples, int num_waveforms, ptrdiff_t *total_num_samples); +// =============================== Helpers ==================================== +cq_status cq_print_analog_device(void); +cq_status cq_print_avail_channels(void); +cq_status cq_print_channel(channel *ch); +cq_status cq_print_qpos(qubit *qr); + +ptrdiff_t cq_duration_to_samples(double duration); +double cq_samples_to_duration(ptrdiff_t num_samples); + +cq_status cq_set_device_sample_rate(double rate); +cq_status cq_set_device_min_pulse_duration(double duration); +cq_status cq_set_device_max_pulse_duration(double duration); +cq_status cq_set_device_interaction_coeff(double coeff); +cq_status cq_set_device_min_qubit_dist(double distance); +cq_status cq_set_device_max_num_shots(int shots); +cq_status cq_set_device_coupling_func(double(*coupler)(double *q0, double *q1)); + #endif + diff --git a/src/device/analog/analog.c b/src/device/analog/analog.c index 53c8ea2..1e1cfbd 100644 --- a/src/device/analog/analog.c +++ b/src/device/analog/analog.c @@ -22,10 +22,10 @@ //============================ VALIDATION ===================================== -static cq_status validate_num_qubits(int num_qubits) { +static cq_status validate_num_qubits(ptrdiff_t num_qubits) { if (num_qubits <= 0 || num_qubits > __CQ_ANALOG_MAX_NUM_QUBITS__) { printf("Error: Specified number of qubits out-of-bounds. " - "Should be in [1, %d] range, given %d.", + "Should be in [1, %d] range, given %ld.", __CQ_ANALOG_MAX_NUM_QUBITS__, num_qubits); return CQ_ERROR; @@ -33,10 +33,10 @@ static cq_status validate_num_qubits(int num_qubits) { return CQ_SUCCESS; } -static cq_status validate_qubits_idx(int qidx) { +static cq_status validate_qubits_idx(ptrdiff_t qidx) { if (qidx < 0 || qidx >= __CQ_ANALOG_MAX_NUM_QUBITS__) { printf("Error: Specified qubit idx out-of-bounds. " - "Should be in [0, %d] range, given %d.", + "Should be in [0, %d] range, given %ld.", __CQ_ANALOG_MAX_NUM_QUBITS__ - 1, qidx); return CQ_ERROR; @@ -44,11 +44,11 @@ static cq_status validate_qubits_idx(int qidx) { return CQ_SUCCESS; } -static cq_status validate_qreg_id(int qreg_id) { +static cq_status validate_qreg_id(ptrdiff_t qreg_id) { if (qreg_id < 0 || qreg_id >= __CQ_ANALOG_MAX_NUM_QUREGS__) { printf("Error: Attempting to access qreg with " - "out-of-bounds index: %d. " + "out-of-bounds index: %ld. " "Should be in [0, %d] range.", qreg_id, __CQ_ANALOG_MAX_NUM_QUREGS__ - 1); @@ -63,14 +63,16 @@ static cq_status validate_channel_type(int type, addressing target) { "(should be in [0, 4] range, given %d).", type); return CQ_ERROR; } - if (target == GLOBAL) { - if (type == RYDBERG_LOCAL || type == RAMAN_LOCAL) { - printf("Error: Expected channel addressing is GLOBAL but LOCAL was given."); + if (target == CQ_ADDR_GLOBAL) { + //if (type == RYDBERG_CQ_ADDR_LOCAL || type == RAMAN_CQ_ADDR_LOCAL) { + if (type == CQ_ADDR_LOCAL) { + printf("Error: Expected channel addressing is CQ_ADDR_GLOBAL but CQ_ADDR_LOCAL was given."); return CQ_ERROR; } - } else if(target == LOCAL) { - if (type == RYDBERG_GLOBAL || type == DMM_GLOBAL) { - printf("Error: Expected channel addressing is LOCAL but GLOBAL was given."); + } else if(target == CQ_ADDR_LOCAL) { + //if (type == RYDBERG_CQ_ADDR_GLOBAL || type == DMM_CQ_ADDR_GLOBAL) { + if (type == CQ_ADDR_GLOBAL) { + printf("Error: Expected channel addressing is CQ_ADDR_LOCAL but CQ_ADDR_GLOBAL was given."); return CQ_ERROR; } } @@ -130,7 +132,7 @@ static cq_status validate_samples(double *samples) { return CQ_SUCCESS; } -static cq_status validate_num_samples(int num_samples) { +static cq_status validate_num_samples(ptrdiff_t num_samples) { if (num_samples < 1) { printf("Error: Specified num_samples < 1."); return CQ_ERROR; @@ -154,7 +156,7 @@ static cq_status validate_result(int *result) { return CQ_SUCCESS; } -static cq_status validate_num_shots(int shots) { +static cq_status validate_num_shots(ptrdiff_t shots) { if (shots < 1) { printf("Error: Number of shots is < 1."); return CQ_ERROR; @@ -211,27 +213,76 @@ static cq_status validate_freq(double freq) { return CQ_SUCCESS; } //========================== ANALOG DEVICE OPS ================================ -cq_status cq_enable_analog_mode(device_mode mode) { - return enable_analog_mode(mode); +cq_status cq_enable_analog_mode(int mode) { + device_mode mode_ = (device_mode)mode; + return enable_analog_mode(mode_); } -cq_status cq_enable_analog_qreg(int qreg_id, int num_qubits) { +cq_status cq_enable_analog_qreg(qubit *qr) { HANDLE_CQ_ERROR(is_analog_device_init()); + if (!qr) return CQ_ERROR; + ptrdiff_t qreg_id = qr->registry_index; + ptrdiff_t num_qubits = qr->N; HANDLE_CQ_ERROR(validate_qreg_id(qreg_id)); HANDLE_CQ_ERROR(validate_num_qubits(num_qubits)); return enable_analog_qreg(qreg_id, num_qubits); } -cq_status cq_disable_analog_qreg(int qreg_id) { +cq_status cq_disable_analog_qreg(qubit *qr) { HANDLE_CQ_ERROR(is_analog_device_init()); + if (!qr) return CQ_ERROR; + ptrdiff_t qreg_id = qr->registry_index; HANDLE_CQ_ERROR(validate_qreg_id(qreg_id)); return disable_analog_qreg(qreg_id); } +cq_status cq_get_channel(channel *ch, int type, qubit *qr, qubit *target) { + HANDLE_CQ_ERROR(is_analog_device_init()); + HANDLE_CQ_ERROR(validate_channel(ch)); + if (!qr) return CQ_ERROR; + ptrdiff_t qreg_id = qr->registry_index; + HANDLE_CQ_ERROR(validate_qreg_id(qreg_id)); + + addressing mode = (addressing)type; + + switch (mode) { + case CQ_ADDR_LOCAL: { + if (!target) { + printf("Error: Target qubit is nullptr. From: %s\n", __func__); + return CQ_ERROR; + } + return get_local_channel(ch, 1, target->offset, qreg_id); + } + case CQ_ADDR_GLOBAL: + if (target) { + printf("Error: Provided target but accessing channel " + "in global mode. From: %s\n", __func__); + return CQ_ERROR; + } + return get_global_channel(ch, 0, qreg_id); + default: + printf("Error: Unknown addressing type.\n"); + return CQ_ERROR; + } + return CQ_SUCCESS; +} + +cq_status cq_retarget_channel(channel *ch, qubit *new_target) { + HANDLE_CQ_ERROR(is_analog_device_init()); + HANDLE_CQ_ERROR(validate_channel(ch)); + HANDLE_CQ_ERROR(validate_channel_type(ch->type, CQ_ADDR_LOCAL)); + if (!new_target) { + printf("Error: New target is nullptr. From %s\n", __func__); + return CQ_ERROR; + } + ptrdiff_t new_target_ = new_target->offset; + return retarget_channel(ch, new_target_); +} + cq_status cq_get_global_channel(channel *ch, int type, int qreg_id) { HANDLE_CQ_ERROR(is_analog_device_init()); HANDLE_CQ_ERROR(validate_channel(ch)); - HANDLE_CQ_ERROR(validate_channel_type(type, GLOBAL)); + HANDLE_CQ_ERROR(validate_channel_type(type, CQ_ADDR_GLOBAL)); HANDLE_CQ_ERROR(validate_qreg_id(qreg_id)); return get_global_channel(ch, type, qreg_id); } @@ -239,24 +290,35 @@ cq_status cq_get_global_channel(channel *ch, int type, int qreg_id) { cq_status cq_get_local_channel(channel *ch, int type, int target, int qreg_id) { HANDLE_CQ_ERROR(is_analog_device_init()); HANDLE_CQ_ERROR(validate_channel(ch)); - HANDLE_CQ_ERROR(validate_channel_type(type, LOCAL)); + HANDLE_CQ_ERROR(validate_channel_type(type, CQ_ADDR_LOCAL)); HANDLE_CQ_ERROR(validate_qubits_idx(target)); HANDLE_CQ_ERROR(validate_qreg_id(qreg_id)); return get_local_channel(ch, type, target, qreg_id); } -cq_status cq_update_qreg_pos(const qpos *new_positions, int num_qubits, int qreg_id) { +cq_status cq_set_qubit_pos(const double *new_positions, qubit *qr) { HANDLE_CQ_ERROR(is_analog_device_init()); if (!new_positions) { printf("Error: Passed nullptr positions. From: %s\n", __func__); return CQ_ERROR; } - + if (!qr) return CQ_ERROR; + ptrdiff_t qreg_id = qr->registry_index; + ptrdiff_t num_qubits = qr->N; HANDLE_CQ_ERROR(validate_num_qubits(num_qubits)); HANDLE_CQ_ERROR(validate_qreg_id(qreg_id)); - return update_qreg_pos(new_positions, num_qubits, qreg_id); -} + qpos new_positions_[__CQ_ANALOG_MAX_NUM_QUBITS__] = {0}; + + for (ptrdiff_t i = 0; i < num_qubits; ++i) { + ptrdiff_t start = 3 * i; + new_positions_[i].x = new_positions[start]; + new_positions_[i].y = new_positions[start + 1]; + new_positions_[i].z = new_positions[start + 2]; + } + + return update_qreg_pos(new_positions_, num_qubits, qreg_id); +} //================================ PULSE ====================================== cq_status cq_init_pulse(pulse *pulse, double duration) { HANDLE_CQ_ERROR(is_analog_device_init()); @@ -264,6 +326,17 @@ cq_status cq_init_pulse(pulse *pulse, double duration) { return init_pulse(pulse, duration); } +cq_status cq_free_pulse(pulse *pulse) { + HANDLE_CQ_ERROR(is_analog_device_init()); + HANDLE_CQ_ERROR(validate_pulse(pulse)); + + if (!pulse->freq) { + printf("Error: pulse was already freed. From: %s\n", __func__); + return CQ_ERROR; + } + return free_pulse(pulse); +} + cq_status cq_play(channel *ch, pulse *pulse) { HANDLE_CQ_ERROR(is_analog_device_init()); HANDLE_CQ_ERROR(validate_channel(ch)); @@ -276,7 +349,7 @@ cq_status cq_capture(channel *ch, pulse *pulse, int *result, int shots) { HANDLE_CQ_ERROR(is_analog_device_init()); HANDLE_CQ_ERROR(validate_channel(ch)); // can capture only with channels that have valid target - HANDLE_CQ_ERROR(validate_channel_type(ch->type, LOCAL)); + HANDLE_CQ_ERROR(validate_channel_type(ch->type, CQ_ADDR_LOCAL)); HANDLE_CQ_ERROR(validate_channel_params(ch)); HANDLE_CQ_ERROR(validate_pulse(pulse)); HANDLE_CQ_ERROR(validate_result(result)); @@ -425,8 +498,10 @@ cq_status cq_print_channel(channel *ch) { return CQ_SUCCESS; } -cq_status cq_print_qpos(int qreg_id) { +cq_status cq_print_qpos(qubit *qr) { HANDLE_CQ_ERROR(is_analog_device_init()); + if (!qr) return CQ_ERROR; + ptrdiff_t qreg_id = qr->registry_index; HANDLE_CQ_ERROR(validate_qreg_id(qreg_id)); HANDLE_CQ_ERROR(print_qpos(qreg_id)); return CQ_SUCCESS; @@ -442,4 +517,66 @@ double cq_samples_to_duration(ptrdiff_t num_samples) { HANDLE_CQ_ERROR(is_analog_device_init()); if (num_samples < 0) return 0.0; return samples_to_duration(num_samples); -} \ No newline at end of file +} + +cq_status cq_set_device_sample_rate(double rate) { + HANDLE_CQ_ERROR(is_analog_device_init()); + if (rate < 0.0) { + printf("Error: Provided sample rate is negative. From: %s\n", __func__); + return CQ_ERROR; + } + set_device_sample_rate(rate); + return CQ_SUCCESS; +} + +cq_status cq_set_device_min_pulse_duration(double duration) { + HANDLE_CQ_ERROR(is_analog_device_init()); + if (duration < 0.0) { + printf("Error: Provided duration is negative. From: %s\n", __func__); + return CQ_ERROR; + } + set_device_min_pulse_duration(duration); + return CQ_SUCCESS; +} + +cq_status cq_set_device_max_pulse_duration(double duration) { + HANDLE_CQ_ERROR(is_analog_device_init()); + if (duration < 0.0) { + printf("Error: Provided duration is negative. From: %s\n", __func__); + return CQ_ERROR; + } + set_device_max_pulse_duration(duration); + return CQ_SUCCESS; +} + +cq_status cq_set_device_interaction_coeff(double coeff) { + HANDLE_CQ_ERROR(is_analog_device_init()); + set_device_interaction_coeff(coeff); + return CQ_SUCCESS; +} + +cq_status cq_set_device_min_qubit_dist(double distance) { + HANDLE_CQ_ERROR(is_analog_device_init()); + if (distance < 0.0) { + printf("Error: Provided distance is negative. From: %s\n", __func__); + return CQ_ERROR; + } + set_device_min_qubit_dist(distance); + return CQ_SUCCESS; +} + +cq_status cq_set_device_max_num_shots(int shots) { + HANDLE_CQ_ERROR(is_analog_device_init()); + if (shots < 1) { + printf("Error: Provided number of shots is < 1. From: %s\n", __func__); + return CQ_ERROR; + } + set_device_max_num_shots(shots); + return CQ_SUCCESS; +} + +cq_status cq_set_device_coupling_func(double(*coupler)(double *q0, double *q1)) { + HANDLE_CQ_ERROR(is_analog_device_init()); + set_device_coupling_func(coupler); + return CQ_SUCCESS; +} diff --git a/src/device/analog/analog_datatypes.h b/src/device/analog/analog_datatypes.h index 1926046..283af25 100644 --- a/src/device/analog/analog_datatypes.h +++ b/src/device/analog/analog_datatypes.h @@ -21,17 +21,9 @@ typedef struct term_range { ptrdiff_t end; } term_range; -typedef enum channel_type { - RYDBERG_GLOBAL = 0, - RYDBERG_LOCAL = 1, - RAMAN_LOCAL = 2, - DMM_GLOBAL = 3, - MW_GLOBAL = 4 -} channel_type; - typedef enum addressing { - LOCAL = 0, - GLOBAL = 1 + CQ_ADDR_GLOBAL = 0, + CQ_ADDR_LOCAL = 1 } addressing; typedef struct channel_params { @@ -42,12 +34,12 @@ typedef struct channel_params { double retarget_delay; // ns double sample_rate; // GHz double min_pulse_duration; // ns + double max_pulse_duration; // ns int max_targets; // -1 -> no max i.e. global addressing addressing; - int qreg_id; // on which qreg the channel operates + ptrdiff_t qreg_id; // on which qreg the channel operates } channel_params; - #define __CQ_ANALOG_MAX_NUM_QUBITS__ 59 // NOTE: PAULI_STR_LEN == MAX_NUM_QUBITS #define __CQ_ANALOG_MAX_PAULI_STR_LEN__ __CQ_ANALOG_MAX_NUM_QUBITS__ @@ -69,11 +61,17 @@ typedef struct cq_hamiltonian { } cq_hamiltonian; +typedef struct qpos { + double x; + double y; + double z; +} qpos; + #define __CQ_ANALOG_MAX_NUM_CHANNELS__ __CQ_ANALOG_MAX_NUM_QUBITS__ + 1 typedef struct analog_qreg { - int id; + ptrdiff_t id; bool in_use; - int num_qubits; + ptrdiff_t num_qubits; qpos qubit_pos[__CQ_ANALOG_MAX_NUM_QUBITS__]; term_range sys_terms_range; @@ -85,17 +83,20 @@ typedef struct analog_qreg { } analog_qreg; #define __CQ_ANALOG_MAX_NUM_QUREGS__ 64 +// TODO: Device could have func ptr to coupling function +// this could be provided by the user and later used for calculating +// interaction +typedef double (*coupling_func)(double *q0, double *q1); typedef struct analog_device { double sample_rate; // GHz i.e 1/ns double min_pulse_duration; // ns double max_pulse_duration; // ns - double ising_coefficient; - double xy_coefficient; - double max_atom_dist_from_origin; // micrometers - double min_dist_between_atom; // micrometers - int max_num_shots; + double interaction_coeff; + double min_qubit_dist; // micrometers + ptrdiff_t max_num_shots; bool is_initialized; device_mode mode; + coupling_func coupler; analog_qreg qregs[__CQ_ANALOG_MAX_NUM_QUREGS__]; cq_hamiltonian hamiltonians[__CQ_ANALOG_MAX_NUM_QUREGS__]; @@ -105,3 +106,4 @@ typedef struct analog_device { #define __CQ_ANALOG_EPSILON__ 0.0000000001 #endif // CQ_ANALOG_DATATYPES_H + diff --git a/src/device/analog/analog_device.c b/src/device/analog/analog_device.c index 391e80e..6fffc9d 100644 --- a/src/device/analog/analog_device.c +++ b/src/device/analog/analog_device.c @@ -21,7 +21,7 @@ static analog_device device = {0}; static cq_status validate_qreg_is_init(analog_qreg *qreg) { if (!qreg) return CQ_ERROR; if (!qreg->in_use) { - printf("Error: The qreg with index: %d was not initialised in analog mode.\n", qreg->id); + printf("Error: The qreg with index: %td was not initialised in analog mode.\n", qreg->id); return CQ_ERROR; } return CQ_SUCCESS; @@ -33,13 +33,23 @@ static cq_status setup_device_params(device_mode mode) { device.sample_rate = 0.25; device.min_pulse_duration = 16.0; device.max_pulse_duration = 60000.0; - //device.ising_coefficient = 865723.02; - device.ising_coefficient = 5420158.53; - device.xy_coefficient = 3700.0; - device.max_atom_dist_from_origin = 50.0; - device.min_dist_between_atom = 4.0; + device.min_qubit_dist = 4.0; device.max_num_shots = 2000; device.mode = mode; + device.coupler = NULL; + + switch (device.mode) { + case ISING: + device.interaction_coeff = 5420158.53; + break; + case XY: + device.interaction_coeff = 3700.0; + break; + default: { + printf("Error: Unknown device mode!\n"); + return CQ_ERROR; + } + } return CQ_SUCCESS; } @@ -55,7 +65,7 @@ cq_status enable_analog_mode(device_mode mode) { return CQ_SUCCESS; } -cq_status enable_analog_qreg(int qreg_id, int num_qubits) { +cq_status enable_analog_qreg(ptrdiff_t qreg_id, ptrdiff_t num_qubits) { assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); assert(num_qubits > 0 && num_qubits <= __CQ_ANALOG_MAX_NUM_QUBITS__); @@ -76,7 +86,7 @@ cq_status enable_analog_qreg(int qreg_id, int num_qubits) { return CQ_SUCCESS; } -cq_status disable_analog_qreg(int qreg_id) { +cq_status disable_analog_qreg(ptrdiff_t qreg_id) { assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); if (!device.is_initialized) { @@ -98,10 +108,10 @@ cq_status disable_analog_qreg(int qreg_id) { return CQ_SUCCESS; } -cq_status get_global_channel(channel *ch, int type, int qreg_id) { +cq_status get_global_channel(channel *ch, int type, ptrdiff_t qreg_id) { assert(ch != NULL); assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); - //if (validate_channel_type(type, LOCAL) == CQ_ERROR) return CQ_ERROR; + //if (validate_channel_type(type, CQ_ADDR_LOCAL) == CQ_ERROR) return CQ_ERROR; if (!device.is_initialized) { printf("Error: Attempting to run analog operation without " @@ -115,7 +125,7 @@ cq_status get_global_channel(channel *ch, int type, int qreg_id) { return CQ_ERROR; } - for (int i = 0; i < qreg->num_channels; ++i) { + for (ptrdiff_t i = 0; i < qreg->num_channels; ++i) { if (qreg->channels[i].type == type) { return copy_channel(ch, &qreg->channels[i]); } @@ -124,11 +134,11 @@ cq_status get_global_channel(channel *ch, int type, int qreg_id) { return CQ_ERROR; } -cq_status get_local_channel(channel *ch, int type, int target, int qreg_id) { +cq_status get_local_channel(channel *ch, int type, ptrdiff_t target, ptrdiff_t qreg_id) { assert(ch != NULL); assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); assert(target > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUBITS__); - //if (validate_channel_type(type, LOCAL) == CQ_ERROR) return CQ_ERROR; + //if (validate_channel_type(type, CQ_ADDR_LOCAL) == CQ_ERROR) return CQ_ERROR; if (!device.is_initialized) { printf("Error: Attempting to run analog operation without " "analog mode on. From: %s\n", __func__); @@ -143,8 +153,8 @@ cq_status get_local_channel(channel *ch, int type, int target, int qreg_id) { } if (target >= qreg->num_qubits) { - printf("Error: Provided target (%d) is larger than number of qubits " - "in given register (qreg id: %d). From: %s\n", + printf("Error: Provided target (%td) is larger than number of qubits " + "in given register (qreg id: %td). From: %s\n", target, qreg->num_qubits, __func__); return CQ_ERROR; } @@ -174,7 +184,7 @@ cq_hamiltonian * get_hamiltonian(const analog_qreg *qreg) { return &device.hamiltonians[qreg->id]; } -analog_qreg * get_qreg(int qreg_id) { +analog_qreg * get_qreg(ptrdiff_t qreg_id) { assert(device.is_initialized); assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); return &device.qregs[qreg_id]; @@ -195,19 +205,14 @@ double get_device_max_pulse_duration(void) { return device.max_pulse_duration; } -double get_device_ising_coeff(void) { +double get_device_interaction_coeff(void) { assert(device.is_initialized); - return device.ising_coefficient; + return device.interaction_coeff; } -double get_device_xy_coeff(void) { +double get_device_min_qubit_dist(void) { assert(device.is_initialized); - return device.xy_coefficient; -} - -double get_device_min_atom_dist(void) { - assert(device.is_initialized); - return device.min_dist_between_atom; + return device.min_qubit_dist; } int get_device_max_num_shots(void) { @@ -220,6 +225,41 @@ device_mode get_device_operating_mode(void) { return device.mode; } +coupling_func get_device_coupling_func(void) { + assert(device.is_initialized); + return device.coupler; +} + +void set_device_sample_rate(double rate) { + assert(device.is_initialized); + device.sample_rate = rate; +} +void set_device_min_pulse_duration(double duration) { + assert(device.is_initialized); + device.min_pulse_duration = duration; +} +void set_device_max_pulse_duration(double duration) { + assert(device.is_initialized); + device.max_pulse_duration = duration; +} +void set_device_interaction_coeff(double coeff) { + assert(device.is_initialized); + device.interaction_coeff = coeff; +} +void set_device_min_qubit_dist(double distance) { + assert(device.is_initialized); + device.min_qubit_dist = distance; +} +void set_device_max_num_shots(int shots) { + assert(device.is_initialized); + device.max_num_shots = shots; +} + +void set_device_coupling_func(double(*coupler)(double *q0, double *q1)) { + assert(device.is_initialized); + device.coupler = coupler; +} + ptrdiff_t duration_to_samples(double duration) { return (ptrdiff_t)(device.sample_rate * duration); } @@ -230,8 +270,8 @@ double samples_to_duration(ptrdiff_t num_samples) { static const char *get_mode_str(device_mode mode) { switch (mode) { - case RYDBERG: - return "RYDBERG"; + case ISING: + return "ISING"; case XY: return "XY"; default: @@ -243,26 +283,21 @@ void print_analog_device(void) { assert(device.is_initialized); printf("==============================================================\n" "Analog Device Specification:\n" - "Operating Modes: RYDBERG, XY\n" + "Operating Modes: ISING, XY\n" "Selected mode: %s\n" "Sample rate: %f\n" "Min pulse duration: %f\n" "Max pulse duration: %f\n" - "Max number of shots: %d\n" - "Ising coefficient: %f\n" - "\n-------- If RYDBERG or XY: --------\n" - "XY coefficient: %f\n" - "Min distance between atoms: %f\n" - "Max atom distance from origin: %f\n" + "Max number of shots: %td\n" + "Interaction coefficient: %f\n" + "Min distance between qubits: %f\n" "==============================================================\n", get_mode_str(device.mode), device.sample_rate, device.min_pulse_duration , device.max_pulse_duration , device.max_num_shots , - device.ising_coefficient , - device.xy_coefficient , - device.min_dist_between_atom , - device.max_atom_dist_from_origin + get_device_interaction_coeff() , + device.min_qubit_dist ); } diff --git a/src/device/analog/analog_device.h b/src/device/analog/analog_device.h index a682476..02bd518 100644 --- a/src/device/analog/analog_device.h +++ b/src/device/analog/analog_device.h @@ -13,23 +13,31 @@ #include "analog_datatypes.h" cq_status enable_analog_mode(device_mode mode); -cq_status enable_analog_qreg(int qreg_id, int num_qubits); -cq_status disable_analog_qreg(int qreg_id); -cq_status get_global_channel(channel *ch, int type, int qreg_id); -cq_status get_local_channel(channel *ch, int type, int target, int qreg_id); +cq_status enable_analog_qreg(ptrdiff_t qreg_id, ptrdiff_t num_qubits); +cq_status disable_analog_qreg(ptrdiff_t qreg_id); +cq_status get_global_channel(channel *ch, int type, ptrdiff_t qreg_id); +cq_status get_local_channel(channel *ch, int type, ptrdiff_t target, ptrdiff_t qreg_id); cq_status is_analog_device_init(void); cq_hamiltonian * get_hamiltonian(const analog_qreg *qreg); -analog_qreg * get_qreg(int qreg_id); +analog_qreg * get_qreg(ptrdiff_t qreg_id); double get_device_sample_rate(void); double get_device_min_pulse_duration(void); double get_device_max_pulse_duration(void); -double get_device_ising_coeff(void); -double get_device_xy_coeff(void); -double get_device_min_atom_dist(void); +double get_device_interaction_coeff(void); +double get_device_min_qubit_dist(void); int get_device_max_num_shots(void); device_mode get_device_operating_mode(void); +coupling_func get_device_coupling_func(void); + +void set_device_sample_rate(double rate); +void set_device_min_pulse_duration(double duration); +void set_device_max_pulse_duration(double duration); +void set_device_interaction_coeff(double coeff); +void set_device_min_qubit_dist(double distance); +void set_device_max_num_shots(int shots); +void set_device_coupling_func(double(*coupler)(double *q0, double *q1)); ptrdiff_t duration_to_samples(double duration); double samples_to_duration(ptrdiff_t num_samples); diff --git a/src/device/analog/analog_qreg.c b/src/device/analog/analog_qreg.c index 0621133..2d44373 100644 --- a/src/device/analog/analog_qreg.c +++ b/src/device/analog/analog_qreg.c @@ -17,7 +17,7 @@ #include #include -cq_status init_qreg(analog_qreg *qreg, int qreg_id, int num_qubits, cq_hamiltonian *hamiltonian) { +cq_status init_qreg(analog_qreg *qreg, ptrdiff_t qreg_id, ptrdiff_t num_qubits, cq_hamiltonian *hamiltonian) { assert(qreg != NULL); assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); assert(num_qubits > 0 && num_qubits <= __CQ_ANALOG_MAX_NUM_QUBITS__); @@ -37,16 +37,17 @@ cq_status init_qreg(analog_qreg *qreg, int qreg_id, int num_qubits, cq_hamiltoni return CQ_SUCCESS; } -cq_status init_qubit_pos(qpos *qubit_pos, int num_qubits) { +cq_status init_qubit_pos(qpos *qubit_pos, ptrdiff_t num_qubits) { assert(qubit_pos != NULL); assert(num_qubits > 0 && num_qubits <= __CQ_ANALOG_MAX_NUM_QUBITS__); - double min_dist = get_device_min_atom_dist() + 0.00001; - for (int i = 0; i < num_qubits; ++i) { + double min_dist = get_device_min_qubit_dist() + 0.00001; + for (ptrdiff_t i = 0; i < num_qubits; ++i) { qubit_pos[i].x = i * min_dist; qubit_pos[i].y = 0.0; qubit_pos[i].z = 0.0; } + return CQ_SUCCESS; } @@ -85,7 +86,7 @@ cq_status reset_qreg(analog_qreg *qreg) { return CQ_SUCCESS; } -cq_status update_qreg_pos(const qpos *positions, int num_qubits, int qreg_id) { +cq_status update_qreg_pos(const qpos *positions, ptrdiff_t num_qubits, ptrdiff_t qreg_id) { assert(positions != NULL); assert(num_qubits > 0 && num_qubits < __CQ_ANALOG_MAX_NUM_QUBITS__); assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); @@ -94,20 +95,20 @@ cq_status update_qreg_pos(const qpos *positions, int num_qubits, int qreg_id) { assert(qreg != NULL); if (!qreg->in_use) { - printf("Error: The qreg with index: %d was not initialised " + printf("Error: The qreg with index: %td was not initialised " "in analog mode. From: %s\n", qreg->id, __func__); return CQ_ERROR; } if (num_qubits > qreg->num_qubits) { - printf("Error: The passed num_qubits (%d) is larger than the size " - "of register (%d). From: %s\n", + printf("Error: The passed num_qubits (%td) is larger than the size " + "of register (%td). From: %s\n", num_qubits, qreg->num_qubits, __func__); return CQ_ERROR; } - for (int i = 0; i < num_qubits; ++i) { + for (ptrdiff_t i = 0; i < num_qubits; ++i) { qreg->qubit_pos[i].x = positions[i].x; qreg->qubit_pos[i].y = positions[i].y; qreg->qubit_pos[i].z = positions[i].z; @@ -120,22 +121,22 @@ cq_status update_qreg_pos(const qpos *positions, int num_qubits, int qreg_id) { } -cq_status print_qpos(int qreg_id) { +cq_status print_qpos(ptrdiff_t qreg_id) { assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); analog_qreg *qreg = get_qreg(qreg_id); assert(qreg != NULL); if (!qreg->in_use) { - printf("Error: The qreg with index: %d was not initialised " + printf("Error: The qreg with index: %td was not initialised " "in analog mode. From: %s\n", qreg->id, __func__); return CQ_ERROR; } - printf("Qubit positions in qreg %d:\n", qreg_id); - for (int i = 0; i < qreg->num_qubits; ++i) { - printf("q%d: %f %f %f\n", i, + printf("Qubit positions in qreg %td:\n", qreg_id); + for (ptrdiff_t i = 0; i < qreg->num_qubits; ++i) { + printf("q%td: %f %f %f\n", i, qreg->qubit_pos[i].x, qreg->qubit_pos[i].y, qreg->qubit_pos[i].z diff --git a/src/device/analog/analog_qreg.h b/src/device/analog/analog_qreg.h index 4adba8c..88af961 100644 --- a/src/device/analog/analog_qreg.h +++ b/src/device/analog/analog_qreg.h @@ -12,13 +12,15 @@ #include "analog_datatypes.h" -cq_status init_qreg(analog_qreg *qreg, int qreg_id, - int num_qubits, cq_hamiltonian *hamiltonian); -cq_status init_qubit_pos(qpos *qubit_pos, int num_qubits); +cq_status init_qreg(analog_qreg *qreg, ptrdiff_t qreg_id, + ptrdiff_t num_qubits, cq_hamiltonian *hamiltonian); +cq_status init_qubit_pos(qpos *qubit_pos, ptrdiff_t num_qubits); +//cq_status init_qubit_pos(double *qubit_pos, ptrdiff_t num_qubits); cq_status reset_qreg(analog_qreg *qreg); -cq_status update_qreg_pos(const qpos *new_positions, int num_qubits, int qreg_id); +cq_status update_qreg_pos(const qpos *new_positions, ptrdiff_t num_qubits, ptrdiff_t qreg_id); +//cq_status update_qreg_pos(const double *new_positions, ptrdiff_t num_qubits, ptrdiff_t qreg_id); -cq_status print_qpos(int qreg_id); +cq_status print_qpos(ptrdiff_t qreg_id); #endif // CQ_ANALOG_QREG_H diff --git a/src/device/analog/channel.c b/src/device/analog/channel.c index 6d69350..ebb540a 100644 --- a/src/device/analog/channel.c +++ b/src/device/analog/channel.c @@ -8,10 +8,11 @@ */ #include "channel.h" +#include "analog_device.h" #include #include -static cq_status setup_rydberg_local_params(channel_params *params, int qreg_id) { +static cq_status setup_local_channel_params(channel_params *params, ptrdiff_t qreg_id) { assert(params != NULL); params->max_freq = 62.83; @@ -19,16 +20,17 @@ static cq_status setup_rydberg_local_params(channel_params *params, int qreg_id) params->min_amp = 0.0; params->min_retarget_dt = 220.0; params->retarget_delay = 0.0; - params->sample_rate = 0.25; - params->min_pulse_duration = 16; + params->sample_rate = get_device_sample_rate(); + params->min_pulse_duration = get_device_min_pulse_duration(); + params->max_pulse_duration = get_device_max_pulse_duration(); params->max_targets = 1; - params->addressing = LOCAL; + params->addressing = CQ_ADDR_LOCAL; params->qreg_id = qreg_id; return CQ_SUCCESS; } -static cq_status setup_rydberg_global_params(channel_params *params, int qreg_id) { +static cq_status setup_global_channel_params(channel_params *params, ptrdiff_t qreg_id) { assert(params != NULL); params->max_freq = 15.71; @@ -36,44 +38,11 @@ static cq_status setup_rydberg_global_params(channel_params *params, int qreg_id params->min_amp = 0.0; params->min_retarget_dt = 0.0; params->retarget_delay = 0.0; - params->sample_rate = 0.25; - params->min_pulse_duration = 16; + params->sample_rate = get_device_sample_rate(); + params->min_pulse_duration = get_device_min_pulse_duration(); + params->max_pulse_duration = get_device_max_pulse_duration(); params->max_targets = -1; - params->addressing = GLOBAL; - params->qreg_id = qreg_id; - - return CQ_SUCCESS; -} - -static cq_status setup_raman_local_params(channel_params *params, int qreg_id) { - assert(params != NULL); - - params->max_freq = 62.83; - params->max_detuning = 125.7; - params->min_amp = 0.0; - params->min_retarget_dt = 220.0; - params->retarget_delay = 0.0; - params->sample_rate = 0.25; - params->min_pulse_duration = 16; - params->max_targets = 1; - params->addressing = LOCAL; - params->qreg_id = qreg_id; - - return CQ_SUCCESS; -} - -static cq_status setup_dmm_global_params(channel_params *params, int qreg_id) { - assert(params != NULL); - - params->max_freq = 0.0; - params->max_detuning = 125.7; - params->min_amp = 0.0; - params->min_retarget_dt = 0.0; - params->retarget_delay = 0.0; - params->sample_rate = 0.25; - params->min_pulse_duration = 16; - params->max_targets = -1; - params->addressing = GLOBAL; + params->addressing = CQ_ADDR_GLOBAL; params->qreg_id = qreg_id; return CQ_SUCCESS; @@ -82,11 +51,9 @@ static cq_status setup_dmm_global_params(channel_params *params, int qreg_id) { cq_status setup_channel_params(analog_qreg *qreg) { assert(qreg != NULL); - int qreg_id = qreg->id; - setup_rydberg_global_params(&qreg->channel_params[RYDBERG_GLOBAL], qreg_id); - setup_rydberg_local_params(&qreg->channel_params[RYDBERG_LOCAL], qreg_id); - setup_raman_local_params(&qreg->channel_params[RAMAN_LOCAL], qreg_id); - setup_dmm_global_params(&qreg->channel_params[DMM_GLOBAL], qreg_id); + ptrdiff_t qreg_id = qreg->id; + setup_global_channel_params(&qreg->channel_params[CQ_ADDR_GLOBAL], qreg_id); + setup_local_channel_params(&qreg->channel_params[CQ_ADDR_LOCAL], qreg_id); return CQ_SUCCESS; } @@ -108,10 +75,21 @@ cq_status copy_channel(channel *dest, const channel *src) { return CQ_SUCCESS; } +cq_status retarget_channel(channel *ch, ptrdiff_t new_target) { + assert(ch != NULL); + assert(new_target > -2); + assert(new_target < __CQ_ANALOG_MAX_NUM_QUBITS__); + assert(ch->params != NULL); + + ch->target = new_target; + ch->time += ((channel_params *)ch->params)->retarget_delay; + return CQ_SUCCESS; +} + void print_avail_channels(void) { printf("==============================================================\n" "Available Channels:\n" - "----- RYDBERG_GLOBAL: \n" + "----- CQ_ADDR_GLOBAL: \n" "\tmax_freq = 15.71 \n" "\tmax_detuning = 125.7 \n" "\tmin_amp = 0.0 \n" @@ -120,9 +98,9 @@ void print_avail_channels(void) { "\tsample_rate = 0.25 \n" "\tmin_pulse_duration = 16\n" "\tmax_targets = -1 \n" - "\taddressing = GLOBAL \n\n" + "\taddressing = CQ_ADDR_GLOBAL \n\n" - "----- RYDBERG_LOCAL: \n" + "----- CQ_ADDR_LOCAL: \n" "\tmax_freq = 62.83 \n" "\tmax_detuning = 125.7 \n" "\tmin_amp = 0.0 \n" @@ -131,17 +109,17 @@ void print_avail_channels(void) { "\tsample_rate = 0.25 \n" "\tmin_pulse_duration = 16\n" "\tmax_targets = 1 \n" - "\taddressing = LOCAL \n" + "\taddressing = CQ_ADDR_LOCAL \n" "==============================================================\n" ); } -static const char *get_channel_type_str(channel_type type) { +static const char *get_channel_type_str(addressing type) { switch (type) { - case RYDBERG_LOCAL: - return "RYDBERG_LOCAL"; - case RYDBERG_GLOBAL: - return "RYDBERG_GLOBAL"; + case CQ_ADDR_LOCAL: + return "CQ_ADDR_LOCAL"; + case CQ_ADDR_GLOBAL: + return "CQ_ADDR_GLOBAL"; default: return "Unknown"; } @@ -149,10 +127,10 @@ static const char *get_channel_type_str(channel_type type) { static const char *get_addressing_str(addressing addressing) { switch (addressing) { - case LOCAL: - return "LOCAL"; - case GLOBAL: - return "GLOBAL"; + case CQ_ADDR_LOCAL: + return "CQ_ADDR_LOCAL"; + case CQ_ADDR_GLOBAL: + return "CQ_ADDR_GLOBAL"; default: return "Unknown"; } @@ -166,7 +144,7 @@ void print_channel(channel *ch) { "----- channel: \n" "\tid: %d\n" "\ttype: %s\n" - "\ttarget: %d\n" + "\ttarget: %td\n" "\ttime: %f\n" "\tmax_freq = %f \n" "\tmax_detuning = %f \n" diff --git a/src/device/analog/channel.h b/src/device/analog/channel.h index e028d3e..e2ffec1 100644 --- a/src/device/analog/channel.h +++ b/src/device/analog/channel.h @@ -14,6 +14,7 @@ cq_status setup_channel_params(analog_qreg *qreg); cq_status copy_channel(channel *dest, const channel *src); +cq_status retarget_channel(channel *ch, ptrdiff_t new_target); void print_avail_channels(void); void print_channel(channel *ch); diff --git a/src/device/analog/hamil.c b/src/device/analog/hamil.c index 22004f8..c390e50 100644 --- a/src/device/analog/hamil.c +++ b/src/device/analog/hamil.c @@ -10,23 +10,23 @@ #include "hamil.h" #include "analog_device.h" +#include "utils.h" #include #include #include term_modifier term_modifiers[TERM_MODIFIER_COUNT] = { - &rabi_freq_cos_modifier, - &rabi_freq_sin_modifier, + &freq_cos_modifier, + &freq_sin_modifier, &detuning_modifier }; static cq_status add_pauli_term( cq_hamiltonian *hamiltonian, char pauli, - int target, int var_idx, double sign) { + ptrdiff_t target, int var_idx, double sign) { assert(hamiltonian != NULL); - //assert(hamiltonian->num_terms < __CQ_ANALOG_MAX_NUM_HAM_TERMS__); assert(pauli == 'I' || pauli == 'X' || pauli == 'Y' || pauli == 'Z' ); assert(target > -1 && target < __CQ_ANALOG_MAX_NUM_QUBITS__); assert(var_idx > -1 && var_idx < TERM_MODIFIER_COUNT); @@ -39,7 +39,7 @@ static cq_status add_pauli_term( ptrdiff_t i = hamiltonian->num_terms; hamiltonian->terms[i].paulis[0] = pauli; - hamiltonian->terms[i].indices[0] = target; + hamiltonian->terms[i].indices[0] = (int)target; hamiltonian->terms[i].num_paulis = 1; hamiltonian->terms[i].var_idx = var_idx; hamiltonian->terms[i].sign = sign; @@ -63,19 +63,17 @@ static double qubit_dist(const qpos *a, const qpos *b) { return sqrt(dist); } - - static cq_status ising_interaction(const qpos *q0, const qpos *q1, double *result) { assert(q0 != NULL); assert(q1 != NULL); - double C = get_device_ising_coeff(); + double C = get_device_interaction_coeff(); double dist6 = qubit_dist(q0, q1); - if (dist6 < get_device_min_atom_dist()) { + if (dist6 < get_device_min_qubit_dist()) { printf("Error: The distance between atoms is too small. " "Minimal distance between atoms is %f, given %f\n" "Setting interaction strength to 0.0!", - get_device_min_atom_dist(), dist6); + get_device_min_qubit_dist(), dist6); *result = 0.0; return CQ_ERROR; } @@ -88,13 +86,13 @@ static cq_status xy_interaction(const qpos *q0, const qpos *q1, double *result) assert(q0 != NULL); assert(q1 != NULL); - double C3 = get_device_xy_coeff(); + double C3 = get_device_interaction_coeff(); double dist3 = qubit_dist(q0, q1); - if (dist3 < get_device_min_atom_dist()) { + if (dist3 < get_device_min_qubit_dist()) { printf("Error: The distance between atoms is too small. " "Minimal distance between atoms is %f, given %f\n" "Returning interaction strength = 0.0!", - get_device_min_atom_dist(), dist3); + get_device_min_qubit_dist(), dist3); *result = 0.0; return CQ_ERROR; } @@ -107,8 +105,16 @@ static cq_status interaction(const qpos *q0, const qpos *q1, double *result) { assert(q0 != NULL); assert(q1 != NULL); + coupling_func coupler = get_device_coupling_func(); + if (coupler) { + double q0_[3] = {q0->x, q0->y, q0->z}; + double q1_[3] = {q1->x, q1->y, q1->z}; + *result = coupler(q0_, q1_); + return CQ_SUCCESS; + } + switch(get_device_operating_mode()) { - case RYDBERG: + case ISING: return ising_interaction(q0, q1, result); case XY: return xy_interaction(q0, q1, result); @@ -117,7 +123,7 @@ static cq_status interaction(const qpos *q0, const qpos *q1, double *result) { } } -cq_status add_rydberg_local_term(int target, cq_hamiltonian *hamiltonian) { +cq_status add_driving_local_term(ptrdiff_t target, cq_hamiltonian *hamiltonian) { assert(target > -1 && target < __CQ_ANALOG_MAX_NUM_QUBITS__); assert(hamiltonian != NULL); @@ -125,12 +131,12 @@ cq_status add_rydberg_local_term(int target, cq_hamiltonian *hamiltonian) { // Adding (w(t)cos(p(t))X + w(t)sin(p(t))Y - d(t)(1 - Z)) / 2 if (add_pauli_term(hamiltonian, 'X', target, - TERM_MODIFIER_RABI_COS, + TERM_MODIFIER_FREQ_COS, sign) != CQ_SUCCESS) return CQ_ERROR; if (add_pauli_term(hamiltonian, 'Y', target, - TERM_MODIFIER_RABI_SIN, + TERM_MODIFIER_FREQ_SIN, sign) != CQ_SUCCESS) return CQ_ERROR; if (add_pauli_term(hamiltonian, @@ -146,7 +152,7 @@ cq_status add_rydberg_local_term(int target, cq_hamiltonian *hamiltonian) { return CQ_SUCCESS; } -cq_status add_rydberg_global_term(analog_qreg *qreg, cq_hamiltonian *hamiltonian) { +cq_status add_driving_global_term(analog_qreg *qreg, cq_hamiltonian *hamiltonian) { assert(qreg != NULL); assert(qreg->in_use); assert(qreg->num_qubits < __CQ_ANALOG_MAX_NUM_CHANNELS__); @@ -154,20 +160,20 @@ cq_status add_rydberg_global_term(analog_qreg *qreg, cq_hamiltonian *hamiltonian channel global_ch = {0}; global_ch.id = (int)(qreg->num_channels); - global_ch.type = RYDBERG_GLOBAL; + global_ch.type = CQ_ADDR_GLOBAL; global_ch.target = -1; - global_ch.params = (void *)&qreg->channel_params[RYDBERG_GLOBAL]; + global_ch.params = (void *)&qreg->channel_params[CQ_ADDR_GLOBAL]; qreg->channels_ranges[global_ch.id].start = hamiltonian->num_terms; - for (int i = 0; i < qreg->num_qubits; ++i) { + for (ptrdiff_t i = 0; i < qreg->num_qubits; ++i) { channel local_ch = {0}; local_ch.id = (int)(qreg->num_channels + 1); - local_ch.type = RYDBERG_LOCAL; + local_ch.type = CQ_ADDR_LOCAL; local_ch.target = i; - local_ch.params = (void *)&qreg->channel_params[RYDBERG_LOCAL]; + local_ch.params = (void *)&qreg->channel_params[CQ_ADDR_LOCAL]; qreg->channels_ranges[local_ch.id].start = hamiltonian->num_terms; - add_rydberg_local_term(i, hamiltonian); + add_driving_local_term(i, hamiltonian); qreg->channels_ranges[local_ch.id].end = hamiltonian->num_terms; qreg->channels[local_ch.id] = local_ch; @@ -180,53 +186,13 @@ cq_status add_rydberg_global_term(analog_qreg *qreg, cq_hamiltonian *hamiltonian return CQ_SUCCESS; } -cq_status add_raman_local_term(int target, cq_hamiltonian *hamiltonian) { - // for raman, interaction is the same as for rydberg - // okay - it actually doesn't matter - // from my perspecitve raman and rydberg are the same - i dont care about - // the actual atom states - assert(target > -1 && target < __CQ_ANALOG_MAX_NUM_QUBITS__); - assert(hamiltonian != NULL); - - double sign = 1.0; - // Adding (w(t)cos(p(t))X + w(t)sin(p(t))Y - d(t)(1 - Z)) / 2 - if (add_pauli_term(hamiltonian, - 'X', target, - TERM_MODIFIER_RABI_COS, - sign) != CQ_SUCCESS) return CQ_ERROR; - - if (add_pauli_term(hamiltonian, - 'Y', target, - TERM_MODIFIER_RABI_SIN, - sign) != CQ_SUCCESS) return CQ_ERROR; - - if (add_pauli_term(hamiltonian, - 'I', target, - TERM_MODIFIER_DETUNING, - -sign) != CQ_SUCCESS) return CQ_ERROR; - - if (add_pauli_term(hamiltonian, - 'Z', target, - TERM_MODIFIER_DETUNING, - sign) != CQ_SUCCESS) return CQ_ERROR; - - return CQ_SUCCESS; -} - cq_status add_driving_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian) { assert(qreg != NULL); assert(qreg->in_use); assert(qreg->num_qubits < __CQ_ANALOG_MAX_NUM_CHANNELS__); assert(hamiltonian != NULL); - // actually in NA the driving hamiltonian is the same - // for rydberg, raman and even microwave channels (e.g. Pasqal) - // The only difference is in the physical qubit basis -- - // however from the pov of simulation this does not matter - add_rydberg_global_term(qreg, hamiltonian); - - // TODO: possibly driving for SC system (e.g. DWave) - + add_driving_global_term(qreg, hamiltonian); return CQ_SUCCESS; } @@ -243,7 +209,7 @@ static void print_hamil(cq_hamiltonian *hamiltonian) { static cq_status add_two_pauli_term( cq_hamiltonian *hamiltonian, char pauli_i, char pauli_j, - int i, int j, double interaction_str) { + ptrdiff_t i, ptrdiff_t j, double interaction_str) { assert(hamiltonian != NULL); assert(hamiltonian->num_terms < __CQ_ANALOG_MAX_NUM_HAM_TERMS__); @@ -254,15 +220,14 @@ static cq_status add_two_pauli_term( ptrdiff_t term_idx = hamiltonian->num_terms; hamiltonian->terms[term_idx].paulis[0] = pauli_i; - hamiltonian->terms[term_idx].indices[0] = i; + hamiltonian->terms[term_idx].indices[0] = (int)i; hamiltonian->terms[term_idx].paulis[1] = pauli_j; - hamiltonian->terms[term_idx].indices[1] = j; + hamiltonian->terms[term_idx].indices[1] = (int)j; hamiltonian->terms[term_idx].num_paulis = 2; hamiltonian->real[term_idx] = interaction_str; hamiltonian->imag[term_idx] = 0.0; hamiltonian->num_terms++; - //assert(hamiltonian->num_terms < __CQ_ANALOG_MAX_NUM_HAM_TERMS__); if (hamiltonian->num_terms >= __CQ_ANALOG_MAX_NUM_HAM_TERMS__) { printf("Error: Too many terms in the hamiltonian.\n"); return CQ_ERROR; @@ -271,8 +236,6 @@ static cq_status add_two_pauli_term( return CQ_SUCCESS; } - - cq_status add_xy_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian) { assert(qreg != NULL); assert(qreg->in_use); @@ -289,14 +252,12 @@ cq_status add_xy_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonia // 2(XiXj + YiYj) qreg->sys_terms_range.start = hamiltonian->num_terms; - for (int i = 0; i < qreg->num_qubits; ++i) { - for (int j = i + 1; j < qreg->num_qubits; ++j) { - //double interaction_str = xy_interaction(&qreg->qubit_pos[i], - // &qreg->qubit_pos[j]); + for (ptrdiff_t i = 0; i < qreg->num_qubits; ++i) { + for (ptrdiff_t j = i + 1; j < qreg->num_qubits; ++j) { double interaction_str = 0.0; - if(xy_interaction(&qreg->qubit_pos[i], + HANDLE_CQ_ERROR(xy_interaction(&qreg->qubit_pos[i], &qreg->qubit_pos[j], - &interaction_str) == CQ_ERROR) return CQ_ERROR; + &interaction_str)); interaction_str *= 2.0; add_two_pauli_term(hamiltonian, 'X', 'X', i, j, interaction_str); @@ -315,8 +276,8 @@ cq_status add_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian) device_mode mode = get_device_operating_mode(); switch (mode) { - case RYDBERG: - add_rydberg_interaction_terms(qreg, hamiltonian); + case ISING: + add_ising_interaction_terms(qreg, hamiltonian); break; case XY: add_xy_interaction_terms(qreg, hamiltonian); @@ -329,9 +290,7 @@ cq_status add_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian) return CQ_SUCCESS; } - - -cq_status add_rydberg_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian) { +cq_status add_ising_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian) { assert(qreg != NULL); assert(qreg->in_use); assert(hamiltonian != NULL); @@ -340,16 +299,12 @@ cq_status add_rydberg_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamil // so we get 11 - 1Z - Z1 + ZZ qreg->sys_terms_range.start = hamiltonian->num_terms; - for (int i = 0; i < qreg->num_qubits; ++i) { - for (int j = i + 1; j < qreg->num_qubits; ++j) { - //double interaction_str = ising_interaction(&qreg->qubit_pos[i], - // &qreg->qubit_pos[j]); + for (ptrdiff_t i = 0; i < qreg->num_qubits; ++i) { + for (ptrdiff_t j = i + 1; j < qreg->num_qubits; ++j) { double interaction_str = 0.0; - if(ising_interaction(&qreg->qubit_pos[i], + HANDLE_CQ_ERROR(ising_interaction(&qreg->qubit_pos[i], &qreg->qubit_pos[j], - &interaction_str) == CQ_ERROR) return CQ_ERROR; - - + &interaction_str)); add_two_pauli_term(hamiltonian, 'I', 'I', i, j, interaction_str); add_two_pauli_term(hamiltonian, 'I', 'Z', i, j, -interaction_str); @@ -372,15 +327,10 @@ cq_status update_sys_terms(const analog_qreg *qreg, cq_hamiltonian *hamiltonian) ptrdiff_t coeff_idx = qreg->sys_terms_range.start; for (ptrdiff_t i = 0; i < qreg->num_qubits; ++i) { for (ptrdiff_t j = i + 1; j < qreg->num_qubits; ++j) { - //const double interaction_str = interaction( - // &qreg->qubit_pos[i], - // &qreg->qubit_pos[j]); - double interaction_str = 0.0; - if(interaction(&qreg->qubit_pos[i], + HANDLE_CQ_ERROR(interaction(&qreg->qubit_pos[i], &qreg->qubit_pos[j], - &interaction_str) == CQ_ERROR) return CQ_ERROR; - + &interaction_str)); hamiltonian->real[coeff_idx] = interaction_str; hamiltonian->real[coeff_idx + 1] = -interaction_str; @@ -416,23 +366,23 @@ cq_status reset_hamiltonian(cq_hamiltonian *hamiltonian) { hamiltonian->real[i] = 0.0; hamiltonian->imag[i] = 0.0; hamiltonian->terms[i].num_paulis = 0; - hamiltonian->terms[i].var_idx = TERM_MODIFIER_RABI_COS; + hamiltonian->terms[i].var_idx = TERM_MODIFIER_FREQ_COS; hamiltonian->terms[i].sign = 1.0; } hamiltonian->num_terms = 0; return CQ_SUCCESS; } -#define RABI_SCALING_FACTOR 0.5 +#define FREQ_SCALING_FACTOR 0.5 #define DETUNING_SCALING_FACTOR 0.5 -double rabi_freq_cos_modifier(double freq, double phase, double detuning) { - return RABI_SCALING_FACTOR * freq * cos(phase); +double freq_cos_modifier(double freq, double phase, double detuning) { + return FREQ_SCALING_FACTOR * freq * cos(phase); } -double rabi_freq_sin_modifier(double freq, double phase, double detuning) { +double freq_sin_modifier(double freq, double phase, double detuning) { - return RABI_SCALING_FACTOR * freq * sin(phase); + return FREQ_SCALING_FACTOR * freq * sin(phase); } double detuning_modifier(double freq, double phase, double detuning) { @@ -440,4 +390,4 @@ double detuning_modifier(double freq, double phase, double detuning) { } #undef DETUNING_SCALING_FACTOR -#undef RABI_SCALING_FACTOR +#undef FREQ_SCALING_FACTOR diff --git a/src/device/analog/hamil.h b/src/device/analog/hamil.h index 4eaa4c7..c36f60f 100644 --- a/src/device/analog/hamil.h +++ b/src/device/analog/hamil.h @@ -15,23 +15,14 @@ cq_status add_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian); // static and move to .c? -cq_status add_rydberg_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian); +cq_status add_ising_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian); cq_status add_xy_interaction_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian); cq_status add_driving_terms(analog_qreg *qreg, cq_hamiltonian *hamiltonian); // static and move to .c? -cq_status add_rydberg_local_term(int target, cq_hamiltonian *hamiltonian); -cq_status add_rydberg_global_term(analog_qreg *qreg, cq_hamiltonian *hamiltonian); -cq_status add_raman_local_term(int target, cq_hamiltonian *hamiltonian); - -// this applies global detuning zero amp and negative detuing -// adds -h/2 sum e * d(t) Z where e are the weights in the detuing map of atoms -// A DetuningMap associates a set of locations with a set of weights. The locations are the trap coordinates to address and the weights have to be between 0 and 1. -// SO this is Register thing -cq_status add_dmm_global_term(analog_qreg *qreg); - -// TODO allow to select SC -- something like dwave with corresponding hamils +cq_status add_driving_local_term(ptrdiff_t target, cq_hamiltonian *hamiltonian); +cq_status add_driving_global_term(analog_qreg *qreg, cq_hamiltonian *hamiltonian); cq_status update_sys_terms(const analog_qreg *qreg, cq_hamiltonian *hamiltonian); cq_status zero_driving_terms(ptrdiff_t start, ptrdiff_t end, @@ -41,14 +32,14 @@ cq_status zero_driving_terms(ptrdiff_t start, ptrdiff_t end, cq_status reset_hamiltonian(cq_hamiltonian *hamiltonian); typedef enum term_modifier_type { - TERM_MODIFIER_RABI_COS = 0, - TERM_MODIFIER_RABI_SIN, + TERM_MODIFIER_FREQ_COS = 0, + TERM_MODIFIER_FREQ_SIN, TERM_MODIFIER_DETUNING, TERM_MODIFIER_COUNT } term_modifier_type; -double rabi_freq_cos_modifier(double freq, double phase, double detuning); -double rabi_freq_sin_modifier(double freq, double phase, double detuning); +double freq_cos_modifier(double freq, double phase, double detuning); +double freq_sin_modifier(double freq, double phase, double detuning); double detuning_modifier(double freq, double phase, double detuning); typedef double (*term_modifier)(double, double, double); diff --git a/src/device/analog/pulse.c b/src/device/analog/pulse.c index 3023aca..dac2bf7 100644 --- a/src/device/analog/pulse.c +++ b/src/device/analog/pulse.c @@ -15,6 +15,7 @@ #include #include +#include static cq_status can_channel_play_pulse(channel *ch, pulse *pulse) { @@ -79,6 +80,27 @@ cq_status init_pulse(pulse *pulse, double duration) { pulse->num_samples = num_samples; + pulse->freq = malloc(num_samples * sizeof(double)); + if (!pulse->freq) { + printf("Error: Failed to allocate freq array in pulse. " + "From: %s\n", __func__); + return CQ_ERROR; + } + + pulse->phase = malloc(num_samples * sizeof(double)); + if (!pulse->phase) { + printf("Error: Failed to allocate phase array in pulse. " + "From: %s\n", __func__); + return CQ_ERROR; + } + + pulse->detuning = malloc(num_samples * sizeof(double)); + if (!pulse->detuning) { + printf("Error: Failed to allocate detuning array in pulse. " + "From: %s\n", __func__); + return CQ_ERROR; + } + for (ptrdiff_t i = 0; i < num_samples; ++i) { pulse->freq[i] = 0.0; pulse->phase[i] = 0.0; @@ -88,6 +110,21 @@ cq_status init_pulse(pulse *pulse, double duration) { return CQ_SUCCESS; } +cq_status free_pulse(pulse *pulse) { + assert(pulse != NULL); + assert(pulse->freq != NULL); + assert(pulse->phase != NULL); + assert(pulse->detuning != NULL); + + free(pulse->freq); + free(pulse->phase); + free(pulse->detuning); + pulse->freq = NULL; + pulse->phase = NULL; + pulse->detuning = NULL; + return CQ_SUCCESS; +} + cq_status play(channel *ch, pulse *pulse) { assert(ch != NULL); assert(ch->params != NULL); @@ -97,7 +134,7 @@ cq_status play(channel *ch, pulse *pulse) { channel_params *params = (channel_params *)ch->params; assert(params != NULL); - int qreg_id = params->qreg_id; + ptrdiff_t qreg_id = params->qreg_id; assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); analog_qreg *qreg = get_qreg(qreg_id); @@ -134,7 +171,7 @@ cq_status capture(channel *ch, pulse *pulse, int *result, int shots) { channel_params *params = (channel_params *)ch->params; assert(params != NULL); - int qreg_id = params->qreg_id; + ptrdiff_t qreg_id = params->qreg_id; assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); analog_qreg *qreg = get_qreg(qreg_id); assert(qreg != NULL); diff --git a/src/device/analog/pulse.h b/src/device/analog/pulse.h index 9e7dc07..1b4d0a5 100644 --- a/src/device/analog/pulse.h +++ b/src/device/analog/pulse.h @@ -13,6 +13,7 @@ #include "analog_datatypes.h" cq_status init_pulse(pulse *pulse, double duration); +cq_status free_pulse(pulse *pulse); cq_status play(channel *ch, pulse *pulse); cq_status capture(channel *ch, pulse *pulse, int *result, int shots); cq_status delay(channel *ch, double dt); diff --git a/src/device/analog/simulator.c b/src/device/analog/simulator.c index 423f1c2..593dc3e 100644 --- a/src/device/analog/simulator.c +++ b/src/device/analog/simulator.c @@ -26,7 +26,7 @@ static cq_status get_pauli_strings(cq_hamiltonian *hamiltonian, PauliStr *pauli_ assert(pauli_strings != NULL); assert(hamiltonian->num_terms < __CQ_ANALOG_MAX_NUM_HAM_TERMS__); - for (int i = 0; i < hamiltonian->num_terms; ++i) { + for (ptrdiff_t i = 0; i < hamiltonian->num_terms; ++i) { const PauliStr quest_pauli_str = getPauliStr( hamiltonian->terms[i].paulis, hamiltonian->terms[i].indices, @@ -63,7 +63,7 @@ cq_status simulate_pulse(channel *ch, pulse *pulse, analog_qreg *qreg, cq_hamilt assert(qreg != NULL); assert(hamiltonian != NULL); - int qreg_id = qreg->id; + ptrdiff_t qreg_id = qreg->id; if (quest_hamiltonians[qreg_id].numTerms == 0) { init_quest_hamiltonian(hamiltonian, &quest_hamiltonians[qreg_id]); @@ -117,7 +117,7 @@ int simulate_capture(channel *ch, analog_qreg *qreg) { ch->target); } -void sync_simulator(cq_hamiltonian *hamiltonian, int qreg_id) { +void sync_simulator(cq_hamiltonian *hamiltonian, ptrdiff_t qreg_id) { assert(hamiltonian != NULL); assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); @@ -131,12 +131,12 @@ void sync_simulator(cq_hamiltonian *hamiltonian, int qreg_id) { } } -void print_statevec(int qreg_id) { +void print_statevec(ptrdiff_t qreg_id) { assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); Qureg quest_qureg = qregistry.registers[qreg_id]; #define printbits_n(x,n) for (int j=n;j;j--,putchar('0'|(x>>j)&1)) - for (int i = 0; i < quest_qureg.numAmps; ++i) { + for (ptrdiff_t i = 0; i < quest_qureg.numAmps; ++i) { double prob = creal(quest_qureg.cpuAmps[i]) * creal(quest_qureg.cpuAmps[i]) + cimag(quest_qureg.cpuAmps[i]) * cimag(quest_qureg.cpuAmps[i]); @@ -147,18 +147,18 @@ void print_statevec(int qreg_id) { #undef printbits_n } -void init_simulator_qreg(int qreg_id, int num_qubits) { +void init_simulator_qreg(ptrdiff_t qreg_id, ptrdiff_t num_qubits) { if (!isQuESTEnvInit()) { initQuESTEnv(); } if (qregistry.available[qreg_id]) { qregistry.available[qreg_id] = true; - qregistry.registers[qreg_id] = createQureg(num_qubits); + qregistry.registers[qreg_id] = createQureg((int)num_qubits); } } -void reset_simulator_qreg(int qreg_id) { +void reset_simulator_qreg(ptrdiff_t qreg_id) { assert(qreg_id > -1 && qreg_id < __CQ_ANALOG_MAX_NUM_QUREGS__); initZeroState(qregistry.registers[qreg_id]); //qregistry.available[qreg_id] = false; diff --git a/src/device/analog/simulator.h b/src/device/analog/simulator.h index f4aa0bb..31070fe 100644 --- a/src/device/analog/simulator.h +++ b/src/device/analog/simulator.h @@ -14,8 +14,8 @@ cq_status simulate_pulse(channel *ch, pulse *pulse, analog_qreg *qreg, cq_hamiltonian *hamiltonian); int simulate_capture(channel *ch, analog_qreg *qreg); -void sync_simulator(cq_hamiltonian *hamiltonian, int qreg_id); -void print_statevec(int qreg_id); -void init_simulator_qreg(int qreg_id, int num_qubits); -void reset_simulator_qreg(int qreg_id); +void sync_simulator(cq_hamiltonian *hamiltonian, ptrdiff_t qreg_id); +void print_statevec(ptrdiff_t qreg_id); +void init_simulator_qreg(ptrdiff_t qreg_id, ptrdiff_t num_qubits); +void reset_simulator_qreg(ptrdiff_t qreg_id); #endif // CQ_ANALOG_SIMULATOR_H diff --git a/src/device/analog/waveforms.c b/src/device/analog/waveforms.c index df04d06..4dc7116 100644 --- a/src/device/analog/waveforms.c +++ b/src/device/analog/waveforms.c @@ -382,6 +382,7 @@ cq_status sech_wf(double *samples, double duration, double amp, double sigma) { cq_status sin_wf(double *samples, double duration, double amp, double freq, double phase) { + // sin is rescaled to be in [0, 1] range (if amp == 1.0) assert(samples != NULL); if (validate_duration(duration, get_device_min_pulse_duration(), @@ -392,7 +393,7 @@ cq_status sin_wf(double *samples, double duration, double amp, if (validate_sampling(sample_rate, duration, num_samples) == CQ_ERROR) return CQ_ERROR; for (ptrdiff_t i = 0; i < num_samples; ++i) { - samples[i] = amp * sin(2 * M_PI * freq * (double)i/(double)num_samples + phase); + samples[i] = amp * (0.5 * (1.0 + sin(2 * M_PI * freq * (double)i/(double)num_samples + phase))); } return CQ_SUCCESS; @@ -400,6 +401,7 @@ cq_status sin_wf(double *samples, double duration, double amp, cq_status cos_wf(double *samples, double duration, double amp, double freq, double phase) { + // cos is rescaled to be in [0, 1] range (if amp == 1.0) assert(samples != NULL); if (validate_duration(duration, get_device_min_pulse_duration(), @@ -410,7 +412,7 @@ cq_status cos_wf(double *samples, double duration, double amp, if (validate_sampling(sample_rate, duration, num_samples) == CQ_ERROR) return CQ_ERROR; for (ptrdiff_t i = 0; i < num_samples; ++i) { - samples[i] = amp * cos(2 * M_PI * freq * (double)i/(double)num_samples + phase); + samples[i] = amp * (0.5 * (1.0 + cos(2 * M_PI * freq * (double)i/(double)num_samples + phase))); } return CQ_SUCCESS; diff --git a/tests/device/analog/CMakeLists.txt b/tests/device/analog/CMakeLists.txt index 7e5d263..dcdcb04 100644 --- a/tests/device/analog/CMakeLists.txt +++ b/tests/device/analog/CMakeLists.txt @@ -3,6 +3,7 @@ find_library(MATHS_LIBRARY m REQUIRED) # ------------------------ analog ops ----------------------------- add_executable(test_analog test_analog.c + test_analog_runner.c ) target_link_libraries(test_analog @@ -20,6 +21,7 @@ add_test( # ------------------------ waveforms ------------------------------ add_executable(test_waveforms test_waveforms.c + test_waveforms_runner.c ) target_link_libraries(test_waveforms diff --git a/tests/device/analog/test_analog.c b/tests/device/analog/test_analog.c index c52dd53..9c252eb 100644 --- a/tests/device/analog/test_analog.c +++ b/tests/device/analog/test_analog.c @@ -1,32 +1,34 @@ #include "unity.h" #include "analog.h" +#include "cq.h" #include "src/device/resources.h" #include "src/device/control.h" #include +#define CQ_ADDR_GLOBAL 0 +#define CQ_ADDR_LOCAL 1 + +qubit *qr = NULL; void setUp(void) { int param = 0; initialise_simulator(¶m); const size_t NQUBITS = 5; - int idx = get_next_available_qregistry_slot(); - qregistry.registers[idx] = createQureg(NQUBITS); - qregistry.available[idx] = false; - ++qregistry.num_registers; + alloc_qureg(&qr, NQUBITS); return; } void tearDown(void) { int param = 0; - //finalise_simulator(¶m); + free_qureg(&qr); return; } void test_cq_enable_analog_mode(void) { - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_enable_analog_mode(RYDBERG)); + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_enable_analog_mode(ISING)); // Re-initialization should fail - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_mode(RYDBERG)); + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_mode(ISING)); cq_print_analog_device(); cq_print_avail_channels(); } @@ -52,225 +54,92 @@ void test_cq_enable_analog_qreg(void) { // Good inputs int qreg_id = 0; int num_qubits = 2; - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_enable_analog_qreg(qreg_id, num_qubits)); + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_enable_analog_qreg(qr)); // Re-initialization should fail - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(qreg_id, num_qubits)); + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(qr)); - // Bad qreg_id - qreg_id = 128; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(qreg_id, num_qubits)); - qreg_id = -2; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(qreg_id, num_qubits)); - - qreg_id = 0; - // Bad num_qubits - num_qubits = -3; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(qreg_id, num_qubits)); - num_qubits = 124; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(qreg_id, num_qubits)); - num_qubits = 0; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(qreg_id, num_qubits)); - - // Disabling and re-enabling qreg with different size should work - num_qubits = 3; - cq_disable_analog_qreg(qreg_id); - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_enable_analog_qreg(qreg_id, num_qubits)); - - // "Large" number of qubits should succeed - // (there should be sufficient memory for all internal functions) - //num_qubits = 59; // ofc fails at quest level - //num_qubits = 29; // succeeds but takes a while - num_qubits = 27; // "big" and fast - cq_disable_analog_qreg(qreg_id); - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_enable_analog_qreg(qreg_id, num_qubits)); + // Bad qr + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_enable_analog_qreg(NULL)); + + qubit *qr2 = NULL; + alloc_qureg(&qr2, 6); + cq_disable_analog_qreg(qr); + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_enable_analog_qreg(qr2)); + free_qureg(&qr2); } void test_cq_disable_analog_mode(void) { + // Disabling without enabling fails + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_disable_analog_qreg(qr)); + // Good inputs - int qreg_id = 0; - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_disable_analog_qreg(qreg_id)); + cq_enable_analog_qreg(qr); + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_disable_analog_qreg(qr)); // Repeating on the same qreg should fail - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_disable_analog_qreg(qreg_id)); + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_disable_analog_qreg(qr)); // Bad qreg_id - qreg_id = -1; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_disable_analog_qreg(qreg_id)); - - qreg_id = 128; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_disable_analog_qreg(qreg_id)); + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_disable_analog_qreg(NULL)); } -void test_cq_get_global_channel(void) { +void test_cq_get_channel(void) { channel ch0 = {0}; - channel ch1; - int global_type = 0; // aka RYDBERG_GLOBAL - int qreg_id = 0; - int num_qubits = 5; - double epsilon = 0.0000001; - + // Getting channel on uninitialised qreg. TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_global_channel(&ch0, global_type, qreg_id)); + cq_get_channel(&ch0, CQ_ADDR_LOCAL, qr, &qr[0])); - cq_enable_analog_qreg(qreg_id, num_qubits); + cq_enable_analog_qreg(qr); TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, - cq_get_global_channel(&ch0, global_type, qreg_id)); - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_print_channel(&ch0)); + cq_get_channel(&ch0, CQ_ADDR_LOCAL, qr, &qr[0])); TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, - cq_get_global_channel(&ch1, global_type, qreg_id)); - TEST_ASSERT_EQUAL_INT(ch0.id, ch1.id); - TEST_ASSERT_EQUAL_INT(ch0.type, ch1.type); - TEST_ASSERT_EQUAL_INT(ch0.target, ch1.target); - TEST_ASSERT(ch0.time < epsilon); - TEST_ASSERT(ch1.time < epsilon); - TEST_ASSERT(ch0.time - ch1.time < epsilon); - - // NULL channel - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_global_channel(NULL, global_type, qreg_id)); - - int negative_type = -1; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_global_channel(&ch0, negative_type, qreg_id)); - - int local_type = 1; // aka RYDBERG_LOCAL - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_global_channel(&ch0, local_type, qreg_id)); - - int unknown_type = 4; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_global_channel(&ch0, unknown_type, qreg_id)); + cq_get_channel(&ch0, CQ_ADDR_GLOBAL, qr, NULL)); - // Bad qreg_id - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_global_channel(&ch0, 0, -1)); - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_global_channel(&ch0, 0, 128)); -} - -void test_cq_get_local_channel(void) { - channel ch0 = {0}; - int local_type = 1; // aka RYDBERG_LOCAL - int qreg_id = 0; - int target = 0; - int num_qubits = 5; - - cq_disable_analog_qreg(qreg_id); - cq_enable_analog_qreg(qreg_id, num_qubits); - - - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, - cq_get_local_channel( - &ch0, local_type, target, qreg_id)); + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_print_channel(&ch0)); // NULL channel TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - NULL, local_type, target, qreg_id)); - - // Bad channel types - int negative_type = -1; + cq_get_channel(NULL, CQ_ADDR_LOCAL, qr, &qr[0])); + + // NULL qr TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, negative_type, target, qreg_id)); - int global_type = 0; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, global_type, target, qreg_id)); - - int unknown_type = 4; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, unknown_type, target, qreg_id)); - - // Bad target - int negative_target = -1; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, local_type, negative_target, qreg_id)); + cq_get_channel(&ch0, CQ_ADDR_LOCAL, NULL, &qr[0])); - int target_bigger_than_num_qubits = num_qubits; + // Bad type + int negative_type = -1; TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, local_type, - target_bigger_than_num_qubits, qreg_id)); - + cq_get_channel(&ch0, negative_type, qr, &qr[0])); - int too_big_target = 128; + int too_big_type = 2; TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, local_type, too_big_target, qreg_id)); + cq_get_channel(&ch0, too_big_type, qr, &qr[0])); - // Bad qreg id - int negative_qreg_id = -1; + // Providing target but accessing CQ_ADDR_GLOBAL channel. TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, local_type, target, negative_qreg_id)); + cq_get_channel(&ch0, CQ_ADDR_GLOBAL, qr, &qr[0])); - int too_big_qreg_id = 254; + // Bad target TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_get_local_channel( - &ch0, local_type, target, too_big_target)); - + cq_get_channel(&ch0, CQ_ADDR_LOCAL, qr, NULL)); } -void test_cq_update_qreg_pos(void) { - int num_qubits = 5; - int qreg_id = 0; - cq_disable_analog_qreg(qreg_id); - TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_print_qpos(qreg_id)); - cq_enable_analog_qreg(qreg_id, num_qubits); - - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_print_qpos(qreg_id)); - - qpos new_pos[5] = { - {5.0, 5.0, 0.0}, - {15.0, 15.0, 0.0}, - {25.0, 25.0, 0.0}, - {35.0, 35.0, 0.0}, - {45.0, 45.0, 0.0}, - }; - - TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, - cq_update_qreg_pos(new_pos, num_qubits, qreg_id)); - - cq_print_qpos(qreg_id); - qpos bad_pos[5] = { - {2.0, 5.0, 0.0}, - {3.0, 1.0, 0.0}, - {4.0, 0.0, 0.0}, - {5.0, 0.0, 0.0}, - {6.0, 0.0, 0.0}, - }; - - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_update_qreg_pos(bad_pos, num_qubits, qreg_id)); - - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_update_qreg_pos(NULL, num_qubits, qreg_id)); - - int neg_num_qubits = -1; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_update_qreg_pos(new_pos, neg_num_qubits, qreg_id)); - +void test_cq_retarget_channel(channel *ch, int new_target) { + channel ch0 = {0}; - int bad_num_qubits = num_qubits + 1; - TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_update_qreg_pos(new_pos, bad_num_qubits, qreg_id)); + cq_get_channel(&ch0, CQ_ADDR_LOCAL, qr, &qr[0]); - int negative_qreg_id = -2; TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_update_qreg_pos(new_pos, num_qubits, negative_qreg_id)); - + cq_retarget_channel(NULL, &qr[1])); - int too_big_qreg_id = num_qubits; TEST_ASSERT_EQUAL_INT(CQ_ERROR, - cq_update_qreg_pos(new_pos, num_qubits, too_big_qreg_id)); + cq_retarget_channel(&ch0, NULL)); + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, + cq_retarget_channel(&ch0, &qr[1])); } void test_cq_init_pulse(void) { @@ -290,7 +159,23 @@ void test_cq_init_pulse(void) { double too_long_duration = 10000000000.0; TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_init_pulse(&p, too_long_duration)); +} + +void test_cq_free_pulse(void) { + pulse p = {0}; + double duration = 100.0; + cq_init_pulse(&p, duration); + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, + cq_free_pulse(&p)); + + // Freeing the same pulse twice should fail + TEST_ASSERT_EQUAL_INT(CQ_ERROR, + cq_free_pulse(&p)); + + + TEST_ASSERT_EQUAL_INT(CQ_ERROR, + cq_free_pulse(NULL)); } void test_cq_play(void) { @@ -300,10 +185,10 @@ void test_cq_play(void) { int qreg_id = 0; int num_qubits = 5; - cq_disable_analog_qreg(qreg_id); - cq_enable_analog_qreg(qreg_id, num_qubits); + cq_disable_analog_qreg(qr); + cq_enable_analog_qreg(qr); - cq_get_local_channel(&ch, 1, 0, 0); + cq_get_channel(&ch, CQ_ADDR_LOCAL, qr, &qr[0]); // uninitialised pulse fails to play TEST_ASSERT_EQUAL_INT(CQ_ERROR, @@ -341,8 +226,8 @@ void test_cq_play(void) { void test_cq_capture(void) { int num_qubits = 5; int qreg_id = 0; - cq_disable_analog_qreg(qreg_id); - cq_enable_analog_qreg(qreg_id, num_qubits); + cq_disable_analog_qreg(qr); + cq_enable_analog_qreg(qr); channel ch = {0}; pulse p = {0}; @@ -351,12 +236,12 @@ void test_cq_capture(void) { double duration = 100.0; double epsilon = 0.0000001; - // Only local channel can capture - cq_get_global_channel(&ch, 0, 0); + // Only CQ_ADDR_LOCAL channel can capture + cq_get_channel(&ch, CQ_ADDR_GLOBAL, qr, &qr[0]); TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_capture(&ch, &p, results, num_shots)); - cq_get_local_channel(&ch, 1, 0, 0); + cq_get_channel(&ch, CQ_ADDR_LOCAL, qr, &qr[0]); // uninitialised pulse fails to capture TEST_ASSERT_EQUAL_INT(CQ_ERROR, @@ -399,8 +284,8 @@ void test_cq_delay(void) { // uninitialised channel fails to delay TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_delay(&ch, dt)); - - cq_get_global_channel(&ch, 0, 0); + + cq_get_channel(&ch, CQ_ADDR_GLOBAL, qr, NULL); TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_delay(&ch, dt)); TEST_ASSERT(ch.time - dt < epsilon); @@ -424,14 +309,14 @@ void test_cq_barrier(void) { int qreg_id = 0; double epsilon = 0.0000001; - cq_disable_analog_qreg(qreg_id); - cq_enable_analog_qreg(qreg_id, num_qubits); + cq_disable_analog_qreg(qr); + cq_enable_analog_qreg(qr); // barrier on uninitialised channels fails TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_barrier(channels, num_qubits)); for (ptrdiff_t i = 0; i < num_qubits; ++i) { - cq_get_local_channel(channels[i], 1, i, 0); + cq_get_channel(channels[i], CQ_ADDR_LOCAL, qr, &qr[i]); } TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_barrier(channels, num_qubits)); TEST_ASSERT(channels[0]->time - channels[1]->time < epsilon && @@ -444,23 +329,58 @@ void test_cq_barrier(void) { TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_barrier(channels, neg_num_qubits)); } -// not needed when using generate_test_runner.rb -int main(void) { - UNITY_BEGIN(); - setUp(); - RUN_TEST(test_cq_enable_analog_mode); - RUN_TEST(test_cq_samples_to_duration); - RUN_TEST(test_cq_duration_to_samples); - RUN_TEST(test_cq_enable_analog_qreg); - RUN_TEST(test_cq_disable_analog_mode); - RUN_TEST(test_cq_get_global_channel); - RUN_TEST(test_cq_get_local_channel); - RUN_TEST(test_cq_update_qreg_pos); - RUN_TEST(test_cq_init_pulse); - RUN_TEST(test_cq_play); - RUN_TEST(test_cq_capture); - RUN_TEST(test_cq_delay); - RUN_TEST(test_cq_barrier); - tearDown(); - return UNITY_END(); +void test_cq_set_device_sample_rate(void) { + double negative_rate = -12412.10; + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_set_device_sample_rate(negative_rate)); + + double rate = 0.25; + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_sample_rate(rate)); +} + +void test_cq_set_device_min_pulse_duration(void) { + double negative_duration = -12412.10; + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_set_device_min_pulse_duration(negative_duration)); + + double duration = 123.0; + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_min_pulse_duration(duration)); +} + +void test_cq_set_device_max_pulse_duration(void) { + double negative_duration = -12412.10; + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_set_device_max_pulse_duration(negative_duration)); + + double duration = 400.0; + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_max_pulse_duration(duration)); +} + +void test_cq_set_device_interaction_coeff(void) { + double coeff = 21515.0; + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_interaction_coeff(coeff)); + coeff = -12312.4124; + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_interaction_coeff(coeff)); +} + +void test_cq_set_device_min_qubit_dist(void) { + double dist = 0.2; + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_min_qubit_dist(dist)); + dist = -12312.4124; + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_set_device_min_qubit_dist(dist)); +} + +void test_cq_set_device_max_num_shots(void) { + int shots = 123123; + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_max_num_shots(shots)); + + shots = -734; + TEST_ASSERT_EQUAL_INT(CQ_ERROR, cq_set_device_max_num_shots(shots)); +} + +static double dummy_coupler(double *q0, double *q1) { + return 42.0; +}; + +void test_cq_set_device_coupling_func(void) { + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_coupling_func(NULL)); + + TEST_ASSERT_EQUAL_INT(CQ_SUCCESS, cq_set_device_coupling_func(&dummy_coupler)); } diff --git a/tests/device/analog/test_analog.h b/tests/device/analog/test_analog.h new file mode 100644 index 0000000..f641656 --- /dev/null +++ b/tests/device/analog/test_analog.h @@ -0,0 +1,26 @@ +#ifndef CQ_TEST_ANALOG_H +#define CQ_TEST_ANALOG_H + +void test_cq_enable_analog_mode(void); +void test_cq_samples_to_duration(void); +void test_cq_duration_to_samples(void); +void test_cq_enable_analog_qreg(void); +void test_cq_disable_analog_mode(void); +void test_cq_get_channel(void); +void test_cq_retarget_channel(void); +void test_cq_init_pulse(void); +void test_cq_free_pulse(void); +void test_cq_play(void); +void test_cq_capture(void); +void test_cq_delay(void); +void test_cq_barrier(void); +void test_cq_set_device_sample_rate(void); +void test_cq_set_device_min_pulse_duration(void); +void test_cq_set_device_max_pulse_duration(void); +void test_cq_set_device_interaction_coeff(void); +void test_cq_set_device_min_qubit_dist(void); +void test_cq_set_device_max_num_shots(void); +void test_cq_set_device_coupling_func(void); + +#endif + diff --git a/tests/device/analog/test_analog_runner.c b/tests/device/analog/test_analog_runner.c new file mode 100644 index 0000000..5f163ad --- /dev/null +++ b/tests/device/analog/test_analog_runner.c @@ -0,0 +1,34 @@ +#include "unity.h" +#include "cq.h" +#include "test_analog.h" + +int main(void) { + UnityBegin("test_analog.c"); + + cq_init(0); + + RUN_TEST(test_cq_enable_analog_mode); + RUN_TEST(test_cq_samples_to_duration); + RUN_TEST(test_cq_duration_to_samples); + RUN_TEST(test_cq_enable_analog_qreg); + RUN_TEST(test_cq_disable_analog_mode); + RUN_TEST(test_cq_get_channel); + RUN_TEST(test_cq_retarget_channel); + RUN_TEST(test_cq_init_pulse); + RUN_TEST(test_cq_free_pulse); + RUN_TEST(test_cq_play); + RUN_TEST(test_cq_capture); + RUN_TEST(test_cq_delay); + RUN_TEST(test_cq_barrier); + RUN_TEST(test_cq_set_device_sample_rate); + RUN_TEST(test_cq_set_device_min_pulse_duration); + RUN_TEST(test_cq_set_device_max_pulse_duration); + RUN_TEST(test_cq_set_device_interaction_coeff); + RUN_TEST(test_cq_set_device_min_qubit_dist); + RUN_TEST(test_cq_set_device_max_num_shots); + RUN_TEST(test_cq_set_device_coupling_func); + + cq_finalise(0); + + return UnityEnd(); +} diff --git a/tests/device/analog/test_waveforms.c b/tests/device/analog/test_waveforms.c index 0c6c281..6f89bb9 100644 --- a/tests/device/analog/test_waveforms.c +++ b/tests/device/analog/test_waveforms.c @@ -1,9 +1,9 @@ -#include "unity.h" - +#include "test_waveforms.h" #include "analog.h" +#include "unity.h" void setUp(void) { - cq_enable_analog_mode(RYDBERG); + cq_enable_analog_mode(ISING); return; } @@ -286,6 +286,10 @@ void test_cq_sin_wf(void) { -8.44327926e-01, -7.70513243e-01, -6.84547106e-01, -5.87785252e-01, -4.81753674e-01, -3.68124553e-01, -2.48689887e-01, -1.25333234e-01, }; + for (ptrdiff_t i = 0; i < 100; ++i) { + expected[i] += 1.0; + expected[i] *= 0.5; + } double samples[100] = {0}; double duration = 313.0; @@ -346,6 +350,11 @@ void test_cq_cos_wf(void) { 0.30901699, 0.42577929, 0.53582679, 0.63742399, 0.72896863, 0.80901699, 0.87630668, 0.92977649, 0.96858316, 0.9921147 }; + for (ptrdiff_t i = 0; i < 100; ++i) { + expected[i] += 1.0; + expected[i] *= 0.5; + } + double samples[100] = {0}; double duration = 313.0; double amp = 1.0; @@ -625,6 +634,11 @@ void test_cq_composite_wf(void) { 8.76306680e-001, 9.29776486e-001, 9.68583161e-001, 9.92114701e-001, }; + for (ptrdiff_t i = 100; i < 300; ++i) { + expected[i] += 1.0; + expected[i] *= 0.5; + } + double gaussian_wav[100] = {0}; double sin_wav[100] = {0}; double cos_wav[100] = {0}; @@ -688,19 +702,4 @@ void test_cq_composite_wf(void) { } } -// not needed when using generate_test_runner.rb -int main(void) { - setUp(); - UNITY_BEGIN(); - RUN_TEST(test_cq_gaussian_wf); - RUN_TEST(test_cq_gaussian_sqr_wf); - RUN_TEST(test_cq_interpolated_wf); - RUN_TEST(test_cq_sech_wf); - RUN_TEST(test_cq_sin_wf); - RUN_TEST(test_cq_cos_wf); - RUN_TEST(test_cq_blackman_wf); - RUN_TEST(test_cq_saw_wf); - RUN_TEST(test_cq_custom_wf); - RUN_TEST(test_cq_composite_wf); - return UNITY_END(); -} + diff --git a/tests/device/analog/test_waveforms.h b/tests/device/analog/test_waveforms.h new file mode 100644 index 0000000..382ea4f --- /dev/null +++ b/tests/device/analog/test_waveforms.h @@ -0,0 +1,15 @@ +#ifndef CQ_TEST_WAVEFORMS_H +#define CQ_TEST_WAVEFORMS_H + +void test_cq_gaussian_wf(void); +void test_cq_gaussian_sqr_wf(void); +void test_cq_interpolated_wf(void); +void test_cq_sech_wf(void); +void test_cq_sin_wf(void); +void test_cq_cos_wf(void); +void test_cq_blackman_wf(void); +void test_cq_saw_wf(void); +void test_cq_custom_wf(void); +void test_cq_composite_wf(void); + +#endif diff --git a/tests/device/analog/test_waveforms_runner.c b/tests/device/analog/test_waveforms_runner.c new file mode 100644 index 0000000..e346a79 --- /dev/null +++ b/tests/device/analog/test_waveforms_runner.c @@ -0,0 +1,17 @@ +#include "unity.h" +#include "test_waveforms.h" + +int main(void) { + UnityBegin("test_waveforms.c"); + RUN_TEST(test_cq_gaussian_wf); + RUN_TEST(test_cq_gaussian_sqr_wf); + RUN_TEST(test_cq_interpolated_wf); + RUN_TEST(test_cq_sech_wf); + RUN_TEST(test_cq_sin_wf); + RUN_TEST(test_cq_cos_wf); + RUN_TEST(test_cq_blackman_wf); + RUN_TEST(test_cq_saw_wf); + RUN_TEST(test_cq_custom_wf); + RUN_TEST(test_cq_composite_wf); + return UnityEnd(); +}