Packages
fixpoint
0.19.3
0.22.1
0.21.5
0.21.4
0.21.3
0.21.2
0.21.1
0.21.0
0.20.6
0.20.5
0.20.4
0.20.3
0.20.2
0.20.1
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.18.2
0.18.1
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.13.5
0.13.4
0.13.2
0.13.1
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.2
0.12.1
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.46
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.28
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.1.3
0.1.2
0.1.1
0.1.0
Constraint Programming Solver
Current section
Files
Jump to
Current section
Files
lib/solver/core/distributed.ex
defmodule CPSolver.Distributed do
require Logger
def call(node, solver, mod, function, args) do
:erpc.call(node, mod, function, [solver | args])
end
def worker_nodes(node_list \\ [Node.self() | Node.list()]) do
node_list
end
def choose_worker_node(nodes \\ worker_nodes())
def choose_worker_node(true) do
worker_nodes()
|> choose_worker_node()
end
def choose_worker_node(distributed?) when not distributed? do
Node.self()
end
def choose_worker_node(node_list) when is_list(node_list) do
Enum.random(node_list)
end
def test() do
alias CPSolver.Examples.{Sudoku, Queens}
Logger.configure(level: :info)
leader_node = :leader
if Node.self() |> to_string() |> String.starts_with?(to_string(leader_node)) do
## cluster is up, skip initialization
:ok
else
Node.start(leader_node, :shortnames)
Node.set_cookie(:solver)
# Run the solver with the model that takes noticeable time to complete.
_worker_nodes = Enum.map(["node1", "node2", "node3"], fn node ->
{:ok, _pid, node_name} = :peer.start(%{name: node, longnames: false, args: [~c"-setcookie", ~c"solver"]})
:erpc.call(node_name, :code, :add_paths, [:code.get_path()])
node_name
end)
end
# Run the solver with the model that takes noticeable time to complete.
my_pid = self()
## Distributed Sudoku
Logger.notice("Sudoku test: starting")
five_solutions_sudoku = Sudoku.puzzles().s9x9_5
{:ok, _res} = CPSolver.solve(Sudoku.model(five_solutions_sudoku),
solution_handler: fn solution ->
send(my_pid, {Node.self(), solution})
end,
distributed: Enum.shuffle(Node.list())
)
verify_solutions(5)
Logger.notice("Sudoku test: ok")
## Distributed Queens
Logger.notice("Queens test: starting")
{:ok, _res} = CPSolver.solve(Queens.model(8),
solution_handler: fn solution ->
send(my_pid, {Node.self(), solution})
end,
distributed: Enum.shuffle(Node.list())
)
verify_solutions(92)
Logger.notice("Queens test: ok")
true
end
def verify_solutions(expected_count) do
solutions = CPSolver.Utils.flush()
^expected_count = length(solutions)
true =
solutions
|> MapSet.new(fn {node, _solution} -> node end)
|> tap(fn nodes -> Logger.info("Nodes with solutions: #{Enum.join(nodes, "")}") end)
|> MapSet.subset?(MapSet.new(Node.list()))
end
end