Separating Functional and Parallel Correctness using - - PowerPoint PPT Presentation

separating functional and parallel correctness using
SMART_READER_LITE
LIVE PREVIEW

Separating Functional and Parallel Correctness using - - PowerPoint PPT Presentation

Separating Functional and Parallel Correctness using Nondeterministic Sequential Specifications Jacob Burnim, George Necula, Koushik Sen University of California, Berkeley 1 HotPar ' 10, Berkeley, CA June 14, 2010 Parallel Programming is


slide-1
SLIDE 1

Separating Functional and Parallel Correctness using Nondeterministic Sequential Specifications

Jacob Burnim, George Necula, Koushik Sen University of California, Berkeley

HotPar '10, Berkeley, CA June 14, 2010 1

slide-2
SLIDE 2

Parallel Programming is Hard

Key Culprit: Nondeterministic

interleaving of parallel threads.

Painful to reason simultaneously about

parallelism and functional correctness.

Goal: Decompose efforts in addressing

parallelism and functional correctness.

Allow programmers to reason about

functional correctness sequentially.

Independently show correctness of parallelism.

2

slide-3
SLIDE 3

Our Approach

Goal: Decompose efforts in addressing

parallelism and functional correctness.

Parallel program Functional specification ≤

3

slide-4
SLIDE 4

Our Approach

Goal: Decompose efforts in addressing

parallelism and functional correctness.

Parallel program Functional specification Program / specification

4

slide-5
SLIDE 5

Our Approach

Goal: Decompose efforts in addressing

parallelism and functional correctness.

Parallel program Functional specification Program / specification

5

Parallelism Correctness. Prove independently of complex & sequential function correctness.

slide-6
SLIDE 6

Our Approach

Goal: Decompose efforts in addressing

parallelism and functional correctness.

Parallel program Functional specification Sequential program / specification

6

Want to be able to reason about functional correctness without parallel interleavings. Parallelism Correctness. Prove independently of complex & sequential function correctness.

slide-7
SLIDE 7

Our Approach

Use sequential but nondeterministic

specification for a program’s parallelism.

User annotates intended nondeterminism.

Parallel program Functional specification Nondeterministic sequential program/spec

7

slide-8
SLIDE 8

Our Approach

Use sequential but nondeterministic

specification for a program’s parallelism.

User annotates intended nondeterminism.

Parallel program Functional specification Nondeterministic sequential program/spec Parallelism correct if adds no unintended nondeterminism. Can address functional correctness without parallel interleavings.

8

slide-9
SLIDE 9

Outline

Overview Motivating Example Nondeterministic Sequential (NDSEQ)

Specifications for Parallel Correctness

Proving Parallel Correctness Future Work Conclusions

9

slide-10
SLIDE 10

Motivating Example

Goal: Find minimum-cost solution.

Simplified branch-and-bound benchmark.

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

10

slide-11
SLIDE 11

Motivating Example

Goal: Find minimum-cost solution.

Simplified branch-and-bound benchmark.

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

Input: List of possible solutions. Output: Solution from input queue with minimum cost.

11

slide-12
SLIDE 12

Motivating Example

Goal: Find minimum-cost solution.

Simplified branch-and-bound benchmark.

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

Computes cost of solution w. Expensive.

12

slide-13
SLIDE 13

Motivating Example

Goal: Find minimum-cost solution.

Simplified branch-and-bound benchmark.

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

Computes cost of solution w. Expensive. Computes cheap lower bound on cost of w.

13

slide-14
SLIDE 14

Motivating Example

Goal: Find minimum-cost solution.

Simplified branch-and-bound benchmark.

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

Computes cost of solution w. Expensive. Computes cheap lower bound on cost of w. Prune when w cannot have minimum-cost.

14

slide-15
SLIDE 15

Motivating Example

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

bound: 1 cost: 2

(a)

bound: 0 cost: 3

(b)

bound: 5 cost: 9

(c) queue: best: ∞ best_soln:

15

slide-16
SLIDE 16

Motivating Example

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

bound: 1 cost: 2

(a)

bound: 0 cost: 3

(b)

bound: 5 cost: 9

(c) prune?(a) queue: best: ∞ best_soln:

16

slide-17
SLIDE 17

Motivating Example

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

bound: 1 cost: 2

(a)

bound: 0 cost: 3

(b)

bound: 5 cost: 9

(c) prune?(a) update(a) queue: best: 2 best_soln:

17

slide-18
SLIDE 18

Motivating Example

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

bound: 1 cost: 2

(a)

bound: 0 cost: 3

(b)

bound: 5 cost: 9

