Programação Paralela em Python
      Bibliotecas e Alternativas




            TDC 2010
            Rodrigo Hübner
Vamos discutir...

●   Arquiteturas Computacionais estão se deslocando
para UCP's multicore;
●   Softwares precisam explorar o paralelismo subjacente;
●   Programação multithreading em Python;
●   Bibliotecas existentes...
●   Alternativas;
●   Conclusões.
Exemplo: threading

from threading import Thread

def minha_funcao(argumento):
  print argumento

t = Thread( target = minha_funcao, args = ('algo',))
t.start()
Exemplo: threading

               Problema!

...Python não é totalmente thread-safe...


             O que fazer?
Exemplos: multiprocessing


from multiprocessing import Process

def f(nome):
  print 'Olá', nome

if __name__ == '__main__':
    p = Process(target=f, args=('Rodrigo',))
    p.start()
    p.join()
Exemplos: multiprocessing


from multiprocessing import Process, Queue

def f(q):
  q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get() # prints "[42, None, 'hello']"
    p.join()
Exemplo: Parallel Python
import math, sys, time, pp

def sum_primes(n):
  return sum([x for x in xrange(2,n) if isprime(x)])

ppservers = ()

if len(sys.argv) > 1:
    ncpus = int(sys.argv[1])
    job_server = pp.Server(ncpus, ppservers=ppservers)
else:
    job_server = pp.Server(ppservers=ppservers)

job1 = job_server.submit(sum_primes, (100,), (isprime,), ("math",))

result = job1()
start_time = time.time()

inputs = (100000, 100100, 100200, 100300, 100400, 100500, 100600, 100700)
jobs = [(input, job_server.submit(sum_primes,(input,), (isprime,), ("math",))) for input in inputs]
for input, job in jobs:
   print "Sum of primes below", input, "is", job()

job_server.print_stats()
Parallel Python




      Feio!
Exemplos: MPI for Python


from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

if rank == 0:
   data = {'a': 7, 'b': 3.14}
   comm.send(data, dest=1, tag=11)
elif rank == 1:
   data = comm.recv(source=0, tag=11)
Alternativas...


●Jython possui um ótimo desempenho usando threads
pois não possui o GIL;

●   MPI está implementada em Python.

●   Criar novos processos a partir de threads em Python;

●Aproveitar padrões existentes criando novos
modelos...
Aplicações de modelos...


● Objetivo é aplicar modelos de programação paralela
que que facilite o trabalho do programador e que
forneça escalabilidade.

●Modelo de programação com fluxos de execução
paralelo implícito – TIRT
O módulo TIRT


●   Cria trabalhadores implícitos;

●   Gerenciamento a cargo do ambiente de execução;

●   Balanceamento de carga (Roubo de Tarefas)

●   Oferece escalabilidade.
TIRT: arquitetura
O módulo TIRT: Implementação


●   Anotação de tarefas usando @decorators;

●   multiprocessing;

●Gerenciar objetos compartilhados utilizando Managers
(multiprocessing);

●   NÃO utilizar pré-processamento!
TIRT: Exemplos
01 from tirt import task, barrier, get_n_cpu, final, init
02                                                          20 @init
03 @task                                                    21 def matrix_stuff():
04 def worker(w):                                           22 # Inicializa a matriz
05 first_row = (w - 1) * HEIGHT + 1                         23
06 last_row = first_row + HEIGHT - 1                        24 if __name__ == "__main__":
07 barrier()                                                25 MAX_ITERS = 100
08 for iters in range(1, MAX_ITERS):                        26 N = 5000
09      for i in range(first_row, last_row):                27 HEIGHT = N / get_n_cpu()
10          # Processa pontos vermelhos                     28 GRID = []
11      barrier()                                           29 matrix_stuff()
12      for i in range(first_row, last_row):                30 for i in range(get_n_cpu()):
13          # Processa pontos pretos                        31       worker(i+1)
14      barrier()                                           32 validate()
15
16 @final
17 def validate():
18 # Faz a validação dos resultados obtidos
FIM



     Obrigado

 ●   Rodrigo Hübner
● rhubner@gmail.com

   ● @rodrigohubner

