Zasoby obliczeniowe i zarządzanie zasobami
Model zasobów i zasoby klasyczne
W tej sekcji przedstawimy ramy myślenia o środowiskach obliczeniowych, które można zastosować zarówno do laptopa, jak i skalować do superkomputerów. Po zakończeniu tej sekcji będziesz rozumieć podstawowe komponenty środowiska obliczeniowego i ich wzajemne relacje. Wszystko to przedstawia Iskandar Sitdikov w poniższym filmie.
Model zasobów
Każde klasyczne środowisko obliczeniowe składa się z kilku wzajemnie powiązanych zasobów, które współpracują ze sobą, aby efektywnie uruchamiać aplikacje. Kluczowe zasoby zazwyczaj obejmują:
-
CPU (Central Processing Unit): CPU to podstawowa jednostka przetwarzająca, która interpretuje i wykonuje instrukcje programu. Obsługuje logikę, arytmetykę i operacje sterujące, pełniąc zasadniczo rolę „mózgu” systemu.
-
Cache CPU (L1, L2, L3): Jest to najszybsza pamięć w systemie, wbudowana bezpośrednio w rdzeń CPU lub umieszczona bardzo blisko niego. Przechowuje niewielkie porcje danych i instrukcji, których CPU potrzebuje natychmiast. Różne poziomy (L1, L2, L3) stanowią kompromis: L1 jest najmniejszy i najszybszy, podczas gdy L3 jest największy i najwolniejszy, ale nadal o rzędy wielkości szybszy niż RAM.
-
RAM (Random Access Memory): Pamięć ulotna, która zapewnia duże, tymczasowe miejsce do przechowywania instrukcji programu i aktywnie wykorzystywanych danych. Zapewnia, że CPU może szybko uzyskać dostęp do potrzebnych informacji podczas wykonywania, bez ciągłego polegania na wolniejszych urządzeniach pamięci masowej.
-
Pamięć masowa (lokalna i sieciowa): Pamięć masowa przechowuje dane i oprogramowanie nawet po wyłączeniu systemu, zapewniając długoterminową trwałość dla dużych zbiorów danych i aplikacji. W obliczeniach wysokowydajnych rozwiązania pamięci masowej muszą obsługiwać ogromne ilości danych naukowych lub analitycznych, zarówno szybko, jak i niezawodnie. Pamięć lokalna obejmuje dyski półprzewodnikowe (SSD) oraz dyski twarde (HDD), przy czym SSD są preferowane ze względu na niższe opóźnienia i wyższą przepustowość. Do obsługi danych na dużą skalę równoległe systemy plików, współdzielona sieciowa pamięć masowa oraz systemy obiektowe umożliwiają szybki dostęp na wielu węzłach obliczeniowych, natomiast warstwy pamięci chmurowej i archiwalnej wspierają długoterminowe przechowywanie i skalowalność.
-
GPU (Graphics Processing Unit): Choć początkowo zaprojektowane do renderowania grafiki, współczesne GPU są potężnymi procesorami równoległymi. Są szeroko wykorzystywane do obsługi zadań wymagających wielu równoczesnych obliczeń, takich jak uczenie głębokie, symulacje fizyczne i analityka dużych zbiorów danych. Należy zauważyć, że GPU nie zastępują CPU; CPU kierują logiką programu wyższego poziomu, a GPU przyspieszają wysoce równoległe kroki.
-
Połączenia/szyny: Są to ścieżki komunikacyjne, które łączą CPU, pamięć, pamięć masową i urządzenia peryferyjne. Szyny umożliwiają przesyłanie danych i koordynację między częściami systemu, zapewniając płynną komunikację w całym środowisku obliczeniowym. W systemach HPC komponenty takie jak CPU, GPU i urządzenia pamięci masowej są połączone szybkimi interkonektami, które umożliwiają szybką wymianę danych. GPU zazwyczaj łączą się z systemem za pośrednictwem PCIe, standardowego interfejsu z wieloma liniami danych dla efektywnej komunikacji. Dla wyższej wydajności NVLink zapewnia bezpośrednie, wysokoprzepustowe połączenie między GPU lub między GPU a CPU, zmniejszając opóźnienia i przyspieszając równoległe obciążenia robocze.
-
System plików: System plików organizuje dane na urządzeniach pamięci masowej. Zapewnia strukturę do przechowywania, odzyskiwania i zarządzania plikami, umożliwiając programom i użytkownikom dostęp do informacji w spójny i logiczny sposób.
Każdy typ zasobu ma własne jednostki miary związane z wydajnością. Na przykład CPU są zazwyczaj mierzone w „rdzeniach” i „częstotliwości taktowania”. Przy zakupie laptopa jego specyfikacja zwykle zawiera liczbę rdzeni. Podobna koncepcja dotyczy węzłów obliczeniowych w centrum danych, gdzie każdy węzeł jest powiązany z określoną liczbą rdzeni. Środowiska obliczeniowe, które obejmują wiele typów zasobów (CPU, GPU, a nawet QPU), nazywane są heterogenicznymi środowiskami obliczeniowymi. Takie konfiguracje efektywniej obsługują różnorodne obciążenia robocze, wykorzystując mocne strony każdego typu procesora. Na przykład CPU byłyby używane do zadań ogólnych, a GPU do przetwarzania równoległego. W kontekście zarządzania zasobami i harmonogramowania — zwłaszcza w heterogenicznych środowiskach obliczeniowych — mogą być wymagane dodatkowe jednostki miary oprócz opisanych tutaj.
Dla pamięci jednostką miary są Mega/Giga/Terabajty.
Dla kart graficznych i innych akceleratorów jednostka miary zależy od kontekstu. Podczas gdy ich rzeczywiste możliwości obliczeniowe mierzone są za pomocą szczegółowych metryk — liczby rdzeni przetwarzających, rozmiaru pamięci i przepustowości pamięci — w ogólnych dyskusjach o zasobach klastra lub harmonogramowaniu zadań GPU i podobne akceleratory mogą być liczone na poziomie urządzenia jako liczba przypisanych całych urządzeń (na przykład trzy GPU).
Sieć/łączność/szyny są kluczowym aspektem każdej infrastruktury obliczeniowej, ponieważ decydują o tym, jak szybko dane są przesyłane między komponentami obliczeniowymi. Od LPU do cache CPU, do RAM, do kart PCI, do urządzeń podłączonych do sieci; wszystko to jest komunikacją i kluczowe jest posiadanie dokładnego modelu mentalnego, aby zaprojektować wysoce zoptymalizowane algorytmy dla HPC.
Skalowanie zasobów klasycznych
Obliczenia wysokowydajne (HPC) polegają na skalowaniu tych klasycznych zasobów w celu osiągnięcia szybszych czasów przetwarzania lub zwiększenia ilości danych, które mogą być jednocześnie obsługiwane (na przykład w celu zwiększenia rozmiaru przestrzeni rozwiązań, które można przeszukiwać). Można to osiągnąć poprzez:
-
Skalowanie pionowe: Zwiększanie mocy poszczególnych zasobów, na przykład poprzez użycie mocniejszego CPU lub dodanie większej ilości pamięci w obrębie jednego węzła fizycznego, gdzie węzeł jest jednostką klastra obliczeniowego zawierającą w sobie wiele zasobów obliczeniowych.
-
Skalowanie poziome: Dodawanie większej liczby zasobów, takich jak wiele CPU lub GPU, aby współpracowały na jednym węźle lub, częściej, na wielu węzłach, umożliwiając obliczenia rozproszone.
Niektóre koncepcje skalowania z tej sekcji będą miały zastosowanie w następnej sekcji dotyczącej zasobów obliczeń kwantowych. Inne aspekty zasobów kwantowych będą kwantyfikowane w nowy sposób.
Sprawdź swoje zrozumienie
Na podstawie powyższych opisów spróbuj wywnioskować, jakie są zalety i wady różnych podejść do skalowania: pionowego i poziomego?
Odpowiedź:
Może być wiele poprawnych odpowiedzi. Skalowanie pionowe jest często prostsze, zwłaszcza gdy masz przewidywalne obciążenia robocze, które będą wymagać stałej ilości zasobów. Jednak skalowanie pionowe może być droższe przy modernizacji, ponieważ podstawowa jednostka obliczeniowa nie może być tak łatwo rozbita jak w skalowaniu poziomym. Skalowanie poziome jest bardziej złożone w zarządzaniu i czasami występują trudności lub opóźnienia związane z połączeniami między węzłami. Jest jednak znacznie bardziej adaptacyjne do zmieniających się wymagań zasobów i modułowe, gdy wymagane są modernizacje.
Nowy typ zasobu: QPU (Quantum Processing Unit)
W tej sekcji przedstawimy nowy typ zasobu — zasób kwantowy — oraz zbadamy jego definicję, jednostki miary i łączność z infrastrukturą klasyczną.
Definicja QPU
- Quantum Processing Unit (QPU): QPU obejmuje cały sprzęt odpowiedzialny za przyjmowanie wykonywalnego zestawu instrukcji kwantowych, czyli obwodu kwantowego, i zwracanie dokładnej odpowiedzi.
Oznacza to, że QPU obejmuje jeden lub więcej chipów kwantowych (np. Heron), wiele dodatkowych komponentów w lodówce rozcieńczalnikowej, takich jak wzmacniacze kwantowe, elektronika sterująca, oraz klasyczne zasoby obliczeniowe wymagane do zadań takich jak przechowywanie instrukcji i kształtów fal w pamięci, gromadzenie wyników oraz przyszłe dekodowanie korekcji błędów. Choć lodówka rozcieńczalnikowa jest wymagana do wykonywania tych zadań, wyłączamy ją z tej definicji, aby uwzględnić przypadek wielu QPU w tej samej lodówce.
-
Komputer kwantowy: Komputer kwantowy składa się z QPU oraz klasycznych zasobów obliczeniowych, które hostują środowisko uruchomieniowe.
-
Środowisko uruchomieniowe: Połączenie sprzętu i oprogramowania, które umożliwia uruchamianie programu.
Warstwy w obwodach kwantowych
Zarówno w obliczeniach klasycznych, jak i kwantowych, procesy mogą być wykonywane sekwencyjnie lub równolegle. Ponieważ kubity mają bogatą przestrzeń stanów w porównaniu z bitami klasycznymi, czasami sensowne jest wykonywanie wielu bramek jednokubitowych na kubicie w sekwencji (jak bramka R_x po której następuje bramka R_z). Ponieważ splątanie między kubitami ma kluczowe znaczenie w obliczeniach kwantowych, często zdarza się również, że obwód kwantowy zawiera zestaw bramek splątających działających na wielu kubitach. Te i inne czynniki sprawiają, że często identyfikuje się procesy, które można wykonywać równolegle w skali pojedynczych operacji bramkowych w obwodzie kwantowym. W obliczeniach klasycznych równoległość na poziomie bitów jest również możliwa, ale rzadziej rozważana na poziomie bramek; częściej mówi się o procesach równoległych i sekwencyjnych w większej skali.
W obliczeniach kwantowych mówi się o „warstwie” bramek, które mogą być wykonywane jednocześnie. W wielu zastosowaniach przydatne jest wykonanie zestawu rotacji na wszystkich kubitach, a następnie bramek splątających między parami kubitów. W tych kontekstach mówi się o „warstwie rotacji” (warstwie bramek takich jak R_x, R-y i/lub R_z) oraz o „warstwie splątającej” (takiej jak warstwa z bramkami CNOT). Liczba warstw w obwodzie to „głębokość obwodu”, ważna miara, ponieważ większa głębokość oznacza więcej warstw kumulującego się szumu i błędów.
Wizualna identyfikacja warstw bramek może być trudna, gdy warstwy nie są wyrównane za pomocą barier. W Qiskit bariera służy jako instrukcja w obwodach kwantowych, która pełni rolę wizualnego separatora i ograniczenia podczas kompilacji. Zarówno przy rysowaniu obwodu, jak i jego wykonywaniu, żadne bramki nie zostaną przeniesione przez barierę. Może to być istotne w kontekstach takich jak dynamiczne rozsprzęganie, w którym celowo implementuje się bramki upraszczające się do tożsamości w celu tłumienia niektórych typów błędów. Więcej o dynamicznym rozsprzęganiu znajdziesz w tym przewodniku. Aby zobaczyć wizualny efekt barier, porównaj te dwa obrazy tego samego obwodu — pierwszy bez barier i drugi z barierami wymuszającymi wyrównanie warstw.
To ten sam obwód i mają taką samą liczbę warstw. Ale w drugim wyrównanie ułatwia zauważenie, że obwód zawiera:
- Dwie warstwy rotacji: jedną wokół osi Y o , jedną wokół osi Z o .
- Trzy warstwy splątające. Zauważ, że każdą bramkę CNOT można nazwać osobną „warstwą”, ponieważ bramek CNOT nie można ponownie uporządkować tak, aby były równoległe, bez zmiany operacji logicznej.
- Kolejne dwie warstwy rotacji: jedną wokół osi Y o , jedną wokół osi Z o .
- Kolejne dwie warstwy splątające. Zauważ, że tym razem pierwsza warstwa została nieco bardziej zrównoleglona niż w pierwszym zestawie warstw splątających.
Głębokość każdego obwodu wynosi 9.
Jednostki miary
W obliczeniach kwantowych możliwości systemu kwantowego są zazwyczaj oceniane za pomocą trzech kluczowych metryk wydajności: skali, jakości i szybkości. Metryki te nie tylko opisują potencjał obliczeniowy urządzenia kwantowego, ale także informują, w jaki sposób zarządza się zasobami i planuje je w praktycznych zastosowaniach.
-
Skala odnosi się do liczby bitów kwantowych (kubitów) w systemie, reprezentując ilość informacji kwantowej, jaką urządzenie może przechowywać. W zarządzaniu zasobami ma to bezpośredni wpływ na szerokość obwodu — liczbę kubitów wymaganych do uruchomienia danego zadania kwantowego. Jednostka kwantowa musi mieć wystarczającą liczbę kubitów, aby obsłużyć przydzielone zadanie.
-
Jakość opisuje, jak dokładnie wykonywane są operacje kwantowe. Często jest określana ilościowo przez layer fidelity (wierność warstwy), która mierzy dokładność wykonania pełnej warstwy bramek kwantowych na wszystkich kubitach. Z perspektywy harmonogramowania wyższa fidelity pozwala na niezawodne wykonywanie głębszych obwodów, co wpływa na potrzebę łagodzenia błędów lub dekompozycji zadań.
-
Szybkość jest mierzona w CLOPS (Circuit Layer Operations Per Second), co wskazuje, ile warstw operacji kwantowych system może wykonać na sekundę. Ma to wpływ na przepustowość i opóźnienia w wykonywaniu zadań oraz pomaga określić, jak szybko jednostka kwantowa może ukończyć dane obciążenie. Ta szybkość jest szczególnie ważna w komputerze kwantowym, ponieważ kubity w większym stopniu cierpią z powodu szumu (noise) i błędów niż ich klasyczne odpowiedniki. Czas, przez który mogą one zachować swoją informację kwantową w użyteczny sposób, opisuje coherence time (czas koherencji), zazwyczaj rzędu 200–300 dla procesorów Heron r3.
Różnice między metrykami kwantowymi a klasycznymi
Możesz myśleć o CLOPS jako o luźnym kwantowym odpowiedniku FLOPS, ale z pewnymi kluczowymi różnicami. CLOPS mierzy szybkość, z jaką procesor kwantowy może wykonywać obwody kwantowe, a konkretnie warstwy operacji w obwodach, obejmujące zarówno obliczenia kwantowe, jak i niezbędne obliczenia klasyczne związane z uruchamianiem obwodów. Został opracowany przez IBM Quantum jako holistyczna miara szybkości wykonywania komputera kwantowego, obejmująca czas wykonywania kwantowego i przetwarzanie klasyczne w czasie rzeczywistym potrzebne do aktualizacji obwodów, w przeciwieństwie do FLOPS, który mierzy wyłącznie zdolność arytmetyczną zmiennoprzecinkową w procesorach klasycznych.
CLOPS dostarcza mierzalnej metryki wydajności, którą można porównywać na istniejącym sprzęcie. IBM Quantum wykorzystuje CLOPS do porównywania różnych procesorów kwantowych, a wartości można znaleźć na stronie Compute resources w IBM Quantum Platform. Wartości CLOPS zależą od możliwości sprzętowych, szybkości bramek, szybkości przetwarzania klasycznego oraz ich integracji.
Liczba kubitów jest wartością stałą dla danego QPU. CLOPS i jakość zależą od regularnej kalibracji i konserwacji i mogą nieznacznie się zmieniać w czasie, nawet dla pojedynczego QPU.
Razem metryki te kierują sposobem alokacji i harmonogramowania systemów kwantowych. W wielu przypadkach cały system kwantowy jest traktowany jako pojedyncza jednostka. Jednak gdy zadanie przekracza pojemność jednej jednostki — czy to pod względem liczby kubitów, głębokości obwodu czy szybkości wykonania — można zastosować techniki takie jak circuit cutting/knitting. Circuit cutting to proces dzielenia dużych zadań kwantowych na mniejsze, łatwiejsze do zarządzania podzadania, które można rozdzielić na wiele chipów kwantowych, umożliwiając skalowalne obliczenia kwantowe pomimo ograniczeń sprzętowych. Circuit knitting odnosi się do procesu następującego po circuit cutting — klasycznego kroku przetwarzania końcowego, który „zszywa” lub łączy wyniki z mniejszych podobwodów z powrotem razem.
Komputery kwantowe nie mają tradycyjnej pamięci w sensie trwałej, adresowalnej pamięci, takiej jak RAM lub pamięć GPU. Klasyczne zasoby obliczeniowe mają dyskretne bity przechowywane w pamięci, co pozwala na zapisywanie, pobieranie i ponowne wykorzystanie danych podczas obliczeń. Zasoby kwantowe używają kubitów, które nie przechowują pamięci w sensie klasycznym. Zamiast tego kubity istnieją w stanach kwantowych, które reprezentują superpozycje 0 i 1 jednocześnie, umożliwiając wykładniczy paralelizm w przestrzeni stanów. Jednak stany kubitów są kruche i nie mogą być klonowane ani deterministycznie odczytywane na etapach pośrednich bez kolapsu stanu kwantowego, więc zachowanie podobne do trwałej pamięci podczas obliczeń nie istnieje. Kubity muszą być utrzymywane w stanie koherentnym przez cały czas wykonywania, a „pamięcią” jest zasadniczo sam stan kwantowy. Pamięć klasyczna może być używana jedynie obok procesora kwantowego, a nie jako wewnętrzna pamięć kwantowa. Ma to istotne implikacje: klasyczne zasoby obliczeniowe mogą swobodnie ponownie wykorzystywać i przechowywać wyniki pośrednie; zasoby kwantowe nie mogą tego robić bez pomiarów, które zaburzają obliczenia.
Łączność z infrastrukturą klasyczną
QPU mogą być połączone z infrastrukturą klasyczną poprzez sieci i różne interfejsy programowania aplikacji (API), które pozwalają programistom oprogramowania na programistyczną interakcję z QPU. Te API są zwykle ukryte za zestawami narzędzi programistycznych (SDK) i bibliotekami (jak Qiskit) i udostępniane naukowcom obliczeniowym w formie abstrakcji programistycznych (jak Qiskit Primitives, o których będziemy mówić w Rozdziale 3: modele programowania).
Warto podkreślić różnicę między ścisłą a luźną integracją zasobów kwantowych i klasycznych. Obecnie QPU nie znajdują się na tym samym węźle co klasyczne zasoby obliczeniowe. W rzeczywistości QPU nie są obecnie podłączone przez PCIe, ale przez sieć. Może się to zmienić w przyszłości, ale istnieją wyzwania inżynieryjne związane z warunkami środowiskowymi optymalnymi dla QPU i klasycznych zasobów obliczeniowych.
Skalowanie zasobów kwantowych
Skalowanie zasobów kwantowych również można podzielić na pionowe i poziome.
- Skalowanie pionowe polegałoby na zwiększaniu liczby kubitów na chipie lub poprawie fidelity urządzeń.
- Skalowanie poziome polegałoby na łączeniu chipów za pomocą sprzęgaczy (couplers) lub klasycznych połączeń.
Sprawdź swoje zrozumienie
Jakie są kwantowe odpowiedniki klasycznych (a) bitów informacji i (b) szybkości procesora?
Odpowiedź:
(a) Bity kwantowe lub kubity — jednostki informacji, które w przeciwieństwie do swoich klasycznych odpowiedników (które mogą przyjmować tylko stan 0 lub 1), mogą znajdować się w superpozycji 0 i 1 jednocześnie.
(b) Circuit layer operations per second, czyli CLOPS — liczba sekwencyjnych operacji, które QPU może wykonać w ciągu sekundy, w tym pewna interakcja z klasycznymi zasobami obliczeniowymi, na przykład ładowanie parametrów z obwodu.
Zarządzanie zasobami
Zarówno zasoby HPC, jak i zasoby kwantowe są cenne i złożone; muszą być starannie zarządzane. W tej sekcji wyjaśnimy, jak zarządzać zasobami dla programów użytkownika. Resource management w infrastrukturze obliczeniowej odnosi się do procesu (1) planowania, (2) alokacji oraz (3) kontroli/zarządzania użyciem zasobów obliczeniowych, takich jak CPU, pamięć, pamięć masowa i przepustowość sieci, w celu zapewnienia wydajnego i skutecznego wykorzystania zasobów.
Planowanie - szacowanie zasobów
Każdy program zużywa zasoby, a szacowanie wymaganych zasobów ma kluczowe znaczenie dla efektywnego resource management. Obejmuje to estimation ilości CPU, pamięci i innych zasobów potrzebnych do wykonania programu. To samo dotyczy zasobów kwantowych. Zasoby kwantowe istnieją jednak w zupełnie innej skali. Procesory kwantowe IBM Quantum® Heron r3 mają 156 kubitów, w porównaniu do wielu miliardów bitów klasycznych w typowym laptopie. Czas i koszt również są istotne. Obecnie IBM Quantum oferuje darmowy plan, Open Plan, który pozwala użytkownikom eksplorować obliczenia kwantowe przy użyciu 10 minut czasu QPU miesięcznie. Niektóre organizacje badawcze wymagają tak dużej ilości czasu QPU, że mają dedykowany komputer kwantowy IBM w swojej siedzibie.
Jednym z etapów estimation zasobów, który jest unikalny dla obliczeń kwantowych, jest głębokość obwodu. Jak wspomniano wcześniej, każda bramka kwantowa i każde opóźnienie pomiędzy operacjami wiąże się z szumem i pewnym prawdopodobieństwem błędu. Im głębszy obwód kwantowy, tym większy szum. Są tu dwie subtelności: bramki dwukubitowe mają znacznie wyższe wskaźniki błędów niż bramki jednokubitowe, więc często można pominąć głębokość jednokubitową. Ponadto nie wszystkie kubity na chipie kwantowym są bezpośrednio połączone. Czasami informacja musi być wymieniana pomiędzy kubitami, aby wykonać wymagane splątania, a sam ten proces wymiany wymaga bramek dwukubitowych. Ta wymiana jest obsługiwana w procesie zwanym "transpilacją", złożonym procesie, który służy także innym celom; zostanie to omówione bardziej szczegółowo w następnej lekcji. Istotną wielkością ograniczającą jest zatem transpilowana głębokość dwukubitowa. Dokładna maksymalna głębokość, przy której można uzyskać wyniki o wysokiej wierności, zależy od obwodu. Jednak dzięki nowoczesnym technikom łagodzenia błędów można uzyskać wyniki o wysokiej wierności przy transpilowanej głębokości dwukubitowej wynoszącej 80 lub więcej.
Alokacja - szeregowanie
Scheduling to proces allocation zasobów programom i zarządzania ich wykonaniem. Obejmuje to:
- Zgłoszenie job: Proces, w którym użytkownik wysyła żądanie (job) do systemu HPC, określając, jakie prace obliczeniowe i zasoby są potrzebne do wykonania.
- Allocation zasobów: Przypisanie dostępnych zasobów systemu HPC (takich jak węzły, CPU, pamięć) do zgłoszonego job na podstawie jego wymagań.
- Wykonanie job: Faktyczne uruchomienie zadań obliczeniowych zdefiniowanych przez job na przydzielonych zasobach HPC.
Istnieją analogie wszystkich tych procesów dla komputerów kwantowych.
- Jobs są zgłaszane przez użytkownika, z wykorzystaniem Qiskit Runtime, zazwyczaj przy użyciu prymitywu Qiskit Runtime, takiego jak
Sampler,Estimatorlub innych. - Użytkownik wybiera z listy backendów, do których ma dostęp. Pełną listę dostępnych backendów można zobaczyć na stronie Compute resources na IBM Quantum Platform. Często po prostu używa się najmniej obciążonego komputera kwantowego. Są jednak przypadki, w których ważne może być użycie konkretnego z powodu układu urządzenia, replikacji wcześniejszych obliczeń itp.
- Wykonanie quantum jobs jest podobne do przypadku HPC. Chociaż niektóre różnice zostały już nakreślone, warto kilka z nich powtórzyć tutaj. QPU zazwyczaj nie znajdują się obecnie na tym samym węźle co klasyczne zasoby obliczeniowe, lecz są połączone poprzez sieć. Może to mieć implikacje dla scheduling. Ponadto komputery kwantowe mogą mieć znaczne czasy queue, a czasy te są zmienne, co utrudnia precyzyjną kontrolę czasu. Sytuacja może być inna w przypadku systemów dedykowanych; zależy to od wewnętrznej administracji komputera kwantowego.
Kontrola/zarządzanie - zarządzanie obciążeniem
Workload management, znany także jako orkiestracja, to proces zarządzania wieloma programami i ich wymaganiami dotyczącymi zasobów. Obejmuje to:
- Provisioning zasobów: Proces przygotowywania i udostępniania zasobów HPC do użycia przez jobs, w tym konfiguracja sprzętu i oprogramowania. Jak zobaczymy później, QPU są zasobami obliczeniowymi, które mogą być provisioned podobnie do klasycznych zasobów HPC, z zastrzeżeniami z poprzedniej sekcji.
- Scheduling jobs: Działanie oprogramowania schedulera polegające na decydowaniu, które jobs są uruchamiane, kiedy i na których zasobach, zarządzanie priorytetami i queues w celu efektywnego wykorzystania systemu HPC. Chociaż to ogólne stwierdzenie odnosi się do zasobów kwantowych, kontrola nad czasem może być mniejsza niż w przypadku innych zasobów.
Przykład:
Rozważmy dobrze znane zadanie jako kontekst dla zrozumienia resource management: znajdowanie czynników pierwszych dużych liczb. Załóżmy dalej, że używany algorytm opiera się na sprawdzaniu siłowym każdego potencjalnego dzielnika. Chociaż często nie jest to najefektywniejsza metoda, łatwo zrozumieć, w jaki sposób może być zarządzany workload.
Planowanie - szacowanie zasobów
- Oszacuj, ile czasu CPU i pamięci może wymagać faktoryzacja pierwsza.
- Zaplanuj zrównoleglenie swojego zadania - ilu CPU/rdzeni użyjesz?
Alokacja - szeregowanie
- Po zgłoszeniu job, scheduler przypisuje rdzenie CPU i pamięć do zadania faktoryzacji pierwszej. Na przykład może przydzielić wszystkie potencjalne dzielniki kończące się cyframi
1, 3, 7, 9odpowiednio do jednego z czterech rdzeni. - Wykonanie job: Algorytm faktoryzacji pierwszej uruchamia się, wykonując dzielenia lub inne kroki faktoryzacji na przydzielonych zasobach, aż do zakończenia zadania.
Kontrola/zarządzanie - zarządzanie obciążeniem
- System orkiestruje kolejność i czas jobs faktoryzacji pierwszej w celu optymalizacji przepustowości.
- Najłatwiejszy do wyobrażenia przypadek to taki, w którym jeden z rdzeni znajduje docelowy czynnik pierwszy. Powinno to zatrzymać obliczenia na innych rdzeniach, aby mogły być użyte do następnego zadania.
Środowiska high-performance computing używają specjalnego oprogramowania do przeprowadzania tych kroków i zarządzania zasobami. W następnej sekcji poznamy szeroko stosowany system oprogramowania do resource management: Slurm.
Przykład z zasobami kwantowymi:
Workflow, który będzie przedmiotem innych lekcji tego kursu, to wyznaczanie stanów podstawowych i energii chemicznych przy użyciu sample-based quantum diagonalization (SQD). Jest to omówione bardziej szczegółowo w Lekcji 4, a także można odwiedzić ten kurs o SQD i pokrewne metody na IBM Quantum Learning. Wszystko, co musimy wiedzieć dla tej dyskusji, to że workflow obejmuje następujące elementy:
- Przygotowanie obwodu kwantowego
- Pomiar obwodu kwantowego
- Wykorzystanie wyników pomiarów do zrzutowania problemu na użyteczną podprzestrzeń
- Diagonalizacja mniejszej, zrzutowanej macierzy przy użyciu klasycznych zasobów obliczeniowych
- Iteracja, albo aby zapewnić samospójność przez rozważania takie jak zachowanie ładunku, i ewentualne iteracje obwodu kwantowego, jeśli ma on parametry wariacyjne.
Planowanie - szacowanie zasobów
- Odwzoruj orbitale elektronowe na kubity, aby ustalić liczbę potrzebnych kubitów.
- Połącz odwzorowany hamiltonian układu i (być może wariacyjny) stan w obwód kwantowy i sprawdź transpilowaną głębokość dwukubitową. Upewnij się, że jest rozsądna.
- Oszacuj rozmiar podprzestrzeni, na którą będziesz rzutować; na tej podstawie oszacuj, ile czasu CPU i pamięci może wymagać diagonalizacja.
- Zaplanuj zrównoleglenie swojego zadania - ilu CPU/rdzeni użyjesz?
Alokacja - szeregowanie
- Użytkownik wybiera QPU; proces transpilacji automatycznie odwzorowuje kubity w twoim abstrakcyjnym obwodzie kwantowym na fizyczne kubity na QPU. Jest to ważne, ponieważ abstrakcyjny obwód może zakładać bezpośrednią łączność, która nie istnieje na chipie, między innymi z innych powodów.
- Po zgłoszeniu job poprzez Qiskit Runtime, job trafia do queue dla wybranego QPU. Użytkownik nie ma kontroli nad czasem queue, choć może to być inaczej w przypadku systemów dedykowanych.
- Klasyczne zasoby obliczeniowe oczekują na wyniki kwantowe.
- Job diagonalizacji jest zgłaszany do zasobów HPC; po zgłoszeniu job, scheduler przypisuje rdzenie CPU i pamięć do zadania diagonalizacji.
- Wykonanie job: Algorytm diagonalizacji uruchamia się, diagonalizując mniejszą zrzutowaną macierz, aż do zakończenia zadania.
Kontrola/zarządzanie - zarządzanie obciążeniem
- System orkiestruje kolejność i czas kroków kwantowych i klasycznych na każdym etapie. Na przykład, gdy zrzutowana macierz zostanie zdiagonalizowana i uzyskana zostanie energia stanu podstawowego, w zależności od kryteriów zbieżności, workflow może wrócić do nowego obwodu kwantowego (z nowym parametrem wariacyjnym).
- Gdy kryteria zbieżności są spełnione przez energię stanu podstawowego, obliczenia na wszystkich rdzeniach zatrzymują się.
Środowiska high-performance computing używają specjalnego oprogramowania do przeprowadzania tych kroków i zarządzania zasobami. W następnej sekcji poznamy szeroko stosowany system oprogramowania do resource management: Slurm. Należy zauważyć, że Slurm nie posiada narzędzi do wszystkich kroków opisanych powyżej. Slurm nie zapewnia wsparcia dla planowania jobs ani szczegółowego workload management, takiego jak komunikacja między komponentami workload. Jest to dobrze dopasowane do obecnego stanu obliczeń kwantowych w HPC, ponieważ QPU są zazwyczaj dostępne przez sieć.
Sprawdź swoje zrozumienie
Załóżmy, że próbujesz przeszukać nieposortowaną bazę danych, aby znaleźć element, który nazwiemy 'celem'. Dla każdej z poniższych akcji podaj, do którego etapu resource management się odnosi:
(a) Szacowanie rozmiaru bazy danych i czasu potrzebnego do sprawdzenia każdego elementu
(b) Zapewnienie, że znalezienie celu na jednym GPU zatrzymuje proces na innych GPU, aby zwolnić je dla następnego problemu.
(c) Podzielenie przestrzeni wyszukiwania na regiony dla każdego z twoich (powiedzmy 10) GPU do przeszukania
Odpowiedź:
(a) Planowanie (b) Kontrola/zarządzanie (c) Alokacja/szeregowanie,
Oprogramowanie: Slurm
W tej sekcji zastosujemy w praktyce koncepcje poznane w tym rozdziale, korzystając z popularnego systemu zarządzania zasobami — Slurm.
Wprowadzenie do Slurm
Slurm to system zarządzania zasobami o otwartym kodzie źródłowym, powszechnie używany w środowiskach obliczeń wysokowydajnościowych. Udostępnia kompleksowy zestaw narzędzi do zarządzania zasobami, planowania zadań i monitorowania wydajności systemu.
Omówimy podstawy korzystania z Slurm, w tym:
- Przesyłanie zadań
- Alokację zasobów
- Monitorowanie zadań
Ponieważ naprawdę trudno jest zapewnić zasoby HPC każdemu uczestnikowi tego kursu, trochę „oszukamy” i udostępnimy Ci repozytorium z obrazami Docker, które naśladują rzeczywisty klaster HPC z Slurm, ale na małą skalę. Pomoże nam to ćwiczyć poznane koncepcje w bezpiecznym, odtwarzalnym środowisku.
Zauważ, że obecnie wszystkie zasoby kwantowe i klasyczne są alokowane na czas trwania całego eksperymentu. Obecnie nie ma naprzemiennej alokacji mieszanych zasobów. Ostatnie zastrzeżenie jest takie, że nawet po uruchomieniu zadania system kwantowy nie będzie bezpośrednio sterowany w sposób, jakiego mógłby oczekiwać częsty użytkownik HPC. Zadanie jest uruchamiane na dowolnym węźle x86, który wykonuje usługę Qiskit Runtime, a ta usługa runtime łączy się z innym harmonogramem, nad którym użytkownik nie ma bezpośredniej kontroli. Ten przepływ pracy i powiązane z nim problemy mogą być znane użytkownikom HPC, którzy mieli wczesne doświadczenia w dążeniu do wyłącznego dostępu do węzłów GPU (pierwotne zastosowanie gres).
Instrukcje instalacji i przegląd konfiguracji
Aby ćwiczyć łączenie zasobów kwantowych i HPC, będziesz potrzebować dostępu do rzeczywistego środowiska HPC lub musisz zasymulować środowisko HPC na swoim lokalnym komputerze. Przewodnik instalacji dla lokalnej konfiguracji z użyciem Docker można znaleźć w tym repozytorium. Przewodnik zawiera odnośniki do pomocy w konfiguracji konta IBM Cloud® oraz instalacji wtyczki SPANK dla QRMI. W tym repozytorium znajduje się również kilka plików Python do przetestowania Twojego środowiska.
Po zakończeniu instalacji użyjmy poniższego polecenia, aby sprawdzić zasoby obliczeniowe Slurm w Twoim terminalu. Jeśli instalacja się powiodła, powinieneś móc potwierdzić łącznie trzy wirtualne węzły.
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
normal up 5-00:00:00 2 idle c[1-2]
quantum* up infinite 1 idle q1
$ scontrol show node
NodeNAME=q1 Arch=x86_64 CoresPerSocket=1
CPUAlloc=0 CPUTot=1 CPULoad=0.34
AvailableFeatures=(null)
ActiveFeatures=(null)
Gres=qpu:1
NodeAddr=q1 NodeHostName=q1 Version=21.08.6
...
Mamy dwie partycje, czyli grupy węzłów: normal i quantum. Partycja normal składa się z węzłów, które mają dostęp tylko do zasobów klasycznych. Partycja quantum ma dostęp do zasobów kwantowych. Szczegóły każdego węzła można zobaczyć, wykonując polecenie scontrol show nodes.
Uruchom prosty przykład hello world w Slurm
Uruchommy najpierw prosty klasyczny przykład hello world z użyciem Slurm. W przykładach będziemy używać Pythona. Utwórzmy hello_world.py, który nie wymaga dodatkowego wyjaśnienia.
$ vim hello_world.py
import time
time.sleep(10)
print("Hello, World!")
~
Teraz musimy powiedzieć menedżerowi zasobów, jakich zasobów potrzebujemy do wykonania tego programu. Slurm udostępnia sposób określenia wszystkich metadanych zadania za pomocą skryptu przesyłającego, który jest po prostu skryptem shell z adnotacjami specyficznymi dla Slurm. Te adnotacje pozwalają określić wymagania dotyczące zasobów, parametry harmonogramowania i inne. Utwórzmy w tym celu skrypt shell hello_world.sh.
$ vim hello_world.sh
#SBATCH --job-name=hello-world
#SBATCH --output=hello-world.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=normal
srun hello_world.py
~
Przejrzyjmy plik przesyłający i zobaczmy, co się w nim dzieje.
Dyrektywy #SBATCH to specyficzne adnotacje określające, jakie mamy wymagania dotyczące wykonania programu. Tutaj możesz określić ilość zasobów — liczbę węzłów, liczbę zadań na węzeł, liczbę zadań i CPU na węzeł i zadanie — oraz inne opcje, takie jak nazwa pliku wyjściowego. Pełna lista opcji jest dostępna w dokumentacji Slurm.
Teraz nadszedł czas, aby uruchomić nasze zadanie Slurm. sbatch to polecenie, które akceptuje plik przesyłający i kolejkuje zadanie do wykonania w Slurm.
$ sbatch hello_world.sh
Submitted batch job 63
Sprawdźmy status naszego programu za pomocą polecenia squeue.
$ squeue
# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_world root R 0:01 1 c1
Po zakończeniu zadania możemy sprawdzić wynik, zaglądając do pliku wyjściowego.
$ cat hello_world_logs.txt
Hello, World!
Sprawdź swoje zrozumienie
Mając poniższy skrypt powłoki Slurm, jaka jest (a) nazwa zadania, (b) nazwa pliku Python oraz (c) nazwa pliku wyjściowego? (d) Wreszcie, czy może on korzystać z zasobów kwantowych, czy nie?
vim hello_learner.sh
#SBATCH --job-name=hello-learner
#SBATCH --output=hello-learner.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
srun hello_learner_qm.py
vim hello_learner.sh
#SBATCH --job-name=hello-learner
#SBATCH --output=hello-learner.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
srun hello_learner_qm.py
Odpowiedź:
(a) hello-learner (b) hello-learner_qm.py (c) hello-learner.out (d) Tak, mógłby. Korzysta on z partycji quantum.
Uruchom prosty przykład hello world Qiskit w Slurm
Następnie spróbujmy wykorzystać również zasoby kwantowe. Stwórzmy i uruchommy prosty program "Hello, Qiskit", który korzysta z zasobów kwantowych.
$ vim hello_qiskit.py
# hello_qiskit.py
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import EstimatorV2 as Estimator
# Create a new circuit with two qubits
qc = QuantumCircuit(2)
# Add a Hadamard gate to qubit 0
qc.h(0)
# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)
observables_labels = ["IZ", "IX", "ZI", "XI", "ZZ", "XX"]
observables = [SparsePauliOp(label) for label in observables_labels]
# switch to QRMI service
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.backend("...")
# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
# Construct the Estimator instance.
estimator = Estimator(mode=backend)
estimator.options.resilience_level = 1
estimator.options.default_shots = 5000
mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]
# One pub, with one circuit to run against five different observables.
job = estimator.run([(isa_circuit, mapped_observables)])
job_result = job.result()
pub_result = job.result()[0]
print("Result", pub_result)
Tutaj użyjemy quantum resource management interface (QRMI), wtyczki Slurm SPANK do obsługi zasobów i zadań kwantowych, która została opracowana wspólnie przez IBM, Pasqal, The Hartree Center oraz RPI. Stworzyliśmy prosty obwód pauli-2-design z losowymi wartościami początkowymi oraz prosty observable i uruchomimy go przy użyciu Estimator, aby uzyskać wartość oczekiwaną. Aby go uruchomić, ponownie potrzebujemy skryptu zgłoszeniowego hello_qiskit.sh, który będzie wymagał zasobów kwantowych.
$ vim hello_qiskit.sh
#SBATCH --job-name=hello-qiskit
#SBATCH --output=hello_qiskit.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-nodes=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
#SBATCH --gres=qpu:1
srun python /data/ch2/hello_qiskit/hello_qiskit.py
~
Przyjrzyjmy się plikowi zgłoszeniowemu i zobaczmy, co się tam dzieje. Mamy jedną nową opcję, którą jest gres. gres to opcja Slurm służąca do definiowania dodatkowych zasobów obliczeniowych. W naszym przypadku tym nowym zasobem będzie nasz zasób kwantowy. Ponieważ określiliśmy zasoby oraz partycję naszego klastra, w której dostępne są zasoby kwantowe, nasze prymitywy Qiskit użyją tych przydzielonych zasobów do wykonania obciążenia kwantowego.
Nadszedł czas, aby uruchomić nasze zadanie Slurm.
$ sbatch hello_qiskit.sh
Następnie sprawdźmy status naszego programu za pomocą polecenia squeue.
$ squeue
# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_qiskit root R 0:01 1 q1
Po zakończeniu zadania możemy przejrzeć logi i wyniki.
$ cat hello_qiskit.out | grep Exp
Expectation Value: 0.8372900070983516
Podsumowanie
Do tej pory dowiedzieliśmy się, czym są zasoby obliczeniowe i jak ich używać do uruchamiania programów w środowiskach heterogenicznych. Stworzyliśmy i uruchomiliśmy również dwa proste programy 'Hello World': jeden dla zasobu klasycznego, a drugi dla zasobu kwantowego, oraz nauczyliśmy się tworzyć skrypty powłoki do zgłaszania zadań i przeglądania wyników.
W kolejnej lekcji wykorzystamy tę wiedzę o kontroli zasobów, aby zastosować modele programowania do zasobów pozyskanych podczas wykonywania zadania.
Cały kod i skrypty używane w tym rozdziale są dostępne dla Ciebie w naszym repozytorium GitHub.