(c) prune?(a) update(a) prune?(b) queue: best: 2 best_soln:

18

slide-19
SLIDE 19

Motivating Example

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

bound: 1 cost: 2

(a)

bound: 0 cost: 3

(b)

bound: 5 cost: 9

(c) prune?(a) update(a) prune?(b) update(b) queue: best_soln: best: 2

19

slide-20
SLIDE 20

Motivating Example

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

bound: 1 cost: 2

(a)

bound: 0 cost: 3

(b)

bound: 5 cost: 9

(c) prune?(a) update(a) prune?(b) update(b) prune?(c) queue: best_soln: best: 2

20

slide-21
SLIDE 21

Motivating Example

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

bound: 1 cost: 2

(a)

bound: 0 cost: 3

(b)

bound: 5 cost: 9

(c) prune?(a) update(a) prune?(b) update(b) prune?(c) queue: best_soln: best: 2

21

slide-22
SLIDE 22

Motivating Example

Goal: Find minimum-cost solution.

Simplified branch-and-bound benchmark.

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

22

slide-23
SLIDE 23

Motivating Example

Goal: Find minimum-cost solution.

Simplified branch-and-bound benchmark.

for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

How do we parallelize this code?

23

slide-24
SLIDE 24

Parallelizing our Example

Goal: Find min-cost solution in parallel.

Simplified branch-and-bound benchmark.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

24

slide-25
SLIDE 25

Parallelizing our Example

Goal: Find min-cost solution in parallel.

Simplified branch-and-bound benchmark.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

Updates to best are atomic. Loop iterations can be run in parallel.

25

slide-26
SLIDE 26

Prove Parallelism Correct?

Claim: Parallelization is correct.

If there are any bugs, they are sequential. Want to prove parallelization correct.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

26

slide-27
SLIDE 27

Prove Parallelism Correct?

Claim: Parallelization is correct.

If there are any bugs, they are sequential. Want to prove parallelization correct.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

Idea: Specify that parallel version gives same result as sequential.

27

slide-28
SLIDE 28

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: ∞ best_soln:

28

slide-29
SLIDE 29

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(a) update(a)

29

slide-30
SLIDE 30

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(a) update(a) update(b) prune?(b)

30

slide-31
SLIDE 31

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(a) update(a) update(b) prune?(b)

31

prune?(c)

slide-32
SLIDE 32

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(a) prune?(c) update(a) update(b) prune?(b)

Sequential program always finds best_soln = (a).

32

slide-33
SLIDE 33

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: ∞ best_soln:

33

slide-34
SLIDE 34

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: ∞ best_soln: prune?(a)

34

slide-35
SLIDE 35

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(b) update(b) prune?(a)

35

slide-36
SLIDE 36

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(b) update(b) prune?(a) prune?(c)

36

slide-37
SLIDE 37

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(b) update(a) update(b) prune?(a) prune?(c)

37

slide-38
SLIDE 38

Parallel-Sequential Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln:

Parallel version can also find best_soln = (b).

prune?(b) update(a) update(b) prune?(a) prune?(c)

38

slide-39
SLIDE 39

Parallel-Sequential Equivalence?

Parallel and sequential not equivalent.

Claim: But parallelism is correct.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

39

slide-40
SLIDE 40

Parallel-Sequential Equivalence?

Parallel and sequential not equivalent.

Claim: But parallelism is correct.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

Some nondeterminism is okay. Specification for the parallelism must indicate intended or algorithmic nondeterminism.

40

slide-41
SLIDE 41

NDSEQ Specification

Use nondeterministic sequential (NDSEQ)

version of program as spec for parallelism.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w nondet-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

41

slide-42
SLIDE 42

NDSEQ Specification

Use nondeterministic sequential (NDSEQ)

version of program as spec for parallelism.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w nondet-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

Allow sequential code to perform iterations in a nondeterministic order.

42

slide-43
SLIDE 43

NDSEQ Specification

Specifies:

For every parallel execution, there must exist

an NDSEQ execution with the same result.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w nondet-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

43

slide-44
SLIDE 44

Parallel-NDSEQ Equivalence?

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(b) update(a) update(b) prune?(a) prune?(c)

Parallel:

No equivalent

sequential execution.

An equivalent

NDSEQ execution?

44

slide-45
SLIDE 45

Parallel-NDSEQ Equivalence?

bound: 1 cost: 2

queue: (a)

bound: 0 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(b) update(a) update(b) prune?(a) prune?(c)

Parallel: NDSEQ:

prune?(b) prune?(c) update(b) update(a) prune?(a) Equivalent.

45

slide-46
SLIDE 46

NDSEQ Specification

