Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d4ff288
Refactor cmakelists into common modules
swernli Mar 5, 2021
a6ad046
Split out QSharpCore lib
swernli Mar 6, 2021
072c41d
Create full dynamic libs, including tracer
swernli Mar 7, 2021
12ec703
Produce QIR dll pipeline artifacts
swernli Mar 7, 2021
079f87e
Fix cmake existence check for generated obj
swernli Mar 7, 2021
8415529
Fix dynamic lib linking in tests
swernli Mar 7, 2021
f473cc4
Use dynamic dependency for non-test libs too
swernli Mar 7, 2021
ab5f859
Clean up simulators CMakeLists
swernli Mar 7, 2021
5be4f01
Expand use of dllexport to support Windows
swernli Mar 7, 2021
e8c3f68
Fix missing include
swernli Mar 7, 2021
24834fa
Add thread_local global context exported accessor
swernli Mar 7, 2021
1d6cfdf
Move implementaiton out of header
swernli Mar 7, 2021
2ed8c91
Fix target_compile_definitions
swernli Mar 7, 2021
bf4c7f4
Fix typos
swernli Mar 7, 2021
d4bc496
More compile definitions
swernli Mar 8, 2021
9cc3e7f
Use tracer types differently
swernli Mar 8, 2021
b78ec6b
Add dllexport to IR
swernli Mar 8, 2021
ef1dfed
Update test linkage, ResultOne/Zero def
swernli Mar 8, 2021
91acd00
Try updating signature of ResultOne/Zero
swernli Mar 8, 2021
ae615f5
Try using dllimport for external global IR
swernli Mar 8, 2021
4dd6875
Fix tracer API export
swernli Mar 8, 2021
a5733e2
Put back cmake install runtime directives
swernli Mar 8, 2021
94f66a5
Return to plat specific handling of Result global
swernli Mar 8, 2021
74e19af
move build and test of QIR to after sln
swernli Mar 8, 2021
ac74215
Update build scripts and readme
swernli Mar 8, 2021
725b07a
Update build scripts for PR feedback
swernli Mar 9, 2021
b01e2eb
Fix qir build with dynamic path update
swernli Mar 9, 2021
c31949a
Rename qir.dll to Microsoft.Quantum.Qir.Runtime
swernli Mar 9, 2021
275d354
Rename QSharpCore and qirtracer dlls
swernli Mar 9, 2021
bb80b93
Separate out quantum__qis into QSharp.Foundation
swernli Mar 9, 2021
4c48ce2
Merge remote-tracking branch 'origin/main' into swernli/qirruntime-re…
swernli Mar 9, 2021
500f0bc
Convert sample to dynamic, add to scripts
swernli Mar 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions build/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,6 @@ if ($Env:ENABLE_NATIVE -ne "false") {
Write-Host "Skipping build of native simulator because ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE."
}


if ($Env:ENABLE_QIRRUNTIME -eq "true") {
$qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime")
& "$qirRuntime/build-qir-runtime.ps1"
if ($LastExitCode -ne 0) {
$script:all_ok = $False
}
} else {
Write-Host "Skipping build of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME"
}


