Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: include gate and measurement noise #45

Merged
merged 4 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,18 @@ If you would like to manually install the library (for example in the case where

When any error is encountered by libquil, it will be stored in memory. A subsequent call to `libquil_error` will return that error message. After calling `libquil_error`, the error is cleared from memory such that immediately calling `libquil_error` after a previous call will return an empty string (indicating no errors since the previous error).

## Quilc functions and types
## Quilc documentation

### Enums

- `program_memory_type_t`
The Quil program memory types.
- `LIBQUIL_TYPE_BIT` is the Quil `BIT` memory type
- `LIBQUIL_TYPE_OCTET` is the Quil `OCTET` memory type
- `LIBQUIL_TYPE_INTEGER` is the Quil `INTEGER` memory type
- `LIBQUIL_TYPE_REAL` is the Quil `REAL` memory type

### Types

- `quil_program`
An opaque pointer to a Quilc program object
Expand All @@ -72,6 +83,11 @@ If you would like to manually install the library (for example in the case where

See [examples/quilc/version.c](examples/quilc/version.c)

- `quilc_compilation_metadata`
Stores compilation metadata returned by `quilc_compile_protoquil`

### Functions

- `libquil_error quilc_get_version_info(quilc_version_info *version_info)`
Allocates a `quilc_version_info` object and stores the pointer to it in `version_info`

Expand Down Expand Up @@ -120,14 +136,22 @@ If you would like to manually install the library (for example in the case where
- `libquil_error_t quilc_chip_spec_from_isa_descriptor(char* isa_json, chip_specification* chip_spec)`
Builds an arbitrary chip specification using the JSON-encoded ISA description

## QVM functions and types
- `libquil_error_t quilc_program_memory_type(quil_program program, char* region_name, program_memory_type* region_type)`
Returns the `quilc_program_memory_type` for the given memory region

## QVM documentation

### Types

- `qvm_multishot_addresses`
An opaque pointer to a QVM multishot addresses object
- `libquil_error_t qvm_multishot_result`
An opaque pointer to a QVM multishot result object
- `libquil_error_t qvm_version_info`
An opaque pointer to a QVM version info object

### Functions

- `libquil_error_t qvm_get_version_info(qvm_version_info* version_info)`
Get a new `qvm_version_info`
- `libquil_error_t qvm_version_info_version(qvm_version_info version_info, char** version)`
Expand All @@ -141,8 +165,15 @@ If you would like to manually install the library (for example in the case where

For example, if your register was named `ro` and you wanted to get indices 0 and 2, you would provide `"ro"` for `name` and `{0, 2}` for `indices`. (`len` is the length of `indices`.)

- `libquil_error_t qvm_multishot(quil_program program, qvm_multishot_addresses addresses, int trials, qvm_multishot_result *result)`
Execute `program` on the QVM `trials`-number of times, collecting the `addresses` into `result`
- `libquil_error_t qvm_multishot_addresses_get_all(qvm_multishot_addresses addresses, char* name, int shot_index, void\*\* results, int* results_len)
Request all results for the given memory address.

On return, `*results` will be an array of length `results_len`. The specific data type contained in the array is to be interpreted by the caller.

- `libquil_error_t qvm_multishot(quil_program program, qvm_multishot_addresses addresses, int trials, double* gate_noise, double* measurement_noise, qvm_multishot_result *result)`
Execute `program` on the QVM `trials`-number of times, collecting the `addresses` into `result`.

`gate_noise` and `measurement_noise` are length-3 arrays which affect gate execution and measurement respectively. One or both can be `NULL` which indicates no noise is to be applied.

See [examples/qvm/multishot.c](examples/qvm/multishot.c)

Expand Down
55 changes: 53 additions & 2 deletions examples/qvm/multishot.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void multishot_with_explicit_ro_indices() {

qvm_multishot_result qvm_res;
int num_trials = 10;
if (qvm_multishot(program, addresses, num_trials, &qvm_res) !=
if (qvm_multishot(program, addresses, num_trials, NULL, NULL, &qvm_res) !=
LIBQUIL_ERROR_SUCCESS) {
LIBQUIL_ERROR("failed to call qvm_multishot");
exit(1);
Expand Down Expand Up @@ -82,7 +82,8 @@ void multishot_with_implicit_ro_indices() {

qvm_multishot_result qvm_res;
int num_trials = 10;
if (qvm_multishot(program, addresses, num_trials, &qvm_res) !=
double gate_noise[] = {0.0, 0.0, 0.0};
if (qvm_multishot(program, addresses, num_trials, NULL, NULL, &qvm_res) !=
LIBQUIL_ERROR_SUCCESS) {
LIBQUIL_ERROR("failed to call qvm_multishot");
exit(1);
Expand All @@ -108,11 +109,61 @@ void multishot_with_implicit_ro_indices() {
lisp_release_handle(program);
}

void multishot_with_noise() {
quil_program program;

char *source = "DECLARE ro BIT[3]; X 0; I 1; X 2; MEASURE 0 ro[0]; MEASURE 1 "
"ro[1]; MEASURE 2 ro[2]";

if (quilc_parse_quil(source, &program) != LIBQUIL_ERROR_SUCCESS) {
LIBQUIL_ERROR("failed to parse quil");
exit(1);
}

qvm_multishot_addresses addresses;
if (qvm_multishot_addresses_new(&addresses) != LIBQUIL_ERROR_SUCCESS) {
LIBQUIL_ERROR("failed to create addresses");
exit(1);
}

int indices[3] = {0, 1, 2};
if (qvm_multishot_addresses_set(addresses, "ro", indices, 3) !=
LIBQUIL_ERROR_SUCCESS) {
LIBQUIL_ERROR("failed to set address indices");
exit(1);
}

qvm_multishot_result qvm_res;
int num_trials = 10;
double gate_noise[] = {0.1, 0.1, 0.1};
double measurement_noise[] = {0.1, 0.0, 0.0};
if (qvm_multishot(program, addresses, num_trials, gate_noise,
measurement_noise, &qvm_res) != LIBQUIL_ERROR_SUCCESS) {
LIBQUIL_ERROR("failed to call qvm_multishot");
exit(1);
}

for (int i = 0; i < num_trials; i++) {
char vals[3];
if (qvm_multishot_result_get(qvm_res, "ro", i, &vals) !=
LIBQUIL_ERROR_SUCCESS) {
LIBQUIL_ERROR("failed to call qvm_multishot_result_get");
exit(1);
}
printf("Trial %d\n\tro[0]=%d\n\tro[1]=%d\n\tro[2]=%d\n", i, vals[0],
vals[1], vals[2]);
}

lisp_release_handle(qvm_res);
lisp_release_handle(program);
}

int main(int argc, char **argv) {
init("../../libquil.core");

multishot_with_explicit_ro_indices();
notmgsk marked this conversation as resolved.
Show resolved Hide resolved
multishot_with_implicit_ro_indices();
multishot_with_noise();

return 0;
}
12 changes: 9 additions & 3 deletions src/qvm/api.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@
results-map
program-memory-descriptors)

(defun qvm-multishot (compiled-quil addresses trials)
(defun qvm-multishot (compiled-quil addresses trials gate-noise-ptr measurement-noise-ptr)
"Executes COMPILED-QUIL on a pure-state QVM TRIALS numbers of times. At the end of each execution, the measurements for ADDRESSES are collected. The return value is a list of those measurements."
(let* ((num-qubits (cl-quil.frontend::qubits-needed compiled-quil))
(results (%perform-multishot compiled-quil num-qubits addresses trials nil nil)))
(gate-noise (unless (null-pointer-p gate-noise-ptr)
(unpack-c-array-to-lisp-list gate-noise-ptr 3 :double)))
(measurement-noise (unless (null-pointer-p measurement-noise-ptr)
(unpack-c-array-to-lisp-list measurement-noise-ptr 3 :double)))
(results (%perform-multishot compiled-quil num-qubits addresses trials gate-noise measurement-noise)))
(make-qvm-multishot-result
:results-map results
:program-memory-descriptors (cl-quil:parsed-program-memory-definitions compiled-quil))))
Expand Down Expand Up @@ -164,7 +168,9 @@
qvm-multishot-result
((program quil-program)
(addresses qvm-multishot-addresses)
(trials :int)))
(trials :int)
(gate-noise :pointer)
(measurement-noise :pointer)))
(("multishot_result_get" qvm-multishot-result-get)
:void
((qvm-result qvm-multishot-result)
Expand Down
Loading