Podstawy MPI-2: część I

43
Podstawy MPI-2: część I Literatura: Using MPI-2. Advanced Features of the Message-Passing Interface, W. Gropp, E. Lusk, R. Thakur, MIT Press, Cambridge, 1999. Przykłady są dostępne na sieci pod http://www-unix.mcs.anl.gov/mpi/usingmpi2 / Prezentacja Introduction to parallel I/O and MPI-IO ”, R. Thakur, ANL Tutorial Rozszerzenia standardu MPI” na stronie Poznańskiego Centrum Sieciowo-

description

Podstawy MPI-2: część I. Literatura: Using MPI-2. Advanced Features of the Message-Passing Interface , W. Gropp, E. Lusk, R. Thakur, MIT Press, Cambridge, 1999. Przykłady są dostępne na sieci pod http://www-unix.mcs.anl.gov/mpi/usingmpi2/ - PowerPoint PPT Presentation

Transcript of Podstawy MPI-2: część I

Page 1: Podstawy MPI-2: część I

Podstawy MPI-2: część I

Literatura:

• Using MPI-2. Advanced Features of the Message-Passing Interface, W. Gropp, E. Lusk, R. Thakur, MIT Press, Cambridge, 1999. Przykłady są dostępne na sieci pod http://www-unix.mcs.anl.gov/mpi/usingmpi2/

• Prezentacja “Introduction to parallel I/O and MPI-IO”, R. Thakur, ANL

• Tutorial “Rozszerzenia standardu MPI” na stronie Poznańskiego Centrum Sieciowo-Superkomupterowego.

