Programowanie GPU z Python

Programowanie GPU z Python
W tym artykule zanurzymy się w programowaniu GPU z Pythonem. Korzystając z łatwości Pythona, możesz odblokować niesamowitą moc obliczeniową GPU karty graficznej (jednostka przetwarzania grafiki). W tym przykładzie będziemy współpracować z biblioteką NVIDIA CUDA.

Wymagania

Do tego ćwiczenia będziesz potrzebować fizycznej maszyny z Linux i GPU opartym na NVIDIA, albo uruchom instancję GPU na Amazon Web Services. Albo powinien działać dobrze, ale jeśli zdecydujesz się na użycie maszyny fizycznej, musisz upewnić się, że masz zainstalowane sterowniki zastrzeżone NVIDIA, patrz instrukcje: https: // linuxhint.com/instal-nvidia-drivers-linux

Będziesz także potrzebował zainstalowanego zestawu narzędzi CUDA. Ten przykład używa Ubuntu 16.04 LTS W szczególności, ale dostępne są pobieranie większości głównych dystrybucji Linux w następującym adresie URL: https: // deweloper.nvidia.COM/CUDA-DOWNLOODS

Wolę .Pobieranie oparte na Deb, a te przykłady założą, że wybrałeś tę trasę. Pobrany plik to .Pakiet Deb, ale nie ma .rozszerzenie Deb, więc zmiana nazwy na posiadanie .Deb na końcu jego pomocny. Następnie instalujesz go z:

sudo dpkg -i -plecak -nazwa.Deb

Jeśli masz monit o instalację klawisza GPG, postępuj zgodnie z podanymi instrukcjami.

Teraz musisz zainstalować sam pakiet CUDA. Aby to zrobić, uruchom:

Sudo apt-get Aktualizacja
sudo apt -get install cuda -y

Ta część może potrwać trochę czasu, więc możesz chcieć wziąć filiżankę kawy. Po zakończeniu zalecam ponowne uruchomienie, aby upewnić się, że wszystkie moduły są prawidłowo przeładowane.

Następnie będziesz potrzebować dystrybucji Python Anaconda. Możesz pobrać to tutaj: https: // www.anakonda.com/pobierz/#Linux

Chwyć wersję 64-bitową i zainstaluj ją w ten sposób:

sh anaconda*.cii

(Gwiazda w powyższym poleceniu zapewni, że polecenie zostanie uruchomione niezależnie od drobnej wersji)

Domyślna lokalizacja instalacji powinna być w porządku, aw tym samouczku użyjemy go. Domyślnie instaluje się do ~/anaconda3

Na końcu instalacji zostaniesz poproszony o podjęcie decyzji, czy chcesz dodać Anacondę do swojej ścieżki. Odpowiedz tak tutaj, aby ułatwić uruchomienie niezbędnych poleceń. Aby zapewnić tę zmianę, po zakończeniu instalatora wyloguj się, a następnie zaloguj się z powrotem na swoje konto.

Więcej informacji na temat instalacji AnaConda: https: // Linuxhint.com/install-anaconda-python-on-ubuntu/

Wreszcie będziemy musieli zainstalować NUMBA. Numba używa kompilatora LLVM do kompilacji Pythona do kodu maszynowego. To nie tylko poprawia wydajność zwykłego kodu Pythona, ale także zapewnia klej niezbędny do wysyłania instrukcji do GPU w formie binarnej. Aby to zrobić, uruchom:

CDED instaluj Numba

Ograniczenia i korzyści programowania GPU

Kuszące jest myślenie, że możemy przekonwertować każdy program Python na program oparty na GPU, dramatycznie przyspieszając jego wydajność. Jednak GPU na karcie graficznej działa znacznie inaczej niż standardowy procesor w komputerze.

PROPUS obsługuje wiele różnych danych wejściowych i wyjściowych oraz mają szeroki asortyment instrukcji dotyczących radzenia sobie z takimi sytuacjami. Są również odpowiedzialni za dostęp do pamięci, radzenie sobie z magistralą systemową, obsługę pierścieni ochrony, segmenty i funkcjonalność wejściowa/wyjściowa. Są ekstremalnymi wielozadaniowcami bez konkretnego skupienia.

Z drugiej strony GPU są zbudowane w celu przetwarzania prostych funkcji z oślepiająco szybką prędkością. Aby to osiągnąć, oczekują bardziej jednolitego stanu danych wejściowych i wyjściowych. Poprzez specjalizowanie się w funkcjach skalarnych. Funkcja skalarna wymaga jednego lub więcej danych wejściowych, ale zwraca tylko jedno wyjście. Wartości te muszą być typy wstępnie zdefiniowane przez Numpy.

Przykładowy kod

W tym przykładzie utworzymy prostą funkcję, która ma listę wartości, dodaje je razem i zwraca sumę. Aby zademonstrować moc GPU, uruchomimy jedną z tych funkcji na procesorze i jedną na GPU i wyświetlimy czasy. Udokumentowany kod jest poniżej:

importować Numpy jako NP
Od czasu importuj default_timer jako timer
z Numba Import Vectorize
# Powinno to być zasadniczo wysoka wartość. Na mojej maszynie testowej to zajęło
# 33 sekundy na uruchomienie procesora i nieco ponad 3 sekundy na procesorze graficznym.
Num_elements = 100000000
# To jest wersja procesora.
def vector_add_cpu (a, b):
C = NP.zer (num_elements, dtype = np.float32)
Dla i w zakresie (Num_Elements):
c [i] = a [i] + b [i]
zwrot c
# To jest wersja GPU. Zwróć uwagę na dekorator @vectorize. To mówi
# Numba, aby przekształcić to w funkcję wektoryzowaną GPU.
@Vectorize ([„float32 (float32, float32)”], target = 'cuda')
def vector_add_gpu (a, b):
zwrócić A + B;
def main ():
a_source = np.te (num_elements, dtype = np.float32)
b_source = np.te (num_elements, dtype = np.float32)
# Czas funkcji procesora
start = timer ()
wektor_add_cpu (a_source, b_source)
vector_add_cpu_time = timer () - start
# Czas funkcji GPU
start = timer ()
wektor_add_gpu (a_source, b_source)
vector_add_gpu_time = timer () - start
# Czasy raportu
Drukuj („Funkcja procesora zajęła %F sekund.„ % wektor_add_cpu_time)
Drukuj („Funkcja GPU zajęła %F sekund.„ % wektor_add_gpu_time)
powrót 0
Jeśli __name__ == "__main__":
główny()

Aby uruchomić przykład, wpisz:

Python GPU-przykład.py

Uwaga: Jeśli napotykasz problemy podczas uruchamiania programu, spróbuj użyć „CDEA Install Accelerate”.

Jak widać, wersja procesora działa znacznie wolniej.

Jeśli nie, twoje iteracje są zbyt małe. Dostosuj NUM_ELEMNES do większej wartości (na mojej, znak bramki wydawał się wynosić około 100 milionów). Wynika to z faktu, że konfiguracja GPU zajmuje niewielką, ale zauważalną ilość czasu, więc aby operacja jest tego warta, potrzebne jest wyższe obciążenie pracą. Po podniesieniu go powyżej progu urządzenia zauważysz znaczne ulepszenia wydajności wersji GPU w wersji procesora.

Wniosek

Mam nadzieję, że podobało Ci się nasze podstawowe wprowadzenie do programowania GPU z Pythonem. Chociaż powyższy przykład jest trywialny, zapewnia ramy, które musisz podjąć swoje pomysły, wykorzystując moc GPU.