PyQIR is a set of APIs for generating, parsing, and evaluating Quantum Intermediate Representation (QIR).

Overview

PyQIR

PyQIR is a set of APIs for generating, parsing, and evaluating Quantum Intermediate Representation (QIR). It consists of the following components:

  • pyqir_generator [examples]:
    This package provides a Python API for generating QIR (bitcode and IR). It is intended to easily integrate the QIR toolchain into existing Python-based frontends.

  • pyqir-jit [examples]:
    This package provides an easy way to execute generated QIR. It contains the necessary just-in-time compilation infrastructure as well an extensibility mechanism to define what actions to perform when a gate is applied in Python.

  • pyqir-parser:
    This package provides a Python API for loading QIR for basic analysis and transformation. For more advanced scenarios, we recommend taking a look at the LLVM-based infrastructure provide by the QAT tool.

This repository furthermore contains the qirlib; a Rust library wrapping LLVM libraries for working with QIR that is used by the above Python packages.

Documentation

Feedback

If you have feedback about the content in this repository, please let us know by filing a new issue!

Contributing

There are many ways in which you can contribute to PyQIR, whether by contributing a feature or by engaging in discussions; we value contributions in all shapes and sizes! We refer to this document for guidelines and ideas for how you can get involved.

Contributing a pull request to this repo requires to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. We are still working on setting up a suitable CLA-bot to automate this process. A CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately. Once it is set up, simply follow the instructions provided by the bot. You will only need to do this once.

Code of Conduct

This project has adopted the community covenant Code of Conduct. Please contact [email protected] for Code of Conduct issues or inquires.