• MPI Forum (http://www.mpi-forum.org)

Page 2: Podstawy MPI-2: część I

Historia

• 1992: Pierwsze spotkanie MPI Forum na konferencji Supercomputing ‘92. Początek prac nad standardem MPI-1.

• 1994: Pierwsze wydanie książki “Using MPI” pomaga przekonać programistów równoległych do tego standardu. Użytkownicy PVM wskazują jednak na brak możliwości dynamicznej alokacji procesów, wszyscy użytkownicy wskazują na konieczność równoległych operacji I/O a CRAY-T3D (biblioteka shmem) i CM-5 udowadniają użyteczność jednostronnych operacji na pamięci.

• 1995: spotkanie MPI-2 Forum i ponowne podjęcie prac nad standardem MPI. Trochę zmodyfikowany standard MPI-1.1

• 1997: MPI-2 dostępna dla użytkowników.

Page 3: Podstawy MPI-2: część I

Nowe rzeczy w MPI-2Główne modyfikacje (“wielka trójka”)

• Równoległe operacje wejścia/wyjścia.

• Operacje na pamięci odległej.

• Dynamiczne zarządzanie procesami

Pomniejsze modyfikacje

• Specyfikacje zewnętrznych interfejsów.

• Połączenie z C++ i Fortranem 90.

• Wątki.

• Łączenie modułów w różnych językach.

• Rozszerzone operacje komunikacji zbiorowej (np. na interkomunikatorach).

Page 4: Podstawy MPI-2: część I

Równoległe operacje wejścia/wyjścia MPI-IO

• Pisanie do pliku jest wysłaniem wiadomości do systemu plików; narzędzia do tego celu już są w MPI.

• Podstawowe funkcje MPI-IO: – open, – close, – seek, – read, – write

Argumenty tych funkcji są podobne jak w UNIXowym I/O.

Page 5: Podstawy MPI-2: część I

Cechy operacji MPI-IO

• Rozproszenie pamięci oraz rekordów pliku.

• Zbiorowe operacje I/O.

• Niewstrzymuące operacje I/O.

• Specyfikacja offsetu położenia rekordu w pliku w celu uniknięcia oddzielnych operacji seek.

• Lokalne i globalne wskaźniki plików.

• Reprezentacje danych przenaszalne i możliwe do definiowania przez użytkownika.

• Wskazówki dla implementacji i systemu plików.

Page 6: Podstawy MPI-2: część I

Operacje na pamięci odległej

• Model przesyłania wiadomości: dane są przesyłane przy użyciu pary send/receive.

• Model pamięci wspólnej: procesory mają dostęp do wspólnej części pamięci i mogą pobierać lub umieszczać w niej dane.

• W MPI-2 zdefiniowano operacje put, get i collect, które umożliwiają dostęp do pamięci innego procesora w sposób analogiczny do modelu pamięci wspólnej. Te operacje określa się mianem operacji na pamięci odległej, zdalnych operacji na pamięci lub jednostronnych operacji na pamięci (ang. “one-sided” lub “remote memory” operations).

• Pamięć dostępną dla innego procesora specyfikuje się jako okno pamięci (window).

Page 7: Podstawy MPI-2: część I

Cechy operacji na pamięci odległej w MPI-2

• Zrównoważenie efektywności i przenaszalności między różnymi architekturami, włączając maszyny SMP (Shared Memory multiProcessors), NUMA (NonuUiform Memory Access), MPP (distributed memory Massively Parallel Processors), klastry SMP, czy sieci heterogeniczne.

• Zachowanie “spojrzenia i czucia” (look and feel) MPI.

• Uwzględnienie subtelnych różnic zachowania pamięci takich, jak koherencja pamięci cache, zgodność sekwencyjna, itp.

• Oddzielenie synchronizacji od przesyłania danych w celu zwiększenia efektywności.

Page 8: Podstawy MPI-2: część I

Dynamiczne zarządzanie procesami

• W MPI-2 dany proces może

– uczestniczyć w tworzeniu nowego procesu MPI (operacja rozmnażania; ang. spawning),

– nawiązać komunikację z procesami wystartowanymi oddzielnie (operacja połączenia).

• Główe cele przy projektowaniu takiego API (Application Programing Interface):

– Utrzymanie prostoty i elastyczności.

– Interakcja z systemem operacyjnym, zarządcą zasobów, procesu oraz złożonym otoczeniem programowym.

– Unikanie efektu “wyścigu” źle wpływającego na dokładność.

• Aby osiągnąć te cele, operacje zarządzania pamięcią muszą być zbiorowe, zarówno w obrębie procesów macierzystych jak i potomych. Procesy potomne są reprezentowane przez interkomunikatory.

Page 9: Podstawy MPI-2: część I

MPI-IO

Page 10: Podstawy MPI-2: część I

Sekwencyjne I/O w programie równoległym

Master

plik

Pamięć

Procesor

Pisze/czyta tylko master, który odpowiednio zbiera dane od innych procesorów lub rozsyła do nich przeczytane dane.

Page 11: Podstawy MPI-2: część I

MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); for (i=0; i<BUFSIZE; i++) buf[i] = myrank * BUFSIZE + i; if (myrank != 0) MPI_Send(buf, BUFSIZE, MPI_INT, 0, 99, MPI_COMM_WORLD); else { myfile = fopen("testfile", "w"); fwrite(buf, sizeof(int), BUFSIZE, myfile); for (i=1; i<numprocs; i++) { MPI_Recv(buf, BUFSIZE, MPI_INT, i, 99, MPI_COMM_WORLD, &status); fwrite(buf, sizeof(int), BUFSIZE, myfile); } fclose(myfile); }

Przykład pisania tylko przez mastera

Page 12: Podstawy MPI-2: część I

Zalety takiej organizacji pisania/czytania

• Maszyna na której chodzi program równoległy może dopuszczać I/O tylko z jednego albo ograniczonej liczby procesów lub znacznie ograniczać wydajność jeżeli każdy procesor pisze do oddzielnego pliku na wspólnym systemie plików (np. bigben w PSC czy galera w TASKu).

• Można używać zaawansowanych nierównoległych bibliotek I/O (np. biblioteki zarządzania danymi).

