# WeaveNet code for submission

The code is provided only for the review of the paper and not publicly available yet. 

The implementation of the proposed method is in `./src/networks.py`, (WeaveNet at line 209, Feature Weaving Layer at line 195, Set Encoder at line 169.

# Installation
## Preliminaly requirement
- installation of pytorch and torch-geometric should be done in advance.

## Operation
```
% pip3 install -r requirements.txt
```
## Docker
- DockerFile
```
FROM pytorch/pytorch:1.7.0-cuda11.0-cudnn8-runtime
ENV TORCH=1.7.0
ENV CUDA=cu110

#ARG HTTP_PROXY
#ENV HTTP_PROXY $HTTP_PROXY
#ENV HTTPS_PROXY $HTTP_PROXY
#ENV FTP_PROXY $HTTP_PROXY
#ENV http_proxy $HTTP_PROXY
#ENV https_proxy $HTTP_PROXY

RUN pip install --force torch-scatter -f https://pytorch-geometric.com/whl/torch-${TORCH}+${CUDA}.html
RUN pip install --force torch-sparse -f https://pytorch-geometric.com/whl/torch-${TORCH}+${CUDA}.html
RUN pip install --force torch-cluster -f https://pytorch-geometric.com/whl/torch-${TORCH}+${CUDA}.html
RUN pip install --force torch-spline-conv -f https://pytorch-geometric.com/whl/torch-${TORCH}+${CUDA}.html
RUN pip install torch-geometric

WORKDIR /work

COPY ./ /work/

RUN cd /work;pip install -r requirements.txt

ENV LIBRARY_PATH /usr/local/cuda/lib64/stubs

```

- How to build an image (when proxy setting is not required) 
```
% docker build . 
```

- How to build an image when proxy setting is required.
  1. decomment the rows related to HTTP_PROXY in the DockerFile
  2. build the image with an approproate option.
```
% docker build . --build-arg HTTP_PROXY=$HTTP_PROXY
```
  

Note: nvidia-driver should be enough new to support CUDA11.0. otherwise, prlease modify `./Dockerfile` and direct an image with older version while adjusting `ENV CUDA=cu110`.

## Check the environment with a minimum execution
- You can check whether your environment is correctly set or not by executing the following minimum sample.
```
% bash run_minimum_exp.sh
```


# How to reproduce the experimental results

## Experiments in 4.1 of the main paper and B.1 in the appendix
1. Data Generation
```
% bash run_generate_dataset4exp1.sh
```
2. Train and test WN-6, WN-18, WN-18f/b, and all the learning-based baselines in 4.1 (Figs. 4,5,6)
```
% bash run_exp1.sh
```
3. Train and test all the other baselines in B.1 (Fig. 15)
```
% bash run_exp1_supp.sh
```

### Output

All the test results are output into files in csv format.

- The format of Output directory  
  `./checkpoint/{NetworkType}-{L}-{D}-{D'}-{asym|sym}-{res|no-res}/{learning_rate params}/{Train Dist(UU|DD|...|L)}{NxM}/`
  - sample-wise scores: `{epochs}_net_{Test Dist}_size-{N}_test_result.csv`
  - Average scores:     `{epochs}_net_{Test Dist}_size-{N}_test_result_avg.csv`
  
## Experiments in 4.2 of the main paper and B.2 in the appendix
1. Data Generation
```
% bash run_generate_dataset4exp2.sh
```
2. Train and test WN-60f/b with N=20, 30. (Tables 2,3)
```
% bash run_exp2.sh
```
3. Train and test ablation models in B.2 (Tables 8,9)
```
% bash run_exp2_supp.sh
```

Note that we used the following repository to produce the results by algorithmic baselines.

    https://github.com/ntzia/stable-marriage

The result is in `./exp2_baselines` of this repository

The distribution parameters of LibimSeTi dataset is hard-coded in `src/data_loader.py`.
You can extract these parameters by following script.
```
% bash run_analyze_LibimSeTi.sh
```


## Experiments in 4.3 of the main paper
1. Data Generation
```
% bash run_generate_dataset4exp3.sh
```
2. Train and test WN-80f/b with N=100 (Tables 4, 5)
```
% bash run_exp3.sh
```

## Scores by traditional algorithmic methods
You can find sample-wise scores in `scores_by_algorithms`, which are calculated by [code provided a third party](https://github.com/ntzia/stable-marriage)

# Structure of the source code

## The structure at a glance

```
├── Dockerfile
├── requirements.txt
├── README.md
├── checkpoints/
├── datasets/
│   ├── test/
│   └── validation/
├── scores_by_algorithms
├── tensorboard_log/
├── run_minimum_exp.sh
├── run_exp1.sh
├── run_exp1_supp.sh
├── run_exp2.sh
├── run_exp3.sh
├── run_generate_dataset4exp1.sh
├── run_generate_dataset4exp2.sh
├── run_generate_dataset4exp3.sh
├── run_analyze_LibimSeTi.sh
├── count_rating_frequency4LibimSeTi.py
├── print_exp_dir.py
├── src/
│   ├── data_loader.py
│   ├── match_gs_algo.py
│   ├── models.py
│   ├── networks.py
│   └── utils.py
├── generate_dataset.py
├── train.py
└── test.py
```

## Install-related files
- Dockerfile
- requirements.txt
- README.md

## Output-related dir
- `checkpoints/`
  - `train.py` outputs training history and trained model parameters.
  - `test.py` outputs test results.
- `datasets/`
  - `generate_dataset.py` outputs generated samples.
- `tensorboard_log/`
  - `train.py` outputs training history in tensorboard format.
  
## Complementary dataset
- `scores_by_algorithms` contains sample-wise fairness costs of matchings optained by algorithmic methods.

## Batch Scripts
- `run_*.sh`
  - See 'How to reproduce the experimental results'

## main scripts
Note that all these script has the `--help` option. Please see the help messages to know their command options.  
- `src/`
  - source files of the proposed method and learning-based baselines
- `generate_dataset.py` 
  - outputs generated samples.
  ``` 
  % python3 generate_dataset.py -N 10 --distrib_m U --distrib_f U --dist_dir ./datasets/validation --seed 36295
  % python3 generate_dataset.py -N 5 --distrib_m U --distrib_f U --dist_dir ./datasets/test --seed 36295
  ```
- `train.py`
  - train a learning-based model
  ``` 
  % python3 train.py --network_type WeaveNet -L 18 -w 64 -W 64 --use_resnet -d UU -N 10 10 -e 1000
  ```
- `test.py`
  - test the trained model with an indicated test/validation dataset.
  ```
  % python3 test.py ./checkpoints/WeaveNet-6-64-64-s-res/lr0.0001-m1.0-u0.7-s0.0-f0.0-b0.0-cp2.0/UU10x10/01000_net.pth ./datasets/test/UU_size-05_test.dat
  ```
  
## subscript
- `count_rating_frequency4LibimSeTi.py` is used in `run_analyze_LibimSeTi.sh`
- `print_exp_dir.py` is used in `run_exp*.sh` to obtain the path to the trained model for executing `test.py`.
