25 Nisan 2018 Çarşamba

mpi

Giriş
Şu satırı dahil ederiz.
#include <boost/mpi.hpp>
Daha kolay kullanmak için şu satırı dahil ederiz.
namespace mpi = boost::mpi;
Gönderilen mesajın boost açısından serializable olması gerekir. Yani boost::archive::binary_oarchive ve boost::archive::binary_iarchive kullanması gerekir. Dolayısıyla şunun gibi satırları da dahil ederiz.
#include <boost/serialization/string.hpp>
Derleme
mpic++ ile derleriz. Şöyle yaparız. boost_mpi kütüphanesi ile linkleriz
$ mpic++ -o boostmpi boostmpi.cpp -lboost_mpi
Şöyle yaparız.
mpic++ test.cpp -lboost_mpi
Şöyle yaparız.
clang++ -I /usr/local/include/ timer.cpp -o timer -lboost_system -lboost_mpi
Çalıştırma
orterun ile çalıştırırız. Şöyle yaparız.
$ orterun ./boostmpi
I am process 2 on 4.
I am process 3 on 4.
I am process 0 on 4.
I am process 1 on 4.
$ 
environment Sınıfı
Şu satırı dahil ederiz.
#include <boost/mpi/environment.hpp>
Constructor - default
Şöyle yaparız.
mpi::environment env;
Constructor - argc + argv
Şöyle yaparız.
int main (int argc , char* argv[])
{
  mpi::environment env(argc,argv);
  ...
  return 0;
}
Aynı şeyi MPI ile yapmak istersek şöyle yaparız.
int main(int argc, char *argv[]) {
   
  // initialize MPI  
  MPI_Init(&argc,&argv);
  ...
  

  // done with MPI  
  MPI_Finalize();
}
processor_name metodu
Şöyle yaparız.
std::string s(env.processor_name());
Aynı şeyi MPI ile yapmak istersek şöyle yaparız.
int  len; 
char hostname[MPI_MAX_PROCESSOR_NAME];
MPI_Get_processor_name(hostname, &len);
communicator Sınıfı
Şu satırı dahil ederiz.
#include <boost/mpi/communicator.hpp>
Constructor
Şöyle yaparız.
mpi::communicator world;
iprobe metodu
Şöyle yaparız.
optional<status> stat= world.iprobe(0, 0);
if (stat)
{
  optional<int> count = (*stat).count<int>();
  if (count)
  {
    std::cout << *count << std::endl;
  }
}
MPI_Iprobe metoduna denk gelir.

irecv metodu
Örnek
Şöyle yaparız.
std::string rmsg;
mpi::request req = world.irecv (mpi::any_source, mpi::any_tag, rmsg);
Örnek
Şöyle yaparız.
std::shared_ptr<std::string> p = std::shared_ptr<std::string>(new std::string());
boost::mpi::request req = world.irecv(0, 0, *p);
Örnek
Şöyle yaparız.
std::list<int> q;
boost::mpi::request req = comm.irecv<std::list<int>>(1, 0, q);
isend metodu
Şöyle yaparız.
int a[70];
auto req = world.isend(0, 0, a);
MPI_Isend metoduna denk gelir.

rank metodu
Şöyle yaparız.
if (world.rank() == 0) {
  ...
} else {
  ...
}
Şöyle yaparız.
std::cout << "I am process " << world.rank() << " of " << world.size()
            << "." << std::endl;
Aynı şeyi MPI ile yapmak istersek şöyle yaparız.
int  numtasks, rank, len; 
char hostname[MPI_MAX_PROCESSOR_NAME];

// get number of tasks 
MPI_Comm_size(MPI_COMM_WORLD,&numtasks);

// get my rank  
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

// this one is obvious  
MPI_Get_processor_name(hostname, &len);
printf ("Number of tasks= %d My rank= %d Running on %s\n",numtasks,rank,hostname);
send metodu
Şöyle yaparız. İlk parametre hangi katılımcıya gönderileceğini, ikinci parametre tag bilgisini, üçüncü parametre mesajı içerir.
std::string msg = "Hello world";
world.send(1, 17, msg);
split metodu
Şöyle yaparız.
mpi::communicator world;

int group_id = world.rank()%3;

mpi::communicator local = world.split(group_id);
size metodu
Şöyle yaparız.
std::cout << "I am process " << world.rank() 
          << " on " << world.size() << "." << std::endl;
Çıktı olarak şunu alırız.
I am process 2 on 4.
I am process 3 on 4.
I am process 0 on 4.
I am process 1 on 4.
request Sınıfı
Constructor
Şöyle yaparız.
mpi::request req;
assignment operator metodu
Şöyle yaparız.
mpi::request req;
req = world.irecv (...,...,...);
cancel metodu
Açıklaması şöyle
A call to MPI_CANCEL marks for cancellation a pending, nonblocking communication operation (send or receive). The cancel call is local. It returns immediately, possibly before the communication is actually cancelled. It is still necessary to call MPI_REQUEST_FREE, MPI_WAIT or MPI_TEST (or any of the derived operations) with the cancelled request as argument after the call to MPI_CANCEL If a communication is marked for cancellation, then a MPI_WAIT call for that communication is guaranteed to return, irrespective of the activities of other processes (i.e., MPI_WAIT behaves as a local function);
Şöyle yaparız.
req.cancel();
req.wait();
test metodu
İmzası şöyle
/**
  *  Determine whether the communication associated with this request
  *  has completed successfully. If so, returns the @c status object
  *  describing the communication. Otherwise, returns an empty @c
  *  optional<> to indicate that the communication has not completed
  *  yet. Note that once @c test() returns a @c status object, the
  *  request has completed and @c wait() should not be called.
  */
optional<status> test();
Bir kere çağrılabilir. Açıklaması şöyle
optional< status > test(); Determine whether the communication associated with this request has completed successfully. If so, returns the status object describing the communication. Otherwise, returns an empty optional<> to indicate that the communication has not completed yet. Note that once test() returns a status object, the request has completed and wait() should not be called.
Örnek
Şöyle yaparız.
std::shared_ptr<std::string> p = std::shared_ptr<std::string>(new std::string());
boost::mpi::request req = world.irecv(0, 0, *p);
while (!req.test())
{
  Sleep(10);
}
Örnek
Şöyle yaparız.
boost::optional<mpi::status> stat = req.test();
status Sınıfı
Constructor
Şöyle yaparız.
mpi::request req = ...;
boost::optional<mpi::status> stat = req.test();
operator bool metodu
Şöyle yaparız.
boost::optional<mpi::status> stat = ...;
if (stat) {
  ...
};
source metodu
Şöyle yaparız. Mesajın hangi rank'ten geldiğini gösterir.
std::cout << "From " << stat->source() << std::endl;
tag metodu
Şöyle yaparız.
std::cout << "Tagged " << stat->tag() << std::endl;
Free Style Metodlar
all_reduce metodu
Şöyle yaparız.
boost::mpi::all_reduce(
  comm, 
  boost::mpi::inplace_t<int*>(ptr_int_array), 
  n_elements, 
  std::plus<double>());



Hiç yorum yok:

Yorum Gönder