Ping Pong

  1. Napiši program v katerem si dva prrocesa (rank 0 in rank 1) ponavljajoče izmenjujeta sporočila v obliki celoštevičnega polja sem in tja. Uporabite polja iz knjižnice NumPy. Program deluje tako pri tenisu
    1. rank 0 pošlje sporočilo na rank 1
    2. rank 1 sprejme to sporočilo in pošlje sprejeto sporočilo nazaj na rank 0
    3. rank 0 sprejme sporočilo od rank 1 in ga vrne
  2. # -*- 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)
  3. Program popravite tako, da bo delaloval tudi če bo več procesorjev, kot je potrebno. V tem primeru naj ostali procesorji ne delajo nič.

  4. 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:

    Rezultati Ping Pinga
    velikost (byte)# iteracijSkupen čas (s)Čas na sporočiloHitrost prenosa (MB/s)
         
         
         
  5. Opazujte kako se čas preminja z velikostjo sporočila. Kaj je asimptotična hitrost prenosa?
  6. Izriši graf glede na velikost sporočila, da določite latenco (čas potreben za sporočilo nične velikosti).
  7. Napišite program v katerem glavni proces pošilja sporočilo vsem ostalim procesom v MPI.COMM_WORLD in nato sprejme sporočila nazaj. Kako se spreminja potreben čas sporočila glede na število procesov?
  8. 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
  9. Napišimo program, ki bo seštel globalno vsoto z uporabo posredovanja naključnih števil okoli obroča. Vsak proces mora poznati številko svojih sosedov v obroču.
    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))
  10. Č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?

  11. Izmerite čas potreben ya globalno vsoto in koliko je potrebno za obdelavo posameznega sporočila?

  12. Uporabite sendrecv() ukaz namesto para send/recv.