Obsługa przyspieszania wieloprocesowego i wielowątkowego
Ta strona opisuje, w jakim zakresie qiskit-addon-sqd obsługuje przyspieszanie wielowątkowe i wieloprocesowe oraz jakie założenia może przyjąć programista obliczeń wysokiej wydajności (HPC) przy integrowaniu tego pakietu z przyspieszonym obciążeniem.
Założenie jednowątkowości
O ile nie określono inaczej, API w tym pakiecie są przeznaczone do wywoływania z jednego wątku. Wysokopoziomowe API udostępniane przez ten pakiet nie gwarantują reentrancji, a użytkownicy końcowi nie powinni wywoływać ich z żadnego wątku innego niż wątek główny.
Zbiorcze wykonanie wieloprocesowe
Ten pakiet obsługuje zbiorcze przyspieszanie wieloprocesowe w stylu SPMD (single-program, multiple-data), w którym cały program jest uruchamiany jako wiele izolowanych procesów działających z jawną globalną synchronizacją i komunikacją między nimi (na przykład mpirun -n 128 python my_program.py). Ponieważ styl SPMD dobrze współpracuje z harmonogramami zadań i innym oprogramowaniem równoległym oraz skaluje się do dużej liczby procesów, jest to zalecany model dla obciążeń wysokiej wydajności i dużej skali i jest on tematem tej strony.
Chociaż pakiet został zaprojektowany tak, by obsługiwać różne backendy wykonania zbiorczego, jego obecna implementacja jest ukierunkowana na MPI, standardowe API przekazywania komunikatów dla systemów HPC. Niezależnie od implementacji pakiet zakłada, że każdym procesem steruje jeden wątek. W przypadku MPI odpowiada to MPI_THREAD_FUNNELED lub niższemu poziomowi.
Jeśli funkcja obsługuje wykonanie zbiorcze, jej dokumentacja musi to stwierdzać. Jeśli dokumentacja nie wspomina o wykonaniu zbiorczym, funkcja nie ma semantyki zbiorczej i musi być wywoływana wyłącznie z procesu sterującego.
Szczegółowa semantyka wartości zwracanych i synchronizacji funkcji zbiorczej jest opisana razem z samą funkcją. Ogólnie dokumentacja powinna jasno określać:
-
Czy funkcja ma być wywoływana niezależnie przez każdy proces na jego własnych danych lokalnych, czy zbiorczo przez wszystkie procesy.
-
Jak jej argumenty muszą być zgodne między procesami.
-
Jak dostarczana jest jej wartość zwracana — czy wynik istnieje tylko w procesie sterującym, czy wszystkie procesy otrzymują tę samą wartość, czy też każdy proces otrzymuje uchwyt do lokalnej części rozproszonej struktury danych.
Obecnie tylko jedna funkcja obsługuje wywołanie zbiorcze ze wszystkich procesów: diagonalize_fermionic_hamiltonian(). Gdy jest wywoływana zbiorczo, krok solwera wartości własnych jest miejscem, w którym uczestniczą wszystkie procesy i wnoszą pracę, więc implementacja solwera może wykorzystać każdy proces. Pozostałe części pętli odzyskiwania konfiguracji nie mają implementacji rozproszonej i działają tylko w procesie sterującym (rank 0).
Każda podprzestrzeń iteracji jest przekazywana do solwera wartości własnych w jednym wywołaniu, więc implementacja może swobodnie podzielić procesy na grupy i diagonalizować kilka podprzestrzeni równolegle. To, jak solwer wykorzystuje dostępne mu procesy, jest właściwością danego solwera wartości własnych.
Niektóre istniejące implementacje solwerów wartości własnych wymagają, aby program wywołujący działał poza środowiskiem MPI/SPMD, ponieważ same uruchamiają i zarządzają własnymi procesami równoległymi, na przykład wywołując mpirun w imieniu użytkownika. Ten tryb jest wygodny w pracy interaktywnej i w notebookach i nadal jest obsługiwany; jego wymagania wobec programu wywołującego opisano w dokumentacji API funkcji diagonalize_fermionic_hamiltonian().
Obsługa błędów w kontekście wieloprocesowym
Funkcja wywoływana zbiorczo ze wszystkich procesów nie może zgłaszać wyjątku ani przerywać tylko jednego procesu, ponieważ pozostawiłoby to pozostałe procesy w zakleszczeniu lub niespójnym stanie. Zamiast tego obsługa błędów opiera się na semantyce fail-stop dla całego kontekstu wykonania: w razie błędu implementacja musi być gotowa przerwać zbiorczo cały kontekst wykonania (na przykład używając MPI_Abort).
API nie może zagwarantować skoordynowanego raportowania błędów ani zbiorczego dostarczania wyjątków między procesami, ponieważ implementacje MPI nie dają takich gwarancji. Implementacja może dodatkowo próbować uwidocznić błąd dla wszystkich uczestniczących procesów — na przykład sprawiając, że każdy proces zgłasza wyjątek — ale można to zapewnić jedynie w trybie best-effort i nie wolno na tym polegać w kwestii poprawności ani odzyskiwania.
Są to właściwości, które implementacja zbiorcza może mieć, a nie gwarancje dotyczące jakiejkolwiek konkretnej implementacji. W tym pakiecie jedynym krokiem zbiorczym jest solwer wartości własnych (zobacz poprzednią sekcję); jego domyślna implementacja nie jest rozproszona, więc te uwagi dotyczą niestandardowego, zbiorczego solwera wartości własnych dostarczonego przez użytkownika.