Skip to content

Commit f9fd1c3

Browse files
committed
Implement Promise-First optimization
1 parent cc40009 commit f9fd1c3

File tree

5 files changed

+356
-228
lines changed

5 files changed

+356
-228
lines changed

ArchSem/GenPromising.v

Lines changed: 87 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -183,27 +183,38 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
183183
it generic *)
184184
Structure BasicExecutablePM := {
185185
pModel :> PromisingModel;
186-
(** try to compute ALL allowed promises, if that is not possible (not
187-
enough fuel) then fail with error message.
188186

189-
Soundness and completeness proofs are required to show that when not
190-
failing, promise_select effectively computes the allowed_promises
191-
set.*)
192-
promise_select :
187+
enumerate_promises_and_terminal_states :
193188
(* fuel *) nat → (* tid *) nat →
194189
(* termination condition *) (registerMap → bool) →
195190
memoryMap → pModel.(tState) → PromMemory.t pModel.(mEvent) →
196-
Exec.res string pModel.(mEvent);
191+
result string (list pModel.(mEvent) * list pModel.(tState));
197192

198193
promise_select_sound :
199-
∀ fuel tid term initMem ts mem,
200-
∀ ev ∈ (promise_select fuel tid term initMem ts mem),
201-
ev ∈ pModel.(allowed_promises) tid initMem ts mem;
194+
∀ fuel tid term initMem ts mem promises tstates,
195+
Ok (promises, tstates) =
196+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
197+
∀ ev ∈ promises, ev ∈ pModel.(allowed_promises) tid initMem ts mem;
198+
202199
promise_select_complete :
203-
∀ fuel tid term initMem ts mem,
204-
¬ Exec.has_error (promise_select fuel tid term initMem ts mem) →
205-
∀ ev ∈ pModel.(allowed_promises) tid initMem ts mem,
206-
ev ∈ promise_select fuel tid term initMem ts mem
200+
∀ fuel tid term initMem ts mem promises tstates,
201+
Ok (promises, tstates) =
202+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
203+
∀ ev ∈ pModel.(allowed_promises) tid initMem ts mem, ev ∈ promises;
204+
205+
terminal_state_no_outstanding_promise :
206+
∀ fuel tid term initMem ts mem promises tstates,
207+
Ok (promises, tstates) =
208+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
209+
∀ tts ∈ tstates, pModel.(tState_nopromises) tts;
210+
211+
terminal_state_is_terminated :
212+
∀ fuel tid term initMem ts mem promises tstates,
213+
Ok (promises, tstates) =
214+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
215+
∀ tts ∈ tstates, term (pModel.(tState_regs) tts);
216+
217+
(* TODO: add terminal_state_is_reachable *)
207218
}.
208219
Arguments BasicExecutablePM : clear implicits.
209220

@@ -341,10 +352,24 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
341352
Local Notation mEvent := (mEvent prom).
342353
Local Notation t := (t tState mEvent n).
343354

355+
(** The type of final promising state return by run *)
356+
Definition final := { x : t | terminated prom term x }.
357+
358+
Definition make_final (p : t) := exist (terminated prom term) p.
359+
360+
(** Convert a final promising state to a generic final state *)
361+
Program Definition to_final_archState (f : final) :
362+
{s & archState.is_terminated term s} :=
363+
existT (to_archState prom f) _.
364+
Solve All Obligations with
365+
hauto unfold:terminated unfold:archState.is_terminated l:on db:vec, brefl.
366+
344367
(** Get a list of possible promises for a thread by tid *)
345368
Definition promise_select_tid (fuel : nat) (st : t)
346369
(tid : fin n) : Exec.res string mEvent :=
347-
prom.(promise_select) fuel tid (term tid) (initmem st) (tstate tid st) (events st).
370+
'(promises, _) ← mlift $ prom.(enumerate_promises_and_terminal_states)
371+
fuel tid (term tid) (initmem st) (tstate tid st) (events st);
372+
mchoosel promises.
348373

349374
(** Take any promising step for that tid and promise it *)
350375
Definition cpromise_tid (fuel : nat) (tid : fin n)
@@ -368,45 +393,6 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
368393
promise ← mchoosel (enum bool);
369394
if (promise : bool) then cpromise_tid fuel tid else run_tid isem prom tid.
370395

