ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL •...

31
JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA Marcin Lewandowski [ [email protected] ]

Transcript of ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL •...

Page 1: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA

Marcin Lewandowski [ [email protected] ]

Page 2: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

HPC

2

Page 3: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Co zrównoleglać (logicznie i fizycznie)?

• Programowanie z asynchronicznymi zdarzeniami – np. interfejs użytkownika, komunikacja sieciowa, obsługa operacji I/O (pliki), etc.

• Programy których wydajność można zwiększyć przez ukrycie latencji (opóźnień): – Długo trwające operacje I/O (zapis/odczyt z plików, komunikacja

sieciowa) – W czasie trwania tych operacji program może wykonać inną

potrzebną pracę • Programy intensywnie obliczeniowe:

– Zagadnienia numeryczne, które silnie wykorzystują jednostki obliczeniowe mogą uzyskać znacznie przyśpieszenie przy wykonywaniu na komputerze z wieloma procesorami/rdzeniami jeśli zadani zostanie podzielone na wątki (lub procesy)

3

Page 4: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Równoległość zadań

4 Źródło: http://en.wikipedia.org/wiki/OpenMP

Page 5: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Co to jest proces?

• Niezależny kontekst wykonawczy wraz z własną odizolowaną przestrzenią pamięci i zasobami

• Procesy pomiędzy sobą nie dzielą niczego (z wyjątkiem maszyny ;-)

• Procesy muszą komunikować się między sobą za pomocą mechanizmów IPC (Inter-Process Communication); do wymiany danych oraz synchronizacji

• Procesy są „ciężkie” (wymagają sporo zasobów)

5

Page 6: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Co to jest wątek?

• Kontekst wykonywania programu • Współdzieli pamięć i stan ze swoim rodzicem

(procesem w którym żyje). • Wątki są „lekkie” (tj. nie wymagają dużych zasobów) • Posiadają własny stos (i prywatne zmienne lokalne) • Nie muszą używać IPC do komunikacji z innymi

wątkami w procesie • Wątki Python = wątki systemu operacyjnego (w Linux

POSIX “Threads” – pthreads)

6

Page 7: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Wątek vs. Proces

• Wątki współdzielą wszystko, dlatego programista musi pilnować wielodostępu do wspólnych danych

• Procesy nie współdzielą nic, dlatego programista musi explicite zatroszczyć się o współdzielenie danych/stanu pomiędzy procesy

7

Page 8: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Python GIL

• Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem, co niestety ogranicza możliwość fizycznego zrównoleglenia.

• Co robi GIL: – GIL zapewnia, że tylko jeden wątek jest wykonywany w

danej chwili przez interpreter Pythona (cPythonVM) – GIL kontroluje sposób wykonywania wątków. Python ustala

jak długo wątek ma być wykonywany (~10 instrukcji). – Python wykorzystuje wątki systemu operacyjnego, ale sam

kontroluje przekazywanie kontekstu wykonawczego.

8

Page 9: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

GIL

• Co dobrego daje GIL: – Realizuje koncepcję kooperatywnej wielozadaniowości – Interpreter wie najlepiej kiedy bezpiecznie przełączyć

kontekst wykonywania – Często jest bardzie efektywny od wielozadaniowości z

wywłaszczaniem – Może być ‚zwolniony’ w module C (np. dla

długotrwałych operacji I/O) – Łatwe kodowanie (nie musimy się pilnować) – Łatwą implementację modułów rozszerzeń

9

Page 10: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Moduły Moduł Funkcje

thread _thread (w Python 3+)

Nisko poziomowy moduł do wielowątkowości

threading Wysoko poziomowy moduł do wielowątkowości (zbudowany na bazie modułu thread)

multiprocessing Wysoko poziomowy moduł do wieloprocesowości

subprocess Zarządzanie podprocesami

select Waiting for I/O completion

10

Page 11: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Moduł threading

• Wysoko poziomowy moduł do realizacji wielowątkowości

• Zbudowany na nisko poziomowym module thread

• Działa w oparciu o wątki systemu operacyjnego

• Równoległość jest ograniczona przez GIL

11