• Wszystkie wyniki są w jednym pliku, na którym takie operacje jak ftp, cp, mv są łatwiejsze i szybsze niż na wielu.

Wady

• Obniżanie efektywności kodu poprzez sekwencyjność operacji pisania/czytania i konieczność przesyłania danych.

Page 13: Podstawy MPI-2: część I

Równoległe nie-MPI I/O w programie równoległym

plik

Pamięć

Procesor

Każdy procesor pisze do oddzielnego pliku albo niezależnie czyta z tego samego lub oddzielnego pliku

Page 14: Podstawy MPI-2: część I

Przykład pisania przez każdy procesor do oddzielnego pliku o nazwie zawierającej rząd procesora

MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); for (i=0; i<BUFSIZE; i++) buf[i] = myrank * BUFSIZE + i; sprintf(filename, "testfile.%d", myrank); myfile = fopen(filename, "w"); fwrite(buf, sizeof(int), BUFSIZE, myfile); fclose(myfile); MPI_Finalize(); return 0;

W FORTRANie rząd procesora można umieścić w nazwie pliku przez pisanie do łańcucha, np.

character*64 fname …….. write (fname,'(2a,bz,i3.3)') ‘plik_',taskid

Page 15: Podstawy MPI-2: część I

Zalety takiego podejścia

• Operacje I/O są równoległe ale mogą korzystać z sekwencyjnych bibliotek I/O.

Wady• Często pliki wyprodukowane przez poszczególne procesory

trzeba łączyć w jeden do dalszego przetwarzania.

• Program używających te pliki jako pliki danych często sam musi być równoległy i chodzić na tej samej liczbie procesorów co program, który je wyprodukował.

• Uciążliwość w “ogarnięciu” i wykonywaniu opearacji takich jak cp, mv, ftp na dziesiątkach a nawet tysiącach małych plików.

• Pojawianie się nieoczekiwanych błędów przy jednoczesnym czytaniu jednego dużego pliku danych przez wiele procesorów.

Page 16: Podstawy MPI-2: część I

Kod piszący wyniki do wielu plików z użyciem MPI-IO

MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); for (i=0; i<BUFSIZE; i++) buf[i] = myrank * BUFSIZE + i; sprintf(filename, "testfile.%d", myrank); MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &myfile); MPI_File_write(myfile, buf, BUFSIZE, MPI_INT, MPI_STATUS_IGNORE); MPI_File_close(&myfile); MPI_Finalize();

Page 17: Podstawy MPI-2: część I

MPI_FILE_OPEN(comm, filename, amode, info, fh) [ IN comm] komunikator (handle) [ IN filename] nazwa pliku (string) [ IN amode] tryb dostępu do pliku (integer) [ IN info] obiekt info (handle) [ OUT fh] “pokrętło” utworzonego pliku (handle)

C:

int MPI_File_open(MPI_Comm comm, char *filename, int amode, MPI_Info info, MPI_File *fh)

FORTRAN/FORTRAN 90:

MPI_FILE_OPEN(COMM, FILENAME, AMODE, INFO, FH, IERROR)CHARACTER*(*) FILENAME INTEGER COMM, AMODE, INFO, FH, IERROR

C++: static MPI::File MPI::File::Open(const MPI::Intracomm& comm, const char* filename, int amode, const MPI::Info& info)

Page 18: Podstawy MPI-2: część I

MPI_FILE_WRITE(fh, buf, count, datatype, status) [ INOUT fh] “pokrętło” pliku (handle) [ IN buf] początkowy adres buforu (choice) [ IN count] liczba elementów danych w buforze (integer) [ IN datatype] typ każdego elementu danych (handle) [ OUT status] obiekt stanu (Status)

C:int MPI_File_write(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status)

FORTRAN/FORTRAN90:MPI_FILE_WRITE(FH, BUF, COUNT, DATATYPE, STATUS, IERROR) <type> BUF(*) INTEGER FH, COUNT, DATATYPE, STATUS(MPI_STATUS_SIZE), IERROR