Does this NDSEQ specification really capture correctness of the parallelism?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w nondet-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

46

slide-47
SLIDE 47

Recall: Our Approach

Use sequential but nondeterministic

specification for a program’s parallelism.

User annotates intended nondeterminism.

Parallel program Functional specification Nondeterministic but sequential program/spec Parallelism correct if adds no unintended nondeterminism.

47

Can address functional correctness without parallel interleavings.

slide-48
SLIDE 48

Recall: Our Approach

Use sequential but nondeterministic

specification for a program’s parallelism.

User annotates intended nondeterminism.

Parallel program Functional specification Nondeterministic but sequential program/spec

48

Prove independently

  • f complex functional

correctness. Can address functional correctness without parallel interleavings.

slide-49
SLIDE 49

Parallel-NDSEQ Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 2 cost: 2

queue: (a)

bound: 2 cost: 2

(b)

bound: 5 cost: 9

(c) best_soln: best: ∞

49

slide-50
SLIDE 50

Parallel-NDSEQ Equivalence?

bound: 2 cost: 2

queue: (a)

bound: 2 cost: 2

(b)

bound: 5 cost: 9

(c) best_soln: prune?(a) prune?(b) best: ∞

50

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

slide-51
SLIDE 51

Parallel-NDSEQ Equivalence?

bound: 2 cost: 2

queue: (a)

bound: 2 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(a) prune?(b) update(a)

51

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

slide-52
SLIDE 52

Parallel-NDSEQ Equivalence?

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

bound: 2 cost: 2

queue: (a)

bound: 2 cost: 2

(b)

bound: 5 cost: 9

(c) best_soln: prune?(a) prune?(b) update(a) update(b)

52

best: 2

slide-53
SLIDE 53

Parallel-NDSEQ Equivalence?

bound: 2 cost: 2

queue: (a)

bound: 2 cost: 2

(b)

bound: 5 cost: 9

(c) best_soln: prune?(c) prune?(a) prune?(b) update(a) update(b)

53

best: 2 parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

slide-54
SLIDE 54

Parallel-NDSEQ Equivalence?

bound: 2 cost: 2

queue: (a)

bound: 2 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(c) prune?(a) prune?(b) update(a) update(b)

54

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

Parallel code can avoid pruning by interleaving iterations. NDSEQ version must prune either (a) or (b).

slide-55
SLIDE 55

Parallel-NDSEQ Equivalence?

bound: 2 cost: 2

queue: (a)

bound: 2 cost: 2

(b)

bound: 5 cost: 9

(c) best: 2 best_soln: prune?(c) prune?(a) prune?(b) update(a) update(b)

55

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

Parallel code can avoid pruning by interleaving iterations. NDSEQ should have freedom to not prune.

slide-56
SLIDE 56

NDSEQ Specification

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w nondet-for (w in queue): if (lower_bnd(w) >= best): if (*): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

Allows NDSEQ version to nondeterministically not prune when pruning is possible.

56

slide-57
SLIDE 57

NDSEQ Specification

Claim: NDSEQ code a good specification

for the correctness of the parallelism.

parallel-for (w in queue): if (lower_bnd(w) >= best): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w nondet-for (w in queue): if (lower_bnd(w) >= best): if (*): continue cost = compute_cost(w) if cost < best: best = cost best_soln = w

57

slide-58
SLIDE 58

Recall: Our Approach

Use sequential but nondeterministic

specification for a program’s parallelism.

User annotates intended nondeterminism.

Parallel program Functional specification Nondeterministic but sequential program/spec Prove parallel correctness independent of complex functional correctness. Can address functional correctness without parallel interleavings.

58

slide-59
SLIDE 59

NDSEQ Functional Correctness

59

Claim: much easier

Consider recursive Boolean programs Consider Model Checking: Reachability Parallel Programs

pushdown system with multiple stacks

