Skip to content

Commit

Permalink
feat: Support all Quil types in multishot results (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
notmgsk authored Nov 15, 2023
1 parent 0c2995f commit 84499b7
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 10 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
name: Install SBCL, libraries, and quicklisp
run: |
sudo apt update && sudo apt install -y sbcl build-essential
sudo git clone --branch sbcl-2.2.4 git://git.code.sf.net/p/sbcl/sbcl /usr/src/sbcl
sudo git clone --single-branch --branch sbcl-2.2.4 git://git.code.sf.net/p/sbcl/sbcl /usr/src/sbcl
cd /usr/src/sbcl && sudo sh make.sh && sudo sh make-shared-library.sh
sudo apt remove -y sbcl
sudo sh install.sh
Expand Down Expand Up @@ -63,6 +63,7 @@ jobs:
cd $GITHUB_WORKSPACE/libquil
ls
sbcl --noinform --non-interactive --eval '(ql:quickload :sbcl-librarian)'
sbcl --dynamic-space-size 8192 --noinform --non-interactive --eval '(ql:quickload :libquil)'
make
- name: Test
Expand Down Expand Up @@ -139,6 +140,7 @@ jobs:
cd $GITHUB_WORKSPACE/libquil
ls
sbcl --noinform --non-interactive --eval '(ql:quickload :sbcl-librarian)'
sbcl --dynamic-space-size 8192 --noinform --non-interactive --eval '(ql:quickload :libquil)'
make
- name: ls
Expand Down
5 changes: 3 additions & 2 deletions examples/qvm/multishot.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void multishot_with_explicit_ro_indices() {
}

for (int i = 0; i < num_trials; i++) {
int vals[3];
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");
Expand Down Expand Up @@ -89,7 +89,8 @@ void multishot_with_implicit_ro_indices() {
}

for (int i = 0; i < num_trials; i++) {
int *vals, len;
int len;
char *vals;

if (qvm_multishot_result_get_all(qvm_res, "ro", i, &vals, &len) !=
LIBQUIL_ERROR_SUCCESS) {
Expand Down
29 changes: 28 additions & 1 deletion src/quilc/api.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,43 @@
(setf (cffi:mem-aref (sb-alien:alien-sap result-lens-ptr) :int i)
(length gls)))))))

