Skip to content

Commit

Permalink
Remove Refs to Microsoft.Quantum in Libraries (#2041)
Browse files Browse the repository at this point in the history
This removes the references to `Microsoft.Quantum` namespaces in the Q#
libraries and replaces them with references to `Std` namespaces. This
also changes many "See Also" references to links and adds logic to the
VS Code extension that supports those links.
  • Loading branch information
ScottCarda-MS authored Nov 21, 2024
1 parent 7d47bf9 commit 85eef3f
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 44 deletions.
3 changes: 1 addition & 2 deletions compiler/qsc_doc_gen/src/generate_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,10 +463,9 @@ fn generate_exported_file_content(
// Note: we are assuming the package kind does not change
let true_metadata = get_metadata(package_kind, true_ns.clone(), true_item, display)?;
let true_fqn = true_metadata.fully_qualified_name();
let name = true_metadata.name;

let summary = format!(
"This is an exported item. The actual definition is found here: [{name}](xref:Qdk.{true_fqn})"
"This is an exported item. The actual definition is found here: [{true_fqn}](xref:Qdk.{true_fqn})"
);

metadata.summary = summary.clone();
Expand Down
6 changes: 3 additions & 3 deletions compiler/qsc_doc_gen/src/generate_docs/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,21 +118,21 @@ fn redirect_generation() {
---
uid: Qdk.Microsoft.Quantum.Core.Length
title: Length exported item
description: "Q# Length exported item: This is an exported item. The actual definition is found here: [Length](xref:Qdk.Std.Core.Length)"
description: "Q# Length exported item: This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length)"
ms.date: {TIMESTAMP}
ms.topic: managed-reference
qsharp.kind: export
qsharp.package: __Std__
qsharp.namespace: Microsoft.Quantum.Core
qsharp.name: Length
qsharp.summary: "This is an exported item. The actual definition is found here: [Length](xref:Qdk.Std.Core.Length)"
qsharp.summary: "This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length)"
---
# Length exported item
Fully qualified name: Microsoft.Quantum.Core.Length
This is an exported item. The actual definition is found here: [Length](xref:Qdk.Std.Core.Length)
This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length)
"#]]
.assert_eq(full_contents.as_str());
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/qsc_partial_eval/src/tests/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,5 +602,5 @@ fn evaluation_error_within_stdlib_yield_correct_package_span() {
}
"#,
});
assert_error(&error, &expect!["UnexpectedDynamicValue(PackageSpan { package: PackageId(1), span: Span { lo: 13850, hi: 13865 } })"]);
assert_error(&error, &expect!["UnexpectedDynamicValue(PackageSpan { package: PackageId(1), span: Span { lo: 13910, hi: 13925 } })"]);
}
4 changes: 1 addition & 3 deletions library/std/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ Files in the library match the contained namespace. This makes it easier to find

Unless otherwise noted, callables that are defined as `body intrinsic` are generated into external declarations in QIR with exact callable name and signature matches. The containing namespace is not included in the generated name. This simplifies QIR code generation and makes correlating Q# declaration to the resulting QIR program easier. Body intrinsic callables should avoid using generics and aggregate types if possible to keep the corresponding LLVM signatures simple and increase the likelihood of hardware compatibility.

One notable exception to this is the `Microsoft.Quantum.Core.Length` function, which is both `body intrinsic` and generic across the array type. As a result, it needs special handling during monomorphization and code generation to correlate it to the right pattern for extracting length from the array structure. Open question: should this be transitioned to an operator or some other form that avoid such a prominent counterexample?

### QIR Quantum Gate Instructions