Undecidable [Ramalingam '00]

Nondeterministic sequential programs

pushdown systems

Decidable [Finkel et al. '97, Bouajjani et al. '97, and others]

slide-60
SLIDE 60

Outline

Overview Motivating Example Nondeterministic Sequential (NDSEQ)

Specifications for Parallel Correctness

Proving Parallel Correctness Future Work Conclusions

60

slide-61
SLIDE 61

NDSEQ Specification

Specifies:

For every parallel execution, there exists an

NDSEQ execution with the same result.

parallel-for (w in queue): if (lower_bnd(w) >= best): if (*): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w nondet-for (w in queue): if (lower_bnd(w) >= best): if (*): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

61

slide-62
SLIDE 62

Proving NDSEQ Equivalence

Prove: For every parallel execution, there is

an NDSEQ one yielding the same result.

prune?(c) prune?(a) prune?(b) update(a) update(b)

Parallel:

best_soln: (b)

62

slide-63
SLIDE 63

Proving NDSEQ Equivalence

Prove: For every parallel execution, there is

an NDSEQ one yielding the same result.

prune?(c) prune?(a) prune?(b) update(a) update(b)

Parallel: NDSEQ:

prune?(c) prune?(a) prune?(b) update(a) update(b) best_soln: (b) best_soln: (b)

63

slide-64
SLIDE 64

Proving NDSEQ Equivalence

Prove: For every parallel execution, there is

an NDSEQ one yielding the same result.

prune?(c) prune?(a) prune?(b) update(a) update(b)

Parallel: NDSEQ:

prune?(c) prune?(a) prune?(b) update(a) update(b) best_soln: (b) best_soln: (b)

64

slide-65
SLIDE 65

Proving NDSEQ Equivalence

Prove: For every parallel execution, there is

an NDSEQ one yielding the same result.

prune?(c) prune?(a) prune?(b) update(a) update(b)

Parallel: NDSEQ:

prune?(c) prune?(a) prune?(b) update(a) update(b) best_soln: (b) best_soln: (b)

Can we prove that such a rearrangement is always possible?

65

slide-66
SLIDE 66

Proving NDSEQ Equivalence

Is it always possible to move a prune?

check later in a parallel execution without changing the result?

prune?(a) prune?(b) update(b) prune?(a) prune?(b) update(b) update(a) update(a)

… …

66

slide-67
SLIDE 67

Proving NDSEQ Equivalence

Is it always possible to move a prune?

check later in a parallel execution without changing the result?

Yes – if the check does not prune.

prune?(a) prune?(b) update(b) prune?(a) prune?(b) update(b) update(a) update(a)

… …

67

slide-68
SLIDE 68

Proving NDSEQ Equivalence

(1) Can prune?(x) move past prune?(y).

if (lower_bnd(x) >= best): if (*): continue if (lower_bnd(y) >= best): if (*): continue

state: σ1 state: σ2

68

slide-69
SLIDE 69

Proving NDSEQ Equivalence

(1) Can prune?(x) move past prune?(y).

if (lower_bnd(x) >= best): if (*): continue if (lower_bnd(y) >= best): if (*): continue

state: σ1 state: σ2

if (lower_bnd(x) >= best): if (*): continue if (lower_bnd(y) >= best): if (*): continue

state: σ1 state: σ2

69

slide-70
SLIDE 70

Proving NDSEQ Equivalence

(2) Can prune?(x) move past update?(y).

if (lower_bnd(x) >= best): if (*): continue best = * best_soln = *

state: σ1 state: σ2

70

slide-71
SLIDE 71

Proving NDSEQ Equivalence

(2) Can prune?(x) move past update?(y).

if (lower_bnd(x) >= best): if (*): continue best = * best_soln = *

state: σ1 state: σ2

if (lower_bnd(x) >= best): if (*): continue best = * best_soln = *

state: σ1 state: σ2

71

slide-72
SLIDE 72

Proving NDSEQ Equivalence

This is proof by reduction [Lipton ’75].

[Elmas, et al., POPL 09] has proved

atomicity by reduction with SMT solvers.

parallel-for (w in queue): if (lower_bnd(w) >= best): if (*): continue cost = compute_cost(w) atomic: if cost < best: best = cost best_soln = w

Right- mover Atomic

72

slide-73
SLIDE 73

Outline

Overview Motivating Example Nondeterministic Sequential (NDSEQ)

Specifications for Parallel Correctness

Proving Parallel Correctness Future Work + Conclusions

73

slide-74
SLIDE 74

Future Work

Prove parallel-NDSEQ equivalence for

real benchmarks.

Automated proofs using SMT solving.

Combine with tools for verifying sequential

programs with nondeterminism.

Model checking techniques (e.g., CEGAR)

Also interested in dynamically checking

NDSEQ specifications.

74

slide-75
SLIDE 75

NDSEQ and Debugging

75

Given parallel execution exhibiting error:

Can we produce an NDSEQ trace exhibiting

the same wrong behavior?

If so, bug is sequential and programmer can

debug on a sequential (but NDSEQ) trace.

Can we efficiently produce NDSEQ trace

given static proof of parallel correctness?

Dynamically checking NDSEQ specs?

Ideally, efficiently: (1) finds equivalent

NDSEQ trace, or (2) localizes parallel bug.

slide-76
SLIDE 76

Questions?

Email jburnim@cs.berkeley.edu

76