371-
(** Run only promise steps. If a thread has reached termination
372-
no progress is made in the thread (either instruction running or
373-
promises *)
374-
Fixpoint run_step_promise_first (fuel : nat) (terminated : fin n -> bool) : Exec.t t string () :=
375-
st ← mGet;
376-
let all_terminated := ∀ tid ∈ (enum (fin n)), terminated tid in
377-
if decide all_terminated then
378-
mret ()
379-
else
380-
if fuel is S fuel then
381-
tid ← mchoose n;
382-
if decide $ (terminated tid) then
383-
run_step_promise_first fuel terminated
384-
else
385-
let ev_res := promise_select_tid fuel st tid in
386-
if decide (Exec.has_error ev_res) then
387-
run_step_promise_first fuel (λ t, if decide (t = tid) then true else (terminated t))
388-
else
389-
let res_st :=
390-
ev ← ev_res;
391-
mret $ promise_tid prom st tid ev
392-
in
393-
mlift $ Exec.make ((.,()) <$> res_st.(Exec.results)) ((st,.) <$> res_st.(Exec.errors));;
394-
run_step_promise_first fuel terminated
395-
else mthrow "Could not finish promise-first within the size of the fuel".
396-
397-
(** The type of final promising state return by run *)
398-
Definition final := { x : t | terminated prom term x }.
399-
400-
Definition make_final (p : t) := exist (terminated prom term) p.
401-
402-
403-
(** Convert a final promising state to a generic final state *)
404-
Program Definition to_final_archState (f : final) :
405-
{s & archState.is_terminated term s} :=
406-
existT (to_archState prom f) _.
407-
Solve All Obligations with
408-
hauto unfold:terminated unfold:archState.is_terminated l:on db:vec, brefl.
409-
410396
(** Computational evaluate all the possible allowed final states according
411397
to the promising model prom starting from st *)
412398
Fixpoint run (fuel : nat) : Exec.t t string final :=
@@ -418,52 +404,77 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
418404
run fuel
419405
else mthrow "Could not finish running within the size of the fuel".
420406

421-
(** Computational evaluate all the possible allowed final states according
422-
to the promising model prom starting from st *)
423-
Fixpoint run_promise_first (fuel : nat) : Exec.t t string final :=
424-
st ← mGet;
425-
if decide $ terminated prom term st is left pt then mret (make_final st pt)
426-
else
427-
if fuel is S fuel then
428-
run_step_promise_first (S fuel);;
429-
run_promise_first fuel
407+
(** Explore all possible promise-based executions across all threads. *)
408+
Fixpoint prune_promises_and_states (fuel_per_tid fuel : nat)
409+
(finals : list final) : Exec.t t string (list final) :=
410+
if fuel is S fuel then
411+
st ← mGet;
412+
(* Find out next possible promises or terminating states at the current thread *)
413+
executions ←
414+
for (tid : fin n) in enum (fin n) do
415+
'(promises_per_tid, tstates_per_tid) ←
416+
mlift $ prom.(enumerate_promises_and_terminal_states)
417+
fuel_per_tid tid (term tid) (initmem st) (tstate tid st) (events st);
418+
mret (map (λ ev, (ev, tid)) promises_per_tid, tstates_per_tid)
419+
end;
420+
421+
(* Compute cartesian products of the possible thread states *)
422+
let tstates_sys :=
423+
fold_left (λ partial_sts tstates_tid,
424+
List.flat_map (λ tstate,
425+
if is_emptyb partial_sts then [[tstate]]
426+
else map (λ partial_st, partial_st ++ [tstate]) partial_sts
427+
) tstates_tid
428+
) (map snd executions) [] in
429+
let new_finals :=
430+
omap (λ tstates,
431+
if (list_to_vec_n n tstates) is Some tstates_vec then
432+
let st := Make tstates_vec st.(PState.initmem) st.(PState.events) in
433+
if decide $ terminated prom term st is left pt
434+
then Some (make_final st pt)
435+
else None
436+
else None
437+
) tstates_sys in
438+
439+
(* Non-deterministically choose the next promise and the tid for pruning *)
440+
let promises_all := List.concat (map fst executions) in
441+
if is_emptyb promises_all then
442+
mret (new_finals ++ finals)
443+
else
444+
'(next_ev, tid) ← mchoosel promises_all;
445+
mSet (λ st, promise_tid prom st tid next_ev);;
446+
prune_promises_and_states fuel_per_tid fuel (new_finals ++ finals)
447+
else mret finals.
430448

431449
(** Computational evaluate all the possible allowed final states according
432450
to the promising model prom starting from st
433451
with promise-first optimization *)
434452
Definition run_promise_first (fuel : nat) : Exec.t t string final :=
435-
st ← mGet;
436-
(* Execute promise-first *)
437-
run_step_promise_first fuel;;
453+
finals ← prune_promises_and_states fuel fuel [];
454+
mchoosel finals.
438455

439-
if decide $ terminated prom term st is left pt then mret (make_final st pt)
440-
else
441-
if fuel is S fuel then
442-
run_step (S fuel);;
443-
run fuel
444-
else mthrow "Could not finish running within the size of the fuel".
445456
End CPS.
446457
Arguments to_final_archState {_ _ _}.
447458
End CPState.
448459

449460
(** Create a computational model from an ISA model and promising model *)
450461
Definition Promising_to_Modelc (isem : iMon ()) (prom : BasicExecutablePM)
451462
(fuel : nat) : archModel.c ∅ :=
452-
fun n term (initMs : archState n) =>
463+
λ n term (initMs : archState n),
453464
PState.from_archState prom initMs |>
454465
archModel.Res.from_exec
455466
$ CPState.to_final_archState
456467
<$> CPState.run isem prom term fuel.
457468

458469
(** Create a computational model from an ISA model and promising model
459470
with promise-free optimization *)
460-
Definition Promising_to_Modelc_promise_first (isem : iMon ()) (prom : BasicExecutablePM)
471+
Definition Promising_to_Modelc_pf (isem : iMon ()) (prom : BasicExecutablePM)
461472
(fuel : nat) : archModel.c ∅ :=
462-
fun n term (initMs : archState n) =>
473+
λ n term (initMs : archState n),
463474
PState.from_archState prom initMs |>
464475
archModel.Res.from_exec
465476
$ CPState.to_final_archState
466-
<$> CPState.run_promise_first isem prom term fuel.
477+
<$> CPState.run_promise_first prom term fuel.
467478

468479
(* TODO state some soundness lemma between Promising_to_Modelnc and
469480
Promising_Modelc *)

0 commit comments

Comments
 (0)