Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom operations sample #1995

Merged
merged 25 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0cbf87a
add custom measurements sample
orpuente-MS Oct 31, 2024
3eb81b5
Merge branch 'main' into oscarpuente/custom-measurements-sample
orpuente-MS Nov 18, 2024
8d57c34
add custom operations sample
orpuente-MS Nov 18, 2024
c0f9372
fix unit tests
orpuente-MS Nov 18, 2024
6574fa6
fix formatting
orpuente-MS Nov 18, 2024
fe56c36
use QIR compliant names
orpuente-MS Nov 18, 2024
5800eca
write the sample as a multifile project
orpuente-MS Nov 18, 2024
2a539bf
fix CNOT gate and BellPair comments
orpuente-MS Nov 19, 2024
6f9b55c
Fix CNOT
orpuente-MS Nov 19, 2024
c62aefc
Update samples/algorithms/MajoranaQubits/src/GateSet.qs
orpuente-MS Nov 19, 2024
d3c8464
simplify sample
orpuente-MS Nov 19, 2024
5bcdd2f
express PreparePlus in terms of Mx to stay within the measurements ba…
orpuente-MS Nov 19, 2024
4ee6d46
remove lints
orpuente-MS Nov 19, 2024
54ab66c
remove lints
orpuente-MS Nov 19, 2024
ac8ebf0
Show how the BellMeasurement can detect the four Bell states.
orpuente-MS Nov 19, 2024
c9a080c
improve comments of `BellPair` operation
orpuente-MS Nov 19, 2024
acc20fc
improve Bell Measurement docstring
orpuente-MS Nov 19, 2024
e4f4529
correct BellPair comment
orpuente-MS Nov 19, 2024
ac3ad41
more specific comment in BellPair preparation
orpuente-MS Nov 19, 2024
53f6ad1
use mathematical angular bracket in comment and docstring
orpuente-MS Nov 20, 2024
606aa39
Add Mz gate for simmetry
orpuente-MS Nov 22, 2024
7bd97f6
Rename `PreparePlus` to `PrepareX`
orpuente-MS Nov 22, 2024
a9a8fd3
fix Mz wrapper
orpuente-MS Nov 22, 2024
0d65c22
remove innacurate docstring sentence
orpuente-MS Nov 22, 2024
9434fdf
include `PrepareZ` for completness
orpuente-MS Nov 22, 2024
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
1 change: 1 addition & 0 deletions samples/algorithms/MajoranaQubits/qsharp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
71 changes: 71 additions & 0 deletions samples/algorithms/MajoranaQubits/src/GateSet.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/// A set of gates built upon the custom measurements
/// provided by the hardware provider.
///
/// Source:
/// [1] Surface code compilation via edge-disjoint paths
/// https://arxiv.org/pdf/2110.11493

/// Apply a CNOT gate to the given qubits.
/// Source: [1] Figure 3.
operation CNOT(control : Qubit, target : Qubit) : Unit {
// Prepare an ancilla qubit in the |+> state.
use ancilla = Qubit();
PreparePlus(ancilla);

let a = Mzz(control, ancilla);
let b = Mxx(ancilla, target);
let c = M(ancilla);
orpuente-MS marked this conversation as resolved.
Show resolved Hide resolved
Reset(ancilla);

if b == One {
Z(control);
}

if a != c {
X(target);
}
}


/// Prepare a qubit in the |+> state.
operation PreparePlus(q : Qubit) : Unit {
if Mx(q) == One {
Z(q);
}
}

/// Prepare a Bell Pair.
/// Source: [1] Figure 18a.
operation BellPair(q1 : Qubit, q2 : Qubit) : Unit {
// Collapse the qubits to the X basis.
orpuente-MS marked this conversation as resolved.
Show resolved Hide resolved
M(q1);
M(q2);

// If their parity is different, flip the second qubit.
if Mxx(q1, q2) == One {
Z(q2);
}
}

/// Measure a Bell Pair.
/// Source: [1] Figure 18b.
operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) {
let z = Mzz(q1, q2);
let x = Mxx(q1, q2);
(x, z)
}

