Udostępnij za pośrednictwem


Wprowadzenie do języka programowania kwantowego Q#

Q# to język programowania typu open source opracowany przez firmę Microsoft do pisania programów kwantowych. Q# jest zawarty w pakiecie Quantum Development Kit (QDK). Aby uzyskać więcej informacji, zobacz Konfigurowanie zestawu Quantum Development Kit.

Jako język programowania kwantowego Q# spełnia następujące wymagania dotyczące języka, kompilatora i środowiska uruchomieniowego:

  • Niezależny od sprzętu: kubity w algorytmach kwantowych nie są powiązane z konkretnym sprzętem kwantowym ani układem. Kompilator Q# i środowisko uruchomieniowe obsługują mapowanie z kubitów programu do kubitów fizycznych, co umożliwia uruchamianie tego samego kodu na różnych procesorach kwantowych.
  • Integracja obliczeń kwantowych i klasycznych:Q# umożliwia integrację obliczeń kwantowych i klasycznych, co jest niezbędne dla uniwersalnych obliczeń kwantowych.
  • zarządzanie kubitami:Q# zapewnia wbudowane operacje i funkcje do zarządzania kubitami, w tym tworzenie stanów superpozycji, splątanie kubitów i wykonywanie pomiarów kwantowych.
  • Przestrzegaj praw fizyki:Q# i algorytmy kwantowe muszą przestrzegać zasad fizyki kwantowej. Na przykład nie można bezpośrednio skopiować ani uzyskać dostępu do stanu kubitu w elemecie Q#.

Aby uzyskać więcej informacji na temat źródeł Q#, zobacz wpis w blogu Dlaczego potrzebujemy Q#?.

Q# Struktura programu

Przed rozpoczęciem pisania Q# programów ważne jest zrozumienie ich struktury i składników. Rozważmy następujący program Q# o nazwie Superpozycja, który tworzy stan superpozycji:

namespace Superposition {
    @EntryPoint()
    operation MeasureOneQubit() : Result {
        // Allocate a qubit. By default, it's in the 0 state.  
        use q = Qubit();  
        // Apply the Hadamard operation, H, to the state.
        // It now has a 50% chance of being measured as 0 or 1.
        H(q);      
        // Measure the qubit in the Z-basis.
        let result = M(q);
        // Reset the qubit before releasing it.
        Reset(q);
        // Return the result of the measurement.
        return result;
    }
}