(defun find-program-memory-descriptor (program region-name)
(let* ((regions (cl-quil:parsed-program-memory-definitions program)))
(find region-name regions
:key #'cl-quil:memory-descriptor-name
:test #'equalp)))

(defun quil-memory-type-to-int (memory-type)
(adt:match cl-quil:quil-type memory-type
(cl-quil:quil-bit 0)
(cl-quil:quil-octet 1)
(cl-quil:quil-integer 2)
(cl-quil:quil-real 3)))

(defun parsed-program-get-memory-region-type (program region-name region-type-ptr)
(let ((region (find-program-memory-descriptor program region-name)))
(if (null region)
(error "region ~a not found in program" region)
(setf (cffi:mem-ref (sb-alien:alien-sap region-type-ptr) :int)
(quil-memory-type-to-int (cl-quil:memory-descriptor-type region))))))

(sbcl-librarian:define-enum-type program-memory-type "program_memory_type_t"
("LIBQUIL_TYPE_BIT" 0)
("LIBQUIL_TYPE_OCTET" 1)
("LIBQUIL_TYPE_INTEGER" 2)
("LIBQUIL_TYPE_REAL" 3))

(sbcl-librarian:define-api quilc (:error-map error-map
:function-prefix "quilc_")
(:literal "/* Quilc types */")
(:type quil-program chip-specification quilc-version-info compilation-metadata)
(:type program-memory-type quil-program chip-specification quilc-version-info compilation-metadata)
(:literal "/* Quilc functions */")
(:function
(("get_version_info" quilc-get-version-info) quilc-version-info ())
(("version_info_version" quilc-version-info-version) :void ((version-info quilc-version-info) (ptr :pointer)))
(("version_info_githash" quilc-version-info-githash) :void ((version-info quilc-version-info) (ptr :pointer)))
(("parse_quil" cl-quil.frontend:safely-parse-quil) quil-program ((source :string)))
(("program_memory_type" parsed-program-get-memory-region-type) :void ((program quil-program) (region-name :string) (region-type-ptr :pointer)))
(("print_program" cl-quil.frontend:print-parsed-program) :void ((program quil-program)))
(("compile_quil" cl-quil:compiler-hook) quil-program ((program quil-program) (chip-spec chip-specification)))
(("compilation_metadata_len" compilation-metadata-len) :int ((metadata compilation-metadata)))
Expand Down
41 changes: 35 additions & 6 deletions src/qvm/api.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,49 @@

(sbcl-librarian:define-handle-type qvm-multishot-result "qvm_multishot_result")

(defstruct qvm-multishot-result
results-map
program-memory-descriptors)

(defun qvm-multishot (compiled-quil addresses trials)
"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)))
results))
(make-qvm-multishot-result
:results-map results
:program-memory-descriptors (cl-quil:parsed-program-memory-definitions compiled-quil))))

(defun qvm-multishot-result-get (multishot-result address-name shot-index result-pointer)
(let* ((results (elt (gethash address-name multishot-result) shot-index)))
(let* ((results-map (qvm-multishot-result-results-map multishot-result))
(memory-descriptors (qvm-multishot-result-program-memory-descriptors multishot-result))
(memory-descriptor (find address-name memory-descriptors
:key #'cl-quil:memory-descriptor-name
:test #'equalp))
(results (elt (gethash address-name results-map) shot-index)))
(loop :for val :in results
:for i :from 0 :do
(setf (cffi:mem-aref (sb-alien:alien-sap result-pointer) :int i) val))))
(setf (cffi:mem-aref (sb-alien:alien-sap result-pointer)
(memory-descriptor-type-to-cffi-type
(cl-quil:memory-descriptor-type memory-descriptor))
i)
val))))

(defun memory-descriptor-type-to-cffi-type (descriptor-type)
(adt:match cl-quil:quil-type descriptor-type
(cl-quil:quil-bit :char)
(cl-quil:quil-octet :char)
(cl-quil:quil-integer :int)
(cl-quil:quil-real :double)))

(defun qvm-multishot-result-get-all (multishot-result address-name shot-index result-ptr result-len-ptr)
(let* ((results (elt (gethash address-name multishot-result) shot-index))
(let* ((results-map (qvm-multishot-result-results-map multishot-result))
(results (elt (gethash address-name results-map) shot-index))
(len (length results))
(ptr (cffi:foreign-alloc :int :initial-contents results)))
(descriptors (qvm-multishot-result-program-memory-descriptors multishot-result))
(memory-descriptor (find address-name descriptors :key #'cl-quil:memory-descriptor-name :test #'equalp))
(cffi-type (memory-descriptor-type-to-cffi-type
(cl-quil:memory-descriptor-type memory-descriptor)))
(ptr (cffi:foreign-alloc cffi-type :initial-contents results)))
(setf (cffi:mem-ref (sb-alien:alien-sap result-ptr) :pointer) ptr)
(setf (cffi:mem-ref (sb-alien:alien-sap result-len-ptr) :int) len)))

Expand Down Expand Up @@ -135,7 +162,9 @@
(name :string)))
(("multishot" qvm-multishot)
qvm-multishot-result
((program quil-program) (addresses qvm-multishot-addresses) (trials :int)))
((program quil-program)
(addresses qvm-multishot-addresses)
(trials :int)))
(("multishot_result_get" qvm-multishot-result-get)
:void
((qvm-result qvm-multishot-result)
Expand Down

0 comments on commit 84499b7

Please sign in to comment.