Skip to content

Repository files navigation

libquil

libquil provides a C API for Quilc and QVM.

Installation

Supported operating systems and architectures

We provide pre-built binaries for the following systems

  • Linux x64 (tested specifically on Ubuntu)
  • macOS aarch64 (Apple Silicon)

Other platforms can be built from source — see Building from source.

Requirements

These libraries are required by libquil:

  • BLAS, LAPACK for linear algebra routines
  • libffi for cross-language execution

magicl loads BLAS and LAPACK at runtime under their unversioned names, libblas.so and liblapack.so (.dylib on macOS). Those names come from the development packages, so the -dev packages have to be installed; a runtime-only package such as Debian's libblas3 will not work.

On systems which use apt to install packages (e.g. Ubuntu), these libraries can be installed with the command

sudo apt install libblas-dev libffi-dev liblapack-dev

On systems which use brew to install packages (e.g macOS), these libraries can be installed with the command

brew install openblas libffi

On macOS, OpenBLAS supplies both BLAS and LAPACK.

Automated installation

A script is provided to automate installation of the library. It will detect the host operating system and install the library to an appropriate location. A version identifier can be provided to install a particular version of the library. If no version is provided, the latest version of the library will be installed.

Note: by default the library is installed into /usr/local, which needs root. Pass --prefix to install somewhere you can write instead — see Installing without root.

Note: on macOS the installer also marks the library files as trusted. The files themselves are not signed and macOS will, by default, flag them as insecure.

Run the following command

curl https://raw.githubusercontent.com/rigetti/libquil/main/scripts/install.sh | sudo bash

If you would like to install a particular version of the library, run the following command

curl https://raw.githubusercontent.com/rigetti/libquil/main/scripts/install.sh | sudo bash -s <version-identifier>

replacing <version-identifier> with the desired version, e.g. 0.3.0.

By default the installer checks for the libraries above and stops if any are missing, leaving it to you to install them. Pass --install-deps to have it install them for you with apt or Homebrew, skipping any that are already present:

curl https://raw.githubusercontent.com/rigetti/libquil/main/scripts/install.sh | sudo bash -s -- --install-deps

It requires apt on Linux and Homebrew on macOS, and fails if neither is available. install.sh --help lists the options.

Installing without root

--prefix chooses where the library goes, and root is needed only when that location is not writable:

curl https://raw.githubusercontent.com/rigetti/libquil/main/scripts/install.sh | bash -s -- --prefix "${HOME}/.local"

A prefix other than /usr/local is not on any default search path. The installer finishes by printing the variables that make it usable — LIBQUIL_SRC_PATH and LIBQUIL_LIB_PATH to build against it, and DYLD_LIBRARY_PATH (LD_LIBRARY_PATH on Linux) to run.

Manual installation

If you would like to manually install the library (for example in the case where you want to install the library to a non-standard location), find the appropriate version and operating system from the releases page. Within the .zip archive you will find the library and header files that are required to use the library. Move these into your file system.

Building from source

Building requires an SBCL with a linkable runtime (libsbcl.so). SBCL does not build one by default, and neither Homebrew's sbcl bottle nor Ubuntu's sbcl ships one, so SBCL itself has to be built from source.

git clone --branch sbcl-2.6.7 https://git.code.sf.net/p/sbcl/sbcl
cd sbcl
sh make.sh --with-sb-linkable-runtime && sh make-shared-library.sh && sh install.sh

SBCL's install.sh puts both the sbcl binary and libsbcl.so in SBCL's home directory, where libquil's Makefile finds the latter automatically. To use a runtime from elsewhere, pass it explicitly:

make LIBSBCL=/path/to/sbcl/src/runtime/libsbcl.so

Note: the sbcl that builds libquil and the libsbcl.so it is linked against must come from the same build, not merely the same version. SBCL stamps a build ID into both, and a mismatch is only caught at runtime, as core was built for runtime "..." but this is "...". Installing SBCL from source as above satisfies this; leaving a packaged sbcl earlier on PATH than the one just installed does not.

The Lisp dependencies (quilc, qvm, magicl, sbcl-librarian) are expected in your Quicklisp local-projects directory. Then:

make

To install what you just built, into /usr/local or anywhere you can write:

make install                          # needs root
make install PREFIX="${HOME}/.local"  # does not

For a prefix other than /usr/local this prints the LIBQUIL_SRC_PATH, LIBQUIL_LIB_PATH and library-path variables to build and run against it.

C API Reference

These come from sbcl_librarian_err.h, which is installed alongside libquil.h.

  • lisp_err_t Enum which indicates whether a function call was successful (LISP_ERR_SUCCESS) or not (LISP_ERR_FAILURE, LISP_ERR_BUG, LISP_ERR_FATAL). Most functions will have this as their return type.

  • lisp_err_t get_error_message(char** error_msg) Used to retrieve the last error message.

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

  • lisp_err_t enable_backtrace(int enabled) Turns backtrace capture on the error message on or off.

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

  • chip_specification An opaque pointer to a Quilc chip specification object

  • quilc_version_info An opaque pointer to a Quilc version object

    See examples/quilc/version.c

  • quilc_compilation_metadata Stores compilation metadata returned by quilc_compile_protoquil

