shooter Opublikowano 8 Grudnia 2007 Zgłoś Opublikowano 8 Grudnia 2007 (edytowane) Jak zaimplementowac srodowisko MPI? AGH udostepnia konto na serwerze, ale nie ma pliku naglowkowego <mpi.h> Edytowane 8 Grudnia 2007 przez shooter Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
PelzaK Opublikowano 8 Grudnia 2007 Zgłoś Opublikowano 8 Grudnia 2007 i każdy tutaj wie co to jest MPI :). Trudno poszukać tego pliku za pomocą gogli? :wink: Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 9 Grudnia 2007 Zgłoś Opublikowano 9 Grudnia 2007 Dodatkowo oprócz pliku mpi.h, aby skompilowany program uruchomić na wielu maszynach jednocześnie, na każdym z komputerów musi być uruchomiony specjalny demon. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 9 Grudnia 2007 Zgłoś Opublikowano 9 Grudnia 2007 (edytowane) A czy mozna zastosowac MPI do dwurdzeniowego procesora tak, aby zademonstrowac dzialanie na jednym komputerze? Edytowane 9 Grudnia 2007 przez shooter Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 9 Grudnia 2007 Zgłoś Opublikowano 9 Grudnia 2007 (edytowane) Można uruchomić MPI w trybie emulacji, wtedy dowolna liczba procesorów (komputerów) jest emulowana jako wątki, od systemu zależy jak te wątki zostaną ewentualnie na dwa procesory porozdzielane. Dodatkowo MPI zapewnia, że taka emulacja na wątkach nie jest deterministyczna, tzn za każdym uruchomieniem można się spodziewać innego przeplotu wątków i innych czasów przydzielonych dla poszczególnych wątków, dzięki temu bardziej realistycznie jest emulowana sieć i praca na wielu komputerach. Edytowane 11 Grudnia 2007 przez Ragnor Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 10 Grudnia 2007 Zgłoś Opublikowano 10 Grudnia 2007 Czy moglbys przyblizyc jak wykonac emulacje? Bylbym bardzo wdzieczny, zreszta nie tylko ja, ale i sporo ludzi z mojego roku studiow. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 11 Grudnia 2007 Zgłoś Opublikowano 11 Grudnia 2007 Do uruchamianie programów używałem MPICH 2 (implementuje MPI 1 i 2), jest dostępny też pod windowsa, więc lokalnie można wszelkie testy przeprowadzać. Posiada on bogatą dokumentacje więc nie powinno być problemu z rozszyfrowaniem co i jak. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 11 Grudnia 2007 Zgłoś Opublikowano 11 Grudnia 2007 Gdy tego uzywam nie moge sie polaczyc ze swoim komputerem, lol. Aby uruchomic program w MPI nalezy to robic przez inny program dostarczony z biblioteka. W tym programie wyskakuje mi komunikat, ze nie mozna sie polaczyc z komputerem Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 11 Grudnia 2007 Zgłoś Opublikowano 11 Grudnia 2007 Gdy tego uzywam nie moge sie polaczyc ze swoim komputerem, lol. Aby uruchomic program w MPI nalezy to robic przez inny program dostarczony z biblioteka. W tym programie wyskakuje mi komunikat, ze nie mozna sie polaczyc z komputerem Używasz tego programu lokalnie? Opisz dokładnie krok po kroku co robisz i jakie dokładnie komunikaty dostajesz. Z tego co pamiętam MPICH2 wymaga konta (usera) i odpowiedniego hasła aby uruchomić dane zadania w systemie. Ja na te potrzeby w windowsie stworzyłem nowego usera (z prawami admina) i go zarejestrowałem w mpi, wcześniej miałem tylko domyślnego użytkownika. Dopiero po takim triku MPICH2 dobrze pracował. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 12 Grudnia 2007 Zgłoś Opublikowano 12 Grudnia 2007 Wchodze do katalogu w MPICH2/bin i odpalam program MPIexec wrapper. podaje mu sciezke do przykladu - MPICH2/examples/cpi.exe i klikam execute. Wyskakuje mi komunikat: Unable to connect "i tu nazwa mojego kompa". Jesli mozesz to opisz co nalezy zrobic i czy kazda aplikacje nalezy odpalac przez tego wrappera? Czyli na dwoch jajkach mozna oszukac MPI i zademonstrowac na jednym kompie? Z gory wielkie dzieki za wszystko. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 12 Grudnia 2007 Zgłoś Opublikowano 12 Grudnia 2007 Tak jak wspomniałem wcześniej w windowsie utwórz nowe konto użytkownika (z prawami administratora) np. test i obowiązkowo z hasłem np. test. Następnie uruchom wmpiregister i podaj tam nazwę użytkownika i jego hasło a następnie daj register. Teraz sprawdź jak zachowa się przykład cpi.exe. Aplikacje nie trzeba odpalać przez ten okienkowy program, w labelce ShowCommand widnieje odpowiadające polecenie konsolowe za pomocą jakiego możesz odpalić program w mpi z pominięciem tego gui. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 12 Grudnia 2007 Zgłoś Opublikowano 12 Grudnia 2007 Dzieki wielkie Ragnorze!!! MPI dziala az milo. Na C2D przy 2 watkach dziala 2 razy szybciej. Czyli wszystko OK. POZDRAWIAM i zycze najlepszego!!! Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 18 Grudnia 2007 Zgłoś Opublikowano 18 Grudnia 2007 Chodzi mi jeszcze o implementacje. Przyklad dziala, ale nie moge zlinkowac programu, gryz wyskakuje błąd: mpi.obj : error LNK2019: unresolved external symbol "void __cdecl MPI::Init(int &,char * * &)" (?Init@MPI@@YAXAAHAAPAPAD@Z) referenced in function _main. Moglbys napisac jak implementowales MPI? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 18 Grudnia 2007 Zgłoś Opublikowano 18 Grudnia 2007 Napisz czym i jak (dokładna komenda) próbujesz kompilować program. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 18 Grudnia 2007 Zgłoś Opublikowano 18 Grudnia 2007 (edytowane) Z implementacją sobie poradziłem. Komendy MPI dzialaja. Mam teraz problem - zrownoleglic w MPI eliminacje Gaussa. W openMP jeszcze jakos bym to napisal ale w MPI ciezko. Oto Gauss: int partial_pivoting(double **m, int size, int a){ double max=m[a][a]; double tmp; int index; bool zm=false; for (int i=1; i<size-a; i++) if(fabs(m[a+i][a])>max) { max=fabs(m[a+i][a]); index=a+i; zm=true; } for(int i=a; i<=size-a; i++) //zamiana wierszy { tmp=m[a][i]; m[a][i]=m[index][i]; m[index][i]=tmp; } if(zm) return 0; else return 1;}//////////////////////////////////////////////////////////////////////////////////Gaussvoid gauss(double** m, int size){ double alfa; for(int k=0; k<size; k++) { for(int i=k+1; i<size; i++) { if(m[k][k] == 0) if(partial_pivoting(m, k, size)) { cout << endl << "Macierz jest osobliwa." << endl; break; } alfa = m[i][k] / m[k][k]; for(int j=k; j<=size; j++) m[i][j] = m[i][j] - alfa * m[k][j]; } } } chodzi o zrownoleglenie samej funkcji Gauss. Masz moze pomysł jak to rozpracować z MPI? Edytowane 18 Grudnia 2007 przez shooter Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
KrOOliK89 Opublikowano 18 Grudnia 2007 Zgłoś Opublikowano 18 Grudnia 2007 (edytowane) Podawaj kod w znacznikach code, bo bez tego to [gluteus maximus] blada, wcina wcięcia i nie wiem czy będzie się chciało komuś analizować kod. Edytowane 18 Grudnia 2007 przez KrOOliK89 Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 19 Grudnia 2007 Zgłoś Opublikowano 19 Grudnia 2007 Napisz jak chciałbyć to zrównoleglić w OpenMP ja pomyślę jak można to przenieść na MPI. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 20 Grudnia 2007 Zgłoś Opublikowano 20 Grudnia 2007 Wymyśliłem coś takiego. Pewnie nie do końca poprawne, ale ... //Gauss void gauss(double** m, int size){ double alfa; for(int k=0; k<size; k++) { for(int i=k+1; i<size; i++) { if(m[k][k] == 0) if(partial_pivoting(m, k, size)) { cout << endl << "Macierz jest osobliwa." << endl; break; } alfa = m[i][k] / m[k][k]; #pragma omp parallel sections { #pragma omp section { for(int j=k; j<=size; j+=2) m[i][j] = m[i][j] - alfa * m[k][j]; } #pragma omp section { for(int j=k+1; j<=size; j+=2) m[i][j] = m[i][j] - alfa * m[k][j]; } } } } } Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 21 Grudnia 2007 Zgłoś Opublikowano 21 Grudnia 2007 Na OpenMP nie znam się ale z tego co widzę, ten algorytm jest zrównoleglony tylko do 2 maszyn, mam racje? Interesuje Cię zrównoleglenie algorytmu na konkretną liczbę maszyn/procesów powiedzmy 2,4,8 czy też na jakąś dowolną liczbę: p (gdzie p zależne od 'size')? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 21 Grudnia 2007 Zgłoś Opublikowano 21 Grudnia 2007 Chce to zrobic dla 2 procesorow. Zeby tylko dzialalo. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 21 Grudnia 2007 Zgłoś Opublikowano 21 Grudnia 2007 Jeśli chcesz to napisać z wykorzystaniem MPI to musisz trochę zmienić podejście do problemu. W MPI każdy proces może działać na osobnej mazynie, więc nie ma czegoś takiego jak wspólna pamięc (w szczególności każdy proces będzie miał własną macierz/tablicę z danymi). Aby wymienić informacje, wyniki między procesami, trzeba je jawnie wysłać do innego (lub wszystkich) procesów oraz w danych procesach je odebrać. Procesy mogą być uruchamiane na różnych pod względem konfiguracji maszynach, więc należy zadbać o synchronizacje obliczeń, tak aby szybsza maszyna czekała na zakończenie obliczeń na wolniejszej. Jako że dane są przesyłane przez sieć, trzeba minimalizować liczbę rozmów między procesami, gdyż to można zabić cały zysk z zrównoleglenia algorytmu. Na początku zapoznaj się z takimi funkcjami MPI jak MPI_send, MPI_receiv, MPI_geather itd.. poznaj do czego służą, zwykle mają one dużo parametrów ale ważne są może 2,3 ;), reszte wstawia się prawię zawsze taką samą. W MPI dla uproszczenia struktury algorytmu często zakłada się, że jeden z procesów koordynuje działanie innych jest tzw. 'masterem', zwykle się przyjmuje, że jest to proces numer 0, inne procesy to tzw 'workerzy'. Co do algorytmu to można do niego podejść tak, że najbardziej wewnętrzną pętle możesz tak wykonać (pseudokod): alfa = m[i][k] / m[k][k];if (moj_numer == 0) { for(int j=k; j<=size; j+=2) { m[i][j] = m[i][j] - alfa * m[k][j]; } wyślij własne przeliczone dane do procesu 1 odbierz przeliczone dane z procesu 0 dodaj odebrane dane do własnej tablicy m} else { // zakładam że są tylk 2 procesy for(int j=k+1; j<=size; j+=2) m[i][j] = m[i][j] - alfa * m[k][j]; } odbierz przeliczone dane z procesu 1 wyślij własne przeliczone dane do procesu 0 dodaj odebrane dane do własnej tablicy m} Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
shooter Opublikowano 8 Stycznia 2008 Zgłoś Opublikowano 8 Stycznia 2008 (edytowane) Szanowny Ragnorze. Napisalem kod w MPI, dziala dla 1 procesu, ale nie chce dla wiekszej ilosci. Co jest nie tak? Bardzo prosze o porade. Wydaje mi sie, ze cos jest nie tak z MPI_Status. #include <cstdlib>#include <iostream>#include "matrix.h"#undef SEEK_SET#undef SEEK_END#undef SEEK_CUR#include <MPI/mpi.h>void senddata(double** a, double* b, int rank, int size, int msize, MPI_Status status){ int i; if(rank == 0) { for(i = 0;i < msize;i++) { if(i % size == 0) continue; a[i][msize] = b[i]; MPI_Send(a[i],msize+1,MPI_DOUBLE,(i % size),0, MPI_COMM_WORLD); MPI_Send(&(b[i]),1,MPI_DOUBLE,(i % size),0, MPI_COMM_WORLD); } } else { for(i = 0;i < msize;i++) { if(i % size != rank) continue; MPI_Recv(a[i],msize+1,MPI_DOUBLE,0,0, MPI_COMM_WORLD, &status); MPI_Recv(&(b[i]),1,MPI_DOUBLE,0,0, MPI_COMM_WORLD, &status); b[i] = a[i][msize]; } }}void senddataback(double** a, double* b, int rank ,int size, int msize, MPI_Status status){ int i; if(rank == 0) { for(i = 0;i < msize;i++) { if(i % size == 0) continue; b[i] = a[i][msize]; MPI_Recv(a[i],msize+1,MPI_DOUBLE, (i % size), 0, MPI_COMM_WORLD, &status); MPI_Recv(&(b[i]),1,MPI_DOUBLE,(i % size), 0, MPI_COMM_WORLD, &status); } } else { for(i = 0;i < msize;i++) { if(i % size != rank) continue; MPI_Send(a[i],msize+1,MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); MPI_Send(&(b[i]),1,MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); a[i][msize] = b[i]; } }}void eliminate(double** a , double* b, int rank ,int size, int msize){ int i,j,k; for(k = 0; k < msize;k++) { if(k % size == rank) { if(a[k][k] == 0) { cout <<"dzielenie przez 0"; MPI_Finalize(); exit(0); } /* prepare my row */ for(j = k + 1;j < msize;j++) { a[k][j] = a[k][j]/a[k][k]; } b[k] = b[k]/a[k][k]; a[k][k] = 1; /* end prepare */ a[k][msize] = b[k]; MPI_Bcast(a[k],msize+1,MPI_DOUBLE, rank, MPI_COMM_WORLD); for(i = k + 1;i < msize;i++) { if(i % size != rank)continue; for(j = k + 1;j < msize;j++) { a[i][j] = a[i][j] - a[i][k] * a[k][j]; } b[i] = b[i] - a[i][k] * b[k]; a[i][k] = 0; } } else { MPI_Bcast(a[k],msize+1,MPI_DOUBLE,k % size, MPI_COMM_WORLD); MPI_Bcast(&(b[k]),1,MPI_DOUBLE,k % size, MPI_COMM_WORLD); b[k] = a[k][msize]; for(i = k + 1;i < msize;i++) { if(i % size != rank)continue; for(j = k + 1;j < msize;j++) { a[i][j] = a[i][j] - a[i][k] * a[k][j]; } b[i] = b[i] - a[i][k] * b[k]; a[i][k] = 0; } } }}void backward(double** a, double* b, int msize){ int i,j,k; for(i = msize-1;i >= 0;i--) { for(k = i+1;k < msize;k++) { b[i] = b[i] - a[i][k]; } for(j = i - 1;j >= 0;j--) { a[j][i] = a[j][i] * b[i]; } }}int main( int argc, char *argv[] ){ int id_proc, num_procs; int size; //rozmiar macierzy double wtime1, wtime2; size = 1500; double** m; double* V; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&num_procs); MPI_Comm_rank(MPI_COMM_WORLD,&id_proc); MPI_Status status; if(id_proc == 0) { m = new double* [size]; V = new double [size]; for(int i=0; i<size; i++) m[i] = new double[size]; for (int i=0; i<size; i++) for(int j=0; j<size+1; j++) m[i][j] = 1+rand()%10; } MPI_Bcast(&size, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); if(id_proc != 0) { m = new double* [size]; V = new double [size]; for(int i=0; i<size; i++) m[i] = new double[size]; } senddata(m, V, id_proc, num_procs, size, status); eliminate(m, V, id_proc, num_procs, size); senddataback(m, V, id_proc, num_procs, size, status); backward(m, V, size); MPI_Finalize(); //system("PAUSE"); return 0;} Edytowane 8 Stycznia 2008 przez shooter Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Ragnor Opublikowano 9 Stycznia 2008 Zgłoś Opublikowano 9 Stycznia 2008 Widzę, że kodu trochę jest, ale w tej chwili łatwiej mi będzie odnaleźć błąd, jeśli zamiast analizować kod, opiszesz mi modelowo jak przebiega cały program i jak komunikują się ze sobą procesy. Z tego co zauważyłem program nie ma ograniczenia do 2 procesów. Dla przykładu jakie zadanie ma ten wiersz kodu w programie (w metodzie main): MPI_Bcast(&size, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); z tego co widzę size jest typu int a nie double, a do tego nikt tego komunikatu nigdzie nie odbiera (możliwe ,że w tym momencie, gdy program ma więcej niż 2 procesy to po prostu się blokuje). Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...