Page 12: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Obiekt threading.Thread • class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}) – konstruktor

z argumentami nazwanymi: – group – powinno być None; zarezerwowane dla przyszłych rozszerzeń (ThreadGroup). – target – wołalny obiekt, który ma być uruchomiony w nowym wątku przez metodę run() – name – nazwa wątku. Domyślnie tworzona w konstruktorze w postaci “Thread-N”, gdzie N jest liczbą. – args – is the argument tuple for the target invocation. Defaults to (). – kwargs – is a dictionary of keyword arguments for the target invocation. Defaults to {}.

• Jeśli podklasa nadpisuje konstruktor musi wywołać na samym początku metodę klasy bazowej Thread.__init__().

• Thread.start() – startuje wątek. Musi być wywołana tylko raz dla obiektu (zgłasza wyjątek RuntimeException jeśli wywołana więcej razy). Startuje wątek, w którym będzie wywołana metoda run().

• Thread.run() – metoda realizowana w wątku, która może być przedefiniowana w klasie potomnej. Metoda w klasie bazowej wywołuje obiekt przekazany w konstruktorze (target) z argumentami args i kwargs.

• Thread.join([timeout]) – czeka na zakończenie wątku. Jest to metoda blokująca z zadanym czasem timeout (float w sekundach). W celu określenia stanu wątku po timeout należy użyć metod: isAlive(). Metoda join() może być wywoływana wiele razy dla jednego wątku.

12

Page 13: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Obiekt threading.Lock • Prymitywny obiekt synchronizacyjny typu lock; nie związany z

konkretnym wątkiem. • Lock ma dwa stany „locked” i „unlocked”. Po utworzeniu jest w

stanie „unlocked”. • Lock.acquire() – Gdy w stanie „unlocked” zmienia natychmiast stan

na ”locked”; Gdy w stanie „locked”, acquire() blokuje do momenty wywołania release() w innym wątku i ustawia do stanu „locked”.

• Lock.release() – powinna być wołana tylko w stanie „locked” w celu natychmiastowej zmiany stanu na „unlocked”. Wyjątek RuntimeError jest generowany gdy zwalniany jest obiekt w stanie „unlocked”. Gdy więcej wątków jest zablokowanych na acquire(), tylko jeden z nich jest odblokowywany dla jednego wywołania release().

• Wszystkie te metody są wykonywane atomowo.

13

Page 14: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Obiekt threading.Semaphore • Jeden z najstarszy obiektów synchronizacyjnych (wymyślony przez W.

Dijkstra). • Semafor zarządza wewnętrznym licznikiem, który jest zmniejszany przy

każdym wywołaniu acquire() i zwiększany przy każdym wywołaniu release(). Licznik jest zawsze >=0

• Funkcja acquire() wołana dla Semafora o wartości 0 blokuje się do momentu kiedy inny wątek wywoła release().

• class threading.Semaphore([value]) – tworzy semafor; opcjonalny argument value określa początkową wartość licznika (domyślnie 1).

• Semaphore.acquire([blocking]) – pobiera semafor. – Wywołany bez argumentów (lub blocking=Ture): jeśli licznik >0 zmniejsza jego

wartość o 1 i wraca natychmiast, jeśli licznik=0 blokuje do do momentu wywołania release() w innym wątku.

– Wywołany z blocking=False: działa w trybie nie blokującym zwracając False natychmiast gdy nie może pobrać semafora lub True gdy udało się go pobrać.

• Semaphore.release() – zwalnia semafor; zwiększając stan licznika o 1.

14

Page 15: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Moduł multiprocessing • Interfejs „wielowątkowy” opartym na procesach • Składnia analogiczna do modułu threading:

– threading : • Thread(target=do_work, args=(work_queue,))

– multiprocessing: • Process(target=do_work, args=(work_queue,))

• TRZEBA PAMIĘTAĆ!

– Procesy nie współdzielą NICZEGO (w szczególności pamięci)! – Wymiana danych pomiędzy procesami może odbywać się przez

jeden z mechanizmów komunikować IPC (Inter-Process Communication)

15

Page 16: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Wątki Python/C