The library includes a set of one- and two-qubit gates represented as `__quantum__qis__*__body` or `__quantum__qis__*__adj` QIR declarations. The expectation is that these gates form a common QIR API surface that Q# is compiled into. Any target would either need to support these quantum gate instructions natively or provide a QIR definition of that gate instruction in terms of supported native gates. These definitions can then be linked with the QIR program via LLVM tools and resolve to the target specific gate set. This approach provides broader compatibility at the QIR level and avoids the need for front end language targetting; as a result, this Q# library design is not expected to require any target packages or operation substitution.
The library includes a set of one- and two-qubit gates represented as `__quantum__qis__*__body` or `__quantum__qis__*__adj` QIR declarations. The expectation is that these gates form a common QIR API surface that Q# is compiled into. Any target would either need to support these quantum gate instructions natively or provide a QIR definition of that gate instruction in terms of supported native gates. These definitions can then be linked with the QIR program via LLVM tools and resolve to the target specific gate set. This approach provides broader compatibility at the QIR level and avoids the need for front end language targeting; as a result, this Q# library design is not expected to require any target packages or operation substitution.

To avoid using any opaque array types in the quantum gate instruction set, the library utilizes decomposition strategies to express the Q# controlled specialization (which allows an arbitrary number of controls) in terms of singly- and doubly-controlled gates. While this makes simulation somewhat more expensive in terms of allocating extra controls and performing more operations, it more closely matches the patterns used by hardware and provides better API surface for QIR programs to have hardware compatibility.