C++:void MPI::File::Write(const void* buf, int count, const MPI::Datatype& datatype, MPI::Status& status) void MPI::File::Write(const void* buf, int count, const MPI::Datatype& datatype)

Page 19: Podstawy MPI-2: część I

MPI_FILE_CLOSE(fh) [ INOUT fh] “pokrętło” pliku (handle)

C:int MPI_File_close(MPI_File *fh)

FORTRAN/FORTRAN90:MPI_FILE_CLOSE(FH, IERROR)INTEGER FH, IERROR

C++:void MPI::File::Close()

Page 20: Podstawy MPI-2: część I

Schemat równoległego pisania/czytania z tego samego pliku przez wiele procesorów.

Każdy procesor ma w danej chwili dostęp do innej części pliku.

plik

Pamięć

Procesor

Page 21: Podstawy MPI-2: część I

Kod piszący wyniki do jednego pliku z użyciem MPI-IO: C

MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); for (i=0; i<BUFSIZE; i++) buf[i] = myrank * BUFSIZE + i; MPI_File_open(MPI_COMM_WORLD, "testfile", MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &thefile); MPI_File_set_view(thefile, myrank * BUFSIZE * sizeof(int), MPI_INT, MPI_INT, "native", MPI_INFO_NULL); MPI_File_write(thefile, buf, BUFSIZE, MPI_INT, MPI_STATUS_IGNORE); MPI_File_close(&thefile); MPI_Finalize();

Page 22: Podstawy MPI-2: część I

Kod piszący wyniki do jednego pliku z użyciem MPI-IO: FORTRAN90

call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, myrank, ierr)

do i = 0, BUFSIZE buf(i) = myrank * BUFSIZE + i enddo call MPI_FILE_OPEN(MPI_COMM_WORLD, 'testfile', & MPI_MODE_WRONLY + MPI_MODE_CREATE, & MPI_INFO_NULL, thefile, ierr) ! assume 4-byte integers disp = myrank * BUFSIZE * 4 call MPI_FILE_SET_VIEW(thefile, disp, MPI_INTEGER, & MPI_INTEGER, 'native', & MPI_INFO_NULL, ierr) call MPI_FILE_WRITE(thefile, buf, BUFSIZE, MPI_INTEGER, & MPI_STATUS_IGNORE, ierr) call MPI_FILE_CLOSE(thefile, ierr) call MPI_FINALIZE(ierr)

Page 23: Podstawy MPI-2: część I

MPI_FILE_SET_VIEW(fh, disp, etype, filetype, datarep, info) [ INOUT fh] “pokrętło” pliku (handle) [ IN disp] przesunięcie (pozycja początkowego rekordu) (integer) [ IN etype] elementarny typ danych (handle) [ IN filetype] typ pliku (handle) [ IN datarep] reprezentacja danych (string) [ IN info] obiekt informacyjny (handle)

C:int MPI_File_set_view(MPI_File fh, MPI_Offset disp, MPI_Datatype etype, MPI_Datatype filetype, char *datarep, MPI_Info info)

FORTRAN/FORTRAN90MPI_FILE_SET_VIEW(FH, DISP, ETYPE, FILETYPE, DATAREP, INFO, IERROR)INTEGER FH, ETYPE, FILETYPE, INFO, IERROR CHARACTER*(*) DATAREPINTEGER(KIND=MPI_OFFSET_KIND) DISP

C++ void MPI::File::Set_view(MPI::Offset disp, const MPI::Datatype& etype, const MPI::Datatype& filetype, const char* datarep, const MPI::Info& info)

Page 24: Podstawy MPI-2: część I

Czytanie pliku przez inną liczbę procesorów niż użyta to jego zapisu

MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_File_open(MPI_COMM_WORLD, "testfile", MPI_MODE_RDONLY, MPI_INFO_NULL, &thefile); MPI_File_get_size(thefile, &filesize); /* in bytes */ filesize = filesize / sizeof(int); /* in number of ints */ bufsize = filesize / numprocs + 1; /* local number to read */ buf = (int *) malloc (bufsize * sizeof(int)); MPI_File_set_view(thefile, myrank * bufsize * sizeof(int), MPI_INT, MPI_INT, "native", MPI_INFO_NULL); MPI_File_read(thefile, buf, bufsize, MPI_INT, &status); MPI_Get_count(&status, MPI_INT, &count); printf("process %d read %d ints\n", myrank, count); MPI_File_close(&thefile); MPI_Finalize();

Page 25: Podstawy MPI-2: część I

MPI_FILE_GET_SIZE(fh, size)[IN fhfile] “pokrętło” pliku (handle)[OUT size] rozmiar pliku w bajtach (integer)

C:int MPI_File_get_size(MPI_File fh, MPI_Offset *size)

FORTRAN/FORTRAN90:MPI_FILE_GET_SIZE(FH, SIZE, IERROR)INTEGER FH, IERROR INTEGER(KIND=MPI_OFFSET_KIND) SIZE

C++MPI::Offset MPI::File::Get_size() const

Page 26: Podstawy MPI-2: część I

MPI_FILE_READ(fh, buf, count, datatype, status)[INOUT fh] “pokrętło” pliku (handle)[OUT buf] początkowy adres buforu (choice)[IN count] liczba elementów buforu (integer)IN datatype datatype of each buffer element (handle)[OUT status] obiekt stanu (Status)

C:int MPI_File_read(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status)

FORTRAN/FORTRAN90:MPI_FILE_READ(FH, BUF, COUNT, DATATYPE, STATUS, IERROR) <type> BUF(*) INTEGER FH, COUNT, DATATYPE, STATUS(MPI_STATUS_SIZE), IERROR C++:void MPI::File::Read(void* buf, int count, const MPI::Datatype& datatype, MPI::Status& status) void MPI::File::Read(void* buf, int count, const MPI::Datatype& datatype)

Page 27: Podstawy MPI-2: część I

Wydruk z programu piszącego bufor (dla BUFSIZE=2 i 4 procesorów)

mpirun -np 4 ./io3p | sort -n -k 1Processor 0 buf[0]=0Processor 0 buf[1]=1Processor 1 buf[0]=2Processor 1 buf[1]=3Processor 2 buf[0]=4Processor 2 buf[1]=5Processor 3 buf[0]=6Processor 3 buf[1]=7

Wydruk z programu czytającego bufor (dla 2 procesorów)

mpirun -np 2 ./io35p | sort -n -k 1process 0 read 5 intsprocess 1 read 3 intsprocessor 0 buf[0]=0processor 0 buf[1]=1processor 0 buf[2]=2processor 0 buf[3]=3processor 0 buf[4]=4processor 1 buf[0]=5processor 1 buf[1]=6processor 1 buf[2]=7

Page 28: Podstawy MPI-2: część I

Inne sposoby pisania do pliku wspóldzielonego

• MPI_File_seek• MPI_File_read_at• MPI_File_write_at• MPI_File_read_shared• MPI_File_write_shared

Wszystkie te operacje są operacjami komunikacji zbiorowej

Page 29: Podstawy MPI-2: część I

Niewstrzymujące instrukcje czytania/pisania

Standardowe operacje read i write są operacjami wstrzymującymi jak standardowe send i receive ale można użyć

• MPI_File_iread• MPI_File_iwrite

Żeby upewnić się, że pliki zostały zapisane/przeczytane należy dodać w odpowiednim miejscu instrukcję MPI_Wait tak jak w przypadku niewstrzymującego send lub receive.

Page 30: Podstawy MPI-2: część I

Zbiorowe instrukcje czytania/pisania

Odpowiednikami operacji komunikacji zbiorowej są

• MPI_File_read_all• MPI_File_write_all

Pierwszą operacją można porównać do broadcast a drugą do gather.

