From 7940720f33a217b2590b31b107fdcc585cc8c6ca Mon Sep 17 00:00:00 2001 From: Mark Skilbeck Date: Wed, 15 Nov 2023 16:33:20 +0000 Subject: [PATCH 1/4] fix: include gate and measurement noise --- examples/qvm/multishot.c | 56 +++++++++++++++++++++++++++++++++++++--- src/qvm/api.lisp | 12 ++++++--- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/examples/qvm/multishot.c b/examples/qvm/multishot.c index da06009..0196179 100644 --- a/examples/qvm/multishot.c +++ b/examples/qvm/multishot.c @@ -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); @@ -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, &qvm_res, NULL, NULL) != LIBQUIL_ERROR_SUCCESS) { LIBQUIL_ERROR("failed to call qvm_multishot"); exit(1); @@ -108,11 +109,60 @@ 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(); - multishot_with_implicit_ro_indices(); + // multishot_with_implicit_ro_indices(); return 0; } diff --git a/src/qvm/api.lisp b/src/qvm/api.lisp index b64f1d2..eff18be 100644 --- a/src/qvm/api.lisp +++ b/src/qvm/api.lisp @@ -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)))) @@ -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) From 6debd781113cad4f6c4e4ccd6ac378a13b3d6559 Mon Sep 17 00:00:00 2001 From: Mark Skilbeck Date: Thu, 16 Nov 2023 12:55:53 +0000 Subject: [PATCH 2/4] uncomment example --- examples/qvm/multishot.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/qvm/multishot.c b/examples/qvm/multishot.c index 0196179..6e55bb3 100644 --- a/examples/qvm/multishot.c +++ b/examples/qvm/multishot.c @@ -83,7 +83,7 @@ void multishot_with_implicit_ro_indices() { qvm_multishot_result qvm_res; int num_trials = 10; double gate_noise[] = {0.0, 0.0, 0.0}; - if (qvm_multishot(program, addresses, num_trials, &qvm_res, NULL, NULL) != + if (qvm_multishot(program, addresses, num_trials, NULL, NULL, &qvm_res) != LIBQUIL_ERROR_SUCCESS) { LIBQUIL_ERROR("failed to call qvm_multishot"); exit(1); @@ -162,7 +162,8 @@ int main(int argc, char **argv) { init("../../libquil.core"); multishot_with_explicit_ro_indices(); - // multishot_with_implicit_ro_indices(); + multishot_with_implicit_ro_indices(); + multishot_with_noise(); return 0; } From d13e67e01f78822aa4a605613f1d4da942c040fa Mon Sep 17 00:00:00 2001 From: Mark Skilbeck Date: Thu, 16 Nov 2023 12:56:01 +0000 Subject: [PATCH 3/4] update documentation --- README.md | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 74c5fec..8ff326a 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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` @@ -120,7 +136,12 @@ 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, int* 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 @@ -128,6 +149,9 @@ If you would like to manually install the library (for example in the case where 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)` @@ -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) From f8ed5a05ea683b79fb5979bbeb07e7ebcb32254e Mon Sep 17 00:00:00 2001 From: Mark Skilbeck Date: Thu, 16 Nov 2023 13:12:38 +0000 Subject: [PATCH 4/4] readme typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8ff326a..7ecb01a 100644 --- a/README.md +++ b/README.md @@ -136,8 +136,8 @@ 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 -- `libquil_error_t quilc_program_memory_type(quil_program program, char* region_name, int* region_type) -Returns the `quilc_program_memory_type` for the given memory region +- `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