Expand Down
24 changes: 12 additions & 12 deletions library/std/src/Std/Arrays.qs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ function CircularlyShifted<'T>(stepCount : Int, array : 'T[]) : 'T[] {
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Arrays.Transposed
/// - Microsoft.Quantum.Arrays.Diagonal
/// - [Std.Arrays.Transposed](xref:Qdk.Std.Arrays.Transposed)
/// - [Std.Arrays.Diagonal](xref:Qdk.Std.Arrays.Diagonal)
function ColumnAt<'T>(column : Int, matrix : 'T[][]) : 'T[] {
Fact(IsRectangularArray(matrix), "`matrix` is not a rectangular array");
mutable columnValues = [];
Expand Down Expand Up @@ -238,7 +238,7 @@ function Count<'T>(predicate : ('T -> Bool), array : 'T[]) : Int {
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Arrays.Transposed
/// - [Std.Arrays.Transposed](xref:Qdk.Std.Arrays.Transposed)
function Diagonal<'T>(matrix : 'T[][]) : 'T[] {
Fact(IsRectangularArray(matrix), "`matrix` is not a rectangular array");
let rows = Length(matrix);
Expand Down Expand Up @@ -274,7 +274,7 @@ function Diagonal<'T>(matrix : 'T[][]) : 'T[] {
/// The following samples an alternating array of results.
/// ```qsharp
/// use qubit = Qubit();
/// let results = Microsoft.Quantum.Arrays.DrawMany(q => {X(q); M(q)}, 3, qubit);
/// let results = Std.Arrays.DrawMany(q => {X(q); M(q)}, 3, qubit);
/// ```
operation DrawMany<'TInput, 'TOutput>(op : ('TInput => 'TOutput), nSamples : Int, input : 'TInput) : 'TOutput[] {
mutable outputs = [];
Expand Down Expand Up @@ -505,7 +505,7 @@ function Fold<'State, 'T>(folder : (('State, 'T) -> 'State), state : 'State, arr
/// An array `'U[]` of elements that are mapped by the `action` operation.
///
/// # See Also
/// - Microsoft.Quantum.Arrays.Mapped
/// - [Std.Arrays.Mapped](xref:Qdk.Std.Arrays.Mapped)
operation ForEach<'T, 'U>(action : ('T => 'U), array : 'T[]) : 'U[] {
mutable output = [];
for element in array {
Expand Down Expand Up @@ -686,7 +686,7 @@ function IsEmpty<'T>(array : 'T[]) : Bool {
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Arrays.IsSquareArray
/// - [Std.Arrays.IsSquareArray](xref:Qdk.Std.Arrays.IsSquareArray)
function IsRectangularArray<'T>(array : 'T[][]) : Bool {
if (Length(array) > 0) {
let columnCount = Length(Head(array));
Expand Down Expand Up @@ -754,7 +754,7 @@ function IsSorted<'T>(comparison : (('T, 'T) -> Bool), array : 'T[]) : Bool {
/// `true` if the array is square, `false` otherwise.
///
/// # See Also
/// - Microsoft.Quantum.Arrays.IsRectangularArray
/// - [Std.Arrays.IsRectangularArray](xref:Qdk.Std.Arrays.IsRectangularArray)
function IsSquareArray<'T>(array : 'T[][]) : Bool {
if (Length(array) > 0) {
let columnCount = Length(array);
Expand Down Expand Up @@ -789,7 +789,7 @@ function IsSquareArray<'T>(array : 'T[][]) : Bool {
/// An array `'U[]` of elements that are mapped by the `mapper` function.
///
/// # See Also
/// - Microsoft.Quantum.Arrays.ForEach
/// - [Std.Arrays.ForEach](xref:Qdk.Std.Arrays.ForEach)
function Mapped<'T, 'U>(mapper : ('T -> 'U), array : 'T[]) : 'U[] {
mutable mapped = [];
for element in array {
Expand Down Expand Up @@ -830,7 +830,7 @@ function Mapped<'T, 'U>(mapper : ('T -> 'U), array : 'T[]) : 'U[] {
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Arrays.Mapped
/// - [Std.Arrays.Mapped](xref:Qdk.Std.Arrays.Mapped)
function MappedByIndex<'T, 'U>(mapper : ((Int, 'T) -> 'U), array : 'T[]) : 'U[] {
mutable mapped = [];
for index in 0..Length(array) - 1 {
Expand Down Expand Up @@ -865,7 +865,7 @@ function MappedByIndex<'T, 'U>(mapper : ((Int, 'T) -> 'U), array : 'T[]) : 'U[]
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Arrays.Mapped
/// - [Std.Arrays.Mapped](xref:Qdk.Std.Arrays.Mapped)
function MappedOverRange<'T>(mapper : (Int -> 'T), range : Range) : 'T[] {
mutable output = [];
for element in range {
Expand Down Expand Up @@ -1320,7 +1320,7 @@ function Tail<'A>(array : 'A[]) : 'A {
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Arrays.Zipped
/// - [Std.Arrays.Zipped](xref:Qdk.Std.Arrays.Zipped)
function Unzipped<'T, 'U>(array : ('T, 'U)[]) : ('T[], 'U[]) {
mutable first = [];
mutable second = [];
Expand Down Expand Up @@ -1429,7 +1429,7 @@ function Windows<'T>(size : Int, array : 'T[]) : 'T[][] {
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Arrays.Unzipped
/// - [Std.Arrays.Unzipped](xref:Qdk.Std.Arrays.Unzipped)
function Zipped<'T, 'U>(left : 'T[], right : 'U[]) : ('T, 'U)[] {
let arrayLength = MinI(Length(left), Length(right));
mutable zipped = [];
Expand Down
6 changes: 3 additions & 3 deletions library/std/src/Std/Canon.qs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ operation ApplyToEach<'T>(singleElementOperation : ('T => Unit), register : 'T[]
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Canon.ApplyToEach
/// - [Std.Canon.ApplyToEach](xref:Qdk.Std.Canon.ApplyToEach)
operation ApplyToEachA<'T>(singleElementOperation : ('T => Unit is Adj), register : 'T[]) : Unit is Adj {
for item in register {
singleElementOperation(item);
Expand Down Expand Up @@ -83,7 +83,7 @@ operation ApplyToEachA<'T>(singleElementOperation : ('T => Unit is Adj), registe
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Canon.ApplyToEach
/// - [Std.Canon.ApplyToEach](xref:Qdk.Std.Canon.ApplyToEach)
operation ApplyToEachC<'T>(singleElementOperation : ('T => Unit is Ctl), register : 'T[]) : Unit is Ctl {
for item in register {
singleElementOperation(item);
Expand Down Expand Up @@ -112,7 +112,7 @@ operation ApplyToEachC<'T>(singleElementOperation : ('T => Unit is Ctl), registe
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Canon.ApplyToEach
/// - [Std.Canon.ApplyToEach](xref:Qdk.Std.Canon.ApplyToEach)
operation ApplyToEachCA<'T>(singleElementOperation : ('T => Unit is Adj + Ctl), register : 'T[]) : Unit is Adj + Ctl {
for item in register {
singleElementOperation(item);
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/Std/Intrinsic.qs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ operation R1(theta : Double, qubit : Qubit) : Unit is Adj + Ctl {
///
/// WARNING:
/// This operation uses the **opposite** sign convention from
/// Microsoft.Quantum.Intrinsic.R.
/// Std.Intrinsic.R.
///
/// # Input
/// ## numerator
Expand Down Expand Up @@ -523,7 +523,7 @@ operation ResetAll(qubits : Qubit[]) : Unit {
///
/// WARNING:
/// This operation uses the **opposite** sign convention from
/// Microsoft.Quantum.Intrinsic.R.
/// Std.Intrinsic.R.
///
/// # Input
/// ## pauli
Expand Down
26 changes: 13 additions & 13 deletions library/std/src/Std/Math.qs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Std.Diagnostics.*;
/// [Wikipedia article - Pi](https://en.wikipedia.org/wiki/Pi)
///
/// # See Also
/// - Microsoft.Quantum.Math.E
/// - [Std.Math.E](xref:Qdk.Std.Math.E)
function PI() : Double {
3.14159265358979323846
}
Expand All @@ -39,7 +39,7 @@ function PI() : Double {
/// [Wikipedia article - e](https://en.wikipedia.org/wiki/E_(mathematical_constant))
///
/// # See Also
/// - Microsoft.Quantum.Math.PI
/// - [Std.Math.PI](xref:Qdk.Std.Math.PI)
function E() : Double {
2.7182818284590452354
}
Expand Down Expand Up @@ -103,7 +103,7 @@ function IsNaN(d : Double) : Bool {
/// ```
///
/// # See Also
/// - Microsoft.Quantum.Math.IsNaN
/// - [Std.Math.IsNaN](xref:Qdk.Std.Math.IsNaN)
function IsInfinite(d : Double) : Bool {
return d == 1.0 / 0.0 or d == -1.0 / 0.0;
}
Expand Down Expand Up @@ -820,11 +820,11 @@ function HammingWeightI(n : Int) : Int {
/// The factorial of `n`.
///
/// # Remarks
/// For inputs greater than 20, please use `Microsoft.Quantum.Math.FactorialL`.
/// For inputs greater than 20, please use `Std.Math.FactorialL`.
///
/// # See Also
/// - Microsoft.Quantum.Math.FactorialL
/// - Microsoft.Quantum.Math.ApproximateFactorial
/// - [Std.Math.FactorialL](xref:Qdk.Std.Math.FactorialL)
/// - [Std.Math.ApproximateFactorial](xref:Qdk.Std.Math.ApproximateFactorial)
function FactorialI(n : Int) : Int {
Fact(n >= 0, "The factorial is not defined for negative inputs.");
Fact(n <= 20, "The largest factorial that can be stored as an Int is 20!. Use FactorialL or ApproximateFactorial.");
Expand Down Expand Up @@ -865,8 +865,8 @@ function FactorialI(n : Int) : Int {
/// The factorial of `n`.
///
/// # See Also
/// - Microsoft.Quantum.Math.FactorialI
/// - Microsoft.Quantum.Math.ApproximateFactorial
/// - [Std.Math.FactorialI](xref:Qdk.Std.Math.FactorialI)
/// - [Std.Math.ApproximateFactorial](xref:Qdk.Std.Math.ApproximateFactorial)
function FactorialL(n : Int) : BigInt {
Fact(n >= 0, "The factorial is not defined for negative inputs.");

Expand Down Expand Up @@ -896,8 +896,8 @@ function FactorialL(n : Int) : BigInt {
/// The approximate factorial of `n`.
///
/// # See Also
/// - Microsoft.Quantum.Math.FactorialI
/// - Microsoft.Quantum.Math.FactorialL
/// - [Std.Math.FactorialI](xref:Qdk.Std.Math.FactorialI)
/// - [Std.Math.FactorialL](xref:Qdk.Std.Math.FactorialL)
function ApproximateFactorial(n : Int) : Double {
Fact(n >= 0, "The factorial is not defined for negative inputs.");
Fact(n <= 169, "The largest approximate factorial that can be stored as a Double is 169!. Use FactorialL.");
Expand Down Expand Up @@ -979,9 +979,9 @@ function LogGammaD(x : Double) : Double {
/// The natural logarithm of the factorial of the provided input.
///
/// # See Also
/// - Microsoft.Quantum.Math.ApproximateFactorial
/// - Microsoft.Quantum.Math.FactorialI
/// - Microsoft.Quantum.Math.FactorialL
/// - [Std.Math.ApproximateFactorial](xref:Qdk.Std.Math.ApproximateFactorial)
/// - [Std.Math.FactorialI](xref:Qdk.Std.Math.FactorialI)
/// - [Std.Math.FactorialL](xref:Qdk.Std.Math.FactorialL)
function LogFactorialD(n : Int) : Double {
LogGammaD(IntAsDouble(n) + 1.0)
}
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/Std/Measurement.qs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ open QIR.Intrinsic;
/// The result of measuring in the `Z ⊗ Z ⊗ ••• ⊗ Z` basis.
///
/// # See also
/// - Microsoft.Quantum.Measurement.MeasureEachZ
/// - [Std.Measurement.MeasureEachZ](xref:Qdk.Std.Measurement.MeasureEachZ)
operation MeasureAllZ(register : Qubit[]) : Result {
Measure(Repeated(PauliZ, Length(register)), register)
}
Expand Down Expand Up @@ -54,8 +54,8 @@ operation MeasureAllZ(register : Qubit[]) : Result {
/// and returns one result. The operation does not reset the qubits.
///
/// # See also
/// - Microsoft.Quantum.Measurement.MeasureAllZ
/// - Microsoft.Quantum.Measurement.MResetEachZ
/// - [Std.Measurement.MeasureAllZ](xref:Qdk.Std.Measurement.MeasureAllZ)
/// - [Std.Measurement.MResetEachZ](xref:Qdk.Std.Measurement.MResetEachZ)
operation MeasureEachZ(register : Qubit[]) : Result[] {
mutable results = [];
for qubit in register {
Expand All @@ -76,7 +76,7 @@ operation MeasureEachZ(register : Qubit[]) : Result[] {
/// An array of measurement results.
///
/// # See also
/// - Microsoft.Quantum.Measurement.MeasureEachZ
/// - [Std.Measurement.MeasureEachZ](xref:Qdk.Std.Measurement.MeasureEachZ)
operation MResetEachZ(register : Qubit[]) : Result[] {
mutable results = [];
for qubit in register {
Expand Down
18 changes: 17 additions & 1 deletion vscode/src/webview/docview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@ function DocsPage(props: { fragmentsToRender: ItemDocs[] }) {
const [searchText, setSearchText] = useState("");

useEffect(() => {
// Update the xref links to navigate to the correct member
document.querySelectorAll('a[href^="xref:"]').forEach((a) => {
const anchor = a as HTMLAnchorElement;
const xref = "xref:";
let link = anchor.href.slice(xref.length);
link = link.replaceAll(".", "/");
// Just for Qdk links, we want to strip out the leading "Qdk."
if (link.startsWith("Qdk/")) {
link = link.slice(4);
}
a.addEventListener("click", (e) => {
e.preventDefault();
setPath(link);
});
});

// If the member is navigated to, scroll to it after rendering
const member = currPath.split("/")[2];
scrollToElement(member);
Expand All @@ -184,7 +200,7 @@ function DocsPage(props: { fragmentsToRender: ItemDocs[] }) {
? []
: getSearchResults(searchText, props.fragmentsToRender);

// Used to bold the text links when overing
// Used to bold the text links when hovering
function overLi(e: MouseEvent) {
(e.target as HTMLElement).style.fontWeight = "600";
(e.target as HTMLElement).style.textDecoration = "underline";
Expand Down

0 comments on commit 85eef3f

Please sign in to comment.