Page 31: Podstawy MPI-2: część I

Operacje na pamięci odległej

Page 32: Podstawy MPI-2: część I

• Okno dostępu do pamięci: część pamięci adresowej danego procesora udostępnionej dla innych procesorów będących w danym komunikatorze.

• Utworzenie okna dostępu do pamięci jest operacją komunikacji zbiorowej.

• Okna dostępu do pamięci tworzą rozproszony obiekt złożony z częśći pamięci procesorów dostępnych dla innych.

• W obrębie okna są dostępne operacje:– get: uzyskiwanie danych z okna pamięci,

– put: umieszczanie danych w oknie pamięci,

– accumulate: modyfikacja danych w oknie dostępu do pamięci (np. dodawanie nowego składnika do sumy).

Te operacje są niewstrzymujące i wymagają synchronizacji (fence).

Page 33: Podstawy MPI-2: część I

get

put

Lokalna przestrzeń adresowa

Okna dostępu do pamięci odległej

Ilustracja operacji na pamięci odległej

Procesor 0 Procesor 1

Page 34: Podstawy MPI-2: część I

Dla ilustracji rozważymy jeszcze raz obliczanie liczby przez całkowanie numeryczne pochodnej funkcji arcus tangens metodą trapezów.

dxx

1

021

14)1arctan(4

n

ii

n

i

fn

nin 11

2

4

5.01

14

Ilustracja przybliżonego obliczania liczby przez całkowanie numeryczne dla liczby przedziałów n=10.

Page 35: Podstawy MPI-2: część I

Zrównoleglenie algorytmu

1. Przedział całkowania dzieli się na n części: 1, 2,..., n

2. W układzie m procesorów, procesor 1 sumuje wkłady dla części 1, m+1, procesor 2 dla 2, m+2itd.

3. Procesory przesyłają swoje obliczone cząstkowe sumy do mastera, który oblicza sumę całkowitą.

Źródło programu z użyciem MPI-1 (operacje broadcast i reduce) (C)Źrodło programu z użyciem MPI-2 (operacje na pamięci odległej) (C)

Page 36: Podstawy MPI-2: część I

MPI_Init(&argc,&argv);MPI_Comm_size(MPI_COMM_WORLD,&numprocs);MPI_Comm_rank(MPI_COMM_WORLD,&myid);

MPI_Init(&argc,&argv);MPI_Comm_size(MPI_COMM_WORLD,&numprocs);MPI_Comm_rank(MPI_COMM_WORLD,&myid);

if (myid == 0) { MPI_Win_create(&n, sizeof(int), 1, MPI_INFO_NULL,MPI_COMM_WORLD, &nwin); MPI_Win_create(&pi, sizeof(double), 1, MPI_INFO_NULL,MPI_COMM_WORLD, &piwin); } else { MPI_Win_create(MPI_BOTTOM, 0, 1, MPI_INFO_NULL,MPI_COMM_WORLD, &nwin); MPI_Win_create(MPI_BOTTOM, 0, 1, MPI_INFO_NULL,MPI_COMM_WORLD, &piwin); }

Porównanie kodu w MPI-1 (po lewej) z kodem w MPI-2 (po prawej)

Page 37: Podstawy MPI-2: część I

while (!done) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "); scanf("%d",&n); } MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); if (n == 0) break; h = 1.0 / (double) n; sum = 0.0; for (i = myid + 1; i <= n; i += numprocs) { x = h * ((double)i - 0.5); sum += 4.0 / (1.0 + x*x); } mypi = h * sum;

while (1) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "); scanf("%d",&n); pi = 0.0; } MPI_Win_fence(0, nwin); if (myid != 0) MPI_Get(&n, 1, MPI_INT, 0, 0, 1, MPI_INT, nwin); MPI_Win_fence(0, nwin); if (n == 0) break; else { h = 1.0 / (double) n; sum = 0.0; for (i = myid + 1; i <= n; i += numprocs) { x = h * ((double)i - 0.5); sum += (4.0 / (1.0 + x*x)); } mypi = h * sum;

Page 38: Podstawy MPI-2: część I

MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

if (myid == 0) printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT)); } MPI_Finalize();

