Menggunakan MPI4Py untuk Proses Berbeda di Python
MPI (Message Passing Interface) adalah sebuah protokol komunikasi yang digunakan untuk menghubungkan antara proses-proses yang berjalan secara terpisah pada beberapa node komputer. Salah satu pustaka yang populer digunakan dalam Python adalah MPI4Py.
Dalam artikel ini, kita akan membahas bagaimana cara menggunakan MPI4Py untuk membuat program yang dapat berjalan secara simultan pada beberapa proses di Python. Contoh pertama adalah mengembangkan program "Hello World" dengan menggunakan MPI4Py dan Fortran 90.
Contoh 1: Menggunakan MPI4Py dengan C++ (F2Py)
Pertama-tama, kita akan membuat sebuah file Fortran 90 yang berisi subroutin sayhello
untuk mengembangkan program "Hello World".
subroutine sayhello(comm)
use mpi
implicit none
integer :: comm, rank, size, ierr
call MPI_Comm_size(comm, size, ierr)
call MPI_Comm_rank(comm, rank, ierr)
print *, 'Hello, World! I am process ',rank,' of ',size,'.'
end subroutine sayhello
Kemudian, kita akan menggunakan F2Py untuk mengompilasi file Fortran 90 menjadi sebuah pustaka Python.
$ f2py -c --f90exec=mpif90 helloworld.f90 -m helloworld
Setelah itu, kita dapat menjalankan program "Hello World" dengan menggunakan MPI4Py dan C++ (F2Py).
from mpi4py import MPI
import helloworld
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
helloworld.sayhello(comm)
Contoh 2: Menggunakan Scatter dalam Python
Dalam contoh ini, kita akan membuat sebuah program yang dapat membagi sebuah array menjadi beberapa bagian dan mengirimkannya ke proses-proses lain.
Misalnya, kita memiliki sebuah array data
dengan ukuran 8 elemen dan kita ingin membaginya menjadi 4 bagian. Kita dapat menggunakan fungsi scatter
dari MPI4Py untuk mencapai tujuan tersebut.
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
data = [i for i in range(8)] if rank == 0 else None
data = comm.scatter(data, root=0)
print str(rank) + ': ' + str(data)
Namun, jika kita menjalankan program tersebut dengan menggunakan 4 proses, maka akan terjadi error.
ValueError: expecting 2 items, got 8
Hal ini dikarenakan bahwa fungsi scatter
memerlukan bahwa data yang akan dibagikan memiliki ukuran yang sesuai dengan jumlah proses. Oleh karena itu, kita perlu mengubah program tersebut untuk membagi array menjadi bagian-bagian yang sesuai dengan jumlah proses.
Contoh 3: Mengirimkan Array NumPy dengan MPI4Py
Dalam contoh ini, kita akan membuat sebuah program yang dapat mengirimkan sebuah array NumPy ke proses-proses lain menggunakan fungsi scatterv
dari MPI4Py.
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
n = 6
if rank == 0:
d1 = np.arange(1, n+1)
split = np.array_split(d1, size)
split_size = [len(split[i]) for i in range(len(split))]
split_disp = np.insert(np.cumsum(split_size), 0, 0)[0:-1]
else:
# Create variables on other cores
d1 = None
split = None
split_size = None
split_disp = None
split_size = comm.bcast(split_size, root=0)
split_disp = comm.bcast(split_disp, root=0)
d1_local = np.zeros(split_size[rank])
comm.Scatterv([d1, split_size, split_disp, MPI.DOUBLE], d1_local, root=0)
print('rank ', rank, ': ', d1_local)
Namun, program tersebut tidak berjalan dengan benar dan terjadi error. Hal ini dikarenakan bahwa array NumPy yang akan dibagikan memiliki ukuran yang tidak sesuai dengan jumlah proses. Oleh karena itu, kita perlu mengubah program tersebut untuk membagi array menjadi bagian-bagian yang sesuai dengan jumlah proses.