Jug Tutorial: Coarse-Level Parallel Programming in Python Luis - - PowerPoint PPT Presentation

jug tutorial coarse level parallel programming in python
SMART_READER_LITE
LIVE PREVIEW

Jug Tutorial: Coarse-Level Parallel Programming in Python Luis - - PowerPoint PPT Presentation

Jug Tutorial: Coarse-Level Parallel Programming in Python Luis Pedro Coelho luis@luispedro.org May 15, 2013 Luis Pedro Coelho (luis@luispedro.org) Jug Tutorial 0 May 15, 2013 (1 / 24) Problem Brute force a password. Luis Pedro


slide-1
SLIDE 1

Jug Tutorial: Coarse-Level Parallel Programming in Python

Luis Pedro Coelho

luis@luispedro.org

May 15, 2013

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (1 / 24)

slide-2
SLIDE 2

Problem

Brute force a password.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (2 / 24)

slide-3
SLIDE 3

Assumptions

The crypt module exists with elements: decrypt: decrtypt ciphertext given a password. isgood: test whether this text could be the plaintext. letters: just the letters. Also, we know that the password is five letters.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (3 / 24)

slide-4
SLIDE 4

Simple Solution

import itertools from crypt import decode, letters, isgood, preprocess ciphertext = file('secret.msg').read() ciphertext = preprocess(ciphertext) for p in itertools.product(letters, repeat=5): text = decode(ciphertext, p) if isgood(text): passwd = "".join(map(chr,p)) print '%s:%s' % (passwd, text)

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (4 / 24)

slide-5
SLIDE 5

This solution does not take advantage of multiple processors.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (5 / 24)

slide-6
SLIDE 6

Tasks

import itertools from crypt import decode, letters, isgood, preprocess ciphertext = file('secret.msg').read() ciphertext = preprocess(ciphertext) def decrypt(ciphertext, p): text = decode(ciphertext, p) if isgood(text): passwd = "".join(map(chr,p)) return (passwd, text) # else: return None results = [] for p in itertools.product(letters, repeat=5): results.append(Task(decrypt,ciphertext,p))

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (6 / 24)

slide-7
SLIDE 7

Python Magic

from jug import TaskGenerator import itertools from crypt import decode, letters, isgood, preprocess ciphertext = file('secret.msg').read() ciphertext = preprocess(ciphertext) @TaskGenerator def decrtypt(ciphertext, p): text = decode(ciphertext, p) if isgood(text): passwd = "".join(map(chr,p)) return (passwd, text) # else: return None results = [] for p in itertools.product(letters, repeat=5): results.append(decrypt(ciphertext,p))

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (7 / 24)

slide-8
SLIDE 8

Enter Jug

You give it the Jugfile, it runs the tasks for you!

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (8 / 24)

slide-9
SLIDE 9

Jug Loop

while len(tasks) > 0: ready = [t for t in tasks if can_run(t)] for t in ready: if not is_running(t): t.run() tasks.remove(t)

Except jug is much fancier!

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (9 / 24)

slide-10
SLIDE 10

Jug Advantages

1

Automatic task-level parallelization with dependency tracking.

2

Remember all intermediate results.

3

Makes writing parallel code look like writing sequential code.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (10 / 24)

slide-11
SLIDE 11

This example is actually not so good. We have 265 ≈ 11M tasks, all of which run very fast. As a rule of thumb, your tasks should take at least a couple of seconds.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (11 / 24)

slide-12
SLIDE 12

Solution each task will be: Given a letter, try all passwords beginning with that letter. Now, we have 26 tasks. Much better.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (12 / 24)

slide-13
SLIDE 13

@TaskGenerator def decrypt(prefix): res = [] for suffix in product(letters, repeat=5-len(prefix)): passwd = np.concatenate([prefix, suffix]) text = decode(ciphertext, passwd) if isgood(text): passwd = "".join(map(chr, passwd)) res.append( (passwd, text) ) return res @TaskGenerator def join(partials): return list(chain(*partials)) results = join([decrypt([p]) for p in letters])

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (13 / 24)

slide-14
SLIDE 14

Let’s call jug now. (Assuming our code is in a file called jugfile.py)

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (14 / 24)

slide-15
SLIDE 15

$jug status Task name Waiting Ready Finished Running

  • jugfile.join

1 jugfile.decrypt 26 ............................................... Total: 1 26 Some tasks are ready. None are running.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (15 / 24)

slide-16
SLIDE 16

$jug execute & [1] 29501 $jug execute & [2] 29502 Executing in the background. . .

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (16 / 24)

slide-17
SLIDE 17

$jug status Task name Waiting Ready Finished Running

  • jugfile.join

1 jugfile.decrypt 24 2 ............................................... Total: 1 24 2 Two tasks running. Good.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (17 / 24)

slide-18
SLIDE 18

Wait a few minutes. . .

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (18 / 24)

slide-19
SLIDE 19

$jug status Task name Waiting Ready Finished Running

  • jugfile.join

1 jugfile.decrypt 14 10 2 ............................................... Total: 1 14 10 2 Ten tasks have finished. Notice how the join task must wait for all the others.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (19 / 24)

slide-20
SLIDE 20

A few more minutes. . .

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (20 / 24)

slide-21
SLIDE 21

$jug status Task name Waiting Ready Finished Running

  • jugfile.join

1 jugfile.decrypt 26 ............................................... Total: 27

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (21 / 24)

slide-22
SLIDE 22

What Now?

All tasks are finished! How do I get to the results?

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (22 / 24)

slide-23
SLIDE 23

import jug jug.init('jugfile', 'jugdata') import jugfile results = jug.task.value(jugfile.results) for p,t in results: print "%s\n\n Password was '%s'" % (t,p)

jug.init is necessary to initialise the jug backend. Then, the jugfile can be directly imported as a Python module.

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (23 / 24)

slide-24
SLIDE 24

For more information

http://luispedro.org/software/jug http://github.com/luispedro/jug

Luis Pedro Coelho (luis@luispedro.org) ⋆ Jug Tutorial 0 ⋆ May 15, 2013 (24 / 24)