{"id":13442762,"url":"https://github.com/quil-lang/qvm","last_synced_at":"2025-03-20T15:30:44.726Z","repository":{"id":37890247,"uuid":"158458026","full_name":"quil-lang/qvm","owner":"quil-lang","description":"The high-performance and featureful Quil simulator.","archived":false,"fork":false,"pushed_at":"2024-04-12T05:15:22.000Z","size":1135,"stargazers_count":412,"open_issues_count":83,"forks_count":57,"subscribers_count":25,"default_branch":"master","last_synced_at":"2024-06-26T04:54:19.234Z","etag":null,"topics":["common-lisp","forest","quantum-computing","quantum-virtual-machine","quil","simulator"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quil-lang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-20T22:14:22.000Z","updated_at":"2024-06-26T04:54:26.224Z","dependencies_parsed_at":"2023-11-11T20:32:14.109Z","dependency_job_id":"5231200b-53cd-40b2-a959-b2cc006a923f","html_url":"https://github.com/quil-lang/qvm","commit_stats":null,"previous_names":["rigetti/qvm"],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quil-lang%2Fqvm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quil-lang%2Fqvm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quil-lang%2Fqvm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quil-lang%2Fqvm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quil-lang","download_url":"https://codeload.github.com/quil-lang/qvm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244147328,"owners_count":20405942,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["common-lisp","forest","quantum-computing","quantum-virtual-machine","quil","simulator"],"created_at":"2024-07-31T03:01:50.296Z","updated_at":"2025-03-20T15:30:44.298Z","avatar_url":"https://github.com/quil-lang.png","language":"Common Lisp","funding_links":[],"categories":["Common Lisp"],"sub_categories":[],"readme":"# qvm: A High-Performance Quantum Virtual Machine\n\n[![github release](https://img.shields.io/github/release/rigetti/qvm.svg)](https://github.com/rigetti/qvm/releases)\n[![docker pulls](https://img.shields.io/docker/pulls/rigetti/qvm.svg)](https://hub.docker.com/r/rigetti/qvm)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3677538.svg)](https://doi.org/10.5281/zenodo.3677538)\n\nThis is the official Quil-Lang *Quantum Virtual Machine* (QVM), a flexible and efficient simulator for [Quil](https://github.com/quil-lang/quil).\n\nThis directory contains two projects. The first, `qvm`, is a classical\nimplementation of the Quantum Abstract Machine (QAM), called a\n\"Quantum Virtual Machine\" (QVM). The second, `qvm-app`, is the\napplication interface to interacting with the QVM, either directly\nthrough the `qvm` binary or via its server interface.\n\nThe definition of the QAM was developed at Rigetti in a paper titled [A\nPractical Quantum Instruction Set Architecture](https://arxiv.org/pdf/1608.03355.pdf).\n\n## QVM, the library\n\nThe QVM library is contained within `./src/`, and provides the\nimplementation of the Quantum Abstract Machine. It evaluates Quil\nprograms (parsed and compiled by [quilc](https://github.com/rigetti/quilc)) on a virtual machine that can\nmodel various characteristics of (though without needing access to) a\ntrue quantum computer.\n\nThe library is released under the [Apache license 2.0](LICENSE.txt).\n\n### Usage\n\nThe QVM library is available on Quicklisp, but of course may not have the latest features.\nIt can be loaded simply with:\n```common-lisp\n* (ql:quickload :qvm)\n```\n\nAlternatively, one can download and load it manually. Please read and follow\nthe instructions in [`lisp-setup.md#install-quicklisp`](doc/lisp-setup.md) to get Quicklisp\ninstalled. Pay particular attention to the section \"Telling Quicklisp\nWhere Your Code Is\".\n\nDownload both this repository *and* [quilc](http://github.com/rigetti/quilc) into the\n`ql:*local-project-directories*` location. If all is correct, the `qvm`\nlibrary can be loaded with\n\n```shell\n$ sbcl\n```\n\n```common-lisp\n* (ql:quickload :qvm)\n(:QVM)\n```\n\nQVM objects are created with `(qvm:make-qvm n)` where `n` is the number of\nqubits the QVM should support; a program can then be loaded into the\nQVM object with `(qvm:load-program *qvm* *program*)` where `*qvm*` is a\nQVM object and `*program*` is a `cl-quil:parsed-program`\nobject.\n\nAlternatively, the `qvm:run-program` function will handle QVM object\ncreation. For example,\n\n``` common-lisp\n* (setq *qvm* (qvm:run-program 2 (cl-quil:parse-quil \"H 0\")))\n```\n\ncreates a 2-qubit QVM object and on it runs the Quil program `H 0`.\n\nThe qubit amplitudes can be inspected\n\n``` common-lisp\n* (qvm::amplitudes *qvm*)\n#(#C(0.7071067811865475d0 0.0d0) #C(0.7071067811865475d0 0.0d0)\n  #C(0.0d0 0.0d0) #C(0.0d0 0.0d0))\n```\n\nwhich shows, as expected, that `H 0` has put qubit-0 (the first two\ncomplex numbers above) into an equal superposition of states `|0\u003e` and\n`|1\u003e`.\n\nMeasurement of a quantum state causes it to collapse into one of its\nbasis states (`|0\u003e` or `|1\u003e`). This can be simulated with\n\n``` common-lisp\n* (qvm:measure-all *qvm*)\n#\u003cPURE-STATE-QVM {1004039753}\u003e\n(0 0)\n```\n\nInspecting the QVM object's state shows that this effect mutates the\ninformation stored on the QVM; i.e. the previous state information is lost\n\n``` common-lisp\n* (qvm::amplitudes *qvm*)\n#(#C(1.0d0 0.0d0) #C(0.0d0 0.0d0)\n  #C(0.0d0 0.0d0) #C(0.0d0 0.0d0))\n```\n\nQubit zero's state has collapsed into the state `|0\u003e`. Repeating this\nprocess (from creating the QVM object to measuring qubits) would show\nthat both states would each come up with probability 0.5.\n\n``` common-lisp\n* (loop :with results := (vector 0 0)\n        :with program := (cl-quil:parse-quil \"H 0\")\n        :repeat 100\n        :for (qvm state) := (multiple-value-list (qvm:measure (qvm:run-program 1 program) 0))\n        :do (incf (aref results state))\n        :finally (return results))\n#(54 46)\n```\n\n### Examples\n\nThe QVM comes with some example code to illustrate usage of the\nQVM. The example code can be found under `./examples/`. To run the\nexample code, first load `qvm-examples`\n\n``` common-lisp\n* (ql:quickload :qvm-examples)\n(:QVM-EXAMPLES)\n```\n\nThe function `bit-reversal-circuit` takes a list of qubit indices and\nreturns a list of instructions that will reverse the qubit amplitudes\nin \"bit-reversal order\" (e.g., the coefficient of `|1110\u003e` gets\nmapped to `|0111\u003e`):\n\n``` common-lisp\n(qvm-examples:bit-reversal-circuit '(1 2 3 4))\n(#\u003cSWAP 1 4\u003e #\u003cSWAP 2 3\u003e)\n```\n\nFor a given list of qubit indices, the function `qft-circuit` returns a\n[Quantum Fourier transform](https://en.wikipedia.org/wiki/Quantum_Fourier_transform) Quil program ready to be passed to quilc for\ncompilation.\n\n``` common-lisp\n* (qvm-examples:qft-circuit '(1 2 3 4))\n#\u003cCL-QUIL:PARSED-PROGRAM {10040ABEE3}\u003e\n```\n\nTo inspect the object, we can use the `cl-quil::print-parsed-program` function\n\n``` common-lisp\n* (cl-quil::print-parsed-program (qvm-examples:qft-circuit '(1 2 3 4)))\nH 4\nCPHASE(pi/2) 3 4\nH 3\nCPHASE(pi/4) 2 4\nCPHASE(pi/2) 2 3\nH 2\nCPHASE(pi/8) 1 4\nCPHASE(pi/4) 1 3\nCPHASE(pi/2) 1 2\nH 1\nSWAP 1 4\nSWAP 2 3\n```\n\n## QVM, the application\n\nThe QVM application is contained with `./app/src/`, and provides a\nstand-alone interface to the QVM library. It can be invoked directly\nwith the binary executable, or alternatively it can provide a server\nthat can be used over the network. Each has their benefits: the former\npermits a simplified interface using the command-line switches (see\noutput of `qvm --help`), while the latter allows many remote connections\nto a single in-memory QVM.\n\nThe application is released under the [GNU Affero General Public\nLicense v3.0](app/LICENSE.txt).\n\n### Usage\n\nTo build the QVM application follow instructions in\n[`lisp-setup.md`](doc/lisp-setup.md). In the top-level directory, run\nthe `Makefile` with\n\n```\n$ make qvm\n```\n\nThis will produce a binary executable `qvm` in the same directory.\n\nIn some situtations, using a large number of qubits may cause heap\nexhaustion. There are two options to ameliorate this.\n\nThe first is to increase the memory available for the QVM, recompile\nand specify the workspace size (in MB)\n\n```\n$ make QVM_WORKSPACE=4096 qvm\n$ make install\n```\n\nThe second is to use a different allocator when running the QVM, by\nusing the `--default-allocator` argument with `\"foreign\"`. For\nexample, to run a 30 qubit benchmark on a QVM configured for far less\nmemory, one can do:\n\n```\n$ qvm --default-allocator \"foreign\" --benchmark 30 -c\n```\n\nThis is *not* the default since this memory is not fully managed by\nthe application.\n\n\nThe QVM application has a few command-line switches used to configure\nthe QVM. To explore those options, see the output of the following command:\n\n```\n$ qvm --help\n```\n\nBy default, the QVM accepts programs from stdin and writes\nresults to stdout. Log messages are written to stderr.\n\n\u003e *Note*: If you're on Windows and using the Command Prompt, the echo\n\u003e command is slightly different to the examples shown below: do not\n\u003e wrap your quil code in quotes. For example, in Command Prompt, you\n\u003e would do `echo H 0 | qvm` *not* `echo \"H 0\" | qvm`.\n\n```\n$ echo 'H 0' | qvm\n******************************\n* Welcome to the Rigetti QVM *\n******************************\nCopyright (c) 2016-2019 Rigetti Computing.\n\n(Configured with 8192 MiB of workspace and 8 workers.)\n\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Selected simulation method: pure-state\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Reading program.\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Allocating memory for QVM of 1 qubits.\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Allocation completed in 7 ms.\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Loading quantum program.\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Executing quantum program.\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Execution completed in 4 ms.\n\u003c134\u003e1 2019-03-07T22:56:55Z workstation.local qvm 21177 - - Printing classical memory and 1-qubit state.\nClassical memory (low -\u003e high indexes):\n    No memory.\nAmplitudes:\n    |0\u003e: 0.7071067811865475,                                    P= 50.0%\n    |1\u003e: 0.7071067811865475,                                    P= 50.0%\n```\n\nAlternatively the QVM can be started as a server that will accept\ninstructions over a network connection\n\n```\n$ qvm -S\n******************************\n* Welcome to the Rigetti QVM *\n******************************\nCopyright (c) 2016-2019 Rigetti Computing.\n\n(Configured with 2048 MiB of workspace and 8 workers.)\n\n\u003c134\u003e1 2019-01-28T19:06:07Z workstation.local qvm 3118 - - Selected simulation method: pure-state\n\u003c134\u003e1 2019-01-28T19:06:07Z workstation.local qvm 3118 - - Starting server on port 5000.\n```\n\nThis is how the [pyQuil](https://github.com/rigetti/pyquil) Python\nlibrary communicates with a QVM.\n\n## Testing\n\nTests can be run from the `Makefile`\n\n```\nmake test\n```\n\nor from within SBCL\n\n```\n* (asdf:test-system :qvm)\n```\n\nAny contribution to this project should foremost not break any current\ntests (run tests before making a pull request), and should be\naccompanied by relevant *new* tests.\n\n## Clearing the Cache\n\nLisp caches a lot of builds so that not every single file needs to be\nrecompiled. In rare instances, there's confusion and the cache doesn't\nget properly invalidated. (This can happen when moving files across\nmachines, for example.) Lisp's cache and Quicklisp's system index can\nbe cleaned by doing the following command:\n\n```\nmake cleanall\n```\n\nThis will delete any built executables as well.\n\n## Automated Build, Test, and Release with Docker\n\nThe CI pipeline for `qvm` produces a Docker image, available at\n[`rigetti/qvm`](https://hub.docker.com/r/rigetti/qvm).\nTo get the latest stable version of `qvm`, run `docker pull rigetti/qvm`.\nTo instead pull a specific version of the QVM, run `docker pull rigetti/qvm:VERSION`,\nwhere `VERSION` is something like `1.10.0`.\n\nAdditionally, all branches and commits for the QVM repository have corresponding\nimage tags. For example, the image that contains the HEAD of branch \"qvm-fixes\"\ncan be pulled with `docker pull rigetti/qvm:qvm-fixes` (NOTE: some characters are\ninvalid in Docker image tags, and are rewritten according to the description of\n[`CI_COMMIT_REF_SLUG`](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)).\nThe image built from the commit with first eight characters `abcd1234` can be\npulled with `docker pull rigetti/qvm:abcd1234`.\n\nThe Dockerfile for qvm builds from two parent Docker images:\n\n1. [`rigetti/lisp`](https://hub.docker.com/r/rigetti/lisp): Contains SBCL, Quicklisp, and\n   third-party libraries.\n2. [`rigetti/quilc`](https://hub.docker.com/r/rigetti/quilc): Contains the Quil Compiler.\n\nThe Dockerfile for qvm intentionally pins the versions of these two images,\nwhich means that the version numbers must be actively incremented as necessary.\nIf the build for qvm is failing, this is probably the place to look, because\nthe unit tests are run inside of a freshly-built qvm Docker image as part of\nthe GitLab CI pipeline.\n\nHowever, because the development workflow for the QVM often involves having\na locally cloned copy of quilc master, there are two additional CI jobs that\noverride the version of quilc and instead build off of `rigetti/quilc:edge`,\nwhich corresponds to the HEAD of master. These jobs are optional, meaning that\nif they fail the overall CI pipeline will not be marked as a failure, but they\nprovide additional useful information to those that develop quilc and the QVM\nin unison.\n\n## Running the QVM with Docker\n\nAs outlined above, the QVM supports two modes of operation: stdin and server.\n\nTo run the `qvm` in stdin mode, do the following:\n\n```shell\necho \"H 0\" | docker run --rm -i rigetti/qvm\n```\n\nTo run the `qvm` in server mode, do the following:\n\n```shell\ndocker run --rm -it -p 5000:5000 rigetti/qvm -S\n```\n\nIf you would like to change the port of the server to `PORT`, you can alter the command as follows:\n\n```shell\ndocker run --rm -it -p PORT:PORT rigetti/qvm -S -p PORT\n```\n\nPort 5000 is exposed using the EXPOSE directive in the `rigetti/qvm` image, so you can\nadditionally use the `-P` option to automatically bind this container port to a randomly\nassigned host port. You can then inspect the mapping using `docker port CONTAINER [PORT]`.\n\n## Release Process\n\n1. Update `VERSION.txt` and push the commit to `master`.\n2. Push a git tag `vX.Y.Z` that contains the same version number as in `VERSION.txt`.\n3. Verify that the resulting build (triggered by pushing the tag) completes successfully.\n4. Publish a [release](https://github.com/rigetti/qvm/releases) using the tag as the name.\n5. Close the [milestone](https://github.com/rigetti/qvm/milestones) associated with this release,\n   and migrate incomplete issues to the next one.\n6. Update the qvm version of downstream dependencies (if applicable, see next section).\n\n## Downstream Dependencies\n\nCurrently, there are a couple different components of the Forest SDK that depend on the QVM:\n\n1. [pyquil](https://github.com/rigetti/pyquil)\n2. [forest-benchmarking](https://github.com/rigetti/forest-benchmarking)\n\nIt is the responsibility of the releaser to verify that the latest QVM release does not\nbreak the test suites of these downstream dependencies. All of these repositories pull the\nlatest released version of the QVM as part of their CI pipelines.\n\n# Feature Flags\n\nThe QVM library and application can be built with support for optional\nfeatures specified by the `*features*` flag in lisp.\n\n## Available Flags\n\n| Feature Flag      | Description                                                                                                                                      |\n|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|\n| `qvm-intrinsics` | Enable assembly intrinsics in the build, enabling optimized functions based on processor support. Currently supports AVX2 matrix multiplication. |\n\n## Building QVM with Feature Flags\n\nTo build with specific flags enabled, set the `QVM_FEATURES` variable while building:\n\n```\n$ make QVM_FEATURES='FEATURES' qvm\n```\n\nNote: Cache needs to be cleaned when adding new feature flags to ensure libraries compile with correct flags.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquil-lang%2Fqvm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquil-lang%2Fqvm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquil-lang%2Fqvm/lists"}