Update projects, docs, cpp files for QIR stdlib (#1578)
* Update projects, docs, cpp files for QIR stdlib This change updates the remaining example and test projects for using the QIR stdlib via the Microsoft.Quantum.Simulator.Runtime as a QIR backend. This resolves #1560, resolves #1568, and resolves #1569. Note that it does not update the samples under examples\QIR\Simulation as these need to be fully rewritten and likely moved to https://github.com/qir-alliance/qir-runner (see Rewrite or Move docs in examples/QIR/Simulation #1577) * Fix development project QDK version * Update examples/QIR/Optimization/README.md Co-authored-by: Robin Kuzmin <9372582+kuzminrobin@users.noreply.github.com> * Use alternative method for copying build dependencies Co-authored-by: Robin Kuzmin <9372582+kuzminrobin@users.noreply.github.com>
This commit is contained in:
Родитель
82e9304d61
Коммит
35ac6ceb3a
|
@ -368,6 +368,7 @@ src/ProjectTemplates/Quantum.Test1/.template.config/template.json
|
|||
src/QsCompiler/QirGeneration/QirGeneration.nuspec
|
||||
/examples/QIR/Development/qir/*
|
||||
/examples/QIR/Development/build
|
||||
/examples/QIR/Optimization/Hello/build
|
||||
src/Telemetry/Tests/coverage.json
|
||||
src/Telemetry/.vscode/settings.json
|
||||
build/267DevDivSNKey2048.snk
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.Quantum.Sdk/0.25.228311"> <!-- TODO(#1569): Requires refactoring for Rust QIR RT. -->
|
||||
<Project Sdk="Microsoft.Quantum.Sdk/0.27.238334">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
@ -9,8 +9,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Quantum.LlvmBindings.Native" Version="13.0.0-CI-20220129-005156" PrivateAssets="All" GeneratePathProperty="true"/>
|
||||
<PackageReference Include="Microsoft.Quantum.Qir.Runtime" Version="0.25.228311-alpha" GeneratePathProperty="true" /> <!-- TODO(#1569): Requires refactoring for Rust QIR RT. -->
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.25.228311" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.27.238334" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
@ -92,18 +91,9 @@
|
|||
<Target Name="CreateCppDriver">
|
||||
<PropertyGroup>
|
||||
<DriverCode>
|
||||
#include "QirContext.hpp"
|
||||
#include "QirRuntime.hpp"
|
||||
#include "SimFactory.hpp"
|
||||
|
||||
using namespace Microsoft::Quantum%3B
|
||||
using namespace std%3B
|
||||
|
||||
extern "C" void Microsoft__Quantum__Qir__Development__RunExample()%3B // NOLINT
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
unique_ptr<IRuntimeDriver> sim = CreateFullstateSimulator()%3B
|
||||
QirContextScope qirctx(sim.get(), true /*trackAllocatedObjects*/)%3B
|
||||
Microsoft__Quantum__Qir__Development__RunExample()%3B
|
||||
return 0%3B
|
||||
}
|
||||
|
@ -114,24 +104,17 @@
|
|||
|
||||
<Target Name="BuildExecutable" Condition="'$(DesignTimeBuild)' != 'true'" DependsOnTargets="CreateCppDriver;Restore" AfterTargets="QSharpCompile;CoreBuild">
|
||||
<PropertyGroup>
|
||||
<QirRuntimeHeaders>$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/any/native/include</QirRuntimeHeaders>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/osx-x64/native</QirRuntimeLibs>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/win-x64/native</QirRuntimeLibs>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/linux-x64/native</QirRuntimeLibs>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/osx-x64/native/libMicrosoft.Quantum.Simulator.Runtime.dylib</SimulatorRuntime>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/win-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/linux-x64/native/libMicrosoft.Quantum.Simulator.Runtime.so</SimulatorRuntime>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/osx-x64/native</SimulatorFolder>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/win-x64/native</SimulatorFolder>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/linux-x64/native</SimulatorFolder>
|
||||
<ClangOptions Condition="$([MSBuild]::IsOsPlatform('Linux')) Or $([MSBuild]::IsOsPlatform('OSX'))">-fseh-exceptions -lstdc++</ClangOptions>
|
||||
<ClangCommand>clang -std=c++17 -Wno-override-module $(ClangOptions) -o $(ExecutablePath) $(QirOutputPath)$(PathCompatibleAssemblyName).ll $(BuildOutputPath)/Main.cpp -I$(BuildOutputPath) -L$(BuildOutputPath) -lMicrosoft.Quantum.Qir.Runtime -lMicrosoft.Quantum.Qir.QSharp.Core -lMicrosoft.Quantum.Qir.QSharp.Foundation</ClangCommand>
|
||||
<OmpOptions Condition="$([MSBuild]::IsOsPlatform('Linux'))">-lomp</OmpOptions>
|
||||
<ClangCommand>clang -std=c++17 -Wno-override-module $(ClangOptions) -o $(ExecutablePath) $(QirOutputPath)$(PathCompatibleAssemblyName).ll $(BuildOutputPath)/Main.cpp -I$(BuildOutputPath) -L$(BuildOutputPath) -lMicrosoft.Quantum.Simulator.Runtime $(OmpOptions)</ClangCommand>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<_QirRuntimeLibFiles Include="$(QirRuntimeLibs)/**/*.*" Exclude="$(QirRuntimeLibs)/**/*.exe" />
|
||||
<_QirRuntimeHeaderFiles Include="$(QirRuntimeHeaders)/**/*.hpp" />
|
||||
<_QirRuntimeHeaderFiles Include="$(QirRuntimeHeaders)/**/*.h" />
|
||||
<_SimulatorLibraries Include="$(SimulatorFolder)/*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="$(SimulatorRuntime)" DestinationFolder="$(BuildOutputPath)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeLibFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeHeaderFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_SimulatorLibraries)" DestinationFolder="$(BuildOutputPath)" SkipUnchangedFiles="true" />
|
||||
<Exec Command="clang --version" IgnoreExitCode="true" ContinueOnError="ErrorAndContinue">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ClangVersionCheckExitCode"/>
|
||||
</Exec>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.Quantum.Sdk/0.25.228311"> <!-- TODO(#1569): Requires refactoring for Rust QIR RT. -->
|
||||
<Project Sdk="Microsoft.Quantum.Sdk/0.27.238334">
|
||||
|
||||
<PropertyGroup>
|
||||
<QscVerbosity>Detailed</QscVerbosity>
|
||||
|
|
|
@ -38,7 +38,7 @@ The function below is all that is needed to JIT compile a QIR program, and consi
|
|||
- load QIR/simulator libraries
|
||||
- parse the QIR program
|
||||
- load the JIT compiler
|
||||
- initialize the QIR Runtime and attach a simulator (see [next section](#building-the-project) for more info)
|
||||
- initialize and attach a simulator (see [next section](#building-the-project) for more info)
|
||||
- run a QIR function
|
||||
|
||||
```py
|
||||
|
@ -48,9 +48,8 @@ def main(qir_file, entry_point):
|
|||
llvm.initialize_native_target()
|
||||
llvm.initialize_native_asmprinter()
|
||||
|
||||
# Load the QIR Runtime libraries
|
||||
for lib in runtime_libs:
|
||||
llvm.load_library_permanently(lib)
|
||||
# Load the simulator library
|
||||
llvm.load_library_permanently(simulator_lib)
|
||||
|
||||
# Parse the provided QIR module
|
||||
file = open(qir_file, 'r')
|
||||
|
@ -60,16 +59,12 @@ def main(qir_file, entry_point):
|
|||
target = llvm.Target.from_default_triple().create_target_machine()
|
||||
jit_engine = llvm.create_mcjit_compiler(module, target)
|
||||
|
||||
# Initialize the QIR Runtime and simulator via exposed C wrapper
|
||||
fun_ptr = llvm.address_of_symbol("InitQIRSim")
|
||||
CFUNCTYPE(None)(fun_ptr)()
|
||||
|
||||
# Run the entry point of the QIR module
|
||||
fun_ptr = jit_engine.get_function_address(entry_point)
|
||||
CFUNCTYPE(None)(fun_ptr)()
|
||||
```
|
||||
|
||||
Here, `runtime_libs` is a hardcoded list of the system-specific QIR libraries.
|
||||
Here, `simulator_lib` is the platform specific path to the simulator library.
|
||||
The name of the QIR source file `qir_file` is provided as a command-line argument, as well the name of the entry point function `entry_point`.
|
||||
|
||||
The way external functions with C-style linkage are invoked from Python is by using the ctypes module.
|
||||
|
@ -78,44 +73,22 @@ The returned value is a raw pointer that can be converted to a function pointer
|
|||
This is done via the function `CFUNCTYPE(<return type>, <argument types>..)(<ptr_name>)`, which also specifies the usage of the standard C calling convention.
|
||||
Refer to the [ctypes documentation](https://docs.python.org/3/library/ctypes.html) for more information on calling external functions from Python.
|
||||
|
||||
The full Python script can be found in `jit-qir.py`.
|
||||
The full Python script can be found in `qir-jit.py`.
|
||||
|
||||
## Building the project
|
||||
|
||||
Currently, it's not easily possible to set up a JIT for QIR entirely from Python, since the QIR Runtime and simulator are compiled from C++.
|
||||
To get around this, a small library for which we can specify C-linkage can handle the QIR-specific initialization, which can then be invoked from Python directly using ctypes.
|
||||
A small function declared with `extern "C"` linkage is sufficient to initialize the Runtime + simulator, as defined in `QIRinit.cpp`:
|
||||
Before being able run QIR via LLVM's JIT compiler, we need to download the necessary simulator library from the [Quantum Simulators](https://www.nuget.org/packages/Microsoft.Quantum.Simulators/) NuGet packages:
|
||||
|
||||
```cpp
|
||||
#include "QirContext.hpp"
|
||||
#include "SimFactory.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace Microsoft::Quantum;
|
||||
|
||||
extern "C" void InitQIRSim()
|
||||
{
|
||||
// initialize Quantum Simulator and QIR Runtime
|
||||
std::unique_ptr<IRuntimeDriver> sim = CreateFullstateSimulator();
|
||||
InitializeQirContext(sim.release(), true);
|
||||
}
|
||||
```
|
||||
|
||||
Before being able run QIR via LLVM's JIT compiler, we need to download the necessary header and library files from the [QIR Runtime](https://www.nuget.org/packages/Microsoft.Quantum.Qir.Runtime) and [Quantum Simulators](https://www.nuget.org/packages/Microsoft.Quantum.Simulators/) NuGet packages:
|
||||
|
||||
- **Linux** (installs mono for the NuGet CLI):
|
||||
- **Linux** (install mono for the NuGet CLI):
|
||||
|
||||
```shell
|
||||
mkdir build
|
||||
sudo apt update && sudo apt install -y mono-complete
|
||||
curl https://dist.nuget.org/win-x86-commandline/latest/nuget.exe --output build/nuget
|
||||
mono build/nuget sources add -name nuget.org -source https://api.nuget.org/v3/index.json
|
||||
mono build/nuget install Microsoft.Quantum.Qir.Runtime -Version 0.18.2106148911-alpha -DirectDownload -DependencyVersion Ignore -OutputDirectory tmp
|
||||
cp tmp/Microsoft.Quantum.Qir.Runtime.0.18.2106148911-alpha/runtimes/any/native/include/* build
|
||||
cp tmp/Microsoft.Quantum.Qir.Runtime.0.18.2106148911-alpha/runtimes/linux-x64/native/* build
|
||||
mono build/nuget install Microsoft.Quantum.Simulators -Version 0.18.2106148911 -DirectDownload -DependencyVersion Ignore -OutputDirectory tmp
|
||||
cp tmp/Microsoft.Quantum.Simulators.0.18.2106148911/runtimes/linux-x64/native/Microsoft.Quantum.Simulator.Runtime.dll build
|
||||
mono build/nuget install Microsoft.Quantum.Simulators -Version 0.27.238334 -DirectDownload -DependencyVersion Ignore -OutputDirectory tmp
|
||||
cp tmp/Microsoft.Quantum.Simulators.0.27.238334/runtimes/linux-x64/native/libMicrosoft.Quantum.Simulator.Runtime.so build
|
||||
cp tmp/Microsoft.Quantum.Simulators.0.27.238334/runtimes/linux-x64/native/libomp.so build
|
||||
rm -r tmp
|
||||
```
|
||||
|
||||
|
@ -124,28 +97,13 @@ Before being able run QIR via LLVM's JIT compiler, we need to download the neces
|
|||
```shell
|
||||
mkdir build
|
||||
curl https://dist.nuget.org/win-x86-commandline/latest/nuget.exe --output build/nuget.exe
|
||||
build/nuget install Microsoft.Quantum.Qir.Runtime -Version 0.18.2106148911-alpha -DirectDownload -DependencyVersion Ignore -OutputDirectory tmp
|
||||
cp tmp/Microsoft.Quantum.Qir.Runtime.0.18.2106148911-alpha/runtimes/any/native/include/* build
|
||||
cp tmp/Microsoft.Quantum.Qir.Runtime.0.18.2106148911-alpha/runtimes/win-x64/native/* build
|
||||
build/nuget install Microsoft.Quantum.Simulators -Version 0.18.2106148911 -DirectDownload -DependencyVersion Ignore -OutputDirectory tmp
|
||||
cp tmp/Microsoft.Quantum.Simulators.0.18.2106148911/runtimes/win-x64/native/Microsoft.Quantum.Simulator.Runtime.dll build
|
||||
build/nuget install Microsoft.Quantum.Simulators -Version 0.27.238334 -DirectDownload -DependencyVersion Ignore -OutputDirectory tmp
|
||||
cp tmp/Microsoft.Quantum.Simulators.0.27.238334/runtimes/win-x64/native/Microsoft.Quantum.Simulator.Runtime.dll build
|
||||
cp tmp/Microsoft.Quantum.Simulators.0.27.238334/runtimes/win-x64/native/Microsoft.Quantum.Simulator.Runtime.lib build
|
||||
cp tmp/Microsoft.Quantum.Simulators.0.27.238334/runtimes/win-x64/native/libomp140.x86_64.dll build
|
||||
rm -r tmp
|
||||
```
|
||||
|
||||
Then compile the initialization library with the following command:
|
||||
|
||||
- **Linux**:
|
||||
|
||||
```shell
|
||||
clang++ -shared -fPIC QIRinit.cpp -Ibuild -o build/libQIRinit.so
|
||||
```
|
||||
|
||||
- **Windows**:
|
||||
|
||||
```shell
|
||||
clang++ -shared QIRinit.cpp -Ibuild -Lbuild -l'Microsoft.Quantum.Qir.Runtime' -l'Microsoft.Quantum.Qir.QSharp.Core' -Wl',/EXPORT:InitQIRSim' -o build/QIRinit.dll
|
||||
```
|
||||
|
||||
## Running a QIR program with JIT
|
||||
|
||||
To run any QIR program through the JIT, simply run the Python script and provide the QIR source file name and entry point as command line arguments, for example:
|
||||
|
|
|
@ -2,22 +2,14 @@ import sys, platform
|
|||
import llvmlite.binding as llvm
|
||||
from ctypes import CFUNCTYPE
|
||||
|
||||
linux_runtime_libs = ["build/libMicrosoft.Quantum.Qir.Runtime.so",
|
||||
"build/libMicrosoft.Quantum.Qir.QSharp.Core.so",
|
||||
"build/libMicrosoft.Quantum.Qir.QSharp.Foundation.so",
|
||||
"build/Microsoft.Quantum.Simulator.Runtime.dll",
|
||||
"build/libQIRinit.so"]
|
||||
linux_simulator_lib = "build/libMicrosoft.Quantum.Simulator.Runtime.so"
|
||||
|
||||
windows_runtime_libs = ["build/Microsoft.Quantum.Qir.Runtime.dll",
|
||||
"build/Microsoft.Quantum.Qir.QSharp.Core.dll",
|
||||
"build/Microsoft.Quantum.Qir.QSharp.Foundation.dll",
|
||||
"build/Microsoft.Quantum.Simulator.Runtime.dll",
|
||||
"build/QIRinit.dll"]
|
||||
windows_simulator_lib = "build/Microsoft.Quantum.Simulator.Runtime.dll"
|
||||
|
||||
if platform.system() == "Linux":
|
||||
runtime_libs = linux_runtime_libs
|
||||
simulator_lib = linux_simulator_lib
|
||||
elif platform.system() == "Windows":
|
||||
runtime_libs = windows_runtime_libs
|
||||
simulator_lib = windows_simulator_lib
|
||||
else:
|
||||
raise Exception("unsupported platform")
|
||||
|
||||
|
@ -27,9 +19,8 @@ def main(qir_file, entry_point):
|
|||
llvm.initialize_native_target()
|
||||
llvm.initialize_native_asmprinter()
|
||||
|
||||
# Load the QIR Runtime libraries
|
||||
for lib in runtime_libs:
|
||||
llvm.load_library_permanently(lib)
|
||||
# Load the simulator library
|
||||
llvm.load_library_permanently(simulator_lib)
|
||||
|
||||
# Parse the provided QIR module
|
||||
file = open(qir_file, 'r')
|
||||
|
@ -39,10 +30,6 @@ def main(qir_file, entry_point):
|
|||
target = llvm.Target.from_default_triple().create_target_machine()
|
||||
jit_engine = llvm.create_mcjit_compiler(module, target)
|
||||
|
||||
# Initialize the QIR Runtime and simulator via exposed C wrapper
|
||||
fun_ptr = llvm.address_of_symbol("InitQIRSim")
|
||||
CFUNCTYPE(None)(fun_ptr)()
|
||||
|
||||
# Run the entry point of the QIR module
|
||||
fun_ptr = jit_engine.get_function_address(entry_point)
|
||||
CFUNCTYPE(None)(fun_ptr)()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<Project Sdk="Microsoft.Quantum.Sdk/0.25.228311"> <!-- TODO(#1569): Requires refactoring for Rust QIR RT. -->
|
||||
|
||||
<Project Sdk="Microsoft.Quantum.Sdk/0.27.238334">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
|
@ -8,27 +7,19 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Quantum.Qir.Runtime" Version="0.25.228311-alpha" GeneratePathProperty="true" /> <!-- TODO(#1569): Requires refactoring for Rust QIR RT. -->
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.25.228311" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.27.238334" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="GetDependencies" AfterTargets="Build">
|
||||
<PropertyGroup>
|
||||
<QirRuntimeHeaders>$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/any/native/include</QirRuntimeHeaders>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/osx-x64/native</QirRuntimeLibs>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/win-x64/native</QirRuntimeLibs>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/linux-x64/native</QirRuntimeLibs>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/osx-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/win-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/linux-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/osx-x64/native</SimulatorFolder>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/win-x64/native</SimulatorFolder>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/linux-x64/native</SimulatorFolder>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<_QirRuntimeLibFiles Include="$(QirRuntimeLibs)/**/*.*" Exclude="$(QirRuntimeLibs)/**/*.exe" />
|
||||
<_QirRuntimeHeaderFiles Include="$(QirRuntimeHeaders)/**/*.hpp" />
|
||||
<_SimulatorLibraries Include="$(SimulatorFolder)/*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="$(SimulatorRuntime)" DestinationFolder="$(BuildOutputPath)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeLibFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeHeaderFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_SimulatorLibraries)" DestinationFolder="$(BuildOutputPath)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
#include "QirContext.hpp"
|
||||
#include "QirRuntime.hpp"
|
||||
#include "SimFactory.hpp"
|
||||
|
||||
using namespace Microsoft::Quantum;
|
||||
using namespace std;
|
||||
|
||||
extern "C" void Hello__HelloQ();
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
unique_ptr<IRuntimeDriver> sim = CreateFullstateSimulator();
|
||||
QirContextScope qirctx(sim.get(), true /*trackAllocatedObjects*/);
|
||||
Hello__HelloQ();
|
||||
return 0;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -304,10 +304,11 @@ Check out the full list of [LLVM passes](https://llvm.org/docs/Passes.html) for
|
|||
Since QIR code *is* LLVM IR, the usual code generation tools provided by LLVM can be used to produce an executable.
|
||||
However, in order to handle QIR-specific types and functions, proper linkage of the QIR runtime and simulator libraries is required.
|
||||
|
||||
### Obtaining the QIR runtime & simulator
|
||||
### Obtaining the QIR standard library & simulator
|
||||
|
||||
The [QIR runtime](https://github.com/microsoft/qsharp-runtime/tree/main/src/Qir/Runtime) is distributed in the form of a NuGet package, from which we will pull the necessary library files.
|
||||
The same goes for the [full state quantum simulator](https://learn.microsoft.com/azure/quantum/machines/full-state-simulator), which the QIR runtime can hook into to simulate the quantum program.
|
||||
The [QIR standard library](https://github.com/qir-alliance/qir-runner/tree/main/stdlib) is a native library that exposes the functionality described in the
|
||||
[QIR specification](https://github.com/qir-alliance/qir-spec), from which the required static libraries are compiled into the the
|
||||
[full state quantum simulator](https://learn.microsoft.com/azure/quantum/machines/full-state-simulator), which acts as the QIR backend to simulate the quantum program.
|
||||
In this section, the project file `Hello.csproj` is modified to generate these library files automatically.
|
||||
|
||||
For convenience, a variable `BuildOutputPath` is defined with the following line added to the top-level `PropertyGroup` section:
|
||||
|
@ -321,19 +322,17 @@ For convenience, a variable `BuildOutputPath` is defined with the following line
|
|||
</PropertyGroup>
|
||||
```
|
||||
|
||||
All QIR runtime and simulator dependencies will be copied there.
|
||||
All QIR dependencies will be copied there.
|
||||
|
||||
Next, the aforementioned NuGet package dependencies must be declared.
|
||||
One for the runtime and one for the simulator, using the `PackageReference` command:
|
||||
Next, the simulator NuGet package dependencies must be declared, using the `PackageReference` command:
|
||||
|
||||
```xml
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Quantum.Qir.Runtime" Version="0.22.187631-alpha" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.22.187631" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
The package versions should match the version of the QDK specified at the top of the file, however, the runtime is only available as an alpha version at the moment.
|
||||
The package version should match the version of the QDK specified at the top of the file.
|
||||
The `GeneratePathProperty` will allow us to directly reference specific files in the packages later on.
|
||||
|
||||
Lastly, a new build target is added called `GetDependencies`:
|
||||
|
@ -344,34 +343,19 @@ Lastly, a new build target is added called `GetDependencies`:
|
|||
|
||||
The property `AfterTargets` indicates the target is to be run after the regular build stage.
|
||||
|
||||
Inside, we simply copy library and C++ header files from the packages into the build folder with the `Copy` command:
|
||||
Inside, we simply copy the simulator library from the packages into the build folder with the `Copy` command:
|
||||
|
||||
```xml
|
||||
<Copy SourceFiles="$(SimulatorRuntime)" DestinationFolder="$(BuildOutputPath)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeLibFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeHeaderFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
```
|
||||
|
||||
The variables used to specify source files must be defined appropriately for each operating system.
|
||||
For example, only these definitions would be active on Windows:
|
||||
|
||||
```xml
|
||||
<QirRuntimeHeaders>$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/any/native/include</QirRuntimeHeaders>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/win-x64/native</QirRuntimeLibs>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/win-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
```
|
||||
|
||||
Note the variable `$(PkgMicrosoft_Quantum_Qir_Runtime)` for example is only available because of the `GeneratePathProperty` in the `Microsoft.Quantum.Qir.Runtime` package declaration.
|
||||
|
||||
Since `QirRuntimeHeaders` and `QirRuntimeLibs` only specify directories (whereas `SimulatorRuntime` specifies a single file), we further filter the files to be copied:
|
||||
|
||||
```xml
|
||||
<_QirRuntimeLibFiles Include="$(QirRuntimeLibs)/**/*.*" Exclude="$(QirRuntimeLibs)/**/*.exe" />
|
||||
<_QirRuntimeHeaderFiles Include="$(QirRuntimeHeaders)/**/*.hpp" />
|
||||
```
|
||||
|
||||
Only `.hpp` files from the QIR header directory will be copied, and no `.exe` files from QIR library directory.
|
||||
|
||||
Put together, the new `Hello.csproj` project file should look as follows:
|
||||
|
||||
```xml
|
||||
|
@ -385,53 +369,31 @@ Put together, the new `Hello.csproj` project file should look as follows:
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Quantum.Qir.Runtime" Version="0.22.187631-alpha" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.22.187631" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="GetDependencies" AfterTargets="Build">
|
||||
<PropertyGroup>
|
||||
<QirRuntimeHeaders>$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/any/native/include</QirRuntimeHeaders>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/osx-x64/native</QirRuntimeLibs>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/win-x64/native</QirRuntimeLibs>
|
||||
<QirRuntimeLibs Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Qir_Runtime)/runtimes/linux-x64/native</QirRuntimeLibs>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/osx-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/win-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
<SimulatorRuntime Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/linux-x64/native/Microsoft.Quantum.Simulator.Runtime.dll</SimulatorRuntime>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/osx-x64/native</SimulatorFolder>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/win-x64/native</SimulatorFolder>
|
||||
<SimulatorFolder Condition="$([MSBuild]::IsOsPlatform('Linux'))">$(PkgMicrosoft_Quantum_Simulators)/runtimes/linux-x64/native</SimulatorFolder>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<_QirRuntimeLibFiles Include="$(QirRuntimeLibs)/**/*.*" Exclude="$(QirRuntimeLibs)/**/*.exe" />
|
||||
<_QirRuntimeHeaderFiles Include="$(QirRuntimeHeaders)/**/*.hpp" />
|
||||
<_SimulatorLibraries Include="$(SimulatorFolder)/*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="$(SimulatorRuntime)" DestinationFolder="$(BuildOutputPath)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeLibFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_QirRuntimeHeaderFiles)" DestinationFolder="$(BuildOutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(_SimulatorLibraries)" DestinationFolder="$(BuildOutputPath)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
```
|
||||
|
||||
Build the project again with `dotnet build` from the project root directory.
|
||||
You should see the following important files appear in a folder named `build`, among others:
|
||||
You should see the simulator library appear in a folder named `build`, among others:
|
||||
|
||||
```
|
||||
build
|
||||
├── Microsoft.Quantum.Qir.QSharp.Core.dll
|
||||
├── Microsoft.Quantum.Qir.QSharp.Foundation.dll
|
||||
├── Microsoft.Quantum.Qir.Runtime.dll
|
||||
├── Microsoft.Quantum.Simulator.Runtime.dll
|
||||
├── QirContext.hpp
|
||||
├── QirRuntime.hpp
|
||||
└── SimFactory.hpp
|
||||
```
|
||||
|
||||
(**Linux**) The `Microsoft.Quantum.Qir.*` dynamic libraries will already have the right naming scheme for Clang to use, but the `Microsoft.Quantum.Simulator.Runtime` library needs to be renamed.
|
||||
The proper name format is `lib<library-name>.so`.
|
||||
|
||||
Execute the following command from the project root directory:
|
||||
|
||||
```bash
|
||||
mv build/Microsoft.Quantum.Simulator.Runtime.dll build/libMicrosoft.Quantum.Simulator.Runtime.so
|
||||
└── Microsoft.Quantum.Simulator.Runtime.lib
|
||||
```
|
||||
|
||||
### Adding a driver
|
||||
|
@ -440,18 +402,9 @@ Trying to compile the QIR code in `Hello.ll` as is would present some problems,
|
|||
A small C++ driver program (`Main.cpp`) will handle the setup and invoke Q# operations or functions directly from the QIR code.
|
||||
|
||||
```cpp
|
||||
#include "QirContext.hpp"
|
||||
#include "QirRuntime.hpp"
|
||||
#include "SimFactory.hpp"
|
||||
|
||||
using namespace Microsoft::Quantum;
|
||||
using namespace std;
|
||||
|
||||
extern "C" void Hello__HelloQ();
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
unique_ptr<IRuntimeDriver> sim = CreateFullstateSimulator();
|
||||
QirContextScope qirctx(sim.get(), true /*trackAllocatedObjects*/);
|
||||
Hello__HelloQ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -459,17 +412,6 @@ int main(int argc, char* argv[]){
|
|||
|
||||
The driver consists of the following elements:
|
||||
|
||||
* header files (to interface with the libraries):
|
||||
|
||||
- `QirContext` : used to register the simulator with the QIR runtime
|
||||
- `QirRuntime` : implements the types and functions defined in the [QIR specification](https://github.com/qir-alliance/qir-spec)
|
||||
- `SimFactory` : provides the Q# simulator
|
||||
|
||||
* namespaces :
|
||||
|
||||
- `Microsoft::Quantum` : the QIR context and simulator live here
|
||||
- `std` : needed for `unique_ptr`
|
||||
|
||||
* external function declarations :
|
||||
|
||||
This is were we declare functions from other compilation units we'd like to invoke.
|
||||
|
@ -478,11 +420,6 @@ The driver consists of the following elements:
|
|||
Normally, C++ function names would be transformed during compilation to include namespace and call argument information in the function name, known as [mangling](https://en.wikipedia.org/wiki/Name_mangling).
|
||||
We can check that the QIR function `Hello_HelloQ` indeed appears in the `Hello.ll` file with that name.
|
||||
|
||||
* simulator invocation:
|
||||
|
||||
Here we create a Q# [full state simulator](https://docs.microsoft.com/azure/quantum/user-guide/machines/full-state-simulator) instance that will run our quantum program and register it with the current context.
|
||||
Following this, everything is set up to call into Q# functions.
|
||||
|
||||
### Compiling the program
|
||||
|
||||
Multiple tools are available for this step, such as the LLVM static compiler + assembler + linker or the JIT compiler.
|
||||
|
@ -491,13 +428,13 @@ Here, Clang is used again, this time to compile and link the `Hello.ll` Q# progr
|
|||
Invoke the following command on Windows:
|
||||
|
||||
```powershell
|
||||
clang++ qir/Hello.ll Main.cpp -Ibuild -Lbuild -l'Microsoft.Quantum.Qir.Runtime' -l'Microsoft.Quantum.Qir.QSharp.Core' -l'Microsoft.Quantum.Qir.QSharp.Foundation' -o build/Hello.exe
|
||||
clang++ qir/Hello.ll Main.cpp -Ibuild -Lbuild -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe
|
||||
```
|
||||
|
||||
On Linux:
|
||||
|
||||
```bash
|
||||
clang++ qir/Hello.ll Main.cpp -Wl,-rpath=build -Ibuild -Lbuild -l'Microsoft.Quantum.Qir.Runtime' -l'Microsoft.Quantum.Qir.QSharp.Core' -l'Microsoft.Quantum.Qir.QSharp.Foundation' -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe
|
||||
clang++ qir/Hello.ll Main.cpp -Wl,-rpath=build -Ibuild -Lbuild -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
@ -521,13 +458,13 @@ The same can be done with the optimized QIR code.
|
|||
On Windows:
|
||||
|
||||
```powershell
|
||||
clang++ qir/Hello-dce-inline.ll Main.cpp -Ibuild -Lbuild -l'Microsoft.Quantum.Qir.Runtime' -l'Microsoft.Quantum.Qir.QSharp.Core' -l'Microsoft.Quantum.Qir.QSharp.Foundation' -o build/Hello.exe && ./build/Hello.exe
|
||||
clang++ qir/Hello-dce-inline.ll Main.cpp -Ibuild -Lbuild -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe && ./build/Hello.exe
|
||||
```
|
||||
|
||||
On Linux:
|
||||
|
||||
```bash
|
||||
clang++ qir/Hello-dce-inline.ll Main.cpp -Wl,-rpath=build -Ibuild -Lbuild -l'Microsoft.Quantum.Qir.Runtime' -l'Microsoft.Quantum.Qir.QSharp.Core' -l'Microsoft.Quantum.Qir.QSharp.Foundation' -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe && ./build/Hello.exe
|
||||
clang++ qir/Hello-dce-inline.ll Main.cpp -Wl,-rpath=build -Ibuild -Lbuild -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe && ./build/Hello.exe
|
||||
```
|
||||
|
||||
As a last example, let's modify the Q# program `Program.qs` with a random bit generator and run through the whole process:
|
||||
|
@ -556,10 +493,10 @@ Steps:
|
|||
* optimize the code `clang -S qir/Hello.ll -O3 -emit-llvm -o qir/Hello-o3.ll`
|
||||
* compile the code on Windows
|
||||
```powershell
|
||||
clang++ qir/Hello-o3.ll Main.cpp -Ibuild -Lbuild -l'Microsoft.Quantum.Qir.Runtime' -l'Microsoft.Quantum.Qir.QSharp.Core' -l'Microsoft.Quantum.Qir.QSharp.Foundation' -o build/Hello.exe
|
||||
clang++ qir/Hello-o3.ll Main.cpp -Ibuild -Lbuild -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe
|
||||
```
|
||||
or Linux
|
||||
```bash
|
||||
clang++ qir/Hello.ll Main.cpp -Wl,-rpath=build -Ibuild -Lbuild -l'Microsoft.Quantum.Qir.Runtime' -l'Microsoft.Quantum.Qir.QSharp.Core' -l'Microsoft.Quantum.Qir.QSharp.Foundation' -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe
|
||||
clang++ qir/Hello.ll Main.cpp -Wl,-rpath=build -Ibuild -Lbuild -l'Microsoft.Quantum.Simulator.Runtime' -o build/Hello.exe
|
||||
```
|
||||
* simulate the program `./build/Hello.exe`
|
||||
|
|
|
@ -11,12 +11,6 @@ namespace Microsoft.Quantum.QsCompiler.Testing.Qir
|
|||
{
|
||||
public static class JitCompilation
|
||||
{
|
||||
[DllImport("Microsoft.Quantum.Qir.QSharp.Core", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr CreateFullstateSimulatorC(long seed);
|
||||
|
||||
[DllImport("Microsoft.Quantum.Qir.Runtime", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] // TODO(#1569): Requires refactoring for Rust QIR RT.
|
||||
public static extern void InitializeQirContext(IntPtr driver, bool trackAllocatedObjects);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate void SimpleFunction();
|
||||
|
||||
|
@ -79,13 +73,8 @@ namespace Microsoft.Quantum.QsCompiler.Testing.Qir
|
|||
NativeLibrary.Load("omp", typeof(JitCompilation).Assembly, null);
|
||||
}
|
||||
|
||||
// Explicitly load dependent libraries so that they are already present in memory when pinvoke
|
||||
// triggers for the Microsoft.Quantum.Qir.QSharp.Core call below.
|
||||
// Explicitly load dependent libraries so that they are already present in memory.
|
||||
NativeLibrary.Load("Microsoft.Quantum.Simulator.Runtime", typeof(JitCompilation).Assembly, null);
|
||||
NativeLibrary.Load("Microsoft.Quantum.Qir.Runtime", typeof(JitCompilation).Assembly, null);
|
||||
NativeLibrary.Load("Microsoft.Quantum.Qir.QSharp.Foundation", typeof(JitCompilation).Assembly, null);
|
||||
|
||||
InitializeQirContext(CreateFullstateSimulatorC(0), true);
|
||||
|
||||
if (!File.Exists(pathToBitcode))
|
||||
{
|
||||
|
@ -111,9 +100,7 @@ namespace Microsoft.Quantum.QsCompiler.Testing.Qir
|
|||
// Linux requires an additional explicit load of the libraries into MCJIT.
|
||||
// Full paths are not needed since .NET already loaded these into program memory above,
|
||||
// but without this explict load the JIT logic won't find them.
|
||||
ExplicitLibraryLoad("libMicrosoft.Quantum.Qir.Runtime.so");
|
||||
ExplicitLibraryLoad("libMicrosoft.Quantum.Qir.QSharp.Foundation.so");
|
||||
ExplicitLibraryLoad("libMicrosoft.Quantum.Qir.QSharp.Core.so");
|
||||
ExplicitLibraryLoad("libMicrosoft.Quantum.Simulator.Runtime.so");
|
||||
}
|
||||
|
||||
var engine = modRef.CreateMCJITCompiler();
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Quantum.Qir.Runtime" Version="0.25.228311-alpha" ExcludeAssets="compile" /> <!-- TODO(#1569): Requires refactoring for Rust QIR RT. -->
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.25.228311" ExcludeAssets="compile" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Quantum.Simulators" Version="0.27.238334" ExcludeAssets="compile" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PrepareReferenceTests" Condition="'$(DesignTimeBuild)' != 'true' And $([MSBuild]::IsOsPlatform('OSX'))" BeforeTargets="CoreCompile">
|
||||
|
|
|
@ -162,7 +162,7 @@ type ExecutionTests(output: ITestOutputHelper) =
|
|||
"interpolated string"
|
||||
true or false, true, false, true, false
|
||||
1, -1, 0
|
||||
1.0, 2.0, 100000.0, 0.10000000000000001, -1.0, 0.0
|
||||
1.0, 2.0, 100000.0, 0.1, -1.0, 0.0
|
||||
Zero, One
|
||||
PauliZ, PauliX, PauliY, [PauliI]
|
||||
1..3, 3..-1..1, 0..-1..0
|
||||
|
|
Загрузка…
Ссылка в новой задаче