function Build-One {
param(
[string]$action,
Expand Down Expand Up @@ -57,6 +45,16 @@ Build-One 'publish' '../src/Simulation/CSharpGeneration.App'

Build-One 'build' '../Simulation.sln'

if ($Env:ENABLE_QIRRUNTIME -eq "true") {
$qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime")
& "$qirRuntime/build-qir-runtime.ps1"
if ($LastExitCode -ne 0) {
$script:all_ok = $False
}
} else {
Write-Host "Skipping build of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME"
}

if (-not $all_ok) {
throw "At least one project failed to compile. Check the logs."
}
6 changes: 2 additions & 4 deletions build/set-env.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ If ($Env:BUILD_VERBOSITY -eq $null) { $Env:BUILD_VERBOSITY ="m" }
If ($Env:ASSEMBLY_VERSION -eq $null) { $Env:ASSEMBLY_VERSION ="$Env:BUILD_BUILDNUMBER" }
If ($Env:NUGET_VERSION -eq $null) { $Env:NUGET_VERSION ="$Env:ASSEMBLY_VERSION-alpha" }

If ($Env:ENABLE_QIRRUNTIME -eq "true") {
If (($Env:ENABLE_NATIVE -ne "false") -and ($Env:NATIVE_SIMULATOR -eq $null) ) {
$Env:NATIVE_SIMULATOR = (Join-Path $PSScriptRoot "..\src\Simulation\Native\build\drop")
}
If (($Env:ENABLE_NATIVE -ne "false") -and ($Env:NATIVE_SIMULATOR -eq $null) ) {
$Env:NATIVE_SIMULATOR = (Join-Path $PSScriptRoot "..\src\Simulation\Native\build\drop")
}

If ($Env:DROPS_DIR -eq $null) { $Env:DROPS_DIR = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\drops")) }
Expand Down
23 changes: 11 additions & 12 deletions build/test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@ if ($Env:ENABLE_NATIVE -ne "false") {
} else {
Write-Host "Skipping test of native simulator because ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE."
}

if (($Env:ENABLE_NATIVE -ne "false") -and ($Env:ENABLE_QIRRUNTIME -eq "true")) {
$qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime")
& "$qirRuntime/test-qir-runtime.ps1"
if ($LastExitCode -ne 0) {
$script:all_ok = $False
}
} else {
Write-Host "Skipping test of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME `
and ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE."
}

function Test-One {
Param($project)

Expand All @@ -49,6 +37,17 @@ function Test-One {

Test-One '../Simulation.sln'

if (($Env:ENABLE_NATIVE -ne "false") -and ($Env:ENABLE_QIRRUNTIME -eq "true")) {
$qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime")
& "$qirRuntime/test-qir-runtime.ps1"
if ($LastExitCode -ne 0) {
$script:all_ok = $False
}
} else {
Write-Host "Skipping test of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME `
and ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE."
}

if (-not $all_ok) {
throw "At least one project failed during testing. Check the logs."
}
89 changes: 5 additions & 84 deletions src/QirRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,97 +27,18 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

set(public_includes "${PROJECT_SOURCE_DIR}/public")
set(test_includes "${PROJECT_SOURCE_DIR}/externals/catch2" "${PROJECT_SOURCE_DIR}/test")

#===============================================================================
# testing related
#
include(CTest)
macro(add_unit_test target)
add_test(
NAME ${target}
COMMAND ${target} ~[skip] -o "${target}_results.xml" -r junit
)

# set the environment path for loading shared libs the tests are using
if(DEFINED ENV{NATIVE_SIMULATOR})
set(TEST_DEPS1 $ENV{NATIVE_SIMULATOR})
else()
set(TEST_DEPS1 "${PROJECT_SOURCE_DIR}/../Simulation/native/build/${CMAKE_BUILD_TYPE}")
endif()

set(TEST_DEPS2 "${CMAKE_BINARY_DIR}/bin")
set_property(TEST ${target} PROPERTY ENVIRONMENT
"LD_LIBRARY_PATH=${TEST_DEPS1}:${TEST_DEPS2}:${LD_LIBRARY_PATH}"
"PATH=${TEST_DEPS1}\;${TEST_DEPS2}\;${PATH}"
"DYLD_LIBRARY_PATH=${TEST_DEPS1}:${TEST_DEPS2}:${DYLD_LIBRARY_PATH}"
)
endmacro(add_unit_test)

#===============================================================================
# compiling from IR
#
# CMake doesn't support LLVM IR files as sources so we compile them with custom
# commands, which produce UTILITY libs that can only be linked in using abs paths
# (rather than the target name):
# Target "qir_bridge_qis" of type UTILITY may not be linked into another
# target. One may link only to INTERFACE, OBJECT, STATIC or SHARED
# libraries, or to executables with the ENABLE_EXPORTS property set.
#
macro(compile_from_qir source_file target)
set(CLANG_ARGS "-c")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CLANG_ARGS
"${CLANG_ARGS}"
"-O0"
"-D_DEBUG"
)
endif()

set(INFILE
"${CMAKE_CURRENT_SOURCE_DIR}/${source_file}.ll"
)
set(OBJFILE
"${CMAKE_CURRENT_BINARY_DIR}/${source_file}.obj"
)

set(OBJFILE_COMPILE "${source_file}-compile")
add_custom_command(OUTPUT ${OBJFILE_COMPILE}
COMMAND ${CMAKE_CXX_COMPILER}
ARGS ${CLANG_ARGS} ${INFILE} "-o" ${OBJFILE}
DEPENDS ${INFILE}
COMMENT "Compiling ${source_file}.ll"
VERBATIM
)

add_custom_target(${source_file}_compile DEPENDS ${OBJFILE_COMPILE})

if (WIN32)
set(QIR_UTILITY_LIB "${CMAKE_CURRENT_BINARY_DIR}/${source_file}-u.lib" )
else()
set(QIR_UTILITY_LIB "${CMAKE_CURRENT_BINARY_DIR}/lib${source_file}-u.a")
endif()

add_custom_command(OUTPUT ${QIR_UTILITY_LIB}
COMMAND ${CMAKE_AR}
ARGS "rc" ${QIR_UTILITY_LIB} ${OBJFILE}
DEPENDS ${source_file}_compile ${INFILE}
COMMENT "Creating a lib from ${source_file}.ll"
VERBATIM
)

if (NOT ${target} STREQUAL "")
add_custom_target(${target} DEPENDS ${QIR_UTILITY_LIB})
endif()
endmacro(compile_from_qir)
include(qir_cmake_include)

if (WIN32)
set(QIR_BRIDGE_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/bridge-rt-u.lib")
set(QIR_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/bridge-qis-u.lib")
set(QSHARP_FOUNDATION_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpFoundation/qsharp-foundation-qis-u.lib")
set(QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpCore/qsharp-core-qis-u.lib")
set(QIR_BRIDGE_TRACER_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/Tracer/tracer-bridge-u.lib")
else()
set(QIR_BRIDGE_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/libbridge-rt-u.a")
set(QIR_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/libbridge-qis-u.a")
set(QSHARP_FOUNDATION_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpFoundation/libqsharp-foundation-qis-u.a")
set(QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpCore/libqsharp-core-qis-u.a")
set(QIR_BRIDGE_TRACER_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/Tracer/libtracer-bridge-u.a")
endif()

Expand Down
13 changes: 3 additions & 10 deletions src/QirRuntime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,11 @@ You can use CMake directly. For example, to produce a release build:
4. cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
5. cmake --build .

Or you can run `build.py` script from QirRuntime folder. The default options for the script are `make debug`.
Or you can run `build-qir-runtime.ps1` script from QirRuntime folder. The script will place the build artifacts into `build/[Debug|Release]` folder. We strongly recommend doing local builds using the build script because it also runs clang-tidy if it is installed.

- (Windows) `python build.py [make/nomake] [debug|release] [noqirgen]`
- (Linux) `python3 build.py [make/nomake] [debug|release] [noqirgen]`
CI builds and tests are enabled for this project. The build for `test/QIR-static/qsharp/qir-gen.csproj` has project dependencies on other parts of the runtime and may trigger a build for those components, while some of the tests depend on `Microsoft.Quantum.Simulator.Runtime` dynamic library built from.

The script will place the build artifacts into `build/[Windows|Linux]/[Debug|Release]` folder. We strongly recommend
doing local builds using the build script because it also runs clang-tidy.

CI builds and tests are enabled for this project. The build has no external dependencies, but some of the tests depend
on `Microsoft.Quantum.Simulator.Runtime` library.
To install prerequisite tools for building the QIR runtime, you can set the `ENABLE_QIRRUNTIME` environment variable to the string `"true"` and run `prerequisites.ps1` or manually install pre-reqs with the steps listed below (Windows script relies on [Chocolatey](https://chocolatey.org/) for installation).

### Windows pre-reqs

Expand All @@ -40,7 +35,6 @@ CI builds and tests are enabled for this project. The build has no external depe
1. Install VS 2019 and enable "Desktop development with C++" component (Clang uses MSVC's standard library on Windows).
1. Install clang-tidy and clang-format if your Clang/LLVM packages didn't include the tools.
1. Install the same version of dotnet as specified by qsharp-runtime [README](../../README.md)
1. <_optional_> To use build/test scripts install Python 3.8.

*Building from Visual Studio and VS Code is **not** supported.
Running cmake from the editors will likely default to MSVC or clang-cl and fail.*
Expand All @@ -58,7 +52,6 @@ Running cmake from the editors will likely default to MSVC or clang-cl and fail.
- $ export CXX=/usr/bin/clang++-11
1. `$ sudo apt install clang-tidy-11` (`$ clang-tidy-11 --version` should return 'LLVM version 11.0.0')
1. Install the same version of dotnet as specified by qsharp-runtime [README](../../README.md)
1. <_optional_> To use build/test scripts, check that you have python3 installed (it should be by default).

See [https://code.visualstudio.com/docs/remote/wsl] on how to use VS Code with WSL.

Expand Down
134 changes: 80 additions & 54 deletions src/QirRuntime/build-qir-runtime.ps1
Original file line number Diff line number Diff line change
@@ -1,68 +1,94 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

if ($Env:ENABLE_QIRRUNTIME -eq "true") {
Write-Host "##[info]Compile Q# Projects into QIR"
$qirStaticPath = Join-Path $PSScriptRoot test QIR-static qsharp
dotnet build $qirStaticPath -c $Env:BUILD_CONFIGURATION -v $Env:BUILD_VERBOSITY
if ($LastExitCode -ne 0) {
Write-Host "##vso[task.logissue type=error;]Failed to compile Q# project at '$qirStaticPath' into QIR."
return
}
Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination (Split-Path $qirStaticPath -Parent)
# Also copy to drops so it ends up in build artifacts, for easier post-build debugging.
Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination $Env:DROPS_DIR
& (Join-Path $PSScriptRoot .. .. build set-env.ps1)
Write-Host "##[info]Compile Q# Projects into QIR"
$qirStaticPath = Join-Path $PSScriptRoot test QIR-static qsharp
dotnet build $qirStaticPath -c $Env:BUILD_CONFIGURATION -v $Env:BUILD_VERBOSITY
if ($LastExitCode -ne 0) {
Write-Host "##vso[task.logissue type=error;]Failed to compile Q# project at '$qirStaticPath' into QIR."
return
}
Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination (Split-Path $qirStaticPath -Parent)
# Also copy to drops so it ends up in build artifacts, for easier post-build debugging.
Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination $Env:DROPS_DIR

Write-Host "##[info]Build QIR Runtime"
$oldCC = $env:CC
$oldCXX = $env:CXX
$oldRC = $env:RC
Write-Host "##[info]Build QIR Runtime"
$oldCC = $env:CC
$oldCXX = $env:CXX
$oldRC = $env:RC

$clangTidy = ""
$clangTidy = ""

if (($IsMacOS) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Darwin"))))
{
Write-Host "On MacOS build QIR Runtim using the default C/C++ compiler (should be AppleClang)"
}
elseif (($IsLinux) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Lin"))))
{
Write-Host "On Linux build QIR Runtime using Clang"
$env:CC = "/usr/bin/clang-11"
$env:CXX = "/usr/bin/clang++-11"
$env:RC = "/usr/bin/clang++-11"
$clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy-11"
}
elseif (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Win"))))
{
Write-Host "On Windows build QIR Runtime using Clang"
$env:CC = "C:\Program Files\LLVM\bin\clang.exe"
$env:CXX = "C:\Program Files\LLVM\bin\clang++.exe"
$env:RC = "C:\Program Files\LLVM\bin\clang++.exe"
$llvmExtras = (Join-Path $PSScriptRoot "externals/LLVM")
$env:PATH += ";$llvmExtras"
} else {
Write-Host "##vso[task.logissue type=error;]Failed to identify the OS. Will use default CXX compiler"
}
if (($IsMacOS) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Darwin"))))
{
Write-Host "On MacOS build QIR Runtime using the default C/C++ compiler (should be AppleClang)"
}
elseif (($IsLinux) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Lin"))))
{
Write-Host "On Linux build QIR Runtime using Clang"
$env:CC = "clang-11"
$env:CXX = "clang++-11"
$env:RC = "clang++-11"
$clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy-11"
}
elseif (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Win"))))
{
Write-Host "On Windows build QIR Runtime using Clang"
$env:CC = "clang.exe"
$env:CXX = "clang++.exe"
$env:RC = "clang++.exe"
$llvmExtras = Join-Path $PSScriptRoot externals LLVM
$env:PATH += ";$llvmExtras"

$qirRuntimeBuildFolder = (Join-Path $PSScriptRoot "build\$Env:BUILD_CONFIGURATION")
if (-not (Test-Path $qirRuntimeBuildFolder)) {
New-Item -Path $qirRuntimeBuildFolder -ItemType "directory"
if (!(Get-Command clang -ErrorAction SilentlyContinue) -and (choco find --idonly -l llvm) -contains "llvm") {
# LLVM was installed by Chocolatey, so add the install location to the path.
$env:PATH += ";$($env:SystemDrive)\Program Files\LLVM\bin"
}

Push-Location $qirRuntimeBuildFolder
if (Get-Command clang-tidy -ErrorAction SilentlyContinue) {
# Only run clang-tidy if it's installed. This is because the package used by chocolatey on
# the build pipeline doesn't include clang-tidy, so we allow skipping that there and let
# the Linux build catch tidy issues.
$clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy"
}
} else {
Write-Host "##vso[task.logissue type=error;]Failed to identify the OS. Will use default CXX compiler"
}

cmake -G Ninja $clangTidy -D CMAKE_BUILD_TYPE="$Env:BUILD_CONFIGURATION" ../..
cmake --build . --target install
$qirRuntimeBuildFolder = (Join-Path $PSScriptRoot "build\$Env:BUILD_CONFIGURATION")
if (-not (Test-Path $qirRuntimeBuildFolder)) {
New-Item -Path $qirRuntimeBuildFolder -ItemType "directory"
}

Pop-Location
Push-Location $qirRuntimeBuildFolder

$env:CC = $oldCC
$env:CXX = $oldCXX
$env:RC = $oldRC
cmake -G Ninja $clangTidy -D CMAKE_BUILD_TYPE="$Env:BUILD_CONFIGURATION" ../..
if ($LastExitCode -ne 0) {
Write-Host "##vso[task.logissue type=error;]Failed to generate QIR Runtime."
}
cmake --build . --target install
if ($LastExitCode -ne 0) {
Write-Host "##vso[task.logissue type=error;]Failed to build QIR Runtime."
}

if ($LastExitCode -ne 0) {
Write-Host "##vso[task.logissue type=error;]Failed to build QIR Runtime."
}
} else {
Write-Host "To enable build of QIR Runtime set ENABLE_QIRRUNTIME environment variable to 'true'"
$os = "win32"
$pattern = "*.dll"
if ($IsMacOS) {
$os = "osx"
$pattern = "*.dylib"
} elseif ($IsLinux) {
$os = "linux"
$pattern = "*.so"
}
$osQirDropFolder = Join-Path $Env:DROPS_DIR QIR $os
if (!(Test-Path $osQirDropFolder)) {
New-Item -Path $osQirDropFolder -ItemType "directory"
}
Copy-Item (Join-Path . bin $pattern) $osQirDropFolder

Pop-Location

$env:CC = $oldCC
$env:CXX = $oldCXX
$env:RC = $oldRC
Loading