1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# Cost model visualisations
```elixir
Mix.install([
{:tucan, "~> 0.3.0"},
{:kino_vega_lite, "~> 0.1.8"}
])
```
## Reading / preprocessing data
```elixir
job_id = "1138"
job_dir = Path.expand(~c"./" ++ job_id) |> Path.absname()
sections_dir = Path.join(job_dir, "sections")
{:ok, cost_model_files} = File.ls(sections_dir)
cost_model_files =
cost_model_files
|> Enum.filter(fn name -> String.contains?(name, "cost-model") end)
# |> Enum.filter(fn name -> String.contains?(name, "vec--Vec") end)
|> Enum.map(fn fname -> Path.join(sections_dir, fname) |> Path.absname() end)
cost_model_files
```
```elixir
defmodule CostModel do
defstruct impl: nil, ops: []
end
defmodule OpCostModel do
defstruct op: nil, x0: nil, x1: nil, x2: nil, x3: nil, nmrse: nil
end
defmodule Parse do
def cost_model_row(row) do
[name, x0, x1, x2, x3, nmrse] = String.split(row, " & ")
[nmrse | _] = String.split(nmrse)
%OpCostModel{
op: name,
x0: String.to_float(x0),
x1: String.to_float(x1),
x2: String.to_float(x2),
x3: String.to_float(x3),
nmrse: String.to_float(nmrse)
}
end
def cost_model_output(fname) do
{:ok, contents} = File.read(fname)
[_, table | _] = String.split(contents, "line\n")
[rows | _] = String.split(table, "\n\\end")
rows = String.split(rows, "\n")
[_, impl] = String.split(fname, "cost-model-")
impl = String.replace(impl, "-", ":")
%CostModel{
impl: impl,
ops: rows |> Enum.map(&cost_model_row/1)
}
end
end
```
<!-- livebook:{"reevaluate_automatically":true} -->
```elixir
cost_models = cost_model_files |> Enum.map(&Parse.cost_model_output/1)
```
## Exploratory Plots
```elixir
defmodule PlotCostModel do
@startn 0
@endn 1000
@resolution 10
def gen_ts(ns, %OpCostModel{x0: x0, x1: x1, x2: x2, x3: x3}) do
Enum.map(ns, fn n -> %{n: n, t: x0 + n * x1 + n * n * x2 + n * n * n * x3} end)
end
def points_op(op) do
ns = @startn..@endn//@resolution
gen_ts(ns, op)
|> Enum.map(fn data -> Map.put(data, :name, op.op) end)
end
def points_model(model) do
model.ops
|> Enum.map(fn op ->
points_op(op)
|> Enum.map(fn point -> Map.put(point, :impl, model.impl) end)
end)
|> List.flatten()
end
def points(models) do
models
|> Enum.map(&points_model/1)
|> List.flatten()
end
def plot_op(op) do
points = points_op(op)
Tucan.lineplot(points, "n", "t", title: op.op)
end
def plot_all_ops(%CostModel{impl: impl, ops: ops}) do
ops
|> Enum.map(&plot_op/1)
|> Tucan.concat(columns: 3)
|> Tucan.set_title(impl)
end
end
```
<!-- livebook:{"reevaluate_automatically":true} -->
```elixir
cost_models
|> Enum.map(&PlotCostModel.plot_all_ops/1)
|> Tucan.vconcat()
```
|