MPI Functions (MPI_Send & MPI_Recv)

Paralel programlamada processler arasında veri  alış-verişi oldukça önemlidir. Seri bir halde yazılmış kodu paralel olarak çalıştırabilir duruma getirirken hangi process’in hangi işi nerede,  nasıl ve ne şekilde yapacağını belirlemek gerekmektedir.

Tabii bu işlem örnekte de olduğu gibi manuel olarak yapılmaktadır. Fakat türetilmiş fonksiyonlarda veri alış-verişi otomatik olarak yapılacaktır.

MPI kütüphanesinin en temel iki fonksiyonu MPI_Send() ve MPI_Recv() dir. İsimlerinden de anlaşılacağı üzere MPI_Send() datayı hedefe göndermek amacı ile kullanılmakta, MPI_Recv() ise gönderilen datanın alınmasını sağlamaktadır.

MPI_Send(
    void* data,
    int count,
    MPI_Datatype datatype,
    int destination,
    int tag,
    MPI_Comm communicator)
MPI_Recv(
    void* data,
    int count,
    MPI_Datatype datatype,
    int source,
    int tag,
    MPI_Comm communicator,
    MPI_Status* status)

 

void *data                          : Gönderilecek olan veri, RAM üzerindeki adresler ile çalıştığı için pointer yapıda.

int count                             : Gönderilecek olan verinin adedi.

MPI_Datatype datatype    : Gönderilecek olan verinin tipi.

int destination                    : Veriyi alacak olan processin numarası.

int tag                                  : Verinin numarası.

MPI_Comm  com               : Processlerin içinde bulunduğu evren.

 

Fonksiyonların parametrelerini okurken anlaşılması zor olan kısımlardan biri MPI_Datatype. Bu anahtar kelime ile processler arasında dolaşan verinin tipini MPI kütüphanesinin kendince belirlemiş olduğu bir veri tipi ile birlikte kullanmak durumundayız.

Go to book

MPI Kütüphanesine ait veri tipleri ve C deki karlışıkları

MPI_SHORT short int
MPI_INT int
MPI_LONG long int
MPI_LONG_LONG long long int
MPI_UNSIGNED_CHAR unsigned char
MPI_UNSIGNED_SHORT unsigned short int
MPI_UNSIGNED unsigned int
MPI_UNSIGNED_LONG unsigned long int
MPI_UNSIGNED_LONG_LONG unsigned long long int
MPI_FLOAT float
MPI_DOUBLE double
MPI_LONG_DOUBLE long double
MPI_BYTE char

Örnek olarak 0 ve 1 numaralı processler arasında number değişkeninin alış-verişini yapan bir C kodu.

int world_rank; // worker (process) numarasını tutacak değişken
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); // aktif evrende şuan çalışan worker (process) numarasını getirir 
int world_size; // aktif evrende çalışan toplam worker (process) sayısı
MPI_Comm_size(MPI_COMM_WORLD, &world_size); // aktif evrende toplam worker (process) sayısını getirir 

int number;
if (world_rank == 0) {
    number = -1; // hedef workera (process) gönderilecek data
    MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); // 0 numaralı etikete sahip, 1 adet number değişkenini 1 numaralı workera yolla  
} else if (world_rank == 1) {
    MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
             MPI_STATUS_IGNORE);
    printf("Process 1 received number %d from process 0\n",
           number);
}