.. _multinode: Multinode Computation Example ============================= Multinode computation refers to the possibility of distributing a every party across several nodes. MP-SPDZ uses the client interface for communication between nodes. This means that you have to run ``Scripts/setup-clients.sh`` and distribute the certificates to run it across several machines. In the following, we will explain the example in :download:`../Programs/Source/multinode_example_main.py` and :download:`../Programs/Source/multinode_example_worker.py`. First, the one main node per party, listens and accepts connections from the worker nodes in the same logical party:: listen_for_clients(15000) ready = regint.Array(n_nodes_per_party) @for_range(n_nodes) def _(i): ready[accept_client_connection(15000)] = 1 runtime_error_if(sum(ready) != n_nodes_party, 'connection problems') Maintaining :py:obj:`ready` helps spot errors but isn't strictly necessary. Meanwhile, the workers connect to main node:: main = init_client_connection(host, 15000, worker_id) Once the connection is established, the main node distributes the data among the workers:: @for_range(n_nodes_per_party) def _(i): data.get_vector(base=i * n_ops_per_node, size=n_ops_per_node).write_fully_to_socket(i) This sends a different chunk :py:obj:`data` to every node. The workers then receive it and execute the computation (squaring every number in the example), and send the result back:: @for_range_opt_multithread(n_threads, n_ops) def _(i): data[i] = data[i] ** 2 data.write_to_socket(main) Finally, the main node receives the result:: @for_range(n_nodes_per_party) def _(i): data.assign_vector(sint.read_from_socket(i, size=n_ops_per_node), base=i * n_ops_per_node) You can execute example with three parties, four worker nodes per party, five threads per worker node, and 1000 operations per thread as follows:: for i in $(seq 0 3); do Scripts/compile-run.py ring multinode_example_worker 5 1000 $i localhost & true done Scripts/compile-run.py ring multinode_example_main 4 5 1000