• Python może tworzyć wątki w modułach C/C++: – Wątki C/C++ są niezależnymi wątkami natywnymi

(nie Pythonowymi) i potencjalnie mogą działać równolegle (o ile zwolnimy GIL).

– W modułach C można programowo zwolnić GIL

• Inną alternatywą jest utworzenie wielu interpreterów Pythona (w jednym lub wielu procesach)

16

Page 17: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Python IPC & Networking • Następujące moduły zapewniają mechanizmy komunikacji IPC:

– subprocess – zarządzanie procesami potomnymi + mechanizm strumieni I/O (popen)

– socket – nisko poziomowy interfejs sieciowy – ssl – warstwa SSL dla socket – signal – obsługa sygnałów dla zdarzeń asynchronicznych – asyncore – asynchroniczne socket – asynchat – asynchroniczne socket + komenda/odpowiedź

• signal, subprocess – działają tylko dla dwóch procesów na tej samej maszynie

• inne moduły komunikacji sieciowej mogą służyć do komunikacji wielu procesów na jednej lub wielu maszynach w sieci.

17

Page 18: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Sumowanie liczb pierwszych 3 implementacje

• Suma liczb pierwszych w zakresie 1-10000 – Jednowątkowa – 152 sek. – Wielowątkowa – 425 sek. ! – Wieloprocesowa – xxx sek.

18 Na podstawie: Jesse Noller, Getting started with Concurrency ...using Multiprocessing and Threading, PyWorks, Atlanta 2008

EX: hpc

Page 19: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Sumowanie liczb pierwszych 3 implementacje

19

MT 4 wątki

Page 20: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Poważne HPC

