Verschillende manieren om de resource-estimator uit te voeren
In dit artikel leert u werken met de Azure Quantum Resource Estimator. De Resource Estimator is zowel beschikbaar in VS Code als online in Azure Portal.
In de volgende tabel ziet u de verschillende manieren om de Resource Estimator uit te voeren.
Gebruikersscenario | Platform | Zelfstudie |
---|---|---|
De resources van een Q#-programma schatten | Visual Studio Code | Selecteer Q# in VS Code bovenaan de pagina |
De resources van een Q#-programma schatten (geavanceerd) | Jupyter Notebook in Visual Studio Code | Selecteer Q# in Jupyter Notebook boven aan de pagina |
De resources van een Qiskit-programma schatten | Azure Quantum Portal | Selecteer Qiskit in Azure Portal bovenaan de pagina |
De resources van een QIR-programma schatten | Azure Quantum Portal | QIR verzenden |
FCIDUMP-bestanden gebruiken als argumentparameters (geavanceerd) | Visual Studio Code | Een probleem met kwantumchemie indienen |
Notitie
De Microsoft Quantum Development Kit (klassieke QDK) wordt na 30 juni 2024 niet meer ondersteund. Als u een bestaande QDK-ontwikkelaar bent, raden we u aan over te stappen op de nieuwe Azure Quantum Development Kit (Moderne QDK) om door te gaan met het ontwikkelen van kwantumoplossingen. Zie Uw Q#-code migreren naar de moderne QDK voor meer informatie.
Vereisten voor VS Code
- De nieuwste versie van Visual Studio Code of open VS Code op het web.
- De nieuwste versie van de Azure Quantum Development Kit-extensie . Zie Installing the Modern QDK on VS Code (De moderne QDK installeren op VS Code) voor installatiedetails.
Tip
U hoeft geen Azure-account te hebben om de lokale resource-estimator uit te voeren.
een nieuw Q#-bestand Creatie
- Open Visual Studio Code en selecteer Bestand > Nieuw tekstbestand om een nieuw bestand te maken.
- Sla het bestand op als
ShorRE.qs
. Dit bestand bevat de Q#-code voor uw programma.
het kwantumalgoritmen Creatie
Kopieer de volgende code naar het ShorRE.qs
bestand:
namespace Shors {
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Unstable.Arithmetic;
open Microsoft.Quantum.ResourceEstimation;
@EntryPoint()
operation RunProgram() : Unit {
let bitsize = 31;
// When chooseing parameters for `EstimateFrequency`, make sure that
// generator and modules are not co-prime
let _ = EstimateFrequency(11, 2^bitsize - 1, bitsize);
}
// In this sample we concentrate on costing the `EstimateFrequency`
// operation, which is the core quantum operation in Shors algorithm, and
// we omit the classical pre- and post-processing.
/// # Summary
/// Estimates the frequency of a generator
/// in the residue ring Z mod `modulus`.
///
/// # Input
/// ## generator
/// The unsigned integer multiplicative order (period)
/// of which is being estimated. Must be co-prime to `modulus`.
/// ## modulus
/// The modulus which defines the residue ring Z mod `modulus`
/// in which the multiplicative order of `generator` is being estimated.
/// ## bitsize
/// Number of bits needed to represent the modulus.
///
/// # Output
/// The numerator k of dyadic fraction k/2^bitsPrecision
/// approximating s/r.
operation EstimateFrequency(
generator : Int,
modulus : Int,
bitsize : Int
)
: Int {
mutable frequencyEstimate = 0;
let bitsPrecision = 2 * bitsize + 1;
// Allocate qubits for the superposition of eigenstates of
// the oracle that is used in period finding.
use eigenstateRegister = Qubit[bitsize];
// Initialize eigenstateRegister to 1, which is a superposition of
// the eigenstates we are estimating the phases of.
// We first interpret the register as encoding an unsigned integer
// in little endian encoding.
ApplyXorInPlace(1, eigenstateRegister);
let oracle = ApplyOrderFindingOracle(generator, modulus, _, _);
// Use phase estimation with a semiclassical Fourier transform to
// estimate the frequency.
use c = Qubit();
for idx in bitsPrecision - 1..-1..0 {
within {
H(c);
} apply {
// `BeginEstimateCaching` and `EndEstimateCaching` are the operations
// exposed by Azure Quantum Resource Estimator. These will instruct
// resource counting such that the if-block will be executed
// only once, its resources will be cached, and appended in
// every other iteration.
if BeginEstimateCaching("ControlledOracle", SingleVariant()) {
Controlled oracle([c], (1 <<< idx, eigenstateRegister));
EndEstimateCaching();
}
R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c);
}
if MResetZ(c) == One {
set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx);
}
}
// Return all the qubits used for oracles eigenstate back to 0 state
// using Microsoft.Quantum.Intrinsic.ResetAll.
ResetAll(eigenstateRegister);
return frequencyEstimate;
}
/// # Summary
/// Interprets `target` as encoding unsigned little-endian integer k
/// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where
/// p is `power`, g is `generator` and N is `modulus`.
///
/// # Input
/// ## generator
/// The unsigned integer multiplicative order ( period )
/// of which is being estimated. Must be co-prime to `modulus`.
/// ## modulus
/// The modulus which defines the residue ring Z mod `modulus`
/// in which the multiplicative order of `generator` is being estimated.
/// ## power
/// Power of `generator` by which `target` is multiplied.
/// ## target
/// Register interpreted as little endian encoded which is multiplied by
/// given power of the generator. The multiplication is performed modulo
/// `modulus`.
internal operation ApplyOrderFindingOracle(
generator : Int, modulus : Int, power : Int, target : Qubit[]
)
: Unit
is Adj + Ctl {
// The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We
// also use `ExpModI` to compute a by which x must be multiplied. Also
// note that we interpret target as unsigned integer in little-endian
// encoding.
ModularMultiplyByConstant(modulus,
ExpModI(generator, power, modulus),
target);
}
/// # Summary
/// Performs modular in-place multiplication by a classical constant.
///
/// # Description
/// Given the classical constants `c` and `modulus`, and an input
/// quantum register |𝑦⟩, this operation
/// computes `(c*x) % modulus` into |𝑦⟩.
///
/// # Input
/// ## modulus
/// Modulus to use for modular multiplication
/// ## c
/// Constant by which to multiply |𝑦⟩
/// ## y
/// Quantum register of target
internal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[])
: Unit is Adj + Ctl {
use qs = Qubit[Length(y)];
for (idx, yq) in Enumerated(y) {
let shiftedC = (c <<< idx) % modulus;
Controlled ModularAddConstant([yq], (modulus, shiftedC, qs));
}
ApplyToEachCA(SWAP, Zipped(y, qs));
let invC = InverseModI(c, modulus);
for (idx, yq) in Enumerated(y) {
let shiftedC = (invC <<< idx) % modulus;
Controlled ModularAddConstant([yq], (modulus, modulus - shiftedC, qs));
}
}
/// # Summary
/// Performs modular in-place addition of a classical constant into a
/// quantum register.
///
/// # Description
/// Given the classical constants `c` and `modulus`, and an input
/// quantum register |𝑦⟩, this operation
/// computes `(x+c) % modulus` into |𝑦⟩.
///
/// # Input
/// ## modulus
/// Modulus to use for modular addition
/// ## c
/// Constant to add to |𝑦⟩
/// ## y
/// Quantum register of target
internal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[])
: Unit is Adj + Ctl {
body (...) {
Controlled ModularAddConstant([], (modulus, c, y));
}
controlled (ctrls, ...) {
// We apply a custom strategy to control this operation instead of
// letting the compiler create the controlled variant for us in which
// the `Controlled` functor would be distributed over each operation
// in the body.
//
// Here we can use some scratch memory to save ensure that at most one
// control qubit is used for costly operations such as `AddConstant`
// and `CompareGreaterThenOrEqualConstant`.
if Length(ctrls) >= 2 {
use control = Qubit();
within {
Controlled X(ctrls, control);
} apply {
Controlled ModularAddConstant([control], (modulus, c, y));
}
} else {
use carry = Qubit();
Controlled AddConstant(ctrls, (c, y + [carry]));
Controlled Adjoint AddConstant(ctrls, (modulus, y + [carry]));
Controlled AddConstant([carry], (modulus, y));
Controlled CompareGreaterThanOrEqualConstant(ctrls, (c, y, carry));
}
}
}
/// # Summary
/// Performs in-place addition of a constant into a quantum register.
///
/// # Description
/// Given a non-empty quantum register |𝑦⟩ of length 𝑛+1 and a positive
/// constant 𝑐 < 2ⁿ, computes |𝑦 + c⟩ into |𝑦⟩.
///
/// # Input
/// ## c
/// Constant number to add to |𝑦⟩.
/// ## y
/// Quantum register of second summand and target; must not be empty.
internal operation AddConstant(c : Int, y : Qubit[]) : Unit is Adj + Ctl {
// We are using this version instead of the library version that is based
// on Fourier angles to show an advantage of sparse simulation in this sample.
let n = Length(y);
Fact(n > 0, "Bit width must be at least 1");
Fact(c >= 0, "constant must not be negative");
Fact(c < 2 ^ n, $"constant must be smaller than {2L ^ n}");
if c != 0 {
// If c has j trailing zeroes than the j least significant bits
// of y won't be affected by the addition and can therefore be
// ignored by applying the addition only to the other qubits and
// shifting c accordingly.
let j = NTrailingZeroes(c);
use x = Qubit[n - j];
within {
ApplyXorInPlace(c >>> j, x);
} apply {
IncByLE(x, y[j...]);
}
}
}
/// # Summary
/// Performs greater-than-or-equals comparison to a constant.
///
/// # Description
/// Toggles output qubit `target` if and only if input register `x`
/// is greater than or equal to `c`.
///
/// # Input
/// ## c
/// Constant value for comparison.
/// ## x
/// Quantum register to compare against.
/// ## target
/// Target qubit for comparison result.
///
/// # Reference
/// This construction is described in [Lemma 3, arXiv:2201.10200]
internal operation CompareGreaterThanOrEqualConstant(c : Int, x : Qubit[], target : Qubit)
: Unit is Adj+Ctl {
let bitWidth = Length(x);
if c == 0 {
X(target);
} elif c >= 2 ^ bitWidth {
// do nothing
} elif c == 2 ^ (bitWidth - 1) {
ApplyLowTCNOT(Tail(x), target);
} else {
// normalize constant
let l = NTrailingZeroes(c);
let cNormalized = c >>> l;
let xNormalized = x[l...];
let bitWidthNormalized = Length(xNormalized);
let gates = Rest(IntAsBoolArray(cNormalized, bitWidthNormalized));
use qs = Qubit[bitWidthNormalized - 1];
let cs1 = [Head(xNormalized)] + Most(qs);
let cs2 = Rest(xNormalized);
within {
for i in IndexRange(gates) {
(gates[i] ? ApplyAnd | ApplyOr)(cs1[i], cs2[i], qs[i]);
}
} apply {
ApplyLowTCNOT(Tail(qs), target);
}
}
}
/// # Summary
/// Internal operation used in the implementation of GreaterThanOrEqualConstant.
internal operation ApplyOr(control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj {
within {
ApplyToEachA(X, [control1, control2]);
} apply {
ApplyAnd(control1, control2, target);
X(target);
}
}
internal operation ApplyAnd(control1 : Qubit, control2 : Qubit, target : Qubit)
: Unit is Adj {
body (...) {
CCNOT(control1, control2, target);
}
adjoint (...) {
H(target);
if (M(target) == One) {
X(target);
CZ(control1, control2);
}
}
}
/// # Summary
/// Returns the number of trailing zeroes of a number
///
/// ## Example
/// ```qsharp
/// let zeroes = NTrailingZeroes(21); // = NTrailingZeroes(0b1101) = 0
/// let zeroes = NTrailingZeroes(20); // = NTrailingZeroes(0b1100) = 2
/// ```
internal function NTrailingZeroes(number : Int) : Int {
mutable nZeroes = 0;
mutable copy = number;
while (copy % 2 == 0) {
set nZeroes += 1;
set copy /= 2;
}
return nZeroes;
}
/// # Summary
/// An implementation for `CNOT` that when controlled using a single control uses
/// a helper qubit and uses `ApplyAnd` to reduce the T-count to 4 instead of 7.
internal operation ApplyLowTCNOT(a : Qubit, b : Qubit) : Unit is Adj+Ctl {
body (...) {
CNOT(a, b);
}
adjoint self;
controlled (ctls, ...) {
// In this application this operation is used in a way that
// it is controlled by at most one qubit.
Fact(Length(ctls) <= 1, "At most one control line allowed");
if IsEmpty(ctls) {
CNOT(a, b);
} else {
use q = Qubit();
within {
ApplyAnd(Head(ctls), a, q);
} apply {
CNOT(q, b);
}
}
}
controlled adjoint self;
}
}
De resource-estimator uitvoeren
De Resource Estimator biedt zes vooraf gedefinieerde qubitparameters, waarvan er vier op gate gebaseerde instructiesets hebben en twee met een Majorana-instructieset. Het biedt ook twee kwantumfoutcorrectiecodes, surface_code
en floquet_code
.
In dit voorbeeld voert u de Resource Estimator uit met behulp van de qubit_gate_us_e3
qubitparameter en de surface_code
kwantumfoutcorrectiecode.
Selecteer Weergave -> Opdrachtpalet en typ 'resource' om de optie Q#: Resourceschattingen berekenen weer te geven. U kunt ook klikken op Schatting in de lijst met opdrachten hieronder
@EntryPoint()
. Selecteer deze optie om het venster Resource Estimator te openen.U kunt een of meer codetypen qubitparameter + foutcorrectie selecteren om de resources voor te schatten. Selecteer voor dit voorbeeld qubit_gate_us_e3 en klik op OK.
Geef het foutbudget op of accepteer de standaardwaarde 0,001. Laat voor dit voorbeeld de standaardwaarde staan en druk op Enter.
Druk op Enter om de standaardresultaatnaam te accepteren op basis van de bestandsnaam, in dit geval ShorRE.
De resultaten bekijken
De Resource Estimator biedt meerdere schattingen voor hetzelfde algoritme, waarbij elk een balans laat zien tussen het aantal qubits en de runtime. Inzicht in de balans tussen runtime en systeemschaal is een van de belangrijkste aspecten van de schatting van resources.
Het resultaat van de resourceschatting wordt weergegeven in het venster Q#-schatting .
Op het tabblad Resultaten wordt een samenvatting van de resourceraming weergegeven. Klik op het pictogram naast de eerste rij om de kolommen te selecteren die u wilt weergeven. U kunt kiezen uit runnaam, schattingstype, qubittype, qec-schema, foutbudget, logische qubits, logische diepte, codeafstand, T-statussen, T-factory's, T factory-breuk, runtime, rQOPS en fysieke qubits.
In de kolom Schattingstype van de resultatentabel ziet u het aantal optimale combinaties van {aantal qubits, runtime} voor uw algoritme. Deze combinaties zijn te zien in het ruimte-tijddiagram.
In het diagram Ruimte-tijd ziet u de afwegingen tussen het aantal fysieke qubits en de runtime van het algoritme. In dit geval vindt de Resource Estimator 13 verschillende optimale combinaties van vele duizenden mogelijke. U kunt de muisaanwijzer op elk {aantal qubits, runtime} aanwijzen om de details van de resourceraming op dat punt te bekijken.
Zie Ruimtetijddiagram voor meer informatie.
Notitie
U moet op één punt van het ruimte-tijddiagram klikken, dat wil weten een {aantal qubits, runtime}-paar, om het ruimtediagram en de details van de resourceschatting voor dat punt te zien.
Het ruimtediagram toont de verdeling van fysieke qubits die worden gebruikt voor het algoritme en de T-factory's, die overeenkomen met een {aantal qubits, runtime} paar. Als u bijvoorbeeld het meest linkse punt in het ruimte-tijddiagram selecteert, is het aantal fysieke qubits dat nodig is om het algoritme uit te voeren 427726, 196686 waarvan algoritme-qubits en 231040 waarvan T factory-qubits zijn.
Ten slotte geeft het tabblad Resourceschattingen de volledige lijst met uitvoergegevens weer voor de Resource Estimator die overeenkomt met een {aantal qubits, runtime} paar. U kunt kostendetails controleren door de groepen samen te vouwen, die meer informatie bevatten. Selecteer bijvoorbeeld het meest linkse punt in het ruimte-tijddiagram en vouw de groep Logische qubitparameters samen.
Logische qubitparameter Waarde QEC-schema surface_code Codeafstand 21 Fysieke qubits 882 Logische cyclustijd 13 milisecs Foutfrequentie logische qubit 3.00E-13 Kruisingsvoorfactor 0.03 Drempelwaarde voor foutcorrectie 0,01 Formule voor logische cyclustijd (4 * twoQubitGateTime
+ 2 *oneQubitMeasurementTime
) *codeDistance
Formule voor fysieke qubits 2 * codeDistance
*codeDistance
Tip
Klik op Gedetailleerde rijen weergeven om de beschrijving van elke uitvoer van de rapportgegevens weer te geven.
Zie de volledige rapportgegevens van de Resource Estimator voor meer informatie.
target De parameters wijzigen
U kunt de kosten voor hetzelfde Q#-programma schatten met behulp van een ander qubittype, foutcorrectiecode en foutbudget. Open het venster Resource Estimator door Weergave -> Opdrachtpalet te selecteren en typ Q#: Calculate Resource Estimates
.
Selecteer een andere configuratie, bijvoorbeeld de op Majorana gebaseerde qubitparameter, qubit_maj_ns_e6
. Accepteer de standaardwaarde voor het foutbudget of voer een nieuwe in en druk op Enter. De Resource Estimator voert de schatting opnieuw uit met de nieuwe target parameters.
Zie Doelparameters voor de Resource Estimator voor meer informatie.
Meerdere configuraties van parameters uitvoeren
De Azure Quantum Resource Estimator kan meerdere configuraties van parameters uitvoeren en de resultaten van target de resourceraming vergelijken.
Selecteer Beeld -> Opdrachtpalet of druk op Ctrl+Shift+P en typ
Q#: Calculate Resource Estimates
.Selecteer qubit_gate_us_e3, qubit_gate_us_e4, qubit_maj_ns_e4 + floquet_code en qubit_maj_ns_e6 + floquet_code en klik op OK.
Accepteer de standaardwaarde voor het foutbudget 0,001 en druk op Enter.
Druk op Enter om het invoerbestand te accepteren, in dit geval ShorRE.qs.
In het geval van meerdere configuraties van parameters worden de resultaten weergegeven in verschillende rijen op het tabblad Resultaten .
Het diagram Ruimte-tijd toont de resultaten voor alle configuraties van parameters. In de eerste kolom van de resultatentabel wordt de legenda voor elke configuratie van parameters weergegeven. U kunt de muisaanwijzer over elk punt bewegen om de details van de resource-schatting op dat punt te bekijken.
Klik op een {aantal qubits, runtime} punt van het ruimte-tijddiagram om het bijbehorende ruimtediagram en de rapportgegevens weer te geven.
Vereisten voor Jupyter Notebook in VS Code
Een Python-omgeving met Python en Pip geïnstalleerd.
De nieuwste versie van Visual Studio Code of open VS Code op het web.
VS Code met de Azure Quantum Development Kit, Python en Jupyter-extensies geïnstalleerd.
De nieuwste Azure Quantum
qsharp
enqsharp-widgets
pakketten.python -m pip install --upgrade qsharp qsharp-widgets
Tip
U hoeft geen Azure-account te hebben om de lokale resource-estimator uit te voeren.
het kwantumalgoritmen Creatie
Selecteer in VS Code opdrachtpalet weergeven > en selecteer Creatie: Nieuwe Jupyter Notebook.
In de rechterbovenhoek detecteert VS Code de versie van Python en de virtuele Python-omgeving die voor het notebook is geselecteerd en geeft deze weer. Als u meerdere Python-omgevingen hebt, moet u mogelijk een kernel selecteren met behulp van de kernelkiezer in de rechterbovenhoek. Als er geen omgeving is gedetecteerd, raadpleegt u Jupyter Notebooks in VS Code voor installatie-informatie.
Importeer het pakket in de eerste cel van het
qsharp
notebook.import qsharp
Voeg een nieuwe cel toe en kopieer de volgende code.
%%qsharp open Microsoft.Quantum.Arrays; open Microsoft.Quantum.Canon; open Microsoft.Quantum.Convert; open Microsoft.Quantum.Diagnostics; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Math; open Microsoft.Quantum.Measurement; open Microsoft.Quantum.Unstable.Arithmetic; open Microsoft.Quantum.ResourceEstimation; operation RunProgram() : Unit { let bitsize = 31; // When choosing parameters for `EstimateFrequency`, make sure that // generator and modules are not co-prime let _ = EstimateFrequency(11, 2^bitsize - 1, bitsize); } // In this sample we concentrate on costing the `EstimateFrequency` // operation, which is the core quantum operation in Shors algorithm, and // we omit the classical pre- and post-processing. /// # Summary /// Estimates the frequency of a generator /// in the residue ring Z mod `modulus`. /// /// # Input /// ## generator /// The unsigned integer multiplicative order (period) /// of which is being estimated. Must be co-prime to `modulus`. /// ## modulus /// The modulus which defines the residue ring Z mod `modulus` /// in which the multiplicative order of `generator` is being estimated. /// ## bitsize /// Number of bits needed to represent the modulus. /// /// # Output /// The numerator k of dyadic fraction k/2^bitsPrecision /// approximating s/r. operation EstimateFrequency( generator : Int, modulus : Int, bitsize : Int ) : Int { mutable frequencyEstimate = 0; let bitsPrecision = 2 * bitsize + 1; // Allocate qubits for the superposition of eigenstates of // the oracle that is used in period finding. use eigenstateRegister = Qubit[bitsize]; // Initialize eigenstateRegister to 1, which is a superposition of // the eigenstates we are estimating the phases of. // We first interpret the register as encoding an unsigned integer // in little endian encoding. ApplyXorInPlace(1, eigenstateRegister); let oracle = ApplyOrderFindingOracle(generator, modulus, _, _); // Use phase estimation with a semiclassical Fourier transform to // estimate the frequency. use c = Qubit(); for idx in bitsPrecision - 1..-1..0 { within { H(c); } apply { // `BeginEstimateCaching` and `EndEstimateCaching` are the operations // exposed by Azure Quantum Resource Estimator. These will instruct // resource counting such that the if-block will be executed // only once, its resources will be cached, and appended in // every other iteration. if BeginEstimateCaching("ControlledOracle", SingleVariant()) { Controlled oracle([c], (1 <<< idx, eigenstateRegister)); EndEstimateCaching(); } R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c); } if MResetZ(c) == One { set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx); } } // Return all the qubits used for oracle eigenstate back to 0 state // using Microsoft.Quantum.Intrinsic.ResetAll. ResetAll(eigenstateRegister); return frequencyEstimate; } /// # Summary /// Interprets `target` as encoding unsigned little-endian integer k /// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where /// p is `power`, g is `generator` and N is `modulus`. /// /// # Input /// ## generator /// The unsigned integer multiplicative order ( period ) /// of which is being estimated. Must be co-prime to `modulus`. /// ## modulus /// The modulus which defines the residue ring Z mod `modulus` /// in which the multiplicative order of `generator` is being estimated. /// ## power /// Power of `generator` by which `target` is multiplied. /// ## target /// Register interpreted as little endian encoded which is multiplied by /// given power of the generator. The multiplication is performed modulo /// `modulus`. internal operation ApplyOrderFindingOracle( generator : Int, modulus : Int, power : Int, target : Qubit[] ) : Unit is Adj + Ctl { // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We // also use `ExpModI` to compute a by which x must be multiplied. Also // note that we interpret target as unsigned integer in little-endian // encoding. ModularMultiplyByConstant(modulus, ExpModI(generator, power, modulus), target); } /// # Summary /// Performs modular in-place multiplication by a classical constant. /// /// # Description /// Given the classical constants `c` and `modulus`, and an input /// quantum register |𝑦⟩, this operation /// computes `(c*x) % modulus` into |𝑦⟩. /// /// # Input /// ## modulus /// Modulus to use for modular multiplication /// ## c /// Constant by which to multiply |𝑦⟩ /// ## y /// Quantum register of target internal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl { use qs = Qubit[Length(y)]; for (idx, yq) in Enumerated(y) { let shiftedC = (c <<< idx) % modulus; Controlled ModularAddConstant([yq], (modulus, shiftedC, qs)); } ApplyToEachCA(SWAP, Zipped(y, qs)); let invC = InverseModI(c, modulus); for (idx, yq) in Enumerated(y) { let shiftedC = (invC <<< idx) % modulus; Controlled ModularAddConstant([yq], (modulus, modulus - shiftedC, qs)); } } /// # Summary /// Performs modular in-place addition of a classical constant into a /// quantum register. /// /// # Description /// Given the classical constants `c` and `modulus`, and an input /// quantum register |𝑦⟩, this operation /// computes `(x+c) % modulus` into |𝑦⟩. /// /// # Input /// ## modulus /// Modulus to use for modular addition /// ## c /// Constant to add to |𝑦⟩ /// ## y /// Quantum register of target internal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl { body (...) { Controlled ModularAddConstant([], (modulus, c, y)); } controlled (ctrls, ...) { // We apply a custom strategy to control this operation instead of // letting the compiler create the controlled variant for us in which // the `Controlled` functor would be distributed over each operation // in the body. // // Here we can use some scratch memory to save ensure that at most one // control qubit is used for costly operations such as `AddConstant` // and `CompareGreaterThenOrEqualConstant`. if Length(ctrls) >= 2 { use control = Qubit(); within { Controlled X(ctrls, control); } apply { Controlled ModularAddConstant([control], (modulus, c, y)); } } else { use carry = Qubit(); Controlled AddConstant(ctrls, (c, y + [carry])); Controlled Adjoint AddConstant(ctrls, (modulus, y + [carry])); Controlled AddConstant([carry], (modulus, y)); Controlled CompareGreaterThanOrEqualConstant(ctrls, (c, y, carry)); } } } /// # Summary /// Performs in-place addition of a constant into a quantum register. /// /// # Description /// Given a non-empty quantum register |𝑦⟩ of length 𝑛+1 and a positive /// constant 𝑐 < 2ⁿ, computes |𝑦 + c⟩ into |𝑦⟩. /// /// # Input /// ## c /// Constant number to add to |𝑦⟩. /// ## y /// Quantum register of second summand and target; must not be empty. internal operation AddConstant(c : Int, y : Qubit[]) : Unit is Adj + Ctl { // We are using this version instead of the library version that is based // on Fourier angles to show an advantage of sparse simulation in this sample. let n = Length(y); Fact(n > 0, "Bit width must be at least 1"); Fact(c >= 0, "constant must not be negative"); Fact(c < 2 ^ n, $"constant must be smaller than {2L ^ n}"); if c != 0 { // If c has j trailing zeroes than the j least significant bits // of y will not be affected by the addition and can therefore be // ignored by applying the addition only to the other qubits and // shifting c accordingly. let j = NTrailingZeroes(c); use x = Qubit[n - j]; within { ApplyXorInPlace(c >>> j, x); } apply { IncByLE(x, y[j...]); } } } /// # Summary /// Performs greater-than-or-equals comparison to a constant. /// /// # Description /// Toggles output qubit `target` if and only if input register `x` /// is greater than or equal to `c`. /// /// # Input /// ## c /// Constant value for comparison. /// ## x /// Quantum register to compare against. /// ## target /// Target qubit for comparison result. /// /// # Reference /// This construction is described in [Lemma 3, arXiv:2201.10200] internal operation CompareGreaterThanOrEqualConstant(c : Int, x : Qubit[], target : Qubit) : Unit is Adj+Ctl { let bitWidth = Length(x); if c == 0 { X(target); } elif c >= 2 ^ bitWidth { // do nothing } elif c == 2 ^ (bitWidth - 1) { ApplyLowTCNOT(Tail(x), target); } else { // normalize constant let l = NTrailingZeroes(c); let cNormalized = c >>> l; let xNormalized = x[l...]; let bitWidthNormalized = Length(xNormalized); let gates = Rest(IntAsBoolArray(cNormalized, bitWidthNormalized)); use qs = Qubit[bitWidthNormalized - 1]; let cs1 = [Head(xNormalized)] + Most(qs); let cs2 = Rest(xNormalized); within { for i in IndexRange(gates) { (gates[i] ? ApplyAnd | ApplyOr)(cs1[i], cs2[i], qs[i]); } } apply { ApplyLowTCNOT(Tail(qs), target); } } } /// # Summary /// Internal operation used in the implementation of GreaterThanOrEqualConstant. internal operation ApplyOr(control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj { within { ApplyToEachA(X, [control1, control2]); } apply { ApplyAnd(control1, control2, target); X(target); } } internal operation ApplyAnd(control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj { body (...) { CCNOT(control1, control2, target); } adjoint (...) { H(target); if (M(target) == One) { X(target); CZ(control1, control2); } } } /// # Summary /// Returns the number of trailing zeroes of a number /// /// ## Example /// ```qsharp /// let zeroes = NTrailingZeroes(21); // = NTrailingZeroes(0b1101) = 0 /// let zeroes = NTrailingZeroes(20); // = NTrailingZeroes(0b1100) = 2 /// ``` internal function NTrailingZeroes(number : Int) : Int { mutable nZeroes = 0; mutable copy = number; while (copy % 2 == 0) { set nZeroes += 1; set copy /= 2; } return nZeroes; } /// # Summary /// An implementation for `CNOT` that when controlled using a single control uses /// a helper qubit and uses `ApplyAnd` to reduce the T-count to 4 instead of 7. internal operation ApplyLowTCNOT(a : Qubit, b : Qubit) : Unit is Adj+Ctl { body (...) { CNOT(a, b); } adjoint self; controlled (ctls, ...) { // In this application this operation is used in a way that // it is controlled by at most one qubit. Fact(Length(ctls) <= 1, "At most one control line allowed"); if IsEmpty(ctls) { CNOT(a, b); } else { use q = Qubit(); within { ApplyAnd(Head(ctls), a, q); } apply { CNOT(q, b); } } } controlled adjoint self; }
Het kwantumalgoritmen schatten
U maakt nu een schatting van de fysieke resources voor de RunProgram
bewerking met behulp van de standaardveronderstellingen. Voeg een nieuwe cel toe en kopieer de volgende code.
result = qsharp.estimate("RunProgram()")
result
Met de qsharp.estimate
functie wordt een resultaatobject gemaakt, dat kan worden gebruikt om een tabel weer te geven met het totale aantal fysieke resources. U kunt kostendetails controleren door de groepen samen te vouwen, die meer informatie bevatten. Zie de volledige rapportgegevens van de Resource Estimator voor meer informatie.
Vouw bijvoorbeeld de groep Logische qubitparameters samen om te zien dat de codeafstand 21 is en het aantal fysieke qubits 882.
Logische qubitparameter | Waarde |
---|---|
QEC-schema | surface_code |
Codeafstand | 21 |
Fysieke qubits | 882 |
Logische cyclustijd | 8 milisecs |
Foutfrequentie logische qubit | 3.00E-13 |
Kruisingsvoorfactor | 0.03 |
Drempelwaarde voor foutcorrectie | 0,01 |
Formule voor logische cyclustijd | (4 * twoQubitGateTime + 2 * oneQubitMeasurementTime ) * codeDistance |
Formule voor fysieke qubits | 2 * codeDistance * codeDistance |
Tip
Voor een compactere versie van de uitvoertabel kunt u gebruiken result.summary
.
Ruimtediagram
De distributie van fysieke qubits die worden gebruikt voor het algoritme en de T-factory's is een factor die van invloed kan zijn op het ontwerp van uw algoritme. U kunt het qsharp-widgets
pakket gebruiken om deze distributie te visualiseren om meer inzicht te krijgen in de geschatte ruimtevereisten voor het algoritme.
from qsharp-widgets import SpaceChart, EstimateDetails
SpaceChart(result)
In dit voorbeeld is het aantal fysieke qubits dat nodig is om het algoritme uit te voeren 829766, waarvan 196686 algoritme-qubits zijn en 633080 waarvan T-factory-qubits.
De standaardwaarden wijzigen en het algoritme schatten
Wanneer u een aanvraag voor een resourceschatting voor uw programma indient, kunt u enkele optionele parameters opgeven. Gebruik het jobParams
veld voor toegang tot alle target parameters die kunnen worden doorgegeven aan de taakuitvoering en bekijk welke standaardwaarden zijn aangenomen:
result['jobParams']
{'errorBudget': 0.001,
'qecScheme': {'crossingPrefactor': 0.03,
'errorCorrectionThreshold': 0.01,
'logicalCycleTime': '(4 * twoQubitGateTime + 2 * oneQubitMeasurementTime) * codeDistance',
'name': 'surface_code',
'physicalQubitsPerLogicalQubit': '2 * codeDistance * codeDistance'},
'qubitParams': {'instructionSet': 'GateBased',
'name': 'qubit_gate_ns_e3',
'oneQubitGateErrorRate': 0.001,
'oneQubitGateTime': '50 ns',
'oneQubitMeasurementErrorRate': 0.001,
'oneQubitMeasurementTime': '100 ns',
'tGateErrorRate': 0.001,
'tGateTime': '50 ns',
'twoQubitGateErrorRate': 0.001,
'twoQubitGateTime': '50 ns'}}
U kunt zien dat de Resource Estimator het qubit_gate_ns_e3
qubitmodel, de surface_code
foutcorrectiecode en het foutbudget 0,001 als standaardwaarden voor de schatting gebruikt.
Dit zijn de target parameters die kunnen worden aangepast:
errorBudget
- het totale toegestane foutbudget voor het algoritmeqecScheme
- het schema voor kwantumfoutcorrectie (QEC)qubitParams
- de fysieke qubitparametersconstraints
- de beperkingen op onderdeelniveaudistillationUnitSpecifications
- de specificaties voor de distillatiealgoritmen van de T-fabriekenestimateType
- enkel of grens
Zie Doelparameters voor de Resource Estimator voor meer informatie.
Qubitmodel wijzigen
U kunt de kosten voor hetzelfde algoritme schatten met behulp van de op Majorana gebaseerde qubitparameter , qubitParams
'qubit_maj_ns_e6'.
result_maj = qsharp.estimate("RunProgram()", params={
"qubitParams": {
"name": "qubit_maj_ns_e6"
}})
EstimateDetails(result_maj)
Correctieschema voor kwantumfouten wijzigen
U kunt de resourceschattingstaak voor hetzelfde voorbeeld opnieuw uitvoeren op de op Majorana gebaseerde qubitparameters met een floqued QEC-schema, qecScheme
.
result_maj = qsharp.estimate("RunProgram()", params={
"qubitParams": {
"name": "qubit_maj_ns_e6"
},
"qecScheme": {
"name": "floquet_code"
}})
EstimateDetails(result_maj)
Foutbudget wijzigen
Voer vervolgens hetzelfde kwantumcircuit opnieuw uit met een errorBudget
van 10%.
result_maj = qsharp.estimate("RunProgram()", params={
"qubitParams": {
"name": "qubit_maj_ns_e6"
},
"qecScheme": {
"name": "floquet_code"
},
"errorBudget": 0.1})
EstimateDetails(result_maj)
Batchverwerking met de resource-estimator
Met de Azure Quantum Resource Estimator kunt u meerdere configuraties van target parameters uitvoeren en de resultaten vergelijken. Dit is handig wanneer u de kosten van verschillende qubitmodellen, QEC-schema's of foutbudgetten wilt vergelijken.
U kunt een batchschatting uitvoeren door een lijst met target parameters door te geven aan de
params
parameter van deqsharp.estimate
functie. Voer bijvoorbeeld hetzelfde algoritme uit met de standaardparameters en de qubitparameters op basis van Majorana met een floqued QEC-schema.result_batch = qsharp.estimate("RunProgram()", params= [{}, # Default parameters { "qubitParams": { "name": "qubit_maj_ns_e6" }, "qecScheme": { "name": "floquet_code" } }]) result_batch.summary_data_frame(labels=["Gate-based ns, 10⁻³", "Majorana ns, 10⁻⁶"])
Model Logische qubits Logische diepte T-statussen Codeafstand T factory's T fabrieksfractie Fysieke qubits rQOPS Fysieke runtime Poort-gebaseerde ns, 10⁻³ 223 3,64 miljoen 4,70m 21 19 76.30 % 829,77k 26,55 min. 31 seconden Majorana ns, 10⁻⁶ 223 3,64 miljoen 4,70m 5 19 63.02 % 79,60k 148,67M 5 seconden U kunt ook een lijst met schattingsparameters maken met behulp van de
EstimatorParams
klasse .from qsharp.estimator import EstimatorParams, QubitParams, QECScheme, LogicalCounts labels = ["Gate-based µs, 10⁻³", "Gate-based µs, 10⁻⁴", "Gate-based ns, 10⁻³", "Gate-based ns, 10⁻⁴", "Majorana ns, 10⁻⁴", "Majorana ns, 10⁻⁶"] params = EstimatorParams(num_items=6) params.error_budget = 0.333 params.items[0].qubit_params.name = QubitParams.GATE_US_E3 params.items[1].qubit_params.name = QubitParams.GATE_US_E4 params.items[2].qubit_params.name = QubitParams.GATE_NS_E3 params.items[3].qubit_params.name = QubitParams.GATE_NS_E4 params.items[4].qubit_params.name = QubitParams.MAJ_NS_E4 params.items[4].qec_scheme.name = QECScheme.FLOQUET_CODE params.items[5].qubit_params.name = QubitParams.MAJ_NS_E6 params.items[5].qec_scheme.name = QECScheme.FLOQUET_CODE
qsharp.estimate("RunProgram()", params=params).summary_data_frame(labels=labels)
Model Logische qubits Logische diepte T-statussen Codeafstand T factory's T-fabrieksfractie Fysieke qubits rQOPS Fysieke runtime Poortgebaseerde μs, 10⁻³ 223 3,64m 4,70m 17 13 40.54 % 216,77k 21,86k 10 uur Poortgebaseerde μs, 10⁻⁴ 223 3,64 miljoen 4,70m 9 14 43.17 % 63,57k 41,30k 5 uur Poort-gebaseerde ns, 10⁻³ 223 3,64m 4,70m 17 16 69.08 % 416,89k 32,79 miljoen 25 seconden Op poort gebaseerde ns, 10⁻⁴ 223 3,64m 4,70m 9 14 43.17 % 63,57k 61,94 miljoen 13 seconden Majorana ns, 10⁻⁴ 223 3,64m 4,70m 9 19 82.75 % 501,48k 82,59 min. 10 seconden Majorana ns, 10⁻⁶ 223 3,64m 4,70m 5 13 31.47 % 42,96k 148,67M 5 seconden
Pareto grensschatting uitvoeren
Bij het schatten van de resources van een algoritme is het belangrijk om rekening te houden met de afweging tussen het aantal fysieke qubits en de runtime van het algoritme. U kunt overwegen om zoveel mogelijk fysieke qubits toe te passen om de runtime van het algoritme te verminderen. Het aantal fysieke qubits wordt echter beperkt door het aantal fysieke qubits dat beschikbaar is in de kwantumhardware.
De Pareto frontier-schatting biedt meerdere schattingen voor hetzelfde algoritme, elk met een afweging tussen het aantal qubits en de runtime.
Als u de resource-estimator wilt uitvoeren met behulp van pareto-grensschatting, moet u de
"estimateType"
target parameter opgeven als"frontier"
. Voer bijvoorbeeld hetzelfde algoritme uit met de op Majorana gebaseerde qubitparameters met een surface-code met behulp van Pareto frontier-schatting.result = qsharp.estimate("RunProgram()", params= {"qubitParams": { "name": "qubit_maj_ns_e4" }, "qecScheme": { "name": "surface_code" }, "estimateType": "frontier", # frontier estimation } )
U kunt de
EstimatesOverview
functie gebruiken om een tabel weer te geven met het totale aantal fysieke resources. Klik op het pictogram naast de eerste rij om de kolommen te selecteren die u wilt weergeven. U kunt kiezen uit runnaam, schattingstype, qubittype, qec-schema, foutbudget, logische qubits, logische diepte, codeafstand, T-statussen, T-factory's, T factory-breuk, runtime, rQOPS en fysieke qubits.from qsharp_widgets import EstimatesOverview EstimatesOverview(result)
In de kolom Schattingstype van de resultatentabel ziet u het aantal verschillende combinaties van {aantal qubits, runtime} voor uw algoritme. In dit geval vindt de resource-estimator 22 verschillende optimale combinaties van vele duizenden mogelijke.
Ruimte-tijddiagram
Met de EstimatesOverview
functie wordt ook het ruimte-tijddiagram van de resource-estimator weergegeven.
Het ruimte-tijddiagram toont het aantal fysieke qubits en de runtime van het algoritme voor elk {aantal qubits, runtime}-paar. U kunt de muisaanwijzer over elk punt bewegen om de details van de resourceschatting op dat moment te bekijken.
Batchverwerking met pareto grensschatting
Als u meerdere configuraties van target parameters wilt schatten en vergelijken met grensschatting, voegt u toe
"estimateType": "frontier",
aan de parameters.result = qsharp.estimate( "RunProgram()", [ { "qubitParams": { "name": "qubit_maj_ns_e4" }, "qecScheme": { "name": "surface_code" }, "estimateType": "frontier", # Pareto frontier estimation }, { "qubitParams": { "name": "qubit_maj_ns_e6" }, "qecScheme": { "name": "floquet_code" }, "estimateType": "frontier", # Pareto frontier estimation }, ] ) EstimatesOverview(result, colors=["#1f77b4", "#ff7f0e"], runNames=["e4 Surface Code", "e6 Floquet Code"])
Notitie
U kunt kleuren definiëren en namen uitvoeren voor het qubit-tijddiagram met behulp van de
EstimatesOverview
functie.Wanneer u meerdere configuraties van parameters uitvoert met behulp van target de Pareto frontier-schatting, kunt u de resourceschattingen zien voor een specifiek punt van het ruimte-tijddiagram, dat wil gezegd voor elk {aantal qubits, runtime} paar. In de volgende code ziet u bijvoorbeeld de geschatte details van het gebruik voor de tweede uitvoering (schatting van index=0) en de vierde (puntindex=3) kortste runtime.
EstimateDetails(result[1], 4)
U kunt ook het ruimtediagram voor een specifiek punt van het ruimtetijddiagram bekijken. De volgende code toont bijvoorbeeld het ruimtediagram voor de eerste uitvoering van combinaties (schatting van index=0) en de op twee na kortste runtime (puntindex=2).
SpaceChart(result[0], 2)
Vereisten voor Qiskit
- Een Azure-account met een actief abonnement. Als u geen Azure-account hebt, registreert u zich gratis en meldt u zich aan voor een abonnement op basis van betalen per gebruik.
- Een Azure Quantum-werkruimte. Zie een Azure Quantum-werkruimte Creatie voor meer informatie.
De Azure Quantum Resource Estimator target inschakelen in uw werkruimte
De Resource Estimator is een target van de Microsoft Quantum Computing-provider. Als u een werkruimte hebt gemaakt sinds de release van de Resource Estimator, is de Microsoft Quantum Computing-provider automatisch toegevoegd aan uw werkruimte.
Als u een bestaande Azure Quantum-werkruimte gebruikt:
- Open uw werkruimte in de Azure Portal.
- Selecteer in het linkerdeelvenster onder Bewerkingen de optie Providers.
- Selecteer + Een provider toevoegen.
- Selecteer + Toevoegen voor Microsoft Quantum Computing.
- Selecteer Learn & Develop en selecteer Add.
een nieuw notitieblok in uw werkruimte Creatie
- Meld u aan bij de Azure Portal en selecteer uw Azure Quantum-werkruimte.
- Selecteer onder Bewerkingen de optie Notebooks
- Klik op Mijn notitieblokken en klik op Nieuwe toevoegen
- Selecteer in Kerneltypede optie IPython.
- Typ een naam voor het bestand en klik op Creatie bestand.
Wanneer uw nieuwe notitieblok wordt geopend, wordt automatisch de code voor de eerste cel gemaakt op basis van uw abonnement en werkruimtegegevens.
from azure.quantum import Workspace
workspace = Workspace (
resource_id = "", # Your resource_id
location = "" # Your workspace location (for example, "westus")
)
Notitie
Tenzij anders vermeld, moet u elke cel tijdens het maken in de juiste volgorde uitvoeren om compilatieproblemen te voorkomen.
Klik op het driehoekige pictogram 'afspelen' links van de cel om de code uit te voeren.
De vereiste importbewerkingen laden
Eerst moet u extra modules importeren uit azure-quantum en qiskit
.
Klik op + Code om een nieuwe cel toe te voegen en voeg vervolgens de volgende code toe en voer deze uit:
from azure.quantum.qiskit import AzureQuantumProvider
from qiskit import QuantumCircuit, transpile
from qiskit.circuit.library import RGQFTMultiplier
Verbinding maken met de Azure Quantum-service
Maak vervolgens een AzureQuantumProvider-object met behulp van het workspace
object uit de vorige cel om verbinding te maken met uw Azure Quantum-werkruimte. U maakt een back-endexemplaar en stelt de Resource Estimator in als uw target.
provider = AzureQuantumProvider(workspace)
backend = provider.get_backend('microsoft.estimator')
het kwantumalgoritmen Creatie
In dit voorbeeld maakt u een kwantumcircuit voor een vermenigvuldigingsfunctie op basis van de constructie die wordt weergegeven inÉs-Perez en Garcia-Escartin (arXiv:1411.5949), waarbij de Quantum Fourier-transformatie wordt gebruikt om rekenkundige berekeningen te implementeren.
U kunt de grootte van de vermenigvuldiger aanpassen door de bitwidth
variabele te wijzigen. Het genereren van het circuit wordt verpakt in een functie die kan worden aangeroepen met de bitwidth
waarde van de vermenigvuldiger. De bewerking heeft twee invoerregisters, elk de grootte van de opgegeven bitwidth
, en één uitvoerregister dat tweemaal zo groot is als de opgegeven bitwidth
. Met de functie worden ook enkele logische resourcetellingen afgedrukt voor de vermenigvuldigingsfunctie die rechtstreeks uit het kwantumcircuit is geëxtraheerd.
def create_algorithm(bitwidth):
print(f"[INFO] Create a QFT-based multiplier with bitwidth {bitwidth}")
# Print a warning for large bitwidths that will require some time to generate and
# transpile the circuit.
if bitwidth > 18:
print(f"[WARN] It will take more than one minute generate a quantum circuit with a bitwidth larger than 18")
circ = RGQFTMultiplier(num_state_qubits=bitwidth, num_result_qubits=2 * bitwidth)
# One could further reduce the resource estimates by increasing the optimization_level,
# however, this will also increase the runtime to construct the algorithm. Note, that
# it does not affect the runtime for resource estimation.
print(f"[INFO] Decompose circuit into intrinsic quantum operations")
circ = transpile(circ, basis_gates=SUPPORTED_INSTRUCTIONS, optimization_level=0)
# print some statistics
print(f"[INFO] qubit count: {circ.num_qubits}")
print("[INFO] gate counts")
for gate, count in circ.count_ops().items():
print(f"[INFO] - {gate}: {count}")
return circ
Notitie
U kunt schattingstaken voor fysieke resources indienen voor algoritmen die geen T-status hebben, maar die ten minste één meting hebben.
Het kwantumalgoritmen schatten
Creatie een exemplaar van uw algoritme met behulp van de create_algorithm
functie. U kunt de grootte van de vermenigvuldiger aanpassen door de bitwidth
variabele te wijzigen.
bitwidth = 4
circ = create_algorithm(bitwidth)
Maak een schatting van de fysieke resources voor deze bewerking met behulp van de standaardveronderstellingen. U kunt het circuit verzenden naar de resource-schattingsback-end met behulp van de run
methode en vervolgens uitvoeren job.result()
om te wachten tot de taak is voltooid en de resultaten retourneert.
job = backend.run(circ)
result = job.result()
result
Hiermee maakt u een tabel met het totale aantal fysieke resources. U kunt kostendetails controleren door de groepen samen te vouwen, die meer informatie bevatten.
Tip
Voor een compactere versie van de uitvoertabel kunt u gebruiken result.summary
.
Als u bijvoorbeeld de parametergroep Logische qubit samenvouwt, kunt u gemakkelijker zien dat de afstand van de foutcode 15 is.
Parameter logische qubit | Waarde |
---|---|
QEC-schema | surface_code |
Codeafstand | 15 |
Fysieke qubits | 450 |
Logische cyclustijd | 6us |
Foutfrequentie logische qubit | 3.00E-10 |
Kruisingsvoorfactor | 0.03 |
Drempelwaarde voor foutcorrectie | 0,01 |
Formule voor logische cyclustijd | (4 * twoQubitGateTime + 2 * oneQubitMeasurementTime ) * codeDistance |
Formule voor fysieke qubits | 2 * codeDistance * codeDistance |
In de groep Fysieke qubitparameters ziet u de fysieke qubiteigenschappen die voor deze schatting zijn uitgegaan. De tijd voor het uitvoeren van een meting met één qubit en een poort met één qubit wordt bijvoorbeeld uitgegaan van respectievelijk 100 ns en 50 ns.
Tip
U kunt de uitvoer van de Resource Estimator ook openen als een Python-woordenlijst met behulp van de methode result.data().
Zie de volledige lijst met uitvoergegevens voor de resource-estimator voor meer informatie.
Ruimtediagrammen
De distributie van fysieke qubits die worden gebruikt voor het algoritme en de T-factory's is een factor die van invloed kan zijn op het ontwerp van uw algoritme. U kunt deze distributie visualiseren om meer inzicht te krijgen in de geschatte ruimtevereisten voor het algoritme.
result.diagram.space
In het ruimtediagram ziet u het aandeel algoritme-qubits en T-factory-qubits. Merk op dat het aantal T-factory-kopieën, 28, bijdraagt aan het aantal fysieke qubits voor T-factory's als $\text{T factorys} \cdot \text{fysieke qubit per T-factory}= 28 \cdot 18.000 = 504.000$.
Zie Fysieke schatting van de T-fabriek voor meer informatie.
De standaardwaarden wijzigen en het algoritme schatten
Wanneer u een aanvraag voor een resourceschatting voor uw programma indient, kunt u enkele optionele parameters opgeven. Gebruik het jobParams
veld om toegang te krijgen tot alle waarden die kunnen worden doorgegeven aan de taakuitvoering en om te zien welke standaardwaarden zijn aangenomen:
result.data()["jobParams"]
{'errorBudget': 0.001,
'qecScheme': {'crossingPrefactor': 0.03,
'errorCorrectionThreshold': 0.01,
'logicalCycleTime': '(4 * twoQubitGateTime + 2 * oneQubitMeasurementTime) * codeDistance',
'name': 'surface_code',
'physicalQubitsPerLogicalQubit': '2 * codeDistance * codeDistance'},
'qubitParams': {'instructionSet': 'GateBased',
'name': 'qubit_gate_ns_e3',
'oneQubitGateErrorRate': 0.001,
'oneQubitGateTime': '50 ns',
'oneQubitMeasurementErrorRate': 0.001,
'oneQubitMeasurementTime': '100 ns',
'tGateErrorRate': 0.001,
'tGateTime': '50 ns',
'twoQubitGateErrorRate': 0.001,
'twoQubitGateTime': '50 ns'}}
Dit zijn de target parameters die kunnen worden aangepast:
errorBudget
- het totale toegestane foutbudgetqecScheme
- het kwantumfoutcorrectieschema (QEC)qubitParams
- de fysieke qubitparametersconstraints
- de beperkingen op onderdeelniveaudistillationUnitSpecifications
- de specificaties voor de distillatiealgoritmen van de T-fabrieken
Zie Doelparameters voor de resource-estimator voor meer informatie.
Qubitmodel wijzigen
Maak vervolgens een schatting van de kosten voor hetzelfde algoritme met behulp van de op Majorana gebaseerde qubitparameter qubit_maj_ns_e6
job = backend.run(circ,
qubitParams={
"name": "qubit_maj_ns_e6"
})
result = job.result()
result
U kunt de fysieke aantallen programmatisch inspecteren. U kunt bijvoorbeeld details verkennen over de T-factory die is gemaakt om het algoritme uit te voeren.
result.data()["tfactory"]
{'eccDistancePerRound': [1, 1, 5],
'logicalErrorRate': 1.6833177305222897e-10,
'moduleNamePerRound': ['15-to-1 space efficient physical',
'15-to-1 RM prep physical',
'15-to-1 RM prep logical'],
'numInputTstates': 20520,
'numModulesPerRound': [1368, 20, 1],
'numRounds': 3,
'numTstates': 1,
'physicalQubits': 16416,
'physicalQubitsPerRound': [12, 31, 1550],
'runtime': 116900.0,
'runtimePerRound': [4500.0, 2400.0, 110000.0]}
Notitie
Runtime wordt standaard weergegeven in nanoseconden.
U kunt deze gegevens gebruiken om uitleg te geven over hoe de T-factory's de vereiste T-statussen produceren.
data = result.data()
tfactory = data["tfactory"]
breakdown = data["physicalCounts"]["breakdown"]
producedTstates = breakdown["numTfactories"] * breakdown["numTfactoryRuns"] * tfactory["numTstates"]
print(f"""A single T factory produces {tfactory["logicalErrorRate"]:.2e} T states with an error rate of (required T state error rate is {breakdown["requiredLogicalTstateErrorRate"]:.2e}).""")
print(f"""{breakdown["numTfactories"]} copie(s) of a T factory are executed {breakdown["numTfactoryRuns"]} time(s) to produce {producedTstates} T states ({breakdown["numTstates"]} are required by the algorithm).""")
print(f"""A single T factory is composed of {tfactory["numRounds"]} rounds of distillation:""")
for round in range(tfactory["numRounds"]):
print(f"""- {tfactory["numModulesPerRound"][round]} {tfactory["moduleNamePerRound"][round]} unit(s)""")
A single T factory produces 1.68e-10 T states with an error rate of (required T state error rate is 2.77e-08).
23 copies of a T factory are executed 523 time(s) to produce 12029 T states (12017 are required by the algorithm).
A single T factory is composed of 3 rounds of distillation:
- 1368 15-to-1 space efficient physical unit(s)
- 20 15-to-1 RM prep physical unit(s)
- 1 15-to-1 RM prep logical unit(s)
Correctieschema voor kwantumfouten wijzigen
Voer nu de resourceschattingstaak opnieuw uit voor hetzelfde voorbeeld op de qubitparameters op basis van Majorana met een floqued QEC-schema, qecScheme
.
job = backend.run(circ,
qubitParams={
"name": "qubit_maj_ns_e6"
},
qecScheme={
"name": "floquet_code"
})
result_maj_floquet = job.result()
result_maj_floquet
Foutbudget wijzigen
Laten we hetzelfde kwantumcircuit opnieuw uitvoeren met een errorBudget
van 10%.
job = backend.run(circ,
qubitParams={
"name": "qubit_maj_ns_e6"
},
qecScheme={
"name": "floquet_code"
},
errorBudget=0.1)
result_maj_floquet_e1 = job.result()
result_maj_floquet_e1
Notitie
Als u een probleem ondervindt tijdens het werken met de resource-estimator, gaat u naar de pagina Probleemoplossing of neemt u contact op met AzureQuantumInfo@microsoft.com.
Volgende stappen
Feedback
https://aka.ms/ContentUserFeedback.
Binnenkort beschikbaar: In de loop van 2024 zullen we GitHub-problemen geleidelijk uitfaseren als het feedbackmechanisme voor inhoud en deze vervangen door een nieuw feedbacksysteem. Zie voor meer informatie:Feedback verzenden en weergeven voor