Comments
  • Format rust workspace source code using cargo fmt

    Format rust workspace source code using cargo fmt

    This commit was created from the running of cargo fmt --all from the root of the workspace. Some text editors / IDEs have a "Format on Save" option, which when enabled will execute cargo fmt on a per-file basis.

    It might be nice to have formatting checks added to an Action at some point. I'd be happy to follow up with another PR to add such a check.

    opened by nilslice 6
  • Evaluator: Can't evaluate QIR file

    Evaluator: Can't evaluate QIR file

    Using NonadaptiveEvaluator.eval crashes the process when given a QIR .ll file and fails with an encoding exception when given a bitcode version of the same file. Nothing custom was done to generate the QIR (straight from the Q# compiler) or bitcode (just passed directly to llvm::WriteBitcodeToFile). The code itself is very basic - just one of the many Q# examples floating around. pyqir was also installed from pip, not a local version.

    Bitcode issue is likely due to us using LLVM 13 which I believe is a different version than the one you're using, so may not be an issue per-say, but attaching it if you want to look at it further. There might be a way to strip version/encoding from the bitcode, but haven't spent too much time digging as-of yet.

    Just mention if you need any additional info.

    QIR and bitcode files.

    Versions/System Info

    py-evaluator: 0.4.0-alpha.1 OS: Windows 10 Pro, 21H1 Python: 3.8 Rust: 1.60 Q# SDK: 0.24.208024

    bug documentation 
    opened by chemix-lunacy 5
  • Allowing multiple LLVM versions to be used.

    Allowing multiple LLVM versions to be used.

    This PR set up the ability to compile against multiple versions of LLVM. Setting PYQIR_LLVM_FEATURE_VERSION to one of the following values llvm11-0, llvm12-0, and llvm13-0 will change the LLVM version for all components. LLVM-IR doesn't support LLVM 14, so 14 was not added to the build. The default value if the environment variable isn't set is llvm11-0.

    I have not added and build configurations for CI. The default LLVM version for qirlib is not specified, but the build will fail if the features isn't set.

    This PR is based off of the work @nilslice did for #114.

    opened by idavis 5
  • Publish binaries for Apple silicon

    Publish binaries for Apple silicon

    Is your feature request related to a problem? Please describe. It would be useful for our CI to use wheels for M1. Since we're running tests for that platform.

    enhancement 
    opened by Roland-djee 5
  • Rename `Ref` to `ResultRef`

    Rename `Ref` to `ResultRef`

    Following up from our design discussion of result variables, I think Ref may accidentally be a good name for this concept, if we view it as a PyQIR-specific abstraction of a reference cell, and not an LLVM pointer. (Pointer would be a separate type from Ref if we expose those.) See e.g. Rust RefCell or F# reference cells. The key being that we have enough information at compile time to statically erase them into a series of SSA variables, so they don't need to be represented in the IR at all.

    This PR updates how the documentation describes Ref.

    opened by samarsha 5
  • [pyqir-generator] Support for identity gate

    [pyqir-generator] Support for identity gate

    A very useful gate to have as part of basic gateset is the identity gate. On hardware, it can be used to construct an intentional time delay, and in software, it can be useful for debugging purposes.

    Qiskit, for instance, supports the identity gate as part of the basic gateset and cannot be optimized or unrolled: https://qiskit.org/documentation/stubs/qiskit.circuit.library.IGate.html#igate

    Currently, the pyqir BasicQisBuilder does not support an identity gate; instead, one could use two subsequent X gates. However, these could be optimized out at later stages; it would be good to have a dedicated Identity gate for the aforementioned purposes.

    opened by guenp 5
  • Support external functions in generator

    Support external functions in generator

    PyQIR Generator should support adding external function declarations to a module and emitting LLVM call instructions for them using the builder. The initial version of the feature will probably support only external functions with a void return type. That will enable custom quantum instruction sets and state-changing utility functions.

    A draft PR with an initial implementation is available: #54

    There are a few different ideas for how the API can be designed:

    1. Declare function before calling

    SimpleModule could have a method like add_external_function(name, types) that returns a wrapped LLVM function value. Builder could have a method like call(function, args) that takes the function value and a list of arguments.

    module = SimpleModule(...)
    my_function = module.add_external_function("my_function", Qubit)
    module.builder.call(my_function, module.qubits[0])
    

    Pros:

    • Simple and explicit API with minimal magic under the hood
    • Close to LLVM and easy to evolve into a general LLVM call API (e.g. with return types)
    • Good support for mypy and code completion

    Cons:

    • Verbose

    2. Automatically declare function on first call

    There would be no explicit method to add a function - it would happen automatically the first time call(name, args) is used with a new function name. The type of the external function would be inferred from the type of the arguments.

    module = SimpleModule(...)
    module.builder.call("my_function", module.qubits[0])
    

    Pros:

    • Simpler for currently supported cases (statically known function value with void return type)

    Cons:

    • Return type can't easily be inferred in the future
    • Very dynamic; typos in function name string or issues in inferred argument types could lead to hard-to-debug errors. Because an LLVM function definition is implicily added the first time call is used, the first call will always succeed but subsequent calls may fail if the argument types are different.

    3. Automatically declare function on first call with sugar

    A sugared version of option 2 would be to define __getattr__ on Builder that would handle unknown method names. For example, builder.my_external_function(args) would be converted to builder.call("my_external_function", args).

    module = SimpleModule(...)
    module.builder.my_function(module.qubits[0])
    

    Pros:

    • Very concise

    Cons:

    • Does not work as well with Python tooling (type checking, code completion)
    • Function names can clash with other method names on Builder

    Future evolution

    We should consider how the chosen API will evolve into a more general LLVM call instruction API. In particular, the options above all have the call method on Builder, but Builder is not specific to the basic QIR profile. So if we choose a simplified call API, it may stick around alongside the more general API.

    Some features we should consider for future evolution:

    • Arguments may be any LLVM value (e.g. referring to a previous instruction result), not just Python values that are converted into LLVM constants.
    • Functions could have a non-void return type.
    • The function value may not be statically known (but this may require a different API for QIR callables).
    enhancement 
    opened by samarsha 5
  • Choose a Python module/package hierarchy

    Choose a Python module/package hierarchy

    #43 updates the PyQIR packages to use a shared namespace package pyqir (pyqir.generator, pyqir.jit, etc.). It also adds additional hierarchy to the generator modules, so that e.g. SimpleModule must be imported from pyqir.generator.module, instead of simply from pyqir.generator.

    We should take another look at these two things to make sure we're following Python conventions, and are choosing the right level of organization:

    1. Do we want to use namespace packages (pyqir.generator) or independent modules (pyqir_generator or pyqirgenerator)?
    2. Do we want to expose a nested module structure within each package (from pyqir.generator.module import SimpleModule), a flat one (from pyqir.generator import SimpleModule), or both?

    Tasks

    • [x] #58
    • [x] Plan for namespace packages
    enhancement 
    opened by samarsha 5
  • Add conditional feature support for python bindings and more LLVM versions

    Add conditional feature support for python bindings and more LLVM versions

    I'm working on integrating these crates into some of our QIR work, and it would be nice to not include the Python bindings in places where they are not needed.

    Additionally, at least one of our projects allows the use of LLVM version up to 12 or 13, so this PR also includes more features in each crate that uses llvm-ir or inkwell to support those versions too.

    All default-features have been kept unchanged, so the crates should function precisely the same as if none of the new features were added.

    I've confirmed, at least locally, that our downstream projects work as expected when using/disabling these features.

    opened by nilslice 4
  • Correct a few more typos and update some sections of text

    Correct a few more typos and update some sections of text

    Corrects a few more typos (not addressed in #72).

    Updates a few sections of text.

    Aligns spelling of packages names.

    Updates mentions about the CLA bot.

    opened by LaurentAjdnik 4
  • is `output_name` required to be non-none?

    is `output_name` required to be non-none?

    https://github.com/qir-alliance/pyqir/blob/0e524e7c54503b886f71d5b10383e8685b768070/pyqir-parser/pyqir/parser/_parser.py#L646-L654

    PR #152 introduced assert output_name is not None, but this is at odds with the type and the docstring. Is this a bug or is the docstring out of date? A bunch of my unit tests are now crashing because I would use if inst.output_name:

    bug 
    opened by qci-amos 3
  • Add LLVM Opaque Pointer Support

    Add LLVM Opaque Pointer Support

    Once Opaque Pointers in QIR is resolved, the deprecated calls need to be replaced with the new versions: | Old Name | New Name | |----------|----------| |LLVMBuildLoad | LLVMBuildLoad2 | |LLVMBuildCall | LLVMBuildCall2 | |LLVMBuildInvoke | LLVMBuildInvoke2 | |LLVMBuildGEP | LLVMBuildGEP2 | |LLVMBuildInBoundsGEP | LLVMBuildInBoundsGEP2 | |LLVMBuildStructGEP | LLVMBuildStructGEP2 | |LLVMBuildPtrDiff | LLVMBuildPtrDiff2 | |LLVMConstGEP | LLVMConstGEP2 | |LLVMConstInBoundsGEP | LLVMConstInBoundsGEP2 | |LLVMAddAlias | LLVMAddAlias2 |

    maintenance 
    opened by idavis 0
  • Update use of deprecated LLVMParseBitcodeInContext

    Update use of deprecated LLVMParseBitcodeInContext

    In pyqir::module::Module::from_bitcode (#216), we call LLVMParseBitcodeInContext, which is deprecated. There is a newer LLVMParseBitcodeInContext2 but its error handling works differently, so we'll need to figure out how to prevent the program from aborting and get the error string.

    maintenance 
    opened by samarsha 0
  • CI for Apple Silicon

    CI for Apple Silicon

    We need CI for macOS on Apple Silicon (arm64) so that tests and wheels can be automated. We depend on GItHub-hosted runners, so this is blocked by github/roadmap#528 and actions/runner-images#2187.

    maintenance 
    opened by samarsha 0
  • Publish qirlib to crates.io

    Publish qirlib to crates.io

    We should consider publishing qirlib so that Rust users can more easily depend on it. Some things to consider:

    1. API review.
    2. A more recent version of Inkwell needs to be published first.
    enhancement 
    opened by samarsha 1
  • Integer division and remainder instructions

    Integer division and remainder instructions

    Division by constant is supported in pytket and our lower level compiler. It would be good (but not critical) to have it supported in pyqir. The division by zero issue is also easier.

    enhancement 
    opened by Roland-djee 1
Releases(v0.8.0a1)
Owner
QIR Alliance
QIR Alliance
Damavand is a quantum circuit simulator. It can run on laptops or High Performance Computing architectures, such CPU distributed architectures or multi GPU distributed architectures.

Damavand is a code that simulates quantum circuits. In order to learn more about damavand, refer to the documentation. Development status Core feature

prevision.io 6 Mar 29, 2022
SelfOrgMap 5 Nov 4, 2020
A pure, low-level tensor program representation enabling tensor program optimization via program rewriting

Glenside is a pure, low-level tensor program representation which enables tensor program optimization via program rewriting, using rewriting frameworks such as the egg equality saturation library.

Gus Smith 45 Dec 28, 2022
C library for finding nearest (most similar) element in a set

VP-tree nearest neighbor search A relatively simple and readable Rust implementation of Vantage Point tree search algorithm. The VP tree algorithm doe

Kornel 28 Aug 20, 2022
Narwhal and Tusk A DAG-based Mempool and Efficient BFT Consensus.

This repo contains a prototype of Narwhal and Tusk. It supplements the paper Narwhal and Tusk: A DAG-based Mempool and Efficient BFT Consensus.

Facebook Research 134 Dec 8, 2022
MesaTEE GBDT-RS : a fast and secure GBDT library, supporting TEEs such as Intel SGX and ARM TrustZone

MesaTEE GBDT-RS : a fast and secure GBDT library, supporting TEEs such as Intel SGX and ARM TrustZone MesaTEE GBDT-RS is a gradient boost decision tre

MesaLock Linux 179 Nov 18, 2022
Ecosystem of libraries and tools for writing and executing extremely fast GPU code fully in Rust.

Ecosystem of libraries and tools for writing and executing extremely fast GPU code fully in Rust.

Riccardo D'Ambrosio 2.1k Jan 5, 2023
Ecosystem of libraries and tools for writing and executing fast GPU code fully in Rust.

The Rust CUDA Project An ecosystem of libraries and tools for writing and executing extremely fast GPU code fully in Rust Guide | Getting Started | Fe

Rust GPU 2.1k Dec 30, 2022
[WIP] An experimental Java-like language and it's virtual machine, for learning Java and JVM.

Sky VM An experimental Java-like language and it's virtual machine, for learning Java and JVM. Dependencies Rust (rust-lang/rust) 2021 Edition, dual-l

Kk Shinkai 2 Jan 3, 2022
Robust and Fast tokenizations alignment library for Rust and Python

Robust and Fast tokenizations alignment library for Rust and Python

Yohei Tamura 14 Dec 10, 2022
Some hacks and failed experiments surrounding nvidia's gamestream protocol and sunshine/moonlight implementations

Sunrise This repository contains a bunch of experiments surrounding the nvidia gamestream protocol and reimplementations in the form of sunshine and m

Victoria Brekenfeld 5 Dec 21, 2022
💥 Fast State-of-the-Art Tokenizers optimized for Research and Production

Provides an implementation of today's most used tokenizers, with a focus on performance and versatility. Main features: Train new vocabularies and tok

Hugging Face 6.2k Jan 2, 2023
Open deep learning compiler stack for cpu, gpu and specialized accelerators

Open Deep Learning Compiler Stack Documentation | Contributors | Community | Release Notes Apache TVM is a compiler stack for deep learning systems. I

The Apache Software Foundation 8.9k Jan 4, 2023
Distributed compute platform implemented in Rust, and powered by Apache Arrow.

Ballista: Distributed Compute Platform Overview Ballista is a distributed compute platform primarily implemented in Rust, powered by Apache Arrow. It

Ballista 2.3k Jan 3, 2023
Tensors and differentiable operations (like TensorFlow) in Rust

autograd Differentiable operations and tensors backed by ndarray. Motivation Machine learning is one of the field where Rust lagging behind other lang

Ryo ASAKURA 403 Dec 25, 2022
Tiny, no-nonsense, self-contained, Tensorflow and ONNX inference

Sonos' Neural Network inference engine. This project used to be called tfdeploy, or Tensorflow-deploy-rust. What ? tract is a Neural Network inference

Sonos, Inc. 1.5k Jan 8, 2023
Cleora AI is a general-purpose model for efficient, scalable learning of stable and inductive entity embeddings for heterogeneous relational data.

Cleora Cleora is a genus of moths in the family Geometridae. Their scientific name derives from the Ancient Greek geo γῆ or γαῖα "the earth", and metr

Synerise 405 Dec 20, 2022
Orkhon: ML Inference Framework and Server Runtime

Orkhon: ML Inference Framework and Server Runtime Latest Release License Build Status Downloads Gitter What is it? Orkhon is Rust framework for Machin

Theo M. Bulut 129 Dec 21, 2022
A fast, safe and easy to use reinforcement learning framework in Rust.

RSRL (api) Reinforcement learning should be fast, safe and easy to use. Overview rsrl provides generic constructs for reinforcement learning (RL) expe

Thomas Spooner 139 Dec 13, 2022