Current section
Files
Jump to
Current section
Files
lib/evaluation/graph/graph_creation.ex
defmodule Evaluation.Graph.GraphCreation do
alias Evaluation.Graph
def generateGraph(params) do
Graph.new(Keyword.get(params, :hosts))
|> generateVars(Keyword.get(params, :nb_of_vars))
|> generateSignalLevels(params)
end
defp generateVars(g, 0), do: g
defp generateVars(g, n) when is_integer(n) and n > 0 do
hosts = Graph.getHosts(g)
host = Enum.at(hosts, :rand.uniform(Enum.count(hosts))-1)
new_v = String.to_atom("var" <> Integer.to_string(n))
new_g = Graph.addVar(g, new_v, host)
generateVars(new_g, n-1)
end
defp generateSignalLevels(g, params) do
l = Keyword.get(params, :graph_depth)
generateSignalLevels(g, params, l)
end
defp generateSignalLevels(g, _params, 1), do: g
defp generateSignalLevels(g, params, k) when is_integer(k) and k > 1 do
n_avg = Keyword.get(params, :signals_per_level_avg)
n_act = :rand.uniform(2*n_avg - 1)
l = Keyword.get(params, :graph_depth) - k + 2
ss = generateSignals(g, params, l, n_act, [])
new_g = addSignals(g, ss)
generateSignalLevels(new_g, params, k-1)
end
defp generateSignals(_g, _params, _l, 0, ss), do: ss
defp generateSignals(g, params, l, n, ss) do
n_deps_avg = Keyword.get(params, :deps_per_signal_avg)
n_deps_act =
case n_deps_avg do
1 -> 1
2 -> :rand.uniform(3)
3 -> :rand.uniform(3) + 1
_ -> raise "deps_per_signal_avg set too high! Locality parameter not independent anymore."
end
new_sig = String.to_atom("sig" <> Integer.to_string(l) <> Integer.to_string(n))
deps = chooseDeps(g, l, n_deps_act, [])
host = chooseHost(g, params, deps)
generateSignals(g, params, l, n-1, [{new_sig, {host, deps}} | ss])
end
defp chooseDeps(_g, _l, 0, deps), do: deps
defp chooseDeps(g, l, n, []) do
pool = Graph.getNodesAtLevel(g, l-1)
dep = Enum.at(pool, :rand.uniform(Enum.count(pool))-1)
chooseDeps(g, l, n-1, [dep])
end
defp chooseDeps(g, l, n, deps) do
pool = Graph.getNodes(g) -- deps
dep = Enum.at(pool, :rand.uniform(Enum.count(pool))-1)
chooseDeps(g, l, n-1, [dep | deps])
end
defp chooseHost(g, params, deps) do
locality = Keyword.get(params, :nodes_locality)
localHosts =
deps
|> Enum.map(fn d -> Graph.getHost(g, d) end)
|> Enum.uniq
remoteHosts = Graph.getHosts(g) -- localHosts
r = :rand.uniform
hostPool =
cond do
r > locality -> localHosts
r <= locality -> remoteHosts
end
Enum.at(hostPool, :rand.uniform(Enum.count(hostPool))-1)
end
defp addSignals(g, []), do: g
defp addSignals(g, [{sig, {host, deps}} | ss]) do
g_new = Graph.addSignal(g, sig, host, deps)
addSignals(g_new, ss)
end
end