Functions

  • lisp_err_t quilc_get_version_info(quilc_version_info *version_info) Allocates a quilc_version_info object and stores the pointer to it in version_info

    See examples/quilc/version.c

  • lisp_err_t quilc_version_info_version(quilc_version_info version_info, char** version) Allocates memory which indicates the version string of Quilc and stores the pointer to it in version

    See examples/quilc/version.c

  • lisp_err_t quilc_version_info_githash(quilc_version_info version_info, char** githash) Allocates memory which indicates the githash string of Quilc and stores the pointer to it in version

    See examples/quilc/version.c

  • lisp_err_t quilc_parse_quil(char* program, quil_program *result) Parses the program string and stores it in a quil_program

  • lisp_err_t quilc_print_program(quil_program program) Prints the program to stdout

  • lisp_err_t quilc_program_string(quil_program program, char** result) Allocates and populates a char* which is the given program's string representation

  • lisp_err_t quilc_compile_quil(quil_program program, chip_specification chip_spec, quil_program* compiled_program) Compiles the program for the provided chip specification and stores it in a quil_program

  • lisp_err_t quilc_compile_protoquil(quil_program program, chip_specification chip_spec, quil_program* compiled_program) Compiles the (protoquil) program for the provided chip specification and stores it in a quil_program

  • lisp_err_t quilc_conjugate_pauli_by_clifford(void* pauli_indices, int pauli_indices_len, void* pauli_terms, int pauli_terms_len, quil_program clifford, void* phase, void* pauli) Conjugates a Pauli operator by a Clifford operator

    After having called quilc_conjugate_pauli_by_clifford:

    • phase will be the encoded global phase factor
    • pauli will be a string description of the resulting encoded Pauli operator
  • lisp_err_t quilc_generate_rb_sequence(int depth, int qubits, void* gateset_ptr, int gateset_len, int seed, void* interleaver, void* results_ptr, void* result_lens_ptr) Generates a randomized benchmarking sequence

    After having called quilc_generate_rb_sequence:

    • result_lens_ptr (a pre-allocated int array of length depth) will contain integers describing the segmentation of results_ptr
    • results_ptr will be populated with a flat array of integer values, the interpretation of which depends on results_len_ptr. This memory should be freed with free.

    See examples/quilc/generate-rb-sequence.c

  • lisp_err_t quilc_build_nq_linear_chip(int n, chip_specification* chip_spec) Builds a linearly-connected n-qubit chip specification and stores it in chip_spec

  • lisp_err_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

  • lisp_err_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
  • lisp_err_t qvm_multishot_result An opaque pointer to a QVM multishot result object
  • lisp_err_t qvm_version_info An opaque pointer to a QVM version info object

Functions

  • lisp_err_t qvm_get_version_info(qvm_version_info* version_info) Get a new qvm_version_info

  • lisp_err_t qvm_version_info_version(qvm_version_info version_info, char** version) Populate a string at *version which has the QVM version

  • lisp_err_t qvm_version_info_githash(qvm_version_info version_info, char** version) Populate a string at *githash which has the QVM githash

  • lisp_err_t qvm_multishot_addresses_new(qvm_multishot_addresses* addresses) Allocate memory for the qvm_multishot_addresses object

  • lisp_err_t qvm_multishot_addresses_set(qvm_multishot_addresses addresses, char* name, void* indices, int len) Set the indices of a memory region which should be collected when using qvm_multishot.

    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.)

  • `lisp_err_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.

  • lisp_err_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

  • lisp_err_t qvm_multishot_result_get(qvm_multishot_result qvm_result, char* region_name, int region_index, void* result) Get the measurement results for region_index in region_name, storing the data in the pre-allocated result

    result should be a pointer to memory which has been allocated to store N integers, where N is the trials value used for qvm_multishot.

    See examples/qvm/multishot.c

  • lisp_err_t qvm_multishot_measure(quil_program program, void* qubits, int n_qubits, int trials, void* result) Execute program on the QVM trials-number of times, storing measurement results for the specified qubits into result

    result should be a pointer to memory which has been allocated to store n_qubits * trials integers. This memory should be interpreted as the two-dimensional array whose outer dimension is trials and whose inner dimension is n_qubits.

    See examples/qvm/multishot-measure.c

  • lisp_err_t qvm_expectation(quil_program state_prep, void* operators, int n_operators, void* result) Calculate the expectation value <O|P|O> where P is the provided state preparation program state_prep and O is an operator, for each O in operators.

    result should be a pointer to memory that has been allocated to store n_operators double-precision floats.

    See examples/qvm/expectation.c

  • lisp_err_t qvm_wavefunction(quil_program program, void* result) Execute program on the QVM and return the associated wavefunction

    result should be a pointer to memory that has been allocated to store 2 * N_q^2 double-precision floats where N_q is the number of qubits used in the program. The factor of 2 is here to account for the fact that the wavefunction is a complex-valued vector, thus to represent it in C we need two values: one for the real part and one for the imaginary part. result can be interpreted as a two-dimensional array whose outer dimension (size N_q^2) is the wavefunction vector index, and whose inner dimension (size 2) is the pair of values making up the complex value.

    See examples/qvm/wavefunction.c

  • lisp_err_t qvm_probabilities(quil_program program, void* results_ptr) Execute program on the QVM and return the wavefunction probabilities

    result should be a pointer to memory that has been allocated to store N_q^2 double-precision floats where N_q is the number of qubits used in the program. Each index i in result is the probability of finding the wavefunction in the |i> state.

    See examples/qvm/probabilities.c

Lisp functions and types

  • void lisp_release_handle(void* handle) Frees the Lisp-allocated memory for handle

  • int lisp_handle_eq(void* a, void* b) Compare Lisp object handles

  • int init(char* core) Initialize the Lisp runtime using the provided core

    This MUST be performed before using any of the above functions.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages