Skip to content

Commit

Permalink
improve report
Browse files Browse the repository at this point in the history
  • Loading branch information
zapashcanon committed May 26, 2024
1 parent cd23de3 commit 686aff2
Show file tree
Hide file tree
Showing 22 changed files with 609 additions and 300 deletions.
15 changes: 13 additions & 2 deletions bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@ You can additionally specify a timeout:
$ dune exec -- testcomp/testcomp.exe 5 # timeout of 5 seconds
```

### Generate the report:
## Generate the report:

### Installing dependencies:

```shell-session
$ sudo apt install libcairo2-dev
$ git clone git@github.com:thierry-f-78/pie.git
$ cd pie
$ sudo make install DESTDIR=/usr/local/
```

### Running on some benchmark output

```shell-session
$ dune exec -- testcomp/report.exe testcomp/stdout # this is an example of an old run, use the correct file instead
$ dune exec -- report/report.exe testcomp/stdout # this is an example of an old run, use the correct file instead
```
21 changes: 21 additions & 0 deletions bench/report/color.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
type t = int

let reached = 0x59A89C

let other = 0xA559AA

let nothing = 0xF0C571

let timeout = 0xE02B35

let killed = 0x082A54

let lines = 0xCECECE

let dark = 0x000000

let white = 0xFFFFFF

let to_string n = Format.sprintf "#%06x" n

let to_rgb n = `Rgb (n lsr 16, (n land 0x00FF00) lsr 8, n land 0x0000FF)
21 changes: 21 additions & 0 deletions bench/report/color.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
type t

val reached : t

val other : t

val nothing : t

val timeout : t

val killed : t

val lines : t

val dark : t

val white : t

val to_string : t -> string

val to_rgb : t -> [> `Rgb of int * int * int ]
17 changes: 17 additions & 0 deletions bench/report/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(library
(name report)
(modules
color
parse
pie_results
run
runs
run_result
rusage
time_distribution)
(libraries bos fpath gnuplot))

(executable
(name report)
(modules report)
(libraries report))
88 changes: 88 additions & 0 deletions bench/report/parse.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
let ( let* ) o f = match o with Ok v -> f v | Error _ as e -> e

let ( let+ ) o f = match o with Ok v -> Ok (f v) | Error _ as e -> e

let ksprintf = Format.ksprintf

let error = Result.error

let from_file file =
let file = Fpath.to_string file in

let chan = open_in file in

let runs = ref [] in

let parse_file () =
try
while true do
let run = input_line chan in
let result = input_line chan in
let summary = input_line chan in
runs := (run, result, summary) :: !runs
done
with End_of_file -> runs := List.rev !runs
in

Fun.protect ~finally:(fun () -> close_in chan) parse_file;

let runs = !runs in

let parse_float s =
match float_of_string_opt s with
| None -> ksprintf error "malformed float %S" s
| Some f -> Ok f
in

let parse_time t1 t2 t3 =
let* clock = parse_float t1 in
let* utime = parse_float t2 in
let+ stime = parse_float t3 in
{ Rusage.clock; utime; stime }
in

let parse_int s =
match int_of_string_opt s with
| None -> ksprintf error "malformed int %S" s
| Some i -> Ok i
in

let rm_empty_str l = List.filter (fun s -> s <> "") l in

let parse_run (run, result, _summary) =
let* counter, file =
match String.split_on_char ' ' run |> rm_empty_str with
| [ "Run"; counter; file ] -> Ok (counter, Fpath.v file)
| _ -> ksprintf error "malformed run: %S" run
in
let* i =
match String.split_on_char '/' counter |> rm_empty_str with
| [ i; _total ] -> parse_int i
| _ -> ksprintf error "malformed counter: %S" counter
in
let+ res =
match String.split_on_char ' ' result |> rm_empty_str with
| [ "Reached"; "in"; t1; t2; t3 ] ->
let+ rusage = parse_time t1 t2 t3 in
Run_result.Reached rusage
| [ "Timeout"; "in"; t1; t2; t3 ] ->
let+ rusage = parse_time t1 t2 t3 in
Run_result.Timeout rusage
| [ "Other"; n; "in"; t1; t2; t3 ] ->
let* n = parse_int n in
let+ rusage = parse_time t1 t2 t3 in
Run_result.Other (n, rusage)
| [ "Nothing"; "in"; t1; t2; t3 ] ->
let+ rusage = parse_time t1 t2 t3 in
Run_result.Nothing rusage
| [ "Killed"; "in"; t1; t2; t3 ] ->
let+ rusage = parse_time t1 t2 t3 in
Run_result.Killed rusage
| _ -> ksprintf error "malformed result: %S" result
in
{ Run.i; res; file }
in

List.map
(fun v -> match parse_run v with Error e -> failwith e | Ok v -> v)
runs
1 change: 1 addition & 0 deletions bench/report/parse.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val from_file : Fpath.t -> Runs.t
114 changes: 114 additions & 0 deletions bench/report/pie_results.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
open Bos

let string_of_float f = Format.sprintf "%f" f

let output_format = "SVG"

let w = 400 |> string_of_int

let h = 400 |> string_of_int

let legend_color = Color.to_string Color.dark

let legend_size = 10 |> string_of_int

let title = "Owi results"

let title_color = Color.to_string Color.dark

let title_size = 15 |> string_of_int

let background_color = Color.to_string Color.white

let ratio_w_h =
(* must be between 0 and 1 *)
1. |> string_of_float

let pie_line_width = 1 |> string_of_int

let pie_line_color = Color.to_string Color.lines

let percent_explode =
(* must be between 0 and 1 *)
0. |> string_of_float

let percent_extrusion =
(* must be between 0 and 1 *)
0. |> string_of_float

let margin = 10. |> string_of_float

let mk_value (n, color, ratio_explode, name) =
Format.sprintf "%d%s:%f:%s" n (Color.to_string color) ratio_explode name

let make runs output_dir =
let out = Fpath.(output_dir // v "results_owi_count.svg") in

let flags =
[ "-o"
; Fpath.to_string out
; "-f"
; output_format
; "-w"
; w
; "-h"
; h
; "-l"
; legend_color
; "-L"
; legend_size
; "-t"
; title
; "-T"
; title_color
; "-b"
; background_color
; "-r"
; ratio_w_h
; "-c"
; pie_line_width
; "-C"
; pie_line_color
; "-d"
; percent_explode
; "-e"
; percent_extrusion
; "-m"
; margin
; "-s"
; title_size
]
|> Cmd.of_list
in

let count_killed = Runs.count_killed runs in
let count_other = Runs.count_other runs in
let count_timeout = Runs.count_timeout runs in
let count_reached = Runs.count_reached runs in
let count_nothing = Runs.count_nothing runs in

let values =
[ (count_killed, Color.killed, 0., Format.sprintf "Killed (%d)" count_killed)
; (count_other, Color.other, 0., Format.sprintf "Other (%d)" count_other)
; ( count_timeout
, Color.timeout
, 0.
, Format.sprintf "Timeout (%d)" count_timeout )
; ( count_reached
, Color.reached
, 0.
, Format.sprintf "Reached (%d)" count_reached )
; ( count_nothing
, Color.nothing
, 0.
, Format.sprintf "Nothing (%d)" count_nothing )
]
|> List.filter_map (fun ((count, _, _, _) as v) ->
if count = 0 then None else Some v )
|> List.sort (fun (c1, _, _, _) (c2, _, _, _) -> compare c2 c1)
|> List.map mk_value |> Cmd.of_list
in

let pie = Cmd.(v "pie" %% flags %% values) in

OS.Cmd.run pie
1 change: 1 addition & 0 deletions bench/report/pie_results.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val make : Runs.t -> Fpath.t -> (unit, [> Rresult.R.msg ]) Result.t
19 changes: 19 additions & 0 deletions bench/report/report.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
let () =
if Array.length Sys.argv < 3 then
Format.ksprintf failwith "usage: <%s> <FILE>" Sys.argv.(0)

let file = Fpath.v Sys.argv.(1)

let ok_or_fail = function
| Error (`Msg msg) ->
Format.eprintf "ERROR: %s@\n" msg;
exit 1
| Ok v -> v

let runs = Report.Parse.from_file file

let output_dir = Fpath.v "./"

let () =
Report.Pie_results.make runs output_dir |> ok_or_fail;
Report.Time_distribution.make runs output_dir
23 changes: 23 additions & 0 deletions bench/report/run.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
type t =
{ i : int
; res : Run_result.t
; file : Fpath.t
}

let clock { res; _ } =
match res with
| Run_result.Reached t | Timeout t | Nothing t | Killed t | Other (_, t) ->
t.clock

let is_reached { res; _ } = Run_result.is_reached res

let is_timeout { res; _ } = Run_result.is_timeout res

let is_nothing { res; _ } = Run_result.is_nothing res

let is_killed { res; _ } = Run_result.is_killed res

let is_other { res; _ } = Run_result.is_other res

let pp_header total fmt (i, file) =
Format.fprintf fmt "Run %d/%d: %a" i total Fpath.pp file
19 changes: 19 additions & 0 deletions bench/report/run.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
type t =
{ i : int
; res : Run_result.t
; file : Fpath.t
}

val clock : t -> float

val is_nothing : t -> bool

val is_killed : t -> bool

val is_reached : t -> bool

val is_timeout : t -> bool

val is_other : t -> bool

val pp_header : int -> Format.formatter -> int * Fpath.t -> unit
27 changes: 27 additions & 0 deletions bench/report/run_result.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
type t =
| Nothing of Rusage.t
| Killed of Rusage.t
| Reached of Rusage.t
| Timeout of Rusage.t
| Other of int * Rusage.t

let is_nothing = function Nothing _ -> true | _ -> false

let is_killed = function Killed _ -> true | _ -> false

let is_reached = function Reached _ -> true | _ -> false

let is_timeout = function Timeout _ -> true | _ -> false

let is_other = function Other _ -> true | _ -> false

let pp fmt = function
| Timeout t ->
Format.fprintf fmt "Timeout in %g %g %g" t.clock t.utime t.stime
| Nothing t ->
Format.fprintf fmt "Nothing in %g %g %g" t.clock t.utime t.stime
| Reached t ->
Format.fprintf fmt "Reached in %g %g %g" t.clock t.utime t.stime
| Other (code, t) ->
Format.fprintf fmt "Other %i in %g %g %g" code t.clock t.utime t.stime
| Killed t -> Format.fprintf fmt "Killed in %g %g %g" t.clock t.utime t.stime
Loading

0 comments on commit 686aff2

Please sign in to comment.