MPI_Win_fence( 0, piwin); MPI_Accumulate(&mypi, 1, MPI_DOUBLE, 0, 0, 1, MPI_DOUBLE, MPI_SUM, piwin); MPI_Win_fence(0, piwin); if (myid == 0) printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT)); } } MPI_Win_free(&nwin); MPI_Win_free(&piwin); MPI_Finalize();

Page 39: Podstawy MPI-2: część I

MPI_WIN_CREATE(base, size, disp_unit, info, comm, win)[IN base] początkowy adres okna (choice)[IN size] rozmiar okna w bajtach (integer, nieujemny)[IN disp_unit] lokalna jednostka przesunięcia w bajtach (integer, dodatni)[IN info] “pokrętło” obiektu informacyjnego (handle)[IN comm] komunikator (handle)[OUT win] “pokrętło” do okna (handle)

C:int MPI_Win_create(void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win)

FORTRAN/FORTRAN90:MPI_WIN_CREATE(BASE, SIZE, DISP_UNIT, INFO, COMM, WIN, IERROR)<type> BASE(*) INTEGER(KIND=MPI_ADDRESS_KIND) SIZE INTEGER DISP_UNIT, INFO, COMM, WIN, IERROR

C++:static MPI::Win MPI::Win::Create(const void* base, MPI::Aint size, int disp_unit, const MPI::Info& info, const MPI::Intracomm& comm)

Page 40: Podstawy MPI-2: część I

MPI_GET(origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win)[OUT origin_addr] początkowy adres początkowego bufora (choice)[IN origin_count] liczba elementów początkowego bufora (integer, nieujemny)[IN origin_datatype] typ danych każdego elementu (handle)[IN target_rank] rząd procesora celowego (integer, nieujemny)[IN target_disp] przesunięcie okna w stosunku do bufora celowego (integer, nieujemny)[IN target_count] liczba elementów bufora celowego (integer, nieujemny)[IN target_datatype] typ danych poszczególnych elementów bufora celowego (handle)[IN win] obiekt okna używany w komunikacji (handle)

Page 41: Podstawy MPI-2: część I

C:int MPI_Get(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win)

FORTRAN/FORTRAN90MPI_GET(ORIGIN_ADDR, ORIGIN_COUNT, ORIGIN_DATATYPE, TARGET_RANK, TARGET_DISP, TARGET_COUNT, TARGET_DATATYPE, WIN, IERROR)<type> ORIGIN_ADDR(*) INTEGER(KIND=MPI_ADDRESS_KIND) TARGET_DISP INTEGER ORIGIN_COUNT, ORIGIN_DATATYPE, TARGET_RANK, TARGET_COUNT, TARGET_DATATYPE, WIN, IERROR

C++:void MPI::Win::Get(const void *origin_addr, int origin_count, const MPI::Datatype& origin_datatype, int target_rank, MPI::Aint target_disp, int target_count, const MPI::Datatype& target_datatype) const

Page 42: Podstawy MPI-2: część I

MPI_WIN_FENCE(assert, win)[IN assert] asercja programowa (integer)[IN win] obiekt okna (handle)

C:int MPI_Win_fence(int assert, MPI_Win win)

FORTRAN/FORTRAN90:MPI_WIN_FENCE(ASSERT, WIN, IERROR)INTEGER ASSERT, WIN, IERROR

C++:void MPI::Win::Fence(int assert) const

Page 43: Podstawy MPI-2: część I

MPI_WIN_FREE(win)[INOUT win] obiekt okna (handle)

C:int MPI_Win_free(MPI_Win *win)

FORTRAN/FORTRAN90:MPI_WIN_FREE(WIN, IERROR)INTEGER WIN, IERROR

C++:void MPI::Win::Free()