Tdc2010

  • 1.
    Programação Paralela emPython Bibliotecas e Alternativas TDC 2010 Rodrigo Hübner
  • 2.
    Vamos discutir... ● Arquiteturas Computacionais estão se deslocando para UCP's multicore; ● Softwares precisam explorar o paralelismo subjacente; ● Programação multithreading em Python; ● Bibliotecas existentes... ● Alternativas; ● Conclusões.
  • 3.
    Exemplo: threading from threadingimport Thread def minha_funcao(argumento): print argumento t = Thread( target = minha_funcao, args = ('algo',)) t.start()
  • 4.
    Exemplo: threading Problema! ...Python não é totalmente thread-safe... O que fazer?
  • 5.
    Exemplos: multiprocessing from multiprocessingimport Process def f(nome): print 'Olá', nome if __name__ == '__main__': p = Process(target=f, args=('Rodrigo',)) p.start() p.join()
  • 6.
    Exemplos: multiprocessing from multiprocessingimport Process, Queue def f(q): q.put([42, None, 'hello']) if __name__ == '__main__': q = Queue() p = Process(target=f, args=(q,)) p.start() print q.get() # prints "[42, None, 'hello']" p.join()
  • 7.
    Exemplo: Parallel Python importmath, sys, time, pp def sum_primes(n): return sum([x for x in xrange(2,n) if isprime(x)]) ppservers = () if len(sys.argv) > 1: ncpus = int(sys.argv[1]) job_server = pp.Server(ncpus, ppservers=ppservers) else: job_server = pp.Server(ppservers=ppservers) job1 = job_server.submit(sum_primes, (100,), (isprime,), ("math",)) result = job1() start_time = time.time() inputs = (100000, 100100, 100200, 100300, 100400, 100500, 100600, 100700) jobs = [(input, job_server.submit(sum_primes,(input,), (isprime,), ("math",))) for input in inputs] for input, job in jobs: print "Sum of primes below", input, "is", job() job_server.print_stats()
  • 8.
  • 9.
    Exemplos: MPI forPython from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() if rank == 0: data = {'a': 7, 'b': 3.14} comm.send(data, dest=1, tag=11) elif rank == 1: data = comm.recv(source=0, tag=11)
  • 10.
    Alternativas... ●Jython possui umótimo desempenho usando threads pois não possui o GIL; ● MPI está implementada em Python. ● Criar novos processos a partir de threads em Python; ●Aproveitar padrões existentes criando novos modelos...
  • 11.
    Aplicações de modelos... ●Objetivo é aplicar modelos de programação paralela que que facilite o trabalho do programador e que forneça escalabilidade. ●Modelo de programação com fluxos de execução paralelo implícito – TIRT
  • 12.
    O módulo TIRT ● Cria trabalhadores implícitos; ● Gerenciamento a cargo do ambiente de execução; ● Balanceamento de carga (Roubo de Tarefas) ● Oferece escalabilidade.
  • 13.
  • 14.
    O módulo TIRT:Implementação ● Anotação de tarefas usando @decorators; ● multiprocessing; ●Gerenciar objetos compartilhados utilizando Managers (multiprocessing); ● NÃO utilizar pré-processamento!
  • 15.
    TIRT: Exemplos 01 fromtirt import task, barrier, get_n_cpu, final, init 02 20 @init 03 @task 21 def matrix_stuff(): 04 def worker(w): 22 # Inicializa a matriz 05 first_row = (w - 1) * HEIGHT + 1 23 06 last_row = first_row + HEIGHT - 1 24 if __name__ == "__main__": 07 barrier() 25 MAX_ITERS = 100 08 for iters in range(1, MAX_ITERS): 26 N = 5000 09 for i in range(first_row, last_row): 27 HEIGHT = N / get_n_cpu() 10 # Processa pontos vermelhos 28 GRID = [] 11 barrier() 29 matrix_stuff() 12 for i in range(first_row, last_row): 30 for i in range(get_n_cpu()): 13 # Processa pontos pretos 31 worker(i+1) 14 barrier() 32 validate() 15 16 @final 17 def validate(): 18 # Faz a validação dos resultados obtidos
  • 16.
    FIM Obrigado ● Rodrigo Hübner ● rhubner@gmail.com ● @rodrigohubner