Na podstawie komentarzy (//), Q# program najpierw przydziela kubit, stosuje operację, aby umieścić kubit w superpozycji, mierzy stan kubitu, resetuje kubit, a na koniec zwraca wynik.

Podzielmy ten Q# program na jego składniki.

Przestrzenie nazw użytkowników

Q# programy mogą opcjonalnie rozpoczynać się od przestrzeni nazw zdefiniowanej przez użytkownika, takiej jak:

namespace Superposition {
    // Your code goes here.
}

Przestrzenie nazw mogą ułatwić organizowanie powiązanych funkcji. Przestrzenie nazw są opcjonalne w Q# programach, co oznacza, że można napisać program bez definiowania przestrzeni nazw.

Na przykład, program Superpozycja można również napisać bez użycia przestrzeni nazw jako:

@EntryPoint()
operation MeasureOneQubit() : Result {
    // Allocate a qubit. By default, it's in the 0 state.  
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1.
    H(q);      
    // Measure the qubit in the Z-basis.
    let result = M(q);
    // Reset the qubit before releasing it.
    Reset(q);
    // Return the result of the measurement.
    return result;
}

Uwaga

Każdy Q# program może mieć tylko jeden namespace. Jeśli nie określisz przestrzeni nazw, kompilator Q# używa nazwy pliku jako przestrzeni nazw.

Punkty wejścia

Każdy program Q# musi mieć punkt wejścia, który jest punktem początkowym programu. Domyślnie Q# kompilator uruchamia wykonywanie programu z operacji Main(), jeśli jest dostępna, która może znajdować się w dowolnym miejscu w programie. Opcjonalnie możesz użyć atrybutu @EntryPoint() , aby określić dowolną operację w programie jako punkt wykonywania.

Na przykład w programie Superpozycja operacja MeasureOneQubit() jest punktem wejścia programu, ponieważ ma atrybut @EntryPoint() przed definicją operacji:

@EntryPoint()
operation MeasureOneQubit() : Result {
    ...
}

Można jednak również napisać program bez atrybutu @EntryPoint() przez zmianę nazwy operacji MeasureOneQubit() na Main(), na przykład:

// The Q# compiler automatically detects the Main() operation as the entry point. 

operation Main() : Result {
    // Allocate a qubit. By default, it's in the 0 state.  
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1.
    H(q);      
    // Measure the qubit in the Z-basis.
    let result = M(q);
    // Reset the qubit before releasing it.
    Reset(q);
    // Return the result of the measurement.
    return result;
}

Typy

Typy są niezbędne w każdym języku programowania, ponieważ definiują dane, z którymi program może pracować. Q# udostępnia wbudowane typy, które są wspólne dla większości języków, takie jak Int, Double, Booli String, oraz typy definiujące zakresy, tablice i krotki (tuples).

Q# również udostępnia typy specyficzne dla obliczeń kwantowych. Na przykład typ Result reprezentuje wynik pomiaru kubitu i może mieć dwie wartości: Zero lub One.

W programie Superpozycja, operacja MeasureOneQubit() zwraca typ Result, który odpowiada typowi zwracanemu operacji M. Wynik pomiaru jest przechowywany w nowej zmiennej zdefiniowanej przy użyciu instrukcji let :

// The operation definition returns a Result type.
operation MeasureOneQubit() : Result {
    ...
    // Measure the qubit in the Z-basis, returning a Result type.
    let result = M(q);
    ...
}

Innym przykładem typu specyficznego dla kwantu jest typ Qubit, który reprezentuje bit kwantowy.

Q# umożliwia również definiowanie własnych typów niestandardowych. Aby uzyskać więcej informacji, zobacz deklaracje typów .

Przydzielanie kubitów

W Q#przydzielisz kubity przy użyciu słowa kluczowego use i typu Qubit. Kubity są zawsze przydzielane w stanie $\ket{0}$.

Na przykład program superpozycji definiuje pojedynczy kubit i przechowuje go w zmiennej q:

// Allocate a qubit.
use q = Qubit();

Możesz również przydzielić wiele kubitów i uzyskać do nich dostęp za pośrednictwem jego indeksu:

use qubits = Qubit[2]; // Allocate two qubits.
H(qubits[0]); // Apply H to the first qubit.
X(qubits[1]); // Apply X to the second qubit.

Operacje kwantowe

Po przypisaniu kubitu można go następnie przekazać do operacji i funkcji. Operacje to podstawowe bloki konstrukcyjne programu Q#. Q# Operacja jest podroutyną kwantową lub procedurą wywoływaną, która zawiera operacje kwantowe, które zmieniają stan rejestru kubitów.

Aby zdefiniować operację Q# , należy określić nazwę operacji, jej dane wejściowe i dane wyjściowe. W programie Superpozycja operacja MeasureOneQubit() nie przyjmuje żadnych parametrów i zwraca typ Result:

operation MeasureOneQubit() : Result {
    ...
}

Oto podstawowy przykład, który nie przyjmuje żadnych parametrów i nie oczekuje wartości zwracanej. Wartość Unit jest równoważna NULL w innych językach.

operation SayHelloQ() : Unit {
    Message("Hello quantum world!");
}

Standardowa Q# biblioteka udostępnia również operacje, których można używać w programach kwantowych, takich jak operacja Hadamard, Hw Superposition programie. Biorąc pod uwagę kubit w bazie Z, stan kubita jest przekształcany przez H w równą superpozycję, gdzie ma 50% szans na pomiar jako Zero lub One.

Mierzenie kubitów

Chociaż istnieje wiele typów pomiarów kwantowych, Q# koncentruje się na przewidywanych pomiarach na pojedynczych kubitach, nazywanych również pomiarami Pauli.

W Q#, operacja Measure mierzy jeden lub więcej kubitów w określonej bazie Pauli, który może być PauliX, PauliY lub PauliZ. Measure Zwraca typ Result: Zero lub One.

Aby zaimplementować pomiar w bazie obliczeniowej $\lbrace\ket{0},\ket{1}\rbrace$, można również użyć operacji M, która mierzy kubit w bazie Pauliego Z. To sprawia, że M jest równoważne Measure([PauliZ], [qubit]).

Na przykład program superpozycji używa operacji M:

// Measure the qubit in the Z-basis.
let result = M(q);

Resetowanie kubitów

W Q#kubity muszą być w stanie $\ket{0}$, gdy są zwalniane, aby uniknąć błędów w sprzęcie kwantowym. Kubit można zresetować do stanu $\ket{0}$ przy użyciu operacji Reset na końcu programu. Niepowodzenie resetowania kubitu powoduje błąd środowiska uruchomieniowego.

// Reset a qubit.
Reset(q);

Przestrzenie nazw biblioteki standardowej

Q# Standardowa biblioteka zawiera wbudowane przestrzenie nazw, które zawierają funkcje i operacje, których można używać w programach kwantowych. Na przykład Microsoft.Quantum.Intrinsic przestrzeń nazw zawiera często używane operacje i funkcje, takie jak M mierzenie wyników i Message wyświetlanie komunikatów użytkowników w dowolnym miejscu w programie.

Aby wywołać funkcję lub operację, można określić pełną przestrzeń nazw lub użyć instrukcji import, która udostępnia wszystkie funkcje i operacje dla tej przestrzeni nazw i czyni kod bardziej czytelnym. Następujące przykłady uruchamiają tę samą operację:

Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
// imports all functions and operations from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.*;
Message("Hello quantum world!");

// imports just the `Message` function from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.Message;
Message("Hello quantum world!");
// namespaces in the standard library may be imported using `Std` instead of `Microsoft.Quantum`. 
import Std.Intrinsic.*;
Message("Hello quantum world!");

Uwaga

Program Superpozycji nie zawiera żadnych instrukcji import ani wywołań przy użyciu pełnych przestrzeni nazw. Dzieje się tak dlatego, że Q# środowisko programistyczne automatycznie ładuje dwie przestrzenie nazw: Microsoft.Quantum.Core i Microsoft.Quantum.Intrinsic, które zawierają często używane funkcje i operacje.

Możesz skorzystać z przestrzeni nazw Microsoft.Quantum.Measurement, używając operacji MResetZ, aby zoptymalizować program Superpozycja. MResetZ łączy operacje pomiaru i resetowania w jeden krok, jak w poniższym przykładzie:

// Import the namespace for the MResetZ operation.
import Microsoft.Quantum.Measurement.*;

@EntryPoint()
operation MeasureOneQubit() : Result {
    // Allocate a qubit. By default, it's in the 0 state.      
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1. 
    H(q);   
    // Measure and reset the qubit, and then return the result value.
    return MResetZ(q);
}

Dowiedz się, jak opracowywać programy kwantowe za pomocą Q# i usługi Azure Quantum

Q# i Azure Quantum to zaawansowana kombinacja do tworzenia i uruchamiania programów kwantowych. Za pomocą Q# usługi Azure Quantum można pisać programy kwantowe, symulować ich zachowanie, szacować wymagania dotyczące zasobów i uruchamiać je na rzeczywistym sprzęcie kwantowym. Ta integracja umożliwia poznanie potencjału obliczeń kwantowych i opracowanie innowacyjnych rozwiązań złożonych problemów. Bez względu na to, czy jesteś początkującym, czy doświadczonym deweloperem kwantowym, Q# a usługa Azure Quantum udostępnia narzędzia i zasoby potrzebne do odblokowania możliwości obliczeń kwantowych.

Na poniższym diagramie przedstawiono etapy, w których program kwantowy przechodzi podczas opracowywania za pomocą Q# usługi Azure Quantum. Program rozpoczyna się od środowiska deweloperskiego i kończy się przesłaniem zadania do rzeczywistego sprzętu kwantowego.

Diagram przedstawiający przepływ pracy programowania kwantowego.

Przeanalizujmy kroki na diagramie.

Wybierz środowisko projektowe

Uruchamianie programów kwantowych w preferowanym środowisku programistycznym. Możesz użyć edytora kodu online na stronie Azure Quantum, hostowanych notesów Jupyter w obszarze roboczym Azure Quantum w portalu Azure lub lokalnego środowiska programistycznego z programem Visual Studio Code. Aby uzyskać więcej informacji, zobacz Różne sposoby uruchamiania Q# programów.

Pisanie programu kwantowego

Programy kwantowe można pisać w Q# za pomocą Zestawu do Rozwoju Programów Kwantowych (QDK). Aby rozpocząć, zobacz Szybki start: tworzenie pierwszego Q# programu.

Oprócz Q# zestaw QDK oferuje obsługę innych języków do przetwarzania kwantowego, takich jak Qiskit i Cirq.

Integracja z językiem Python

Możesz używać Q# samodzielnie lub razem z językiem Python w różnych IDE. Na przykład można użyć projektu Q# z programem hosta Python, aby wywołać operacje Q# lub zintegrować Q# z Pythonem w notesach Jupyter. Aby uzyskać więcej informacji, zobacz Integrację Q# z Pythonem.

Polecenie %%qsharp

Domyślnie Q# programy w notatnikach Jupyter używają ipykernel pakietu Python. Aby dodać Q# kod do komórki notesu, użyj polecenia %%qsharp, które jest aktywne dzięki pakietowi qsharp języka Python, a następnie dodaj Q# kod.

W przypadku korzystania z programu %%qsharpnależy pamiętać o następujących kwestiach:

  • Najpierw musisz uruchomić import qsharp, aby włączyć %%qsharp.
  • %%qsharp dotyczy komórki notatnika, w której się pojawia, i zmienia typ komórki z Python na Q#.
  • Nie można umieścić instrukcji języka Python przed lub po %%qsharp.
  • Q# kod, który następuje %%qsharp, musi być zgodny ze składnią Q#. Na przykład użyj // zamiast # do oznaczania komentarzy i ; do zakończenia wierszy kodu.

Szacowanie zasobów

Przed uruchomieniem rzeczywistego sprzętu kwantowego należy ustalić, czy program może działać na istniejącym sprzęcie i ile zasobów będzie zużywać.

Narzędzie do szacowania zasobów usługi Azure Quantum pozwala ocenić decyzje dotyczące architektury, porównać technologie kubitu i określić zasoby potrzebne do wykonania danego algorytmu kwantowego. Możesz wybrać spośród wstępnie zdefiniowanych protokołów odpornych na błędy i określić założenia bazowego modelu fizycznego kubitu.

Aby uzyskać więcej informacji, zobacz Uruchamianie pierwszego oszacowania zasobów.

Uwaga

Narzędzie do szacowania zasobów usługi Azure Quantum jest bezpłatne i nie wymaga konta platformy Azure.

Uruchamianie programu w symulacji

Podczas kompilowania i uruchamiania programu kwantowego zestaw QDK tworzy wystąpienie symulatora kwantowego i następnie przekazuje kod Q# do niego. Symulator używa kodu Q# do tworzenia kubitów (symulacji cząstek kwantowych) i stosuje przekształcenia w celu zmodyfikowania ich stanu. Wyniki operacji kwantowych w symulatorze są następnie zwracane do programu. Odizolowanie kodu Q# w symulatorze gwarantuje, że algorytmy są zgodne z prawami fizyki kwantowej i mogą działać poprawnie na komputerach kwantowych.

Prześlij swój program do rzeczywistego sprzętu kwantowego

Po przetestowaniu programu w symulacji możesz uruchomić go na rzeczywistym sprzęcie kwantowym. Po uruchomieniu programu kwantowego w usłudze Azure Quantum tworzysz i uruchamiasz zadanie . Aby przesłać zadanie do dostawców usługi Azure Quantum, potrzebujesz konta platformy Azure i obszaru roboczego kwantowego. Jeśli nie masz obszaru roboczego kwantowego, zobacz Tworzenie obszaru roboczego usługi Azure Quantum.

Usługa Azure Quantum oferuje jedne z najbardziej atrakcyjnych i zróżnicowanych sprzętów kwantowych. Zobacz Dostawcy obliczeń kwantowych, aby uzyskać bieżącą listę obsługiwanych dostawców sprzętu.

Po przesłaniu zadania usługa Azure Quantum zarządza cyklem życia zadania, w tym planowaniem zadań, wykonywaniem i monitorowaniem. Możesz śledzić stan zadania i wyświetlać wyniki w witrynie Azure Quantum Portal.