Programowanie Równoległe wykład 13 Symulacje komputerowe cieczy LBM w CUDA Maciej Matyka Instytut Fizyki Teoretycznej
Transport cieczy i gazów W wielu dziedzinach trzeba rozwiązać zagadnienie transportu cieczy lub gazów aerodynamika opływ (np. samochodów sport biologia i medycyna przepływy w naczyniach krwionośnych próby przewidzenia miejsc narażonych na deformacje technika transport w ośrodkach porowatych problemy optymalizacji przewidywanie pogody etc.
Metody rozwiązania Skala makro (continuum) Navier Stokes Equations (NSE) Smoothed Particle Hydrodynamics (SPH) Dissipative Particle Dynamics (DPD) The Lattice Boltzmann Method (LBM) Lattice Gas Automata (LGA) Molecular Dynamics (MD) Skala mikro (poziom atomowy)
Metody rozwiązania Skala makro (continuum) Navier Stokes Equations (NSE) Lattice Gas Automata (LGA) Molecular Dynamics (MD) Skala mikro (poziom atomowy)
Równania Naviera--Stokesa Równania Naviera-Stokesa dla cieczy nieściśliwej: Nieliniowe równanie różniczkowe drugiego rzędu + równanie ciągłości (gęstość stała) http://en.wikipedia.org/wiki/navier-stokes equations
Rozwiązywanie równań NS Linearyzacja do postaci Ax=B Metody: FDM, FVM, FEM rozwiązanie układu równań liniowych (np. metody iteracyjne) Problemy: Problem nieliniowy zamieniamy na problem liniowy Stabilność / dokładność / istnienie rozwiązania Czas obliczeń Skala w zasadzie tylko continuum Złożoność algorytmów i podatność na błędy (zadanie w zasadzie na lata)
Dynamika molekularna Ogromna ilość atomów Potencjał L-J równania ruchu oddziaływanie atomu z atomem Skala mikroskopowa Allen, M.P et al., Computer Simulation of Liquids, Oxford Univ. Press.
Model gazu sieciowego LGA Najbardziej znanym modelem gazu sieciowego jest opisany przez U. Frisha, B. Hasslachera iy. Pomeau gaz FHP Rys. Kolizje w modelu FHP5 Transport Kolizje U. Frish, B. Hasslacher, Y. Pomeau 1986 Lattice-Gas Automata for the Navier-Stokes Equation, Phys. Rev. Lett. 56, 1505 1508.
LGA w praktyce Praca magisterska: Sebastian Szkoda, Implementacja modelu FHP w technologii NVIDIA CUDA http://www.ift.uni.wroc.pl/~sebastian.szkoda/seb astianszkoda_msc.pdf Implementacja przez podział przestrzenny z komunikacją Przyspieszenie względem CPU Porównanie FHP3 do doświadczenia MPI Bremen)
Problemy Model gazu sieciowego LGA szum statystyczny wymaga uśredniania w czasie wymaga uśredniania w przestrzeni wymaga dużych siatek (pamięć)
Metoda gazu sieciowego Boltzmanna Historycznie wprowadzona jako rozwinięcie LGA Zmienne ni (0,1) zamienione na funkcje rozkładu
Popularność LBM Artykuły w PRE / PRL wspominające o metodzie Boltzmanna czasopisma najbardziej znane dla nas fizyków Wybór sposobu szukania tendencyjny, ale rezultat o czymś mówi
Funkcja rozkładu Funkcja rozkładu jest zdefiniowana jako liczba cząsteczek w skończonym elemencie przestrzeni pędów i położeń: Zadaniem teorii kinetycznej jest znalezienie funkcji dystrybucji dla zadanych oddziaływań międzycząsteczkowych.
Równanie Boltzmanna Ewolucja czasowa funkcji rozkładu jest opisana przez równanie Boltzmanna: Założenia : molekularny chaos (brak korelacji między prędkością, a położeniem cząsteczek) uwzględnienie tylko kolizji dwuciałowych
Przybliżenie BGK Człon kolizji, przybliżenie BGK (Bhatnagar, Gross, Krook (1954)): Liniowa relaksacja do stanu równowagi feq feq wyznaczana np. z rozkładu Macwella- Boltzmanna Uwaga: istnieją bardziej zaawansowane modele kolizji o lepszych właściwościach np. MRT
Model d2q9 Dyskretyzacja i model LBM Wprowadźmy dyskretne wektory prędkości i funkcję rozkładu: f ------> fi v ------> ci Thorne, D., Sukop, M., Lattice Boltzmann Method for the Elder Problem, FIU, CMWR(2004)
Wielkości makroskopowe Prędkości i gęstość wyznaczmy przez sumowanie funkcji rozkładu: Gęstość: Prędkość:
Równanie transportu (dyskretnie) Równanie transportu w modelu sieciowym LBM: gdzie zakres i zależy od użytej sieci.
t=0 Krok transportu
t=1/4 Krok transportu
t=1/2 Krok transportu
t=3/4 Krok transportu
t=1 Krok transportu
Krok Transportu - Implementacja Implementacja kroku transportu: void propagatelbm(int _nx, int _ny, int curr) { int prev = 1 - curr; for(i=0; i < _nx ; i++) for(j=0; j < _ny ; j++) if(f[ j * _nx + i ] & C_FLD) { for(k=0; k< 9; k++) { ip = i+ex[k]; jp = j+ey[k]; } } if( F[ jp * _nx + ip ] & C_BND ) { df [curr][ jp * _nx + ip ][inv[k]] = df [prev][ j * _nx + i ][k]; } else { df [curr][ jp * _nx + ip ][k] = df[prev][ j * _nx + i ][k]; }
Funkcja rozkładu w równowadze Lokalną funkcję rozkładu w równowadze zwykle wyznacza się z rozwinięcia funkcji rozkładu Maxwella-Boltzmanna [1]: gęstość płynu prędkość dźwięku dla sieci współczynniki wagowe sieci macierz jednostkowa [1] S. Succi, O. Filippova, G. Smith, E. Kaxiras Applying the Lattice Boltzmann Equation to Multiscale Fluid Problems, Comp. Sci. Eng., Nov-Dec 2001, 26 36
Kolizje - Implementacja Wyznaczanie członu kolizji: (...) for(k=0; k< 9; k++) { f0 = w[k] * rho * (1.0 - (3.0/2.0) * (ux*ux + uy*uy) + 3.0 * (ex[k] * ux + ey[k]*uy) + (9.0/2.0) * (ex[k] * ux + ey[k]*uy) * (ex[k] * ux + ey[k]*uy)); } df [curr][ j * _nx + i ][k] = (1-omega) * df[curr][ j * _nx + i ][k] + omega*f0; (omega = 1/tau)
Warunki brzegowe Bounce-back na sztywnej ściance Można uzyskać dokładność 2 rzędu stosując wersję mid-grid, szczegóły [2] [2] Succi, Sauro (2001). The Lattice Boltzmann Equation for Fluid Dynamics and Beyond. Oxford University Press
Warunki brzegowe Bounce-back na sztywnej ściance Można uzyskać dokładność 2 rzędu stosując wersję mid-grid, szczegóły [2] [2] Succi, Sauro (2001). The Lattice Boltzmann Equation for Fluid Dynamics and Beyond. Oxford University Press
Warunki brzegowe Bounce-back na sztywnej ściance Można uzyskać dokładność 2 rzędu stosując wersję mid-grid, szczegóły [2] [2] Succi, Sauro (2001). The Lattice Boltzmann Equation for Fluid Dynamics and Beyond. Oxford University Press
Kolizje + transport w jednym kroku Kolizje i transport mogą być umieszczone w pojedynczym wyrażeniu Można powiedzieć, że poniższy kod to pełny algorytm LBM (bez kilku detali )! for(int k=0; k< 9; k++) { int ip = ( i+ex[k] + L ) % (L); int jp = ( j+ey[k] + L ) % (L); // collision + streaming } if( FLAG[ip+jp*L] == 1 ) df [1-c][ i+j*l ][inv[k]] = (1-omega) * df[c][ i+j*l ][k] + omega* w[k] * rho * (1.0f - (3.0f/2.0f) * (ux*ux + uy*uy) + 3.0f * (ex[k] * ux + ey[k]*uy) + (9.0f/2.0f) * (ex[k] * ux + ey[k]*uy) * (ex[k] * ux + ey[k]*uy)); else df [1-c][ip+jp*L][k] = (1-omega) * df[c][ i+j*l ][k] + omega* w[k] * rho * (1.0f - (3.0f/2.0f) * (ux*ux + uy*uy)+ 3.0f * (ex[k] * ux + ey[k]*uy) + (9.0f/2.0f) * (ex[k] * ux + ey[k]*uy) * (ex[k] * ux + ey[k]*uy));
Podsumowanie algorytm LBM Najbardziej podstawowy model LBM składa się z dwóch kroków: Krok kolizji: Krok transportu:
LBM na CUDA LBM nadaje się bardzo dobrze do urównoleglenia Operacje w algorytmie LBM: Wyznaczenie wielkości makroskopowych (lokalna) Wyznaczenie funkcji rozkładu (lokalna) Krok propagacji (nielokalna!): 1) podział sieci na podsieci (jak w pracy S. Szkody) Problem: wymaga komunikacji 2) użycie drugiej siatki (propagacja ping-pong) Problem: wymaga więcej pamięci
Jak przepisać LBM na CUDA? Start: gpu2d.zip (strona wykładu) alokuje pamięć na host (malloc) alokuje pamięć na gpu (cudamalloc) wywołuje kernel CUDA przekazując wskaźnik na pamięć urządzenia jako argument kopiuje dane z pamięci gpu->cpu zapisuje skopiowane dane jako rysunek.ppm (dołączony) global void Trace(float3 *IMG) { int x = blockidx.x * blockdim.x + threadidx.x; int y = blockidx.y * blockdim.y + threadidx.y; if(x*h + y>=w*h) return; IMG[x*H + y].x = float(x)/float(w); IMG[x*H + y].y = float(y)/float(h); IMG[x*H + y].z = float(x+y)/float(w+h); }
Jak przepisać LBM na CUDA? lbm-cpu.zip (strona wykładu) Zwięzła implementacja LBM na CPU Adwekcja cząstek przez pole prędkości
Kroki do wykonania Aby zaimplementować tę wersję LBM na CUDA należy (wersja z dodatkową pamięcią): 1. zmienić strukturę funkcji rozkładu (np. tablice 1d) // df on the device float * c0f0; float * c0f1; float * c0f2; float * c0f3; float * c0f4; float * c0f5; float * c0f6; float * c0f7; float * c0f8; float * c1f0; float * c1f1; float * c1f2; float * c1f3; float * c1f4; float * c1f5; float * c1f6; float * c1f7; float * c1f8; ( ) cudamalloc(&c0f0, _nx*sizeof(float) * _ny * nz); cudamalloc(&c0f1, _nx*sizeof(float) * _ny * nz); cudamalloc(&c0f2, _nx*sizeof(float) * _ny * nz); cudamalloc(&c0f3, _nx*sizeof(float) * _ny * nz); cudamalloc(&c0f4, _nx*sizeof(float) * _ny * nz); ( )
Kroki do wykonania 2. Zamiplementować kernel kolizji: global void devicecollision(float *f0, float *f1,float *f2, float *f3, float *f4, float *f5, float *f6, float *f7, float *f8, int width, int height, int depth, float *U, float *V, int *F) { int i = blockidx.x * blockdim.x + threadidx.x; int j = blockidx.y * blockdim.y + threadidx.y; } ( ) // kod jak w wersji CPU z małymi modyfikacjami // wynikającymi głównie z nowego formatu funkcji rozkładu
Kroki do wykonania 3. Zamiplementować kernel transportu: global void devicepropagate( float *fromf0, float *fromf1,float *fromf2, float *fromf3, float *fromf4, float *fromf5, float *fromf6,float *fromf7, float *fromf8, float *tof0, float *tof1,float *tof2, float *tof3, float *tof4, float *tof5, float *tof6,float *tof7, float *tof8, int width, int height, int depth, float *U, float *V, int *F) { int i = blockidx.x * blockdim.x + threadidx.x; int j = blockidx.y * blockdim.y + threadidx.y; } ( ) // kod jak na CPU z jawnie // wypisanym transportem wg formatu funkcji gęstości // jak w preabule kernela
Schemat działania 1. Inicjalizuj dane (CPU) 2. Inicjalizuj dane (CPU -----> GPU) 3. W pętli: a) Wywołuj kernel kolizji (CUDA) b) Wywołuj kernel transportu (CUDA) c) Przesuń cząstki po polu prędkości w nowe położenia - To też można urównoleglić -> pierwszy wykład z CUDA! d) Narysuj cząstki na ekranie
512 x 512 Przykład działania LBM na CUDA CPU stoi. gdy w tym czasie GPU.
CPU_time / GPU_time Skalowanie LBM dało się szybko (dzień pracy) przyspieszyć około 100 razy Można przyspieszyć jeszcze bardziej (wiele prac) Klastrów obliczeniowych nie da się jeszcze przebić (pamięć, skala obliczeń) multi GPU? Mniejsze zastosowania osobiste tu jak najbardziej CUDA ma sens L
fin
Literatura S. Succi, The Lattice Boltzmann Equation for Fluid Dynamics and Beyond., Oxford University Press (2001) U. Frish, B. Hasslacher, Y. Pomeau 1986 Lattice-Gas Automata for the Navier-Stokes Equation, Phys. Rev. Lett. 56, 1505 1508. G.R. McNamara, G. Zanetti Use of the Boltzmann Equation to Simulate Lattice-Gas Automata, Phys. Rev. Lett. 61(20), 2332 2335. S. Succi, O. Filippova, G. Smith, E. Kaxiras Applying the Lattice Boltzmann Equation to Multiscale Fluid Problems, Comp. Sci. Eng., Nov-Dec 2001, 26 36.