• MPI – Message Passing Interface – dla systemów z pamięcią rozproszoną (http://www.mcs.anl.gov/research/projects/mpi)

• OpenMP – dla systemów z pamięcią współdzieloną (http://openmp.org)

20

Page 21: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

MPI w Python – mpi4py

• MPI jest de facto standardem dla systemów z typu message-passing.

• MPI jest zestawem API (Application Programmer Interfaces) wywoływalnych przez programy użytkownika w C/C++ (i innych językach)

• Istnieje wiele implementacji MPI – zarówno open source (generyczne) oraz zamknięte i zoptymalizowane do konkretnych maszyn.

21

Page 22: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Implementacje MPI dla Pythona

• mpi4py (http://mpi4py.scipy.org) – API bazuje na bibliotece MPI-2 C++ – Działa z open-source implementacjami MPI

(MPICH2, Open MPI, MPICH1, LAM) – mpi4py pozwala na użycie z Pythona kodu

C/C++/Fortran opartego na MPI (za pomocą: Cython, SWIG, F2Py)

• pympi (http://pympi.sourceforge.net) – Starsza implementacja

22 Patrz: http://fperez.org/py4science/2009_siam_cse/mpi4py_ldalcin_bgranger_siam_cse09

Page 23: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

GPGPU

• PyCUDA – Zapewnia na pełny dostęp do Nvidia CUDA API z

Pythona – Many abstractions are already provided for you

• PyOpenCL – j.w. ale przez interfejs OpenCL

23

Page 24: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Różne takie inne opcje

• IPython for parallel computing • Bulk Synchronous Parallel (BSP) model sequence of

super steps • Twisted – reactor based architectures • MPI (pyMPI, Pypar, MPI for Python, pypvm) • Pyro (distributed object system) • Linda (PyLinda) • Scientific Python (master/slave computing model) data

distribution through call parameters/replication • …

24

Page 25: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Lektura uzupełniająca

• Norman Matloff, Programming on Parallel Machines, http://heather.cs.ucdavis.edu/˜matloff/ParProcBook.pdf

• Maurice Herlihy, Nir Shavit, The Art of Multiprocessor Programming, Morgan Kaufmann,2008

• Rohit Chandra, Ramesh Menon, Leo Dagum, David Kohr, Dror Maydan, Jeff McDonald, Parallel Programming in OpenMP, Morgan Kaufmann, 2000

• Barbara Chapman, Gabriele Jost, Ruud van der Pas, Using OpenMP: Portable Shared Memory Parallel Programming, MIT Press, 2007

25

Page 26: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

PYTHON + FORTRAN

26

Page 27: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

f2py • f2py pozwala na automatyczne tworzenie modułów rozszerzeń PYTHON z kodu Fortran 77/90/95:

– F2py automatycznie generuje funkcje obudowujące (wrappers) dla Pythona z kodu Fortran 77/90/95 – Alternatywnie można określić sposób obudowywania procedur w pliku definicji interfejsu.

• Przykładowa procedura dodająca dwa wektory A i B (pamięć dla wszystkich tablic zapewniona przez procedurę wywołującą): C *** Plik add.f *** SUBROUTINE ZADD(A,B,C,N) C DOUBLE COMPLEX A(*) DOUBLE COMPLEX B(*) DOUBLE COMPLEX C(*) INTEGER N DO 20 J = 1, N C(J) = A(J)+B(J) 20 CONTINUE END

• Wywołanie f2py:

> f2py -m add add.f

• Co powinno wygenerować moduł o nazwie: addmodule.c, który można następnie skompilować jak każdy inny moduł C do Pythona.

27

Page 28: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Co potrafi f2py • Tworzy pliki sygnatur dla kodu/funkcji Fortran (pliki .pyf); sygnatury

zawierają wszystkie informacje o funkcji (nazwa, argumenty i ich typy), które są konieczne do utworzenia funkcji opakowującej (wrapper) w C

• Pliku sygnatur można utworzyć „ręcznie” lub może być zmodyfikowany po wygenerowaniu

• Sygnatury mogą być modyfikowane w celu zmiany sposobu przetwarzania argumentów przekazywanych Python->C->Fortran: – F2PY śledzi zależności pomiędzy argumentami (sprawa kolejności inicjalizacji) – Argumenty mogą być opcjonalne lub niewidoczne, co ułatwia wołanie funkcji z

Pythona – Generalnie można dowolnie zmienić sygnaturę funkcji Fortran (np. zmiana

argumentów ich kolejności, typów). Argumenty będą przetworzone zanim trafią do rzeczywistej funkcji Fortran

• F2PY automatycznie generuje dokumentację __doc__ (opcjonalnie też LaTeX) dla tworzonych rozszerzeń

28

Page 29: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

F2py – kompilacja modułu • f2py potrafi także kompilować moduł Fortran i moduł

rozszerzeń: > f2py -c -m add add.f

• Skomplilowany moduł jest już dostępny Python: >>> import add >>> print add.zadd.__doc__ zadd - Function signature: zadd(a,b,c,n) Required arguments: a : input rank-1 array(’D’) with bounds (*) b : input rank-1 array(’D’) with bounds (*) c : input rank-1 array(’D’) with bounds (*) n : input int

29 Patrz dokumentacja: „NumPy User Guide”

Page 30: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

f2py używany z Pythona

• f2py jest napisany w Python i może być z niego bezpośrednio używany:

• Przykład – otwórz, skompiluj i użyj : import numpy.f2py as f2py fid = open(’add.f’) source = fid.read() fid.close() f2py.compile(source, modulename=’add’) import add # use it!!!

30

Page 31: ĘZYK PYTHON DLA KAŻDEGO NAUKOWCAftp.us4us.eu/.../Python_dla_naukowca2-HPC.pdf · Python GIL • Python GIL (Global Interpreter Lock) – zabezpiecza interpreter Pythona przed wielodostępem,

Materiały dodatkowe

• F2py example http://websrv.cs.umt.edu/isis/index.php/F2py_example

• Wrapping Fortran libraries http://www.eurotcl.org/2010/Download/EuroTcl2010-Article-Wrapping_fortran_ArjenMarkus.pdf

• Interfacing Python with Fortran www-uxsup.csx.cam.ac.uk/courses/PythonFortran/f2py1.pdf www-uxsup.csx.cam.ac.uk/courses/PythonFortran/f2py2.pdf

• Wrapping Fortran Code for Python with F2PY mentat.za.net/ctpug-numpy/nmarais-f2pytalk.pdf

31