#+TITLE: MNIST Training with Multi-Party Computation

Small set of scripts for training MNIST networks with a number of
networks using MP-SPDZ.

** Installation (with Docker)


Run the following  from this directory to build a Docker container:

: $ docker build .

At the of the installation, the examples below are run automatically.

** Running locally

After setting everything up, you can use this script to run the
computation:

: $ ./run-local.sh <protocol> <net> <round> <n_threads> <n_epochs> <precision> [<further>]

The options are as follows:

- =protocol= is one of =emul= (emulation), =sh3= (semi-honest
  three-party computation, =mal3= (malicious three-party computation),
  =mal4= (malicious four-party computation). All protocols are assuming an
  honest majority.
- =net= is the network (A-D).
- =n_layers= is the number of dense layers (1-3).
- =round= is the kind of rounding, =prob= for probabilistic and =near= for
  nearest.
- =n_threads= is the number of threads per party.
- =n_epochs= is the number of epochs.
- =precision= is the precision (in bits) after the decimal point.

The following options can be given in addition.

- =rate<rate>= the learning rate, e.g., =rate.1= for a learning rate of 0.1.
- =adam=, =adamapprox=, or =amsgrad= to use Adam, Adam with less
  precise approximation of inverse square root, or AMSgrad instead of
  SGD.

For example,

: $ ./run-local.sh emul D prob 2 20 32 adamapprox

runs 20 epochs of training network D in the emulation with two threads,
probabilistic rounding, 32-bit precision, and Adam with less precise
inverse square root approximation.

** Running remotely

You need to set up hosts that run SSH and have all higher TCP ports
open between each other. We have used =c5.9xlarge= instances in the
same AWS zone and hence 36 threads. The hosts have to run Linux with a
glib not older than Ubuntu 18.04 (2.27), which is the case for Amazon
Linux 2. Honest-majority protocols require three hosts while
dishonest-majority protocols require two.

With Docker, you can run the following script to set up host names,
user name and SSH RSA key. We do *NOT* recommend running it outside
Docker because it might overwrite an existing RSA key file.

: $ ./setup-remote.sh

Without Docker, familiarise yourself with SSH configuration options
and SSH keys. You can use =ssh_config= and the above script to find
out the requirements. =HOSTS= has to contain the hostnames separated
by whitespace.

After setting up, you can the following using the same options as
above:

: $ ./run-remote.sh <protocol> <net> <round> <n_threads> <n_epochs> <precision> [<further>]

For example,

: $ ./run-remote.sh sh3 A near 1 1 16 rate.1

runs one epoch of training network A with semi-honest three-party
computation, one thread, and nearest rounding, 16-bit precision,
and SGD with rate 0.1.