/// User friendly wrapper around the Mx hardware gate.
operation Mx(q : Qubit) : Result {
HardwareIntrinsics.__quantum__qis__mx__body(q)
}

/// User friendly wrapper around the Mxx hardware gate.
operation Mxx(q1 : Qubit, q2 : Qubit) : Result {
HardwareIntrinsics.__quantum__qis__mxx__body(q1, q2)
}

/// User friendly wrapper around the Mzz hardware gate.
operation Mzz(q1 : Qubit, q2 : Qubit) : Result {
HardwareIntrinsics.__quantum__qis__mzz__body(q1, q2)
}
21 changes: 21 additions & 0 deletions samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// A set of custom measurements exposed from a hardware
/// provider using Majorana Qubits.

@Measurement()
@SimulatableIntrinsic()
operation __quantum__qis__mx__body(q : Qubit) : Result {
H(q);
M(q)
}

@Measurement()
@SimulatableIntrinsic()
operation __quantum__qis__mxx__body(q1 : Qubit, q2 : Qubit) : Result {
Std.Intrinsic.Measure([PauliX, PauliX], [q1, q2])
}

@Measurement()
@SimulatableIntrinsic()
operation __quantum__qis__mzz__body(q1 : Qubit, q2 : Qubit) : Result {
Std.Intrinsic.Measure([PauliZ, PauliZ], [q1, q2])
}
29 changes: 29 additions & 0 deletions samples/algorithms/MajoranaQubits/src/Main.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/// # Sample
/// Majorana Qubits
///
/// # Description
/// In hardware providing majorana qubits, common quantum operations
/// are implemented using measurements and Pauli corrections. This
/// sample shows a hypotetical hardware provider exposing some custom
/// gates to Q# and a small library built on top of it.

/// Sample program using custom gates from a hardware provider.
operation Main() : (Result, Result) {
use qs = Qubit[2];
GateSet.BellPair(qs[0], qs[1]);

// Applying X to any of the qubits will result in the (Zero, One) Bell state.
// X(qs[0]); // Uncomment to try

// Applying Z to any of the qubits will result in the (One, Zero) Bell state.
// Z(qs[0]); // Uncomment to try

// Applying X and Z to the pair will result in the (One, One) Bell state.
// Note they can be applied to the same Qubit.
// Z(qs[0]); // Uncomment to try
// X(qs[0]);

let res = GateSet.BellMeasurement(qs[0], qs[1]);
ResetAll(qs);
res
}
27 changes: 27 additions & 0 deletions samples/language/CustomMeasurements.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// # Sample
// Custom Operations
//
// # Description
// The @Measurement attribute in Q# allows you to define custom measurements
// that are lowered to QIR in the same way the `M` measurement in the standard
// library is lowered. That means an `"irreversible"` attribute is added to
// the callable declaration and the output results are moved to the paramaters
// and treated as result registers.
//
// # Who is this for?
// The target audience are library authors targeting specific hardware.

/// Try running the command `Q#: Get QIR for the current Q# program`
/// in VS-Code's Command Palette.
operation Main() : Result {
use q = Qubit();
H(q);
__quantum__qis__mx__body(q)
}

@Measurement()
@SimulatableIntrinsic()
operation __quantum__qis__mx__body(q : Qubit) : Result {
H(q);
M(q)
}
2 changes: 2 additions & 0 deletions samples_test/src/tests/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ pub const COPYANDUPDATEOPERATOR_EXPECT_DEBUG: Expect = expect![[r#"
Updated array: [10, 11, 100, 13]
Updated array: [10, 100, 12, 200]
()"#]];
pub const CUSTOMMEASUREMENTS_EXPECT: Expect = expect!["Zero"];
pub const CUSTOMMEASUREMENTS_EXPECT_DEBUG: Expect = expect!["Zero"];
orpuente-MS marked this conversation as resolved.
Show resolved Hide resolved
pub const DATATYPES_EXPECT: Expect = expect![[r#"
Binary BigInt: 42
Octal BigInt: 42
Expand Down
Loading