qirlib
is a set of APIs for generating, parsing, and evaluating Quantum
Intermediate Representation (QIR). It
is also the native implementation behind PyQIR.
- Rust 1.64+
- LLVM 11.x, 12.x, 13.x, or LLVM 14.x (see Usage below)
qirlib
requires a working LLVM installation to link against. By default, qirlib
assumes a valid LLVM installation is available. This default is to align with the
Inkwell
and
llvm-sys
defaults which are leveraged by
qirlib
. This default can be changed and qirlib
provides features to
bootstrap itself if desired. Building qirlib
can be done with feature flags which will either:
- (default) Use a local LLVM installation. This is either detected on the path or specified with an environment variable.
- Build LLVM from source
- Download a preexisting LLVM build
Supported cargo features are following:
- The use
<llvm version>
is a placeholder forllvm11-0
,llvm12-0
,llvm13-0
, orllvm14-0
. - The use of
<llvm major>
is a placeholder for110
,120
,130
, or140
corresponding to the LLVM releases.
Feature | Link type | Requirements | Description |
---|---|---|---|
default |
external | gcc/clang | Includes external-llvm-linking |
external-llvm-linking |
external | gcc/clang | Uses llvm-sys/inkwell for LLVM linking |
<llvm version>-no-llvm-linking |
none | Disable all LLVM linking. Used for local installation or packaging of LLVM. Includes <llvm version> , llvm-sys-<llvm major>/disable-alltargets-init and inkwell/<llvm version>-no-llvm-linking . Additionally adds no-llvm-linking as a marker used in the code. |
|
<llvm version>-qirlib-llvm-linking |
internal | build-llvm or download-llvm |
let qirlib do the LLVM linking. Includes <llvm version> , llvm-sys-<llvm major>/disable-alltargets-init and inkwell/<llvm version>-no-llvm-linking . Additionally adds qirlib-llvm-linking as a marker used in the code. |
llvm11-0 |
NA | inkwell/llvm11-0 |
Target LLVM 11.1 |
llvm12-0 |
NA | inkwell/llvm12-0 |
Target LLVM 12.0 |
llvm13-0 |
NA | inkwell/llvm13-0 |
Target LLVM 13.0 |
llvm14-0 |
NA | inkwell/llvm14-0 |
Target LLVM 14.0 |
download-llvm |
internal/none | cmake | dowload a precompiled version of LLVM |
build-llvm |
internal/none | gcc/clang, cmake, ninja, git | Build LLVM from source. Installation defaults to OUT_DIR/llvm but can be overridden via the QIRLIB_CACHE_DIR environment variable. |
package-llvm |
none | cc/clang, cmake, ninja, git | Dev use only for packaging LLVM builds. Includes build-llvm and no-llvm-linking |
- Exactly one of the linking features is required:
<llvm version>-qirlib-llvm-linking
external-llvm-linking
<llvm version>-no-llvm-linking
build-llvm
anddownload-llvm
cannot be used withexternal-llvm-linking
- Exactly one of the LLVM version features is required:
llvm11-0
llvm12-0
llvm13-0
llvm14-0
Building qirlib
can be done with crate features which will either download
(and install) a preexisting LLVM build configured via environment variables
(the
Cargo.toml [env] section
can also be used), build LLVM from source and install it, or build LLVM from
source and package it
QIRLIB_LLVM_EXTERNAL_DIR
- Path to where LLVM is already installed by user. Useful if you want to use your own LLVM builds for testing.
QIRLIB_DOWNLOAD_LLVM
- Indicator to whether the build should download LLVM cached builds.
- Build will build LLVM from source if needed unless this variable is
defined and set to
true
QIRLIB_LLVM_BUILDS_URL
- Url from where LLVM builds will be downloaded.
- There is no default value provided. You can use the
package-llvm
feature to create an archive and upload it along with SHA256 checksum file. The checksum file must have the same file name with a file of the same name with.sha256
appended. The build will download both files and verify that the checksum in the the file matches the downloaded archive.
QIRLIB_CACHE_DIR
- Root installation path for LLVM builds (mapped to
CMAKE_INSTALL_PREFIX
) - Default if not specified when building from source:
qirlib
's targetOUT_DIR
/llvm
- Default if not specified when installing:
- Linux/Mac:
target/<llvm version>
- Linux/Mac:
- Root installation path for LLVM builds (mapped to
QIRLIB_LLVM_TAG
- LLVM repo tag to fetch when building LLVM from source.
- Default values are:
llvm11-0
:llvmorg-11.1.0
llvm12-0
:llvmorg-12.0.1
llvm13-0
:llvmorg-13.0.1
llvm14-0
:llvmorg-14.0.6
QIRLIB_LLVM_PKG_NAME
- Optional name of package to be downloaded/created.
LLVM_SYS_*_PREFIX
- Required by
llvm-sys
and must be set to the version of LLVM used for configuration if compiling against an external LLVM installation. - Version dependent and will change as LLVM is updated. (
LLVM_SYS_120_PREFIX
,LLVM_SYS_130_PREFIX
, etc) - Not needed if you have a working LLVM installation on the path and wish to use the installed system version.
- Required by
Using an existing (external) LLVM installation is the default and effects
the linking that is used. The default
feature enables the external-llvm-linking
feature.
[dependencies]
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", features = "llvm11-0" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", features = "llvm12-0" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", features = "llvm13-0" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", features = "llvm14-0" }
llvm-sys
leveraged by qirlib
and Inkwell
will look for llvm-config
on the path in order to determine how to link against LLVM. If this application is not found on the path, then the the LLVM_SYS_<version>_PREFIX
environment variable is used to locate llvm-config
.
This environment variable can be set in your Cargo.toml
in the [env]
section or in the build environment.
In order to build and link LLVM from source, we must also tell
Inkwell
and
llvm-sys
to disable
their own LLVM linking
To do this, we must disable the default behavior (external-llvm-linking
) using:
- The
--no-default-features
command-line flag disables the default features of the package. - The
default-features = false
option can be specified in a dependency declaration.
[dependencies]
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm11-0-qirlib-llvm-linking,build-llvm" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm12-0-qirlib-llvm-linking,build-llvm" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm13-0-qirlib-llvm-linking,build-llvm" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm14-0-qirlib-llvm-linking,build-llvm" }
Or via the terminal (adding -vv so we can see build progress of LLVM)
qirlib> cargo build --release --no-default-features --features "llvm11-0-qirlib-llvm-linking,build-llvm" -vv
# or
qirlib> cargo build --release --no-default-features --features "llvm12-0-qirlib-llvm-linking,build-llvm" -vv
# or
qirlib> cargo build --release --no-default-features --features "llvm13-0-qirlib-llvm-linking,build-llvm" -vv
# or
qirlib> cargo build --release --no-default-features --features "llvm14-0-qirlib-llvm-linking,build-llvm" -vv
Downloading an existing LLVM package and installing it can be configured via Environment variables. This is an advanced feature and requires more effort to use.
In order to build and link LLVM from source, we must also tell
Inkwell
and
llvm-sys
to disable
their own LLVM linking.
To do this, we must disable the default behavior (external-llvm-linking
) using:
- The
--no-default-features
command-line flag disables the default features of the package. - The
default-features = false
option can be specified in a dependency declaration.
[dependencies]
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm11-0-qirlib-llvm-linking,download-llvm" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm12-0-qirlib-llvm-linking,download-llvm" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm13-0-qirlib-llvm-linking,download-llvm" }
# or
qirlib = { git = "https://github.com/qir-alliance/pyqir", branch = "main", default-features = false, features = "llvm14-0-qirlib-llvm-linking,download-llvm" }
Or via the terminal (adding -vv so we can see download progress of LLVM)
qirlib> cargo build --release --no-default-features --features "llvm11-0-qirlib-llvm-linking,download-llvm" -vv
# or
qirlib> cargo build --release --no-default-features --features "llvm12-0-qirlib-llvm-linking,download-llvm" -vv
# or
qirlib> cargo build --release --no-default-features --features "llvm13-0-qirlib-llvm-linking,download-llvm" -vv
# or
qirlib> cargo build --release --no-default-features --features "llvm14-0-qirlib-llvm-linking,download-llvm" -vv
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. A CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately. Simply follow the instructions provided by the bot. You will only need to do this once.