Bài 03: LẬP TRÌNH SONG SONG VỚI MPI
4.1. CáC THAO TáC TRUYỀN THôNG CƠ BẢN
4.1.1. One-to-All Broadcast và All-to-One Reduction
Hình 4.2 sẽ mô tả hai thao tác One-to-All broadcast và All-to-One reduction:

Hình 4.2. One-to-All Broadcast và All-to-One Reduction
Hình 4.3 sẽ mô tả thao tác One-to-All broadcast trên một vòng 8 node. Node 0 được xem là node nguồn để phát tán. Mỗi bước truyền thông điệp được đánh số trên mũi tên, mũi tên cho biết thông điệp đi từ node này tới node kia.

Hình 4.3. One-to-All broadcast trên một vòng 8 node
Hình 4.4 sẽ mô tả thao tác All-to-One Reduction trên một vòng 8 node. Node 0 được xem là node đích của quá trình tập hợp. Mỗi bước truyền thông được đánh số trên mũi tên, mũi tên cho biết thông điệp đi từ node này tới node kia.

Hình 4.4. All-to-One Reduction trên một vòng 8 node
4.1.2. All-to-All Broadcast và All-to-All Reduction
Hình 4.5 sẽ mô tả hai thao tác All-to-All broadcast và All-to-All reduction:

Hình 4.5. All-to-All Broadcast và All-to-All Reduction
Ví dụ : Hình 4.6 mô tả thao tác All-to-all broadcast trên 8 node được đánh nhãn từ 0 đến 7. Số trên mũi tên cho biết là đang ở bước thứ mấy. Số ở trong ngoặc đơn cho biết node nào được gởi đến.

Hình 4.6. All-to-all broadcast trên 8 node
4.1.3. Scatter và Gather
Hình 4.7 sẽ mô tả thao tác Scatter và Gather:

Hình 4.7. Scatter và Gather
Ví dụ: Hình 4.8 mô tả các bước truyền thông cho thao tác Scatter trên hình lập phương 8 node.

Hình 4.8. Thao tác Scatter trên hình lập phương 8 node
4.1.4. All-to-All Personalized Communication
Hình 4.9 sẽ mô tả thao tác All-to-All personalized communication:

Hình 4.9. All-to-All Personalized Communication
Ví dụ: Hình 4.10 mô tả các bước truyền thông cho thao tác All-to-All personalized communication trên hình lập phương 8 node.

Hình 4.10. All-to-All Personalized Communication trên hình lập phương 8 node
4.2. THƯ VIỆN LẬP TRìNH MPI
MPI (Message Passing Interface) là một thư viện phức tạp, bao gồm 129 hàm, trong đó có nhiều tham số và biến số. Sau đây xin gới thiệu một số hàm cơ bản trong thư viện này.
4.2.1. Khởi tạo và kết thúc sử dụng thư viện MPI
Hai hàm này được gọi trong ngôn ngữ C lần lượt như sau:
int MPI_Init(int *argc, char ***argv)
int MPI_Finalize()
4.2.3. Lấy thông tin
int MPI_Comm_size(MPI_Comm comm, int *size)
int MPI_Comm_rank(MPI_Comm comm, int *rank)
4.2.4. Gởi và nhận thông điệp
int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

Hình 4.11. Mô tả hàm MPI_Send và MPI_Recv
4.2.5. Các thao tác toàn cục
- Barrier : đồng bộ hóa tất cả các tiến trình.
- Broadcast : gởi dữ liệu từ một tiến trình đến tất cả các tiến trình.
- Gather : Tập hợp dữ liệu từ tất cả các tiến trình tới một tiến trình.
- Scatter : phân tán dữ liệu từ một tiến trình đến tất cả các tiến trình.
- Reduction : tính tổng, nhân, … dữ liệu phân tán.
- Hàm Barrier
Hàm MPI_Barrier được dùng để thực thi thao tác đồng bộ hóa trong MPI.
Mục đích của nó là cho phép tất cả các tiến trình gặp nhau tại một điểm nào đó trong lúc thực thi. Điều này được mô tả như hình 4.12:

Hình 4.12. Mô tả hàm Barrier
Hàm MPI_Barrier được gọi như sau:
int MPI_Barrier(MPI_Comm comm)
- Hàm Broadcast
Hàm MPI_Bcast được gọi như sau:
int MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int source, MPI_Comm comm)
Hàm này được mô tả như hình 4.13:

Hình 4.13. Mô tả hàm Broadcast
- Hàm Reduction
Hàm MPI_Reduce được gọi như sau:
int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int target, MPI_Comm comm)
Hàm MPI_Reduce được dùng để thu gom các phần tử chứa trong buffer sendbuf của mỗi tiến trình trong nhóm, dùng thao tác nhận dạng trong op, và trả về giá trị thu gom được trong buffer recvbuf của tiến trình có rank là target.
Cả sendbuf và recvbuf phải có count và datatype giống nhau. Tất cả các tiến trình phải gọi hàm MPI_Reduce với giá trị giống nhau cho count, datatype, op, target và comm.
- Hàm Gather
Hàm MPI_Gather được gọi như sau:
int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype senddatatype, void *recvbuf, int recvcount, MPI_Datatype recvdatatype, int target, MPI_Comm comm)
Hàm này được mô tả như hình 4.14:

Hình 4.14. Mô tả hàm Gather
MPI cũng cung cấp hàm MPI_Allgather để dữ liệu được tập hợp đến tất cả các tiến trình không chỉ ở tiến trình đích:
int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype senddatatype, void *recvbuf, int recvcount, MPI_Datatype recvdatatype, MPI_Comm comm)
ý nghĩa của các tham số trong hàm MPI_Allgather cũng giống như các tham số của hàm MPI_Gather, tuy nhiên mỗi tiến trình phải cung cấp một mảng recvbuf để chứa dữ liệu đã tập hợp. Điều này sẽ được mô tả như hình 4.15:

Hình 4.15. Mô tả hàm Gather-to-all
- Hàm Scatter
Hàm MPI_Scatter được gọi như sau:
int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype senddatatype, void *recvbuf, int recvcount, MPI_Datatype recvdatatype, int source, MPI_Comm comm)
Hàm này được mô tả như hình 4.16:

Hình 4.16. Mô tả hàm Scatter
- Hàm All-to-All
int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype senddatatype, void *recvbuf, int recvcount, MPI_Datatype recvdatatype, MPI_Comm comm)
Hàm này được mô tả như hình 4.17:

Hình 4.17. Mô tả hàm All-to-all
4.2.6. Các thao tác truyền thông theo kiểu Non-Blocking
MPI cung cấp một số hàm thực thi các thao tác nhận và gởi thông điệp theo kiểu non-blocking. Những hàm này là MPI_Isend và MPI_Irecv. Hàm MPI_Isend bắt đầu thao tác gởi nhưng chưa hoàn tất, tức là nó trả về trước khi dữ liệu được sao chép ra ngoài buffer. Tương tự, MPI_Irecv bắt đầu thao tác nhận nhưng nó trả về trước khi dữ liệu được nhận và sao chép vào buffer.
Hàm MPI_Isend và MPI_Irecv được gọi lần lượt như sau:
int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source,int tag, MPI_Comm comm, MPI_Request *request)

Hình 4.18. Mô tả truyền thông theo kiểu Non-Blocking