# -*- coding: utf-8 -*-
from mpi4py import MPI
import numpy
comm = MPI.COMM_WORLD
rank = MPI.COMM_WORLD.Get_rank()
size = MPI.COMM_WORLD.Get_size()
name = MPI.Get_processor_name()
if size != 2:
print("Uporabi mpirun -np 2 python pingpong.py")
exit(1)
# predalociramo polje
bufsize = 1*1024*1024
if rank == 0:
data = numpy.arange(bufsize, dtype='i')
elif rank == 1:
data = numpy.empty(bufsize, dtype='i')
loops = 1000
for x in range(loops):
if rank == 0:
comm.Send([data, MPI.INT], dest = 1, tag=0xdead)
comm.Recv([data, MPI.INT], source=1, tag=0xbeef)
else:
comm.Recv([data, MPI.INT], source=0, tag=0xdead)
comm.Send([data, MPI.INT], dest = 0, tag=0xbeef)
if rank == 0:
print "Pretočeno %d MB podatkov" % (2*bufsize*loops/1024/1024)
Program popravite tako, da bo delaloval tudi če bo več procesorjev, kot je potrebno. V tem primeru naj ostali procesorji ne delajo nič.
Vstavite ukaze MPI.Wtime() za merjenje časa. Potrebno bo več ponovitev, še posebej pri manjših sporočilih, da boste dobili relevantne rezultate. Izdelajte tabelo v naslednji obliki:
velikost (byte) | # iteracij | Skupen čas (s) | Čas na sporočilo | Hitrost prenosa (MB/s) |
Preveri hitrost komunikacije na dveh vozliščih preko infinibanda (OPENIB) in etherneta (TCP) z ukazoma
bsub -n 2 -R "span[ptile=1]" -o pp-oib.txt mpirun --mca btl ^tcp python pingpong.py
bsub -n 2 -R "span[ptile=1]" -o pp-tcp.txt mpirun --mca btl ^openib python pingpong.py
from mpi4py import MPI
from random import randint
comm = MPI.COMM_WORLD
rank = MPI.COMM_WORLD.Get_rank()
size = MPI.COMM_WORLD.Get_size()
name = MPI.Get_processor_name()
counter = 0
data = randint(0,100)
for x in xrange(size):
comm.send(data, dest=(rank+1)%size, tag=7)
data = comm.recv(source=(rank+size-1)%size, tag=7)
counter += data
print("[%d] Skupna vsota: %d" % (rank,counter))
Če namesto naključnih števil inicializiramo lokalne vrednosti vseh P procesorjev na (rank+1)**2, ali dobite pravilen rezultat P(P+1)(2P+1)/6?
Izmerite čas potreben ya globalno vsoto in koliko je potrebno za obdelavo posameznega sporočila?
Uporabite sendrecv() ukaz namesto para send/recv.