From 86f0842608a135a2c2fb0d6ea54149a37b977f22 Mon Sep 17 00:00:00 2001 From: Saksham Gupta Date: Fri, 8 Dec 2023 02:58:19 +0530 Subject: [PATCH] Adding MLP Demo and Documentation (#200) * readme for helper scripts added * copyrights added * logo added * Add files via upload (#201) * readme add and image delete * hinet demo added * demo readme added * readme updated * adding mlp demo (#203) * files for mlp demo * Update inference_3D_mlp_02.ipynb * blog updates * mlp demo tested * demos aded --- OnnxBridge/Demo/hinet_cifar10-llama/README.md | 107 ++ .../Demo/hinet_cifar10-llama/fetch_image.sh | 3 + .../Demo/hinet_cifar10-llama/fetch_model.sh | 2 + .../Demo/hinet_cifar10-llama/process_image.sh | 7 + OnnxBridge/Demo/mlp/README.md | 179 ++ OnnxBridge/Demo/mlp/accuracy_match_mlp.ipynb | 1515 +++++++++++++++++ OnnxBridge/Demo/mlp/extract_mlp_model.ipynb | 218 +++ .../Demo/mlp/ezpc_run_on_single_machine.sh | 41 + OnnxBridge/Demo/mlp/ezpc_secure_compile.sh | 18 + OnnxBridge/Demo/mlp/ezpc_setup.sh | 16 + OnnxBridge/README.md | 15 +- OnnxBridge/backend.py | 21 + OnnxBridge/helper/README.md | 47 + OnnxBridge/helper/create_np_array.py | 21 + OnnxBridge/helper/make_model.py | 128 +- OnnxBridge/helper/make_np_arr.py | 21 + OnnxBridge/helper/pre_process.py | 23 +- OnnxBridge/helper/run_onnx.py | 24 +- OnnxBridge/image.png | Bin 0 -> 16907 bytes OnnxBridge/main.py | 21 + OnnxBridge/utils/backend_helper.py | 21 + OnnxBridge/utils/logger.py | 21 + OnnxBridge/utils/nodes.py | 21 + OnnxBridge/utils/onnx2IR_helper.py | 21 + OnnxBridge/utils/onnx_nodes.py | 21 + OnnxBridge/utils/optimizations.py | 21 + inference-app/app_3d.py | 314 ++++ 27 files changed, 2851 insertions(+), 16 deletions(-) create mode 100644 OnnxBridge/Demo/hinet_cifar10-llama/README.md create mode 100755 OnnxBridge/Demo/hinet_cifar10-llama/fetch_image.sh create mode 100755 OnnxBridge/Demo/hinet_cifar10-llama/fetch_model.sh create mode 100755 OnnxBridge/Demo/hinet_cifar10-llama/process_image.sh create mode 100644 OnnxBridge/Demo/mlp/README.md create mode 100644 OnnxBridge/Demo/mlp/accuracy_match_mlp.ipynb create mode 100644 OnnxBridge/Demo/mlp/extract_mlp_model.ipynb create mode 100644 OnnxBridge/Demo/mlp/ezpc_run_on_single_machine.sh create mode 100644 OnnxBridge/Demo/mlp/ezpc_secure_compile.sh create mode 100644 OnnxBridge/Demo/mlp/ezpc_setup.sh create mode 100644 OnnxBridge/helper/README.md create mode 100644 OnnxBridge/image.png create mode 100644 inference-app/app_3d.py diff --git a/OnnxBridge/Demo/hinet_cifar10-llama/README.md b/OnnxBridge/Demo/hinet_cifar10-llama/README.md new file mode 100644 index 00000000..42601c1f --- /dev/null +++ b/OnnxBridge/Demo/hinet_cifar10-llama/README.md @@ -0,0 +1,107 @@ +# HiNet-LLAMA Demo +In this demo we will see how we can use OnnxBridge to perform secure Inference on a Chexpert model using LLAMA backend. +## Setup Env +After having setup the environment using ./setup_env_and_build.sh quick, load the environment: +```bash +source ~/EzPC/mpc_venv/bin/activate +``` +### OR +Setup the env manually using: +```bash +# OnnxBridge dependencies +cd .. +pip install -r requirements.txt + +# LLAMA dependencies +sudo apt update +sudo apt install libeigen3-dev cmake build-essential +``` + +# Server Side + +### Download Model +```bash +./fetch_model.sh +``` +### Compile the Model +Run the following command to compile the model: +```bash + +python ../../main.py --path "model.onnx" --generate "executable" --backend LLAMA --scale 15 --bitlength 40 + +``` +This generates : +- A file with model weigths `~/EzPC/OnnxBridge/Demo/model_input_weights.dat` (Secret Server Data) +- A model output binary : `~/EzPC/OnnxBridge/Demo/model_LLAMA_15.out` which will perform the secure mpc computation. +- A cpp file : `~/EzPC/OnnxBridge/Demo/model_LLAMA_15.cpp` which represents the model architecture needs to be passed to the DEALER and CLIENT. + +# Dealer Side +### Compile Model +Compile the cpp model architecture file received from the server. +```bash +# compile secure code +~/EzPC/OnnxBridge/LLAMA/compile_llama.sh "model_LLAMA_15.cpp" +``` + +### Run Computation +Run the following command to start client side computation and connect with server: +```bash +./model_LLAMA_15 1 +``` +Above command generated two files: +- **server.dat** : pass it to server +- **client.dat** : pass it to client + +# Server side +### Run Computation +Run the following command to start server side computation and wait for client connection: +```bash +./model_LLAMA_15 2 model_input_weights.dat +``` + +# Client Side + +### Download Image +```bash +sudo ./fetch_image.sh +``` + +Client needs to preprocess the image before computation starts: +```bash +./process_image.sh "input.jpg" +``` +This generates two files: +- `input.npy` +- `input_input.inp` for secure inference. + +### Compile Model +Compile the cpp model architecture file received from the server. +```bash +# compile secure code +~/EzPC/OnnxBridge/LLAMA/compile_llama.sh "model_LLAMA_15.cpp" +``` + +### Run Computation +Run the following command to start client side computation and connect with server: +```bash +./model_LLAMA_15 3 127.0.0.1 < input_input.inp > output.txt +``` +Raw Output will be saved in `output.txt` , to get output as numpy array do : +```bash +python ../../helper/make_np_arr.py "output.txt" +``` +This dumps model output as a flattened numpy array(1-D) in output.npy . + +## Verify Output +To verify if everything is working as expected, run the input image with the model itself using the onnx runtime: +```bash +python ../../helper/run_onnx.py model.onnx "input.npy" +``` +It dumps the output in `onnx_output/input.npy` and also prints it on the screen. To compare the both outputs do: +```bash +python ../../helper/compare_np_arrs.py -i onnx_output/expected.npy output.npy +``` +You should get output similar to: +```bash +Arrays matched upto 2 decimal points +``` diff --git a/OnnxBridge/Demo/hinet_cifar10-llama/fetch_image.sh b/OnnxBridge/Demo/hinet_cifar10-llama/fetch_image.sh new file mode 100755 index 00000000..70dcb3ad --- /dev/null +++ b/OnnxBridge/Demo/hinet_cifar10-llama/fetch_image.sh @@ -0,0 +1,3 @@ +#!/bin/bash +sudo wget "https://github.com/drunkenlegend/ezpc-warehouse/raw/main/HiNet_cifar10/image_0.png" -O input.jpg +sudo wget "https://github.com/drunkenlegend/ezpc-warehouse/raw/main/HiNet_cifar10/preprocess.py" -O preprocess.py \ No newline at end of file diff --git a/OnnxBridge/Demo/hinet_cifar10-llama/fetch_model.sh b/OnnxBridge/Demo/hinet_cifar10-llama/fetch_model.sh new file mode 100755 index 00000000..d5053cb8 --- /dev/null +++ b/OnnxBridge/Demo/hinet_cifar10-llama/fetch_model.sh @@ -0,0 +1,2 @@ +#!/bin/bash +wget "https://github.com/drunkenlegend/ezpc-warehouse/raw/main/HiNet_cifar10/cnn3_cifar.onnx" -O model.onnx diff --git a/OnnxBridge/Demo/hinet_cifar10-llama/process_image.sh b/OnnxBridge/Demo/hinet_cifar10-llama/process_image.sh new file mode 100755 index 00000000..a69c8d2f --- /dev/null +++ b/OnnxBridge/Demo/hinet_cifar10-llama/process_image.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +image=$1 + +actualFileName="${image%.*}" +python preprocess.py $image +python ../../helper/convert_np_to_float_inp.py --inp $actualFileName.npy --output ${actualFileName}_input.inp diff --git a/OnnxBridge/Demo/mlp/README.md b/OnnxBridge/Demo/mlp/README.md new file mode 100644 index 00000000..aaba89ca --- /dev/null +++ b/OnnxBridge/Demo/mlp/README.md @@ -0,0 +1,179 @@ +# Inference App - MLP fMRI + +In this demo we will run the Inference App for rs-fMRI using MLP model for interactive but secure inferencing following secure MPC using EzPC. + +## System Requirements + +Check [inference-app Readme](/inference-app/README.md#system-requirements) for system requirements.
+
+To successfully execute this demo we will need three **Ubuntu** VMs [tested on Ubuntu 20.04.6 LTS]: +1. **Dealer** : Works to generate pre-computed randomness and sends it to Client and Server for each inference. +2. **Server** : This party owns the model, and _does not share its model weights with Dealer/Client_, hence uses EzPC SMPC to achieve Secure Inference. +3. **Client** : This party acts as Client, but _does not hold any data by itself_, it gets Masked Image from the frontend, thus this party itself _can't see the image data in cleartext_. On receiving the Masked Image it starts the secure inference with Server and returns the result back to frontend. + + +Additionally we need a machine to run the frontend on, this is independent of OS, can be run on Client machine aswell if UI is available for Client VM, as the frontend runs in a browser. + +## Install Dependencies + +1. On all Ubuntu VM, install dependencies: +```bash +sudo apt update +sudo apt install libeigen3-dev cmake build-essential git zip +``` + +2. On all Ubuntu VM, install the python dependencies in a virtual environment. +``` bash +# Demo directory where we will install our dependencies and follow all the further steps. +mkdir MLP-DEMO +cd MLP-DEMO + +sudo apt install python3.8-venv +python3 -m venv venv +source venv/bin/activate + +wget https://raw.githubusercontent.com/mpc-msri/EzPC/master/OnnxBridge/requirements.txt +pip install --upgrade pip +sudo apt-get install python3-dev build-essential +pip install -r requirements.txt +pip install tqdm pyftpdlib flask +``` + +## Setup Server + +```bash +# Run the below notebook to extract the mlp_model.onnx file from the Github Repo for fMRI-Classification +# https://github.com/AmmarPL/fMRI-Classification-JHU/ +``` +Run the [extract_mlp_model.ipynb](/OnnxBridge/Demo/mlp/extract_mlp_model.ipynb) to download the mlp onnx file. + +```bash +# while inside MLP-DEMO +# copy the mlp_model.onnx file inside MLP-DEMO +cp /path/to/mlp_model.onnx . +mkdir play +cd play +``` + +## Setup Client +Make a temporary Directory. +```bash +# while inside MLP-DEMO +mkdir play +cd play +``` + +## Setup Dealer +Make a temporary Directory. +```bash +# while inside MLP-DEMO +mkdir play +cd play +``` + +## Setup Frontend + + On the system being used as the frontend, follow below instructions to setup Webapp +```bash +# clone repo +git clone https://github.com/mpc-msri/EzPC +cd EzPC + +# create virtual environment and install dependencies +sudo apt update +sudo apt install python3.8-venv +python3 -m venv mlinf +source mlinf/bin/activate +pip install --upgrade pip +sudo apt-get install python3-dev build-essential +pip install -r inference-app/requirements.txt +``` +--- +Generate the scripts and transfer them to respective machines. If server, client and dealer are in same virtual network, then pass the private network IP in the ezpc_cli-app.sh command. + +```bash +cd inference-app +chmod +x ezpc-cli-app.sh +./ezpc-cli-app.sh -m /home//MLP-DEMO/MLP.onnx -s -d [ -nt ] +scp server.sh :/home//MLP-DEMO/play/ +scp dealer.sh :/home//MLP-DEMO/play/ +scp client-offline.sh :/home//MLP-DEMO/play/ +scp client-online.sh :/home//MLP-DEMO/play/ +``` +In the above commands, the file paths and directories are absolute paths on the Ubuntu VMs used. To know more about the `ezpc-cli-app.sh` script see [link](/inference-app/Inference-App.md).
+ +---- + +On all Ubuntu VMs, make the bash scripts executable and execute them. + +```bash +# (on server) +chmod +x server.sh +./server.sh + +# (on dealer) +chmod +x dealer.sh +./dealer.sh + +# (on client) +chmod +x client-offline.sh client-online.sh +./client-offline.sh +``` +----- +#### Create a .`env` file inside `EzPC/inference-app` directory to store the secrets as environment variables ( `_URL` is the IP address of Dealer ), the file should look as below: + _URL = "X.X.X.X" + _USER = "frontend" + _PASSWORD = "frontend" + _FILE_NAME = "masks.dat" + _CLIENT_IP = "X.X.X.X" + +---- +#### Download the preprocessing file for image (specific to model) inside /inference-app directory: +```bash +# This file takes in image as +# preprocess it and returns it as a numpy array of size required by Model. +wget "https://raw.githubusercontent.com/drunkenlegend/ezpc-warehouse/main/MLP_fMRI/preprocess.py" -O preprocess.py +``` + +#### +```bash +# Next we download example image for the app. +cd Assets +mkdir examples && cd examples +wget "https://raw.githubusercontent.com/drunkenlegend/ezpc-warehouse/main/MLP_fMRI/1.png" -O 1.jpg +cd ../.. +``` +---- +#### Replace the USER_INPUTS in constants.py file with below: + + # Description + desc = "In this example app, we demonstrate how infer any fMRI Image with a MLP model trained by JHU in a secure manner using EzPC." + + # preprocess is a function that takes in an image and returns a numpy array + preprocess = get_arr_from_image + + # The input shape of the model, batch size should be 1 + Input_Shape = (1, 1, 45, 54, 45) + assert Input_Shape[0] == 1, "Batch size should be 1" + dims = { + "c": 1, + "h": 45, + "w": 54, + "d": 45, + } + + scale = 15 + + # Labels till 54 + labels_map = {i: i for i in range(56)} + +```bash +# while inside inference-app directory +python app_3d.py +``` + +Open the url received after running the last command on inference-app and play along: +1. Upload fMRI image. +2. Get Encryption Keys +3. Encrypt Image +4. Start Inference \ No newline at end of file diff --git a/OnnxBridge/Demo/mlp/accuracy_match_mlp.ipynb b/OnnxBridge/Demo/mlp/accuracy_match_mlp.ipynb new file mode 100644 index 00000000..1f8da36a --- /dev/null +++ b/OnnxBridge/Demo/mlp/accuracy_match_mlp.ipynb @@ -0,0 +1,1515 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install nibabel\n", + "!pip install torchio" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "gather": { + "logged": 1694162891056 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "import torchvision\n", + "from torchvision import datasets,transforms, models\n", + "import torchvision.transforms.functional as TF\n", + "import nibabel as nib\n", + "from pathlib import Path\n", + "import onnxruntime\n", + "from sklearn.metrics import precision_recall_fscore_support\n", + "from scipy import stats" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "gather": { + "logged": 1694160817159 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "data": { + "application/vnd.livy.statement-meta+json": { + "execution_finish_time": "2023-09-08T08:13:37.0324719Z", + "execution_start_time": "2023-09-08T08:13:36.6005083Z", + "livy_statement_state": "available", + "parent_msg_id": "9528a766-2fc5-42ea-a70c-608dee5e12a0", + "queued_time": "2023-09-08T08:13:31.2594057Z", + "session_id": "0", + "session_start_time": "2023-09-08T08:13:31.2611122Z", + "spark_jobs": { + "jobs": [], + "limit": 20, + "numbers": { + "FAILED": 0, + "RUNNING": 0, + "SUCCEEDED": 0, + "UNKNOWN": 0 + }, + "rule": "ALL_DESC" + }, + "spark_pool": "80619585-8c1b-471a-852e-6b5f92e90b7a", + "state": "finished", + "statement_id": 15 + }, + "text/plain": [ + "StatementMeta(80619585-8c1b-471a-852e-6b5f92e90b7a, 0, 15, Finished, Available)" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# to match fMRI ICA 100 components\n", + "batch_size = 100" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "gather": { + "logged": 1694160825825 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "data": { + "application/vnd.livy.statement-meta+json": { + "execution_finish_time": "2023-09-08T08:13:45.794837Z", + "execution_start_time": "2023-09-08T08:13:45.474047Z", + "livy_statement_state": "available", + "parent_msg_id": "411c6e2b-0836-49eb-b07d-66f8396eaf60", + "queued_time": "2023-09-08T08:13:45.4010881Z", + "session_id": "0", + "session_start_time": null, + "spark_jobs": { + "jobs": [], + "limit": 20, + "numbers": { + "FAILED": 0, + "RUNNING": 0, + "SUCCEEDED": 0, + "UNKNOWN": 0 + }, + "rule": "ALL_DESC" + }, + "spark_pool": "80619585-8c1b-471a-852e-6b5f92e90b7a", + "state": "finished", + "statement_id": 16 + }, + "text/plain": [ + "StatementMeta(80619585-8c1b-471a-852e-6b5f92e90b7a, 0, 16, Finished, Available)" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "class MultilayerPerceptron2(nn.Module):\n", + " # whatever op layer is becomes num ip for next hidden layer\n", + " def __init__(self, input_size=45*54*45, output_size=58):\n", + " super().__init__()\n", + " N = 200\n", + " self.d1 = nn.Linear(input_size, N)\n", + " self.d2 = nn.Linear(N, N)\n", + " self.d3 = nn.Linear(N, N)\n", + " self.d4 = nn.Linear(N, N)\n", + " self.d5 = nn.Linear(N, output_size)\n", + " self.dropout = nn.Dropout(0.66)\n", + " self.flat = nn.Flatten()\n", + " \n", + "\n", + " def forward(self,X):\n", + "\n", + " X = self.flat(X) #X.view(-1,45*54*45)\n", + " X = F.relu(self.d1(X))\n", + " X = F.relu(self.d3(X))\n", + " X = self.dropout(X) \n", + " X = F.relu(self.d4(X))\n", + " X = self.d5(X)\n", + " #X = torch.squeeze(X)\n", + "\n", + " return X" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "gather": { + "logged": 1694160870565 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "# Replace the path below with the path to your model weights\n", + "\n", + "device = 'cuda' if torch.cuda.is_available() else \"cpu\"\n", + "print(f'Device is {device}')\n", + "model_final = torch.load('/path/to/model_mlp_final.pth', map_location=torch.device('cpu'))\n", + "\n", + "model = MultilayerPerceptron2()\n", + "\n", + "\n", + "model.load_state_dict(model_final['model'])\n", + "model = model.to(device)\n", + "model.eval()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "gather": { + "logged": 1694162770925 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "# Replace the path below with the path to your test data\n", + "volPath = \"/home/user/path/to/test_data.nii.gz\"\n", + "niii_mg = nib.load(volPath).get_fdata()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "gather": { + "logged": 1689970420428 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(45, 54, 45, 176)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "niii_mg.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "gather": { + "logged": 1689970420574 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "input_volume = niii_mg[:,:,:,0:batch_size].reshape(batch_size,1,45,54,45)\n", + "input_volume = torch.Tensor(input_volume) #.view(-1,45*54*45)\n", + "input_volume = input_volume.to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "gather": { + "logged": 1689970420699 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([100, 1, 45, 54, 45])\n", + "(45, 54, 45, 100)\n" + ] + } + ], + "source": [ + "print(input_volume.shape)\n", + "print(niii_mg[:,:,:,0:batch_size].shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "gather": { + "logged": 1689972807193 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([42, 42, 42, 42, 42, 42, 42, 6, 42, 32, 56, 44, 10, 56, 51, 42, 10, 34,\n", + " 49, 37, 29, 10, 11, 4, 11, 11, 20, 11, 46, 46, 11, 44, 42, 50, 2, 11,\n", + " 11, 10, 28, 11, 44, 20, 24, 10, 11, 10, 21, 41, 11, 11, 11, 46, 11, 11,\n", + " 24, 53, 38, 10, 28, 11, 11, 7, 24, 11, 11, 10, 46, 49, 11, 11, 7, 11,\n", + " 11, 25, 56, 28, 2, 11, 19, 56, 23, 10, 11, 11, 56, 39, 56, 56, 56, 39,\n", + " 11, 46, 44, 42, 49, 42, 42, 42, 42, 42])\n" + ] + } + ], + "source": [ + "model.load_state_dict(model_final['model'])\n", + "model = model.to(device)\n", + "model.eval()\n", + "\n", + "probs = F.softmax(model(input_volume).detach(), dim=1) \n", + "\n", + "_, predictions = probs.max(1)\n", + "print(predictions)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "gather": { + "logged": 1689970421069 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "np.save(\"input_volume_100batch.npy\", input_volume.detach().numpy())" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "gather": { + "logged": 1689970422515 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Exported graph: graph(%image : Float(100, 1, 45, 54, 45, strides=[109350, 109350, 2430, 45, 1], requires_grad=0, device=cpu),\n", + " %d1.weight : Float(200, 109350, strides=[109350, 1], requires_grad=1, device=cpu),\n", + " %d1.bias : Float(200, strides=[1], requires_grad=1, device=cpu),\n", + " %d3.weight : Float(200, 200, strides=[200, 1], requires_grad=1, device=cpu),\n", + " %d3.bias : Float(200, strides=[1], requires_grad=1, device=cpu),\n", + " %d4.weight : Float(200, 200, strides=[200, 1], requires_grad=1, device=cpu),\n", + " %d4.bias : Float(200, strides=[1], requires_grad=1, device=cpu),\n", + " %d5.weight : Float(58, 200, strides=[200, 1], requires_grad=1, device=cpu),\n", + " %d5.bias : Float(58, strides=[1], requires_grad=1, device=cpu)):\n", + " %onnx::Gemm_11 : Float(100, 109350, strides=[109350, 1], requires_grad=0, device=cpu) = onnx::Flatten[axis=1, onnx_name=\"Flatten_0\"](%image) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/modules/flatten.py:45:0\n", + " %onnx::Relu_12 : Float(100, 200, strides=[200, 1], requires_grad=0, device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1, onnx_name=\"Gemm_1\"](%onnx::Gemm_11, %d1.weight, %d1.bias) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/modules/linear.py:114:0\n", + " %onnx::Gemm_13 : Float(100, 200, strides=[200, 1], requires_grad=0, device=cpu) = onnx::Relu[onnx_name=\"Relu_2\"](%onnx::Relu_12) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/functional.py:1457:0\n", + " %onnx::Relu_14 : Float(100, 200, strides=[200, 1], requires_grad=0, device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1, onnx_name=\"Gemm_3\"](%onnx::Gemm_13, %d3.weight, %d3.bias) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/modules/linear.py:114:0\n", + " %input : Float(100, 200, strides=[200, 1], requires_grad=0, device=cpu) = onnx::Relu[onnx_name=\"Relu_4\"](%onnx::Relu_14) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/functional.py:1457:0\n", + " %onnx::Relu_16 : Float(100, 200, strides=[200, 1], requires_grad=0, device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1, onnx_name=\"Gemm_5\"](%input, %d4.weight, %d4.bias) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/modules/linear.py:114:0\n", + " %onnx::Gemm_17 : Float(100, 200, strides=[200, 1], requires_grad=0, device=cpu) = onnx::Relu[onnx_name=\"Relu_6\"](%onnx::Relu_16) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/functional.py:1457:0\n", + " %score : Float(100, 58, strides=[58, 1], requires_grad=0, device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1, onnx_name=\"Gemm_7\"](%onnx::Gemm_17, %d5.weight, %d5.bias) # /anaconda/envs/azureml_py38/lib/python3.8/site-packages/torch/nn/modules/linear.py:114:0\n", + " return (%score)\n", + "\n" + ] + } + ], + "source": [ + "output_onnx = str(Path(\"mlp_model.onnx\"))\n", + "\n", + "# Export an ONNX model.\n", + "with torch.no_grad():\n", + " torch.onnx.export(\n", + " model=model,\n", + " # Using a fixed batch size of 1 since EzPC doesn't allow dynamic batch size\n", + " args=(input_volume),\n", + " f=output_onnx, \n", + " opset_version=13,\n", + " verbose=True,\n", + " input_names=[\"image\"], \n", + " output_names=[ \"score\"],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "gather": { + "logged": 1689972848533 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([42, 42, 42, 42, 42, 42, 42, 6, 42, 32, 56, 44, 10, 56, 51, 42, 10, 34,\n", + " 49, 37, 29, 10, 11, 4, 11, 11, 20, 11, 46, 46, 11, 44, 42, 50, 2, 11,\n", + " 11, 10, 28, 11, 44, 20, 24, 10, 11, 10, 21, 41, 11, 11, 11, 46, 11, 11,\n", + " 24, 53, 38, 10, 28, 11, 11, 7, 24, 11, 11, 10, 46, 49, 11, 11, 7, 11,\n", + " 11, 25, 56, 28, 2, 11, 19, 56, 23, 10, 11, 11, 56, 39, 56, 56, 56, 39,\n", + " 11, 46, 44, 42, 49, 42, 42, 42, 42, 42])\n" + ] + } + ], + "source": [ + "session = onnxruntime.InferenceSession(output_onnx)\n", + "ort_output = session.run(\n", + " output_names=None,\n", + " input_feed={ \n", + " \"image\": input_volume.numpy(),\n", + " },\n", + ")\n", + "ort_probs = F.softmax(torch.tensor(ort_output[0]), dim=1) \n", + "_, ort_predictions = ort_probs.max(1)\n", + "print(ort_predictions)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "gather": { + "logged": 1689970437958 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Get:1 file:/var/nccl-repo-2.2.13-ga-cuda9.2 InRelease\n", + "Ign:1 file:/var/nccl-repo-2.2.13-ga-cuda9.2 InRelease\n", + "Get:2 file:/var/nccl-repo-2.2.13-ga-cuda9.2 Release [574 B] \u001b[0m\n", + "Hit:3 http://azure.archive.ubuntu.com/ubuntu focal InRelease \u001b[0m\n", + "Hit:4 http://azure.archive.ubuntu.com/ubuntu focal-updates InRelease \n", + "Hit:5 http://azure.archive.ubuntu.com/ubuntu focal-backports InRelease \n", + "Hit:6 http://azure.archive.ubuntu.com/ubuntu focal-security InRelease \n", + "Get:2 file:/var/nccl-repo-2.2.13-ga-cuda9.2 Release [574 B] \u001b[0m\n", + "Hit:7 https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64 InRelease\n", + "Hit:8 https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/ InRelease \u001b[0m\n", + "Hit:9 https://nvidia.github.io/nvidia-container-runtime/stable/ubuntu18.04/amd64 InRelease\n", + "Hit:10 https://apt.repos.intel.com/mkl all InRelease \u001b[0m\n", + "Hit:11 https://nvidia.github.io/nvidia-docker/ubuntu18.04/amd64 InRelease \u001b[0m\n", + "Hit:12 https://storage.googleapis.com/tensorflow-serving-apt stable InRelease \u001b[0m\n", + "Hit:13 https://packages.microsoft.com/repos/azure-cli focal InRelease \u001b[0m\n", + "Hit:14 https://packages.microsoft.com/repos/azurecore focal InRelease \n", + "Hit:15 https://packages.microsoft.com/ubuntu/20.04/prod focal InRelease\n", + "Hit:16 http://ppa.launchpad.net/cran/libgit2/ubuntu focal InRelease\n", + "Hit:18 http://ppa.launchpad.net/git-core/ppa/ubuntu focal InRelease\n", + "Reading package lists... Done\n", + "Building dependency tree \n", + "Reading state information... Done\n", + "82 packages can be upgraded. Run 'apt list --upgradable' to see them.\n", + "Reading package lists... Done\n", + "Building dependency tree \n", + "Reading state information... Done\n", + "libeigen3-dev is already the newest version (3.3.7-2).\n", + "build-essential is already the newest version (12.8ubuntu1.1).\n", + "cmake is already the newest version (3.16.3-1ubuntu1.20.04.1).\n", + "git is already the newest version (1:2.41.0-0ppa1~ubuntu20.04.1).\n", + "The following packages were automatically installed and are no longer required:\n", + " ca-certificates-java cuda-command-line-tools-11-3 cuda-compiler-11-3\n", + " cuda-cudart-11-3 cuda-cudart-dev-11-3 cuda-cuobjdump-11-3 cuda-cupti-11-3\n", + " cuda-cupti-dev-11-3 cuda-cuxxfilt-11-3 cuda-documentation-11-3\n", + " cuda-driver-dev-11-3 cuda-gdb-11-3 cuda-libraries-11-3\n", + " cuda-libraries-dev-11-3 cuda-memcheck-11-3 cuda-nsight-11-3\n", + " cuda-nsight-compute-11-3 cuda-nsight-systems-11-3 cuda-nvcc-11-3\n", + " cuda-nvdisasm-11-3 cuda-nvml-dev-11-3 cuda-nvprof-11-3 cuda-nvprune-11-3\n", + " cuda-nvrtc-11-3 cuda-nvrtc-dev-11-3 cuda-nvtx-11-3 cuda-nvvp-11-3\n", + " cuda-samples-11-3 cuda-sanitizer-11-3 cuda-thrust-11-3 cuda-toolkit-11-3\n", + " cuda-toolkit-11-3-config-common cuda-toolkit-11-config-common\n", + " cuda-toolkit-config-common cuda-tools-11-3 cuda-visual-tools-11-3\n", + " default-jre default-jre-headless fonts-dejavu-extra fonts-droid-fallback\n", + " fonts-noto-mono fonts-urw-base35 ghostscript gsfonts gyp\n", + " imagemagick-6-common java-common javascript-common libaec-dev libaec0\n", + " libatk-wrapper-java libatk-wrapper-java-jni libcublas-11-3\n", + " libcublas-dev-11-3 libcufft-11-3 libcufft-dev-11-3 libcurand-11-3\n", + " libcurand-dev-11-3 libcusolver-11-3 libcusolver-dev-11-3 libcusparse-11-3\n", + " libcusparse-dev-11-3 libdjvulibre-dev libdjvulibre-text libdjvulibre21\n", + " libexif-dev libexif-doc libexif12 libfftw3-double3 libgs9 libgs9-common\n", + " libidn11 libijs-0.35 libilmbase-dev libilmbase24 libjbig-dev libjbig2dec0\n", + " libjs-inherits libjs-is-typedarray libjs-jquery libjs-psl\n", + " libjs-typedarray-to-buffer liblcms2-dev liblqr-1-0 liblqr-1-0-dev\n", + " libmagick++-6-headers libmagick++-6.q16-8 libmagickcore-6-arch-config\n", + " libmagickcore-6-headers libmagickcore-6.q16-6 libmagickwand-6-headers\n", + " libmagickwand-6.q16-6 libnorm-dev libnorm1 libnpp-11-3 libnpp-dev-11-3\n", + " libnvidia-common-530 libnvjpeg-11-3 libnvjpeg-dev-11-3 libpcsclite1\n", + " libpgm-5.2-0 libpgm-dev librsvg2-dev libsodium-dev libsystemd-dev libsz2\n", + " libtiff-dev libtiffxx5 libwmf-dev libwmf0.2-7 libxt-dev node-abbrev node-ajv\n", + " node-ansi node-ansi-align node-ansi-regex node-ansi-styles node-ansistyles\n", + " node-aproba node-archy node-are-we-there-yet node-asap node-asn1\n", + " node-assert-plus node-asynckit node-aws-sign2 node-aws4 node-balanced-match\n", + " node-bcrypt-pbkdf node-bl node-bluebird node-boxen node-brace-expansion\n", + " node-builtin-modules node-builtins node-cacache node-call-limit\n", + " node-camelcase node-caseless node-chalk node-chownr node-ci-info\n", + " node-cli-boxes node-cliui node-clone node-co node-color-convert\n", + " node-color-name node-colors node-columnify node-combined-stream\n", + " node-concat-map node-concat-stream node-config-chain node-configstore\n", + " node-console-control-strings node-copy-concurrently node-core-util-is\n", + " node-cross-spawn node-crypto-random-string node-cyclist node-dashdash\n", + " node-debug node-decamelize node-decompress-response node-deep-extend\n", + " node-defaults node-define-properties node-delayed-stream node-delegates\n", + " node-detect-indent node-detect-newline node-dot-prop node-duplexer3\n", + " node-duplexify node-ecc-jsbn node-editor node-encoding node-end-of-stream\n", + " node-err-code node-errno node-es6-promise node-escape-string-regexp\n", + " node-execa node-extend node-extsprintf node-fast-deep-equal node-find-up\n", + " node-flush-write-stream node-forever-agent node-form-data node-from2\n", + " node-fs-vacuum node-fs-write-stream-atomic node-fs.realpath\n", + " node-function-bind node-gauge node-genfun node-get-caller-file\n", + " node-get-stream node-getpass node-glob node-got node-graceful-fs\n", + " node-har-schema node-har-validator node-has-flag node-has-symbol-support-x\n", + " node-has-to-string-tag-x node-has-unicode node-http-signature\n", + " node-iconv-lite node-iferr node-import-lazy node-imurmurhash node-inflight\n", + " node-inherits node-ini node-invert-kv node-ip node-ip-regex node-is-npm\n", + " node-is-obj node-is-object node-is-path-inside node-is-plain-obj\n", + " node-is-retry-allowed node-is-stream node-is-typedarray node-isarray\n", + " node-isexe node-isstream node-isurl node-jsbn node-json-parse-better-errors\n", + " node-json-schema node-json-schema-traverse node-json-stable-stringify\n", + " node-json-stringify-safe node-jsonify node-jsonparse node-jsonstream\n", + " node-jsprim node-latest-version node-lazy-property node-lcid\n", + " node-locate-path node-lockfile node-lodash node-lodash-packages\n", + " node-lowercase-keys node-lru-cache node-make-dir node-mem node-mime\n", + " node-mime-types node-mimic-fn node-mimic-response node-minimatch\n", + " node-minimist node-mississippi node-mkdirp node-move-concurrently node-ms\n", + " node-mute-stream node-nopt node-normalize-package-data node-npm-bundled\n", + " node-npm-run-path node-npmlog node-number-is-nan node-oauth-sign\n", + " node-object-assign node-once node-opener node-os-locale node-os-tmpdir\n", + " node-osenv node-p-cancelable node-p-finally node-p-is-promise node-p-limit\n", + " node-p-locate node-p-timeout node-package-json node-parallel-transform\n", + " node-path-exists node-path-is-absolute node-path-is-inside\n", + " node-performance-now node-pify node-prepend-http node-process-nextick-args\n", + " node-promise-inflight node-promise-retry node-promzard node-proto-list\n", + " node-prr node-pseudomap node-psl node-pump node-pumpify node-punycode\n", + " node-qs node-qw node-rc node-read node-read-package-json\n", + " node-readable-stream node-registry-auth-token node-registry-url node-request\n", + " node-require-directory node-require-main-filename node-resolve\n", + " node-resolve-from node-retry node-rimraf node-run-queue node-safe-buffer\n", + " node-semver node-semver-diff node-set-blocking node-sha node-shebang-command\n", + " node-shebang-regex node-signal-exit node-slash node-slide node-sorted-object\n", + " node-spdx-correct node-spdx-exceptions node-spdx-expression-parse\n", + " node-spdx-license-ids node-sshpk node-ssri node-stream-each\n", + " node-stream-iterate node-stream-shift node-strict-uri-encode\n", + " node-string-decoder node-string-width node-strip-ansi node-strip-eof\n", + " node-strip-json-comments node-supports-color node-term-size node-text-table\n", + " node-through node-through2 node-timed-out node-tough-cookie\n", + " node-tunnel-agent node-tweetnacl node-typedarray node-typedarray-to-buffer\n", + " node-uid-number node-unique-filename node-unique-string node-unpipe\n", + " node-uri-js node-url-parse-lax node-url-to-options node-util-deprecate\n", + " node-uuid node-validate-npm-package-license node-validate-npm-package-name\n", + " node-verror node-wcwidth.js node-which node-which-module node-wide-align\n", + " node-widest-line node-wrap-ansi node-wrappy node-write-file-atomic\n", + " node-xdg-basedir node-xtend node-y18n node-yallist node-yargs\n", + " node-yargs-parser nsight-compute-2021.1.1 nsight-systems-2021.1.3\n", + " openjdk-11-jre openjdk-11-jre-headless poppler-data python-pkg-resources\n", + "Use 'sudo apt autoremove' to remove them.\n", + "0 upgraded, 0 newly installed, 0 to remove and 82 not upgraded.\n", + "--2023-07-21 20:13:48-- http://wget/\n", + "Resolving wget (wget)... failed: Name or service not known.\n", + "wget: unable to resolve host address ‘wget’\n", + "--2023-07-21 20:13:49-- https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-linux-x86_64.sh\n", + "Resolving github.com (github.com)... 192.30.255.113\n", + "Connecting to github.com (github.com)|192.30.255.113|:443... connected.\n", + "HTTP request sent, awaiting response... 302 Found\n", + "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/537699/a3e2f007-068f-4f18-a381-7db984738e8d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230721%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230721T201349Z&X-Amz-Expires=300&X-Amz-Signature=fe3847053d66661f653f25b27c377707b813020a2b614ec2dbddce16445ffdf2&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=537699&response-content-disposition=attachment%3B%20filename%3Dcmake-3.26.4-linux-x86_64.sh&response-content-type=application%2Foctet-stream [following]\n", + "--2023-07-21 20:13:49-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/537699/a3e2f007-068f-4f18-a381-7db984738e8d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230721%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230721T201349Z&X-Amz-Expires=300&X-Amz-Signature=fe3847053d66661f653f25b27c377707b813020a2b614ec2dbddce16445ffdf2&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=537699&response-content-disposition=attachment%3B%20filename%3Dcmake-3.26.4-linux-x86_64.sh&response-content-type=application%2Foctet-stream\n", + "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 48329261 (46M) [application/octet-stream]\n", + "Saving to: ‘/tmp/cmake.sh’\n", + "\n", + "/tmp/cmake.sh 100%[===================>] 46.09M 68.5MB/s in 0.7s \n", + "\n", + "2023-07-21 20:13:50 (68.5 MB/s) - ‘/tmp/cmake.sh’ saved [48329261/48329261]\n", + "\n", + "FINISHED --2023-07-21 20:13:50--\n", + "Total wall clock time: 1.2s\n", + "Downloaded: 1 files, 46M in 0.7s (68.5 MB/s)\n", + "CMake Installer Version: 3.26.4, Copyright (c) Kitware\n", + "This is a self-extracting archive.\n", + "The archive will be extracted to: /usr/local\n", + "\n", + "Using target directory: /usr/local\n", + "Extracting, please wait...\n", + "\n", + "Unpacking finished successfully\n", + "cmake version 3.26.4 CMake suite maintained and supported by Kitware (kitware.com/cmake).\n", + "fatal: destination path 'EzPC' already exists and is not an empty directory.\n", + "Requirement already satisfied: onnx==1.12.0 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from -r OnnxBridge/requirements.txt (line 1)) (1.12.0)\n", + "Requirement already satisfied: onnxruntime==1.12.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from -r OnnxBridge/requirements.txt (line 2)) (1.12.1)\n", + "Requirement already satisfied: onnxsim==0.4.8 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from -r OnnxBridge/requirements.txt (line 3)) (0.4.8)\n", + "Requirement already satisfied: numpy==1.21.0 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from -r OnnxBridge/requirements.txt (line 4)) (1.21.0)\n", + "Requirement already satisfied: protobuf==3.20.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from -r OnnxBridge/requirements.txt (line 5)) (3.20.1)\n", + "Requirement already satisfied: torchvision==0.13.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from -r OnnxBridge/requirements.txt (line 6)) (0.13.1)\n", + "Requirement already satisfied: idx2numpy==1.2.3 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from -r OnnxBridge/requirements.txt (line 7)) (1.2.3)\n", + "Requirement already satisfied: typing-extensions>=3.6.2.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from onnx==1.12.0->-r OnnxBridge/requirements.txt (line 1)) (4.6.0)\n", + "Requirement already satisfied: sympy in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from onnxruntime==1.12.1->-r OnnxBridge/requirements.txt (line 2)) (1.12)\n", + "Requirement already satisfied: flatbuffers in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from onnxruntime==1.12.1->-r OnnxBridge/requirements.txt (line 2)) (23.5.9)\n", + "Requirement already satisfied: packaging in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from onnxruntime==1.12.1->-r OnnxBridge/requirements.txt (line 2)) (23.0)\n", + "Requirement already satisfied: coloredlogs in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from onnxruntime==1.12.1->-r OnnxBridge/requirements.txt (line 2)) (15.0.1)\n", + "Requirement already satisfied: rich in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from onnxsim==0.4.8->-r OnnxBridge/requirements.txt (line 3)) (13.4.2)\n", + "Requirement already satisfied: torch==1.12.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from torchvision==0.13.1->-r OnnxBridge/requirements.txt (line 6)) (1.12.1)\n", + "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from torchvision==0.13.1->-r OnnxBridge/requirements.txt (line 6)) (9.2.0)\n", + "Requirement already satisfied: requests in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from torchvision==0.13.1->-r OnnxBridge/requirements.txt (line 6)) (2.31.0)\n", + "Requirement already satisfied: six in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from idx2numpy==1.2.3->-r OnnxBridge/requirements.txt (line 7)) (1.16.0)\n", + "Requirement already satisfied: mpmath>=0.19 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from sympy->onnxruntime==1.12.1->-r OnnxBridge/requirements.txt (line 2)) (1.3.0)\n", + "Requirement already satisfied: humanfriendly>=9.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from coloredlogs->onnxruntime==1.12.1->-r OnnxBridge/requirements.txt (line 2)) (10.0)\n", + "Requirement already satisfied: markdown-it-py>=2.2.0 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from rich->onnxsim==0.4.8->-r OnnxBridge/requirements.txt (line 3)) (2.2.0)\n", + "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from rich->onnxsim==0.4.8->-r OnnxBridge/requirements.txt (line 3)) (2.15.1)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from requests->torchvision==0.13.1->-r OnnxBridge/requirements.txt (line 6)) (1.26.16)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from requests->torchvision==0.13.1->-r OnnxBridge/requirements.txt (line 6)) (2022.9.24)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from requests->torchvision==0.13.1->-r OnnxBridge/requirements.txt (line 6)) (3.1.0)\n", + "Requirement already satisfied: idna<4,>=2.5 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from requests->torchvision==0.13.1->-r OnnxBridge/requirements.txt (line 6)) (3.4)\n", + "Requirement already satisfied: mdurl~=0.1 in /anaconda/envs/azureml_py38/lib/python3.8/site-packages (from markdown-it-py>=2.2.0->rich->onnxsim==0.4.8->-r OnnxBridge/requirements.txt (line 3)) (0.1.2)\n" + ] + } + ], + "source": [ + "# Setup EzPC\n", + "!./ezpc_setup.sh" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "gather": { + "logged": 1689970556828 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32;3m2023-07-21 20:14:01,709 - OnnxBridge - INFO <<<<- Application Started ->>>> (backend.py:58)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:01,709 - OnnxBridge - INFO <<<<- Loading onnx graph: mlp_model ->>>> (backend.py:62)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:03,608 - OnnxBridge - INFO <<<<- Model Received : opset version : 13 ->>>> (backend.py:66)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:03,609 - OnnxBridge - INFO <<<<- Batch Size : 100 ->>>> (backend.py:69)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:05,976 - OnnxBridge - INFO <<<<- Model Optimized ->>>> (backend.py:75)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:06,231 - OnnxBridge - INFO <<<<- Shape Inference Done ->>>> (backend.py:78)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:06,231 - OnnxBridge - INFO <<<<- Model is OK! ->>>> (backend.py:83)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,059 - OnnxBridge - INFO <<<<- Dumping model weights in:\n", + " /mnt/batch/tasks/shared/LS_root/mounts/clusters/user2/code/Users/user/EzPC/OnnxBridge/workdir/mlp_model_input_weights.dat ->>>> (backend.py:101)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,059 - OnnxBridge - INFO <<<<- These are to be used as input for party owning the model. ->>>> (backend.py:102)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,217 - OnnxBridge - INFO <<<<- Optimised Stripped Model Loaded ->>>> (backend.py:189)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,217 - OnnxBridge - INFO <<<<- Device Supported ->>>> (backend.py:192)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,217 - OnnxBridge - INFO <<<<- Reading Onnx file to IR Nodes. ->>>> (backend.py:200)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,217 - OnnxBridge - INFO <<<<- Reading Onnx file completed. ->>>> (backend.py:204)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,218 - OnnxBridge - INFO <<<<- Relu Maxpool Optimisation Done. ->>>> (backend.py:207)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,218 - OnnxBridge - INFO <<<<- Onnx Variable -> IR variable Dictionary Created. ->>>> (backend.py:214)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,218 - OnnxBridge - INFO <<<<- BackendRep Created. ->>>> (backend.py:224)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,218 - OnnxBridge - INFO <<<<- Preparing to export Model to LLAMA ->>>> (sytorchBackendRep.py:349)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,218 - OnnxBridge - INFO <<<<- Starting Export... ->>>> (sytorchBackendRep.py:259)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,218 - OnnxBridge - INFO <<<<- Completed Export. ->>>> (sytorchBackendRep.py:326)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,218 - OnnxBridge - INFO <<<<- Secure Model File Saved in Secfloat format as mlp_model_LLAMA_15.cpp ->>>> (sytorchBackendRep.py:360)\n", + "\u001b[0m\u001b[32;3m2023-07-21 20:14:36,256 - OnnxBridge - INFO <<<<- Starting Compilation. ->>>> (main.py:62)\n", + "\u001b[0m-- The C compiler identification is GNU 9.4.0\n", + "-- The CXX compiler identification is GNU 9.4.0\n", + "-- Detecting C compiler ABI info\n", + "-- Detecting C compiler ABI info - done\n", + "-- Check for working C compiler: /usr/bin/cc - skipped\n", + "-- Detecting C compile features\n", + "-- Detecting C compile features - done\n", + "-- Detecting CXX compiler ABI info\n", + "-- Detecting CXX compiler ABI info - done\n", + "-- Check for working CXX compiler: /usr/bin/c++ - skipped\n", + "-- Detecting CXX compile features\n", + "-- Detecting CXX compile features - done\n", + "-- Performing Test CMAKE_HAVE_LIBC_PTHREAD\n", + "-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed\n", + "-- Looking for pthread_create in pthreads\n", + "-- Looking for pthread_create in pthreads - not found\n", + "-- Looking for pthread_create in pthread\n", + "-- Looking for pthread_create in pthread - found\n", + "-- Found Threads: TRUE \n", + "-- Configuring done (23.1s)\n", + "-- Generating done (4.5s)\n", + "-- Build files have been written to: /mnt/batch/tasks/shared/LS_root/mounts/clusters/user2/code/Users/user/EzPC/OnnxBridge/workdir/build_dir\n", + "[ 17%] \u001b[32mBuilding CXX object cryptoTools/CMakeFiles/cryptoTools.dir/cryptoTools/Common/Defines.cpp.o\u001b[0m\n", + "[ 17%] \u001b[32mBuilding CXX object cryptoTools/CMakeFiles/cryptoTools.dir/cryptoTools/Crypto/PRNG.cpp.o\u001b[0m\n", + "[ 17%] \u001b[32mBuilding CXX object cryptoTools/CMakeFiles/cryptoTools.dir/cryptoTools/Common/Log.cpp.o\u001b[0m\n", + "[ 17%] \u001b[32mBuilding CXX object cryptoTools/CMakeFiles/cryptoTools.dir/cryptoTools/Crypto/AES.cpp.o\u001b[0m\n", + "[ 21%] \u001b[32m\u001b[1mLinking CXX static library libcryptoTools.a\u001b[0m\n", + "[ 21%] Built target cryptoTools\n", + "[ 30%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/src/llama/config.cpp.o\u001b[0m\n", + "[ 34%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/src/llama/comms.cpp.o\u001b[0m\n", + "[ 39%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/src/llama/input_prng.cpp.o\u001b[0m\n", + "[ 39%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/src/llama/prng.cpp.o\u001b[0m\n", + "[ 43%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/src/llama/stats.cpp.o\u001b[0m\n", + "[ 47%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/src/llama/utils.cpp.o\u001b[0m\n", + "[ 52%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/and.cpp.o\u001b[0m\n", + "[ 56%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/api.cpp.o\u001b[0m\n", + "[ 60%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/conv.cpp.o\u001b[0m\n", + "[ 65%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/dcf.cpp.o\u001b[0m\n", + "[ 69%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/mult.cpp.o\u001b[0m\n", + "[ 73%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/pubdiv.cpp.o\u001b[0m\n", + "[ 78%] \u001b[32mBuilding CXX object llama/CMakeFiles/LLAMA.dir/relu.cpp.o\u001b[0m\n", + "[ 82%] \u001b[32m\u001b[1mLinking CXX static library libLLAMA.a\u001b[0m\n", + "[ 82%] Built target LLAMA\n", + "[ 91%] \u001b[32mBuilding CXX object CMakeFiles/mlp_model_LLAMA_15.dir/mnt/batch/tasks/shared/LS_root/mounts/clusters/user2/code/Users/user/EzPC/OnnxBridge/workdir/mlp_model_LLAMA_15.cpp.o\u001b[0m\n", + "[ 95%] \u001b[32mBuilding CXX object CMakeFiles/mlp_model_LLAMA_15.dir/mnt/batch/tasks/shared/LS_root/mounts/clusters/user2/code/Users/user/EzPC/sytorch/src/sytorch/backend/cleartext.cpp.o\u001b[0m\n", + "[ 95%] \u001b[32mBuilding CXX object CMakeFiles/mlp_model_LLAMA_15.dir/mnt/batch/tasks/shared/LS_root/mounts/clusters/user2/code/Users/user/EzPC/sytorch/src/sytorch/random.cpp.o\u001b[0m\n", + "[100%] \u001b[32m\u001b[1mLinking CXX executable mlp_model_LLAMA_15\u001b[0m\n", + "[100%] Built target mlp_model_LLAMA_15\n", + "Output binary: ./mlp_model_LLAMA_15\n", + "\u001b[32;3m2023-07-21 20:15:45,686 - OnnxBridge - INFO <<<<- Output Binary generated : mlp_model_LLAMA_15.cpp ->>>> (main.py:72)\n", + "\u001b[0m=== COMPUTATION START ===\n", + "\n", + ">> MatMul2D - Start\n", + " Dealer Time = 764 milliseconds\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + " Dealer time = 104.323 milliseconds\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic) - Start\n", + " Dealer Time = 79.179 milliseconds\n", + ">> Truncate - End\n", + ">> MatMul2D - Start\n", + " Dealer Time = 2 milliseconds\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + " Dealer time = 88.71 milliseconds\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic) - Start\n", + " Dealer Time = 85.44 milliseconds\n", + ">> Truncate - End\n", + ">> MatMul2D - Start\n", + " Dealer Time = 1 milliseconds\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + " Dealer time = 91.152 milliseconds\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic) - Start\n", + " Dealer Time = 95.433 milliseconds\n", + ">> Truncate - End\n", + ">> MatMul2D - Start\n", + " Dealer Time = 0 milliseconds\n", + ">> MatMul2D - End\n", + ">> Truncate (stochastic) - Start\n", + " Dealer Time = 24.63 milliseconds\n", + ">> Truncate - End\n", + "\n", + "=== COMPUTATION END ===\n", + "\n", + "Offline Communication = 792427216 bytes\n", + "Offline Time = 1379.19 milliseconds\n", + "=========\n" + ] + } + ], + "source": [ + "# run EzPC secure compilation and key generation\n", + "!./ezpc_secure_compile.sh" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "gather": { + "logged": 1689630668565 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "FLoat point output saved in input_volume_100batch.inp\n", + "Key Size: 264124032 bytes\n", + "waiting for connection from client...Key Size: 528349616 bytes\n", + "trying to connect with server...connectedconnected\n", + "\n", + "=== COMPUTATION START ===\n", + "\n", + "=== COMPUTATION START ===\n", + "\n", + ">> MatMul2D - Start\n", + ">> MatMul2D - Start\n", + " Key Read Time = Key Read Time = 376 milliseconds\n", + " Compute Time = 15645.2 milliseconds\n", + " Eigen Time = 15645.2 milliseconds\n", + " Reconstruct Time = 0.737 milliseconds\n", + " Online Time = 15645.9 milliseconds\n", + " Online Comm = 320000 bytes\n", + "6313 milliseconds\n", + " Compute Time = 15637.6 milliseconds\n", + " Eigen Time = 15637.6 milliseconds\n", + " Reconstruct Time = 8.291 milliseconds\n", + " Online Time = 15645.9 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> MatMul2D - End\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + ">> Relu (Spline) - Start\n", + " Key Read Time = 1033 milliseconds\n", + " Compute Time = 150.222 milliseconds\n", + " Reconstruct Time = 0.77 milliseconds\n", + " Online Time = 150.992 milliseconds\n", + " Online Comm = 360000 bytes\n", + " Key Read Time = 1248 milliseconds\n", + " Compute Time = 133.398 milliseconds\n", + " Reconstruct Time = 17.688 milliseconds\n", + " Online Time = 151.086 milliseconds\n", + " Online Comm = 360000 bytes\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic)>> Relu (Spline) - End - Start\n", + "\n", + ">> Truncate (stochastic) - Start\n", + " Key Read Time = Key Read Time = 1142 milliseconds\n", + " Compute Time = 79.074 milliseconds\n", + " Reconstruct Time = 3.957 milliseconds\n", + " Online Time = 83.031 milliseconds\n", + " Online Comm = 1237 milliseconds\n", + " Compute Time = 69.014 milliseconds\n", + " Reconstruct Time = 13.959 milliseconds\n", + " Online Time = 82.973 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> Truncate - End\n", + "320000 bytes\n", + ">> Truncate - End\n", + ">> MatMul2D - Start\n", + ">> MatMul2D - Start\n", + " Key Read Time = 3 milliseconds\n", + " Compute Time = 13.539 milliseconds\n", + " Eigen Time = 13.538 milliseconds\n", + " Reconstruct Time = 0.256 milliseconds\n", + " Online Time = 13.795 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + " Key Read Time = 0 milliseconds\n", + " Compute Time = 10.645 milliseconds\n", + " Eigen Time = 10.645 milliseconds\n", + " Reconstruct Time = 4.217 milliseconds\n", + " Online Time = 14.862 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + " Key Read Time = Key Read Time = 1237 milliseconds\n", + " Compute Time = 1080 milliseconds\n", + "132.777 milliseconds\n", + " Reconstruct Time = 5.016 milliseconds\n", + " Online Time = 137.793 milliseconds\n", + " Online Comm = 360000 bytes\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic) - Start\n", + " Compute Time = 137.112 milliseconds\n", + " Reconstruct Time = 0.694 milliseconds\n", + " Online Time = 137.806 milliseconds\n", + " Online Comm = 360000 bytes\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic) - Start\n", + " Key Read Time = 1187 milliseconds\n", + " Compute Time = 69.354 milliseconds\n", + " Reconstruct Time = 8.746 milliseconds\n", + " Online Time = 78.1 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> Truncate - End\n", + " Key Read Time = 1124 milliseconds\n", + " Compute Time = 74.817 milliseconds\n", + " Reconstruct Time = 3.537 milliseconds\n", + " Online Time = 78.354 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> Truncate - End\n", + ">> MatMul2D - Start\n", + ">> MatMul2D - Start\n", + " Key Read Time = 0 milliseconds\n", + " Compute Time = 27.793 milliseconds\n", + " Eigen Time = 27.793 milliseconds\n", + " Reconstruct Time = 0.318 milliseconds\n", + " Online Time = 28.111 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + " Key Read Time = 0 milliseconds\n", + " Compute Time = 25.272 milliseconds\n", + " Eigen Time = 25.271 milliseconds\n", + " Reconstruct Time = 4.833 milliseconds\n", + " Online Time = 30.105 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> MatMul2D - End\n", + ">> Relu (Spline) - Start\n", + " Key Read Time = 813 milliseconds\n", + " Compute Time = 143.898 milliseconds\n", + " Reconstruct Time = 3.551 milliseconds\n", + " Online Time = 147.449 milliseconds\n", + " Online Comm = 360000 bytes\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic) - Start\n", + " Key Read Time = 1095 milliseconds\n", + " Compute Time = 146.737 milliseconds\n", + " Reconstruct Time = 0.687 milliseconds\n", + " Online Time = 147.424 milliseconds\n", + " Online Comm = 360000 bytes\n", + ">> Relu (Spline) - End \n", + ">> Truncate (stochastic) - Start\n", + " Key Read Time = 1161 milliseconds\n", + " Compute Time = 79.845 milliseconds\n", + " Reconstruct Time = 3.705 milliseconds\n", + " Online Time = 83.55 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> Truncate - End\n", + ">> MatMul2D - Start\n", + " Key Read Time = 1485 milliseconds\n", + " Compute Time = 73.54 milliseconds\n", + " Reconstruct Time = 11.752 milliseconds\n", + " Online Time = 85.292 milliseconds\n", + " Online Comm = 320000 bytes\n", + ">> Truncate - End\n", + ">> MatMul2D - Start\n", + " Key Read Time = 0 milliseconds\n", + " Compute Time = 0.307 milliseconds\n", + " Eigen Time = 0.307 milliseconds\n", + " Reconstruct Time = 2.371 milliseconds\n", + " Online Time = 2.678 milliseconds\n", + " Online Comm = 92800 bytes\n", + ">> MatMul2D - End\n", + ">> Truncate (stochastic) - Start\n", + " Key Read Time = 0 milliseconds\n", + " Compute Time = 2.006 milliseconds\n", + " Eigen Time = 2.006 milliseconds\n", + " Reconstruct Time = 3.643 milliseconds\n", + " Online Time = 5.649 milliseconds\n", + " Online Comm = 92800 bytes\n", + ">> MatMul2D - End\n", + ">> Truncate (stochastic) - Start\n", + " Key Read Time = 273 milliseconds\n", + " Compute Time = 21.954 milliseconds\n", + " Reconstruct Time = 0.848 milliseconds\n", + " Online Time = 22.802 milliseconds\n", + " Online Comm = 92800 bytes\n", + " Key Read Time = 385 milliseconds\n", + " Compute Time = 19.674 milliseconds\n", + " Reconstruct Time = 3.202 milliseconds\n", + " Online Time = 22.876 milliseconds\n", + " Online Comm = 92800 bytes\n", + ">> Truncate - End\n", + ">> Truncate - End\n", + "\n", + "=== COMPUTATION END ===\n", + "\n", + "Offline Communication = 175698065 bytes\n", + "Offline Time = 105.018 milliseconds\n", + "Online Rounds = 14\n", + "Online Communication = 90665623 bytes\n", + "Online Time = 16477.9 milliseconds\n", + "Total Eigen Time = 15679.2 milliseconds\n", + "\n", + "Conv + Matmul Time = 15690.5 milliseconds\n", + "Relu time = 436.303 milliseconds\n", + "ReluTruncate time = 0 milliseconds\n", + "MaxPool time = 0 milliseconds\n", + "Select/Bit operations Time = 0 milliseconds\n", + "Truncate time = 269.241 milliseconds\n", + "Total Time (including Key Read) = 30737.9 milliseconds\n", + "\n", + "Conv Online Communication = 0 bytes\n", + "MatMul Online Communication = 1052800 bytes\n", + "Select Online Communication = 0 bytes\n", + "ReLU Online Communication = 1080000 bytes\n", + "RT Online Communication = 0 bytes\n", + "ARS Online Communication = 1052800 bytes\n", + "=========\n", + "0.0266418 -0.00817871 -0.0128479 0.0353394 -0.00326538 -0.0509949 0.0522461 -0.0682068 -0.0409851 0.0514221 -0.0707703 0.0252991 -0.0206909 -0.0411682 0.0562744 -0.0579224 -0.0311279 0.00283813 0.072113 -0.0614014 0.0541077 -0.0105896 -0.0317993 -0.0407715 0.019104 0.0153503 -0.0334778 0.0327759 0.0354004 -0.0187683 -0.0229187 -0.0093689 0.0735779 -0.0576782 0.044281 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419617 -0.0657043 0.0629272 0.0842896 -0.0355225 0.0279846 0.00308228 0.0389404 -0.0274353 0.0319214 0.0578918 -0.0379639 -0.044342 0.048584 -0.066925 -0.0480957 -0.03302 0.0686951 0.0521851\n", + "0.0266418 -0.00817871 -0.0128174 0.0353394 -0.00326538 -0.0509644 0.0522461 -0.0682373 -0.0409851 0.0514526 -0.0707703 0.0253296 -0.0206909 -0.0411682 0.0562744 -0.0579224 -0.0311279 0.00283813 0.072113 -0.0614014 0.0541382 -0.0105896 -0.0317993 -0.0408325 0.019104 0.0153503 -0.0334778 0.0327454 0.0354004 -0.0187683 -0.0229187 -0.0093689 0.0735779 -0.0576782 0.0442505 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419617 -0.0657349 0.0629272 0.0842896 -0.0355225 0.0279846 0.00311279 0.0389404 -0.0274353 0.0318909 0.0578918 -0.0379944 -0.0443726 0.0485535 -0.066925 -0.0480957 -0.03302 0.0686646 0.0521851\n", + "0.0266113 -0.00817871 -0.0128174 0.0353394 -0.0032959 -0.0509949 0.0522461 -0.0682373 -0.0410156 0.0514221 -0.0708008 0.0252991 -0.0206604 -0.0411682 0.0562744 -0.0579224 -0.0310974 0.00286865 0.0720825 -0.0614014 0.0541077 -0.0105896 -0.0318298 -0.040802 0.0190735 0.0153809 -0.0334778 0.0327759 0.0354004 -0.0187683 -0.0229187 -0.0093689 0.0735779 -0.0576782 0.044281 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419617 -0.0657349 0.0629578 0.0842896 -0.0355225 0.0279541 0.00311279 0.0389099 -0.0274353 0.0318909 0.0579224 -0.0379639 -0.044342 0.0485535 -0.066925 -0.0480957 -0.0329895 0.0686646 0.0521851\n", + "0.0266113 -0.00817871 -0.0127869 0.0353699 -0.00326538 -0.0509949 0.0522461 -0.0682373 -0.0409851 0.0514526 -0.0707703 0.0253296 -0.0206604 -0.0411682 0.0562744 -0.0579224 -0.0311279 0.00283813 0.072113 -0.0614014 0.0541077 -0.0105896 -0.0318298 -0.040802 0.019104 0.0153503 -0.0334778 0.0327759 0.0354309 -0.0187378 -0.0229492 -0.00939941 0.0735474 -0.0577087 0.0442505 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419922 -0.0657349 0.0629578 0.0842896 -0.035553 0.0279846 0.00308228 0.0389099 -0.0274353 0.0319214 0.0578918 -0.0379639 -0.0443726 0.0485535 -0.066925 -0.0480652 -0.0329895 0.0686951 0.0521851\n", + "0.0266418 -0.00817871 -0.0128174 0.0353699 -0.00326538 -0.0509949 0.0522156 -0.0682068 -0.0409546 0.0514221 -0.0707703 0.0252991 -0.0206604 -0.0411987 0.0562744 -0.0579224 -0.0311279 0.00286865 0.072113 -0.0614014 0.0541382 -0.0106201 -0.0318298 -0.040802 0.019104 0.0153503 -0.0334778 0.0327454 0.0354309 -0.0187683 -0.0229187 -0.00939941 0.0735779 -0.0576782 0.0442505 -0.0138245 -0.0473938 -0.0126953 0.0796204 0.0419922 -0.0657043 0.0629272 0.0842896 -0.0355225 0.0279541 0.00311279 0.0389099 -0.0274353 0.0318909 0.0578918 -0.0379639 -0.044342 0.0485535 -0.066925 -0.0480652 -0.0329895 0.0686646 0.0521851\n", + "0.0266113 -0.00817871 -0.0128174 0.0353394 -0.00326538 -0.0509644 0.0522766 -0.0682373 -0.0409851 0.0514221 -0.0707703 0.0253296 -0.0206909 -0.0411682 0.0562439 -0.0579529 -0.0311279 0.00283813 0.072113 -0.0614014 0.0541382 -0.0105591 -0.0318298 -0.040802 0.019104 0.0153198 -0.0334778 0.0327759 0.0354004 -0.0187378 -0.0229187 -0.0093689 0.0735474 -0.0577087 0.0442505 -0.013855 -0.0474243 -0.0126953 0.0795898 0.0419617 -0.0657349 0.0629578 0.0842896 -0.0355225 0.0279846 0.00311279 0.0389099 -0.0274048 0.0319214 0.0578918 -0.0379639 -0.0443726 0.0485535 -0.066925 -0.0480957 -0.0329895 0.0686646 0.0521851\n", + "0.0266418 -0.00817871 -0.0128174 0.0353394 -0.00326538 -0.0509949 0.0522461 -0.0682373 -0.0409851 0.0514526 -0.0707703 0.0253296 -0.0206909 -0.0411377 0.0562744 -0.0579224 -0.0310974 0.00286865 0.072113 -0.0614014 0.0541077 -0.0105896 -0.0318298 -0.040802 0.019104 0.0153503 -0.0334778 0.0327759 0.0354309 -0.0187683 -0.0229492 -0.0093689 0.0735474 -0.0577087 0.0442505 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419617 -0.0657349 0.0629578 0.0842896 -0.035553 0.0279846 0.00311279 0.0389099 -0.0274353 0.0318909 0.0578918 -0.0379639 -0.0443726 0.0485535 -0.0668945 -0.0480652 -0.03302 0.0686646 0.0521851\n", + "-0.0259399 -0.0109253 0.0563965 -0.0889893 0.117126 -0.149475 0.131805 0.0785217 0.104279 0.112671 -0.0197144 0.0680847 -0.130066 -0.0329895 0.10376 0.0275574 -0.0877686 0.0688782 0.0746765 -0.0182495 0.0372009 -0.0426941 -0.0925903 -0.120728 0.0337219 0.111542 -0.0252686 0.00942993 0.122009 -0.0396729 -0.0662231 -0.0136108 0.0163574 -0.122681 0.0671997 -0.0255432 -0.123016 0.0229187 0.0887756 0.105011 -0.0513916 0.100403 -0.00939941 -0.0405579 0.106018 -0.128998 0.0706482 -0.118134 0.0464783 0.0854797 -0.0417175 -0.0112 0.0650024 -0.0338135 -0.0401001 -0.0689697 0.0786743 0.0635681\n", + "0.0266418 -0.00817871 -0.0128479 0.0353699 -0.00326538 -0.0509644 0.0522461 -0.0682068 -0.0409851 0.0514221 -0.0707703 0.0252991 -0.0206604 -0.0411682 0.0562439 -0.0579529 -0.0311279 0.00283813 0.072113 -0.0614014 0.0541382 -0.0105896 -0.0317993 -0.0407715 0.019104 0.0153503 -0.0334778 0.0327759 0.0354309 -0.0187378 -0.0229492 -0.00939941 0.0735474 -0.0576782 0.044281 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419617 -0.0657043 0.0629272 0.0842896 -0.035553 0.0279846 0.00311279 0.0389099 -0.0274048 0.0318909 0.0578918 -0.0379944 -0.0443726 0.048584 -0.0669556 -0.0480957 -0.0329895 0.0686646 0.0521851\n", + "-0.122894 -0.0586243 0.0380859 -0.126312 0.126648 -0.00354004 0.101074 -0.016571 -0.113159 -0.0534363 -0.0547485 0.2742 0.0305481 0.0601807 0.161255 0.0493469 -0.0957947 0.058197 0.0684509 -0.16037 -0.0379333 -0.0413208 0.0427856 -0.0100403 -0.0192261 -0.0779724 -0.0408325 -0.0171204 0.0888062 0.0143738 0.0786438 -0.041687 0.314056 -0.143463 -0.0276489 -0.0110168 -0.0216675 0.0603333 0.0444946 -0.0105896 -0.0858765 0.0359497 0.142975 0.0201111 0.138428 0.0213623 0.0669556 0.0817261 -0.0494385 0.222626 -0.145966 -0.00927734 0.0391846 -0.143005 -0.200928 -0.287537 -0.0824585 -0.128326\n", + "0.0221863 0.00479126 -0.138977 0.0555725 0.0161743 0.0366821 0.0736694 -0.0992126 -0.0603027 0.0184937 -0.00244141 0.0750427 -0.0710449 0.0868835 -0.0746155 -0.105377 0.0144958 -0.0147095 -0.0300293 -0.0161438 0.00311279 0.0223389 -0.039032 -0.0682983 -0.0088501 -0.085083 -0.000183105 -0.0992737 0.118469 -0.0324097 -0.0780945 0.0239258 0.0202637 -0.0195923 0.0545654 0.0775146 -0.141327 0.0209656 -0.00704956 0.129486 0.0830994 0.0812378 0.00888062 -0.113739 0.115845 -0.0276794 0.0158081 -0.00186157 -0.0204468 -0.0780945 0.00634766 0.0641479 0.117126 0.055603 -0.0427246 0.0222778 0.169678 -0.0682678\n", + "-0.040741 -0.107635 -0.0612793 -0.0447083 0.0645447 0.0189514 0.138977 -0.122894 -0.0820312 0.104797 0.0218506 0.143982 -0.0093689 0.0180054 -0.0833435 -0.0641785 0.0543823 0.0693359 0.0860291 0.0538025 0.0050354 -0.052063 0.0263672 -0.012146 0.0184021 -0.134888 -0.131989 -0.0561218 0.0609131 -0.0518799 0.0104065 0.0426941 0.00588989 0.0111694 -0.0397339 -0.0223083 -0.233185 -0.0983887 0.0810547 0.0714417 0.175903 0.184906 -0.109436 -0.0217896 0.263672 -0.0536194 0.0660706 -0.0929565 0.111969 -0.123749 -0.0736084 0.0878601 0.186035 0.0528564 0.00125122 -0.143066 0.226715 -0.0306702\n", + "0.040863 -0.0387268 0.256714 -0.334351 -0.0496826 0.187286 0.392395 -0.081543 0.0529785 0.118683 0.426697 0.307526 -0.115082 0.079834 0.10321 0.0753479 0.0438538 0.0186768 -0.0457153 0.107544 -0.149963 -0.0855103 0.304504 -0.0532532 0.103088 -0.216827 0.00112915 -0.066864 -0.0836182 -0.151489 0.0703125 -0.091095 0.148132 -0.168274 0.0115967 -0.0925293 0.0274658 -0.233856 -0.151764 -0.0227966 -0.349976 -0.121429 0.0439758 -0.0281677 0.290131 0.222137 0.352386 0.354126 0.115448 0.0477905 0.0303345 -0.098877 0.126343 -0.17157 -0.118317 -0.489044 0.00979614 -0.118439\n", + "0.0254822 -0.0438538 -0.0218506 0.0342102 -0.00881958 -0.0495911 0.0771179 -0.0574951 -0.0491943 0.0769958 -0.0783691 0.0458069 -0.019165 -0.0317078 -0.00314331 -0.0292664 -0.0402222 -0.00332642 0.0855713 -0.0421753 0.039032 -0.0153809 -0.0376892 -0.048645 0.041626 -0.00735474 -0.0400696 0.0122681 0.043396 0.0178528 -0.0547791 -0.0121765 0.0380249 -0.0142517 0.0267639 -0.00338745 -0.0598145 -0.0451965 0.0628052 0.101105 -0.0305176 0.0854492 0.0488586 -0.0272827 0.0531311 -0.0153809 0.0554199 -0.0418091 0.0184937 0.0498352 -0.0465088 -0.0313721 0.0896912 -0.0859985 -0.0292358 -0.0444336 0.104706 0.0406799\n", + "0.174316 -0.445709 -0.0886841 -0.48172 0.442841 0.506561 -0.183105 0.208954 -0.295746 0.24057 0.267822 0.854675 -0.173737 0.292755 0.146332 0.140381 0.131256 0.297089 0.0712585 0.427582 -0.123932 -0.287079 0.575287 0.209106 -0.0656128 -0.474396 -0.100189 -0.527222 0.503235 0.455872 0.357513 -0.352173 0.641174 -0.266754 -0.418732 -0.318665 -0.533691 -0.884247 -0.593292 0.339355 -0.108978 0.55899 -0.065094 -0.349884 0.467712 -0.148193 0.985474 0.880615 -0.247009 0.500702 -0.108307 1.14313 0.588318 -0.0969849 -0.431763 -1.0925 -0.236755 -0.674622\n", + "0.0264587 -0.00750732 -0.013031 0.0362549 -0.00393677 -0.0513611 0.0523071 -0.0688477 -0.0416565 0.0506897 -0.0710144 0.0256653 -0.0200195 -0.0414124 0.0563965 -0.0576782 -0.0307007 0.00247192 0.0720825 -0.0613708 0.0531616 -0.010376 -0.0323486 -0.0411682 0.019043 0.0156555 -0.0328064 0.0336304 0.0352173 -0.0187378 -0.0232849 -0.0102234 0.0736389 -0.0579834 0.0439453 -0.0147705 -0.0473633 -0.0133057 0.0793457 0.0423889 -0.0648804 0.0631409 0.0839233 -0.0352783 0.0281677 0.00317383 0.0387878 -0.0279541 0.0311279 0.0580139 -0.0381165 -0.0452271 0.0482483 -0.0670166 -0.0483704 -0.0332336 0.0694885 0.0528564\n", + "0.342743 0.153717 -0.0464172 -0.0662231 -0.251923 0.0216675 0.196045 -0.128021 -0.290619 0.664337 0.99411 -0.420685 -0.858063 -0.0649109 -0.354126 -0.0072937 -0.548401 -0.605408 -0.819336 0.300537 0.259369 -0.13147 -0.0720825 0.0197449 0.446228 0.616852 -0.101715 -0.367523 0.181915 0.273926 -0.0655212 0.369141 -0.343079 -0.661255 0.339722 -0.0953064 0.197571 -0.517853 -0.293549 0.365082 -0.309113 -0.318726 0.264252 -0.538879 -0.978455 -0.114166 0.0864868 0.219635 -0.121979 -0.946991 0.259186 -0.0222473 -0.0553284 -0.472046 -0.215668 -0.355469 0.383545 0.869049\n", + "-0.0429077 0.0159607 -0.00558472 0.147156 -0.0743408 -0.0480347 0.103607 -0.196899 -0.094574 0.0136414 -0.00302124 0.127319 -0.0770264 -0.0684509 0.0738525 -0.134674 -0.112671 -0.0735168 -0.0589905 0.0186157 0.133484 0.0131836 -0.0617981 -0.131195 0.0489502 0.0606384 -0.105499 -0.0222168 -0.0761108 -0.0916443 -0.107452 0.092041 -0.0741272 0.0262146 0.295502 0.101227 -0.00344849 0.149963 0.100464 -0.00408936 0.00827026 0.0741272 0.0495605 -0.237671 0.0238647 -0.158081 -0.115448 -0.0516968 0.0631104 -0.0755005 0.102905 -0.126007 0.0168457 -0.107513 0.0242004 0.103668 0.226807 0.00695801\n", + "-1.02866 -0.0976257 -0.254974 -0.425232 0.886993 0.230988 -0.0450134 -0.219086 -0.738281 0.159546 0.372894 0.657288 -0.222595 0.777893 0.102844 -0.0728455 -0.172943 -0.568604 -0.578369 -0.445099 0.420807 0.0827637 0.162109 -0.210968 0.16272 0.279449 0.58725 0.0171509 -0.585907 0.162354 -0.443665 -0.154175 0.470123 0.325012 0.188446 -0.401642 -0.623016 -0.295166 0.334198 -0.507568 0.0914307 -0.285889 -0.51358 0.0238037 0.871002 0.59024 0.621155 -0.346527 0.647461 0.89389 -0.151001 0.235809 0.32373 -0.147308 -0.224243 -0.812439 0.152252 -0.631805\n", + "-0.602753 -0.0124817 0.0615845 -0.120605 0.0194702 0.0451355 0.0932617 -0.242493 -0.0588684 0.00527954 -0.127808 0.570251 0.5578 0.0404053 0.0679626 -0.0767212 0.170471 0.461365 0.244476 -0.27829 -0.00946045 0.0948486 0.0724182 -0.49765 -0.375702 -0.017334 -0.0534363 -0.293091 -0.138123 0.257629 0.258484 -0.533386 0.137604 -0.175323 0.0611572 -0.214722 -0.443024 0.84967 0.147675 0.294037 0.360443 0.119873 -0.251343 0.213715 0.669891 -0.253876 -0.460968 -0.205841 -0.2229 0.00137329 -0.11673 -0.00891113 -0.140961 -0.348145 -0.0636292 -0.286804 0.0700073 -0.131165\n", + "-0.0603638 0.0778503 -0.197571 0.0309753 0.143707 -0.300934 0.0289612 -0.191864 0.404602 0.203186 0.194794 -0.360229 -0.181915 -0.245453 -0.243896 -0.109589 0.0858765 -0.00741577 -0.0888062 -0.203094 -0.0256653 -0.229034 -0.122406 0.312836 0.179413 0.407776 -0.0660095 -0.203857 0.181915 0.717407 -0.00128174 -0.266632 -0.213593 -0.164246 0.101654 -0.0751648 -0.0957031 0.310547 -0.520264 0.330811 0.152802 0.195526 -0.136078 -0.217804 -0.0537109 -0.362152 -0.271118 -0.247681 0.107941 -0.27179 0.111755 0.176697 0.188721 0.0145264 -0.0342407 -0.131348 -0.042572 0.0422058\n", + "-0.750916 -0.0487671 0.903046 0.658752 -0.0806885 -0.444458 0.740295 0.766632 0.664307 -0.51651 1.24176 0.568115 -0.634644 1.23636 0.0353394 -0.111053 -0.527985 -0.514191 -0.327301 -0.144073 0.00991821 0.652924 0.39502 -0.0464478 0.179871 0.23645 0.50827 -0.0482788 -0.489197 -0.741486 -0.125214 0.361023 0.410156 -0.940918 0.593536 -0.491547 -0.00405884 -0.0639343 0.907104 -1.06378 -0.00280762 -0.0102539 -0.0261841 -0.146851 0.224792 0.0588379 0.13269 0.0771179 0.0172119 -0.606323 0.0652161 -0.332306 -0.0614014 0.360413 -0.254669 -0.545166 0.0483398 0.211548\n", + "-0.205017 -0.0985107 0.0665894 -0.178131 0.207214 -0.312653 0.154602 0.268555 -0.0191345 -0.115631 -0.131866 0.666534 -0.0229797 0.253906 0.133545 0.0012207 -0.247528 0.117859 0.0621338 -0.0340576 0.210083 0.168457 -0.151276 -0.170349 -0.199524 0.379761 0.0483093 0.304108 0.00845337 -0.0248718 0.438293 -0.0310669 0.0144653 -0.280975 0.161804 -0.332367 -0.2099 -0.0492554 0.389893 -0.110016 0.078064 0.272491 0.209686 -0.352905 0.477905 -0.233673 0.113983 -0.265869 -0.102203 -0.0435181 0.3862 0.165985 0.170197 -0.227234 0.0272827 0.0975952 0.114746 -0.0321655\n", + "-0.582642 0.67041 -0.0322571 0.116272 1.19791 -0.205872 0.225159 -0.134125 -0.178894 -0.203339 0.423431 -0.00613403 0.152344 0.98468 -1.24826 -0.624054 0.513519 -0.541443 -0.629791 -1.28491 -0.444458 -0.69931 -0.68457 0.635498 0.845978 0.900085 -0.100586 -0.657928 -0.414642 0.298676 -0.510681 -0.0200195 0.0105286 -0.041626 0.0451965 0.276093 0.339874 0.929382 -0.24939 0.0290527 0.471619 -0.143829 -0.385132 -0.397491 0.130951 -0.0678101 -0.593903 -0.276154 -0.568207 -1.43109 0.0110779 0.599823 0.229156 1.17923 -0.91272 1.18469 0.0517578 -0.237091\n", + "0.0597534 -0.109802 -0.143097 -0.0230103 0.0786133 0.1073 0.0313416 -0.122253 -0.0501709 0.132874 -0.019043 0.453613 -0.127258 0.0997009 0.105194 -0.0649414 0.0441895 -0.0993958 0.0849915 0.103729 0.126831 -0.11026 0.0389099 -0.102844 -0.122284 0.0844421 -0.126556 -0.036377 -0.119385 -0.0935669 -0.118164 0.0431824 0.136047 -0.0293579 0.202332 -0.0483398 -0.101227 0.0644226 0.0966797 -0.0491028 -0.00369263 0.207184 -0.0348511 -0.20816 0.085144 -0.106018 -0.0394897 0.0171814 0.00549316 -0.0153503 0.157349 -0.0377197 0.0357971 0.073761 -0.0307007 0.0531921 0.0601501 -0.0369568\n", + "0.380432 0.398651 -1.14279 -0.232574 0.0794373 0.128052 0.484192 0.0706787 -0.443756 0.0542908 1.26785 1.54419 -1.45401 0.300385 -0.185913 0.597076 -0.569427 0.198364 -0.872559 0.612061 0.535217 0.75235 0.482819 0.855072 1.02612 0.214294 0.551727 -0.652466 0.26123 -0.211121 -0.233826 0.810516 -0.158295 -0.632782 0.175507 -0.772522 0.249268 -1.06351 -0.0419922 -0.812805 -0.15979 0.637665 -1.39291 -0.260132 -0.0403442 0.788422 1.07138 0.539948 0.286652 -0.659424 -1.01105 -0.94873 0.0640564 0.720581 -0.975128 -1.29858 -0.0618286 -0.405212\n", + "-0.115845 -0.230988 0.137329 -0.110199 0.131165 0.364136 0.0540771 -0.153961 -0.229065 0.0796814 0.342712 0.543854 -0.0478516 0.263428 0.0235291 -0.442841 0.118103 0.0595398 0.135834 0.0178528 0.619537 -0.213379 0.150604 -0.453583 -0.5065 -0.283936 -0.301758 -0.374146 -0.249176 -0.408966 -0.184235 0.0506897 0.217865 -0.0574341 -0.119537 0.222046 -0.440308 0.237244 0.268127 0.141296 0.302032 0.0690918 0.14444 -0.0918884 0.0765686 -0.276245 -0.269958 0.0702515 -0.145172 -0.653748 0.14978 0.382629 -0.244507 0.118042 -0.187988 0.139984 0.359558 -0.322296\n", + "-1.62271 0.13501 0.0909424 0.408936 1.03387 1.56638 0.838806 0.580658 -1.32892 -2.10086 0.866821 3.16425 0.812317 1.23462 0.630402 -2.3252 0.233673 0.0344849 -0.2854 -1.1619 0.692596 -0.472839 -0.174652 -1.59363 -1.67761 -0.607697 -0.596375 -1.36133 -1.34854 -1.11551 -0.376953 0.0332642 1.92749 -1.155 -0.276276 0.263336 -1.70172 2.24213 1.85022 -1.42654 0.833344 0.466248 -0.774719 0.626495 2.12454 -0.0571594 -1.39404 -0.333557 -0.621033 -1.05209 0.323792 0.467285 -1.2428 1.55396 -0.604858 -1.21335 1.42618 -0.920502\n", + "0.020813 0.0558167 -0.0653992 -0.760925 -0.194092 -0.121002 0.225677 -0.493927 -0.367065 0.141693 0.196289 0.500305 -0.0735779 0.0680847 -0.56543 0.265442 -0.639374 -0.0039978 -0.0158997 0.64032 -0.569458 0.134583 -0.0141602 0.460449 -0.0447083 -0.246033 -0.420135 -0.178406 0.328247 -0.343628 0.847626 -0.0289917 -0.153748 -0.77243 0.409119 -0.196136 0.263031 -0.278473 0.514832 -0.246094 -0.0652771 0.0288696 -0.603485 -0.570862 0.0439148 -0.0132446 0.886383 0.642487 0.265015 -0.604797 -0.442871 0.323944 0.348083 0.568451 0.272552 -0.460297 0.525696 -0.184479\n", + "0.826752 -0.407928 0.673187 -1.60809 0.784058 -0.214966 0.666412 0.255829 -0.158844 1.06934 0.17392 0.522675 -0.523346 0.495697 -0.673004 0.477173 -1.85083 -0.117065 -0.518738 0.842316 -1.25125 0.208557 -0.210968 1.59207 0.472351 -0.166351 0.420349 0.160553 0.501617 1.10944 0.496735 -0.694305 0.646576 -0.702423 0.0134888 -1.17978 0.269684 -1.19586 -0.982483 0.156006 -0.878937 -0.744232 -0.408752 0.133331 0.332642 -0.4729 1.59857 0.561127 0.223175 -0.0245667 -0.955627 0.361725 1.1474 0.0561829 0.250885 -1.93811 -0.379181 0.425781\n", + "-0.591644 -0.602173 0.0716553 0.142731 -0.0722961 -1.04166 -0.298218 1.08139 -0.456909 -0.614136 -0.234039 2.0766 0.193085 1.07224 0.329926 -0.820007 -0.422821 0.355255 0.80072 0.975739 0.22702 -0.526337 0.561951 -0.872192 -0.153259 -0.244781 -0.555786 -0.393799 -0.94455 -0.563629 0.265625 0.104736 -0.177216 -0.302795 -0.371643 -0.317871 -0.858398 -0.799561 1.55957 -0.331818 0.152679 1.10995 -1.49759 0.0845947 1.44171 -0.049469 0.303436 -0.544037 0.332947 -0.343872 0.677185 0.551117 -0.658539 0.262573 0.228516 -0.34787 0.772736 -0.118378\n", + "-0.152924 -1.09735 0.208008 -0.487091 0.869476 0.0929565 -0.613861 1.05887 0.442474 0.459351 0.743988 1.93195 -1.06107 -0.0600586 1.08597 -1.08069 -0.393768 1.2345 0.604279 0.324005 0.215546 0.227722 0.724457 -0.0129395 -0.0289917 -0.747345 0.394104 0.0739746 0.143036 1.07962 0.687012 -0.409363 0.569427 -0.301727 -0.67627 -1.3176 -1.59897 -1.2659 -0.983276 0.789154 -0.574127 -0.01297 0.0525818 0.341217 2.19171 -0.71991 0.248505 -0.696014 -0.306488 0.466675 0.720123 0.743469 -0.451294 -0.723328 -0.577332 -1.58871 -0.223236 -0.166107\n", + "0.745544 -0.502441 -0.619263 -0.196198 0.366058 1.08118 -0.298218 -0.613983 -1.72354 0.106689 1.41656 1.83121 -0.252625 1.58633 0.00695801 -1.85239 -0.365814 0.279419 -0.537384 0.644104 1.35291 0.272308 1.07617 0.219574 0.173431 -0.780884 -0.236206 0.0657959 -1.06763 0.373627 -0.662842 0.870178 1.3443 -1.1022 0.542419 -0.257843 0.210968 -0.179901 -0.189423 -1.39352 -0.6297 -1.40286 1.94427 -0.510742 0.471893 0.552826 -0.274536 1.12073 0.00704956 -0.540314 0.311005 0.00622559 -0.523193 0.220795 -1.53989 -2.03922 -0.114624 -0.405273\n", + "-0.0599365 -0.397308 -0.157776 -0.0528564 -0.0184021 -0.0185242 0.00662231 -0.44928 -0.2854 0.358582 0.417786 0.67041 -0.396057 0.296814 0.0687561 -0.256104 -0.109741 -0.524292 -0.138092 0.55899 0.257141 0.0899353 0.257202 0.0774231 0.329041 0.0707703 -0.256073 0.376038 -0.423187 -0.0961609 0.0953369 0.259003 -0.104004 0.384674 0.914032 -0.127258 -0.0405884 -0.564911 0.0375977 -0.639343 -0.243408 0.148407 0.484863 -0.688934 0.389191 -0.561432 -0.178711 -0.0574646 0.465973 0.16861 0.970276 -0.0760803 0.00817871 -0.255768 -0.263397 -0.180511 0.16983 0.24408\n", + "0.24472 0.0957642 2.67206 -0.952606 0.621918 0.411743 -0.460632 0.48526 -0.206909 -0.404633 0.90863 -1.05396 -0.581177 0.208649 -0.532349 0.158875 -0.877136 0.207672 -0.765533 0.133636 -1.10703 -0.09375 -0.176727 0.571716 0.924408 -0.153503 -0.171112 -0.27417 -0.281067 -0.00741577 0.67807 -1.05978 -0.196564 -0.852631 -0.992126 -1.3912 -0.864899 -1.41693 -0.270599 0.104462 0.232391 -0.971436 -0.351471 0.458832 0.504028 -0.133026 1.72675 1.17331 0.319611 -0.154022 -1.16837 2.23978 0.677826 0.577545 0.348602 -2.35046 -0.167114 0.752197\n", + "-0.0480347 0.000213623 -0.0117188 -0.0315552 0.116425 -0.110352 -0.00363159 -0.0552368 -0.163391 -0.102966 0.0288696 0.488556 0.0656128 -0.299835 0.211456 -0.208099 -0.0415955 0.217194 0.0225525 -0.0501709 -0.0372314 -0.301361 -0.265747 -0.283295 0.341217 0.11499 -0.33313 0.283203 0.138885 -0.289856 0.24057 0.172882 -0.206909 -0.266846 0.106384 -0.369385 -0.167389 0.198883 0.149445 -0.121826 -0.0722046 0.182861 -0.175781 -0.494202 -0.0227966 -0.259216 -0.372742 0.122284 0.251801 0.123199 0.181061 -0.16983 0.0758057 0.146973 0.0983582 0.211243 0.263367 0.0970154\n", + "-0.0834656 0.225952 -1.02905 0.0181274 0.690521 -1.01239 -0.574829 1.43347 -1.52451 -1.23575 -0.27829 4.88651 1.47855 1.32779 0.906738 -2.32883 0.556946 0.812408 0.667267 1.91284 0.689392 -0.785034 1.20865 -1.34903 -0.821411 -0.741089 -1.60861 -0.713715 -0.743988 0.221832 -0.0478516 0.31897 -0.0840149 -1.55023 -0.658722 -0.128448 -3.17996 -0.35498 2.40991 -0.377045 0.952301 1.56116 -2.81924 -0.298859 2.79187 0.379089 -0.0800171 -1.60413 0.662445 0.258423 0.16217 0.170929 -0.165131 2.08334 -0.308136 -2.13217 2.06497 -0.130981\n", + "0.0681763 0.346771 -0.211273 -0.148987 0.112915 -0.236023 0.0468445 -0.0589294 -0.00415039 0.0732422 0.619171 -0.364471 -0.534729 0.0256958 -0.184845 0.120605 -0.173309 -0.0875854 -0.402191 -0.0592346 0.259979 0.412292 -0.360901 0.384186 0.50473 0.372406 0.298279 -0.0543518 0.372803 0.178925 -0.299316 -0.0473633 -0.431549 0.118378 -0.0454712 -0.106415 0.067749 -0.0884705 -0.327942 0.187347 -0.0620422 0.0366516 -0.16922 -0.218262 0.16684 0.153595 0.00387573 -0.138428 0.0461121 0.0672913 -0.124908 -0.266418 0.166138 0.146454 -0.103912 -0.187897 0.0633545 0.268555\n", + "-0.00997925 1.11591 0.317261 -2.69965 -1.00955 -1.51501 2.36917 0.323181 1.62482 -0.0479126 0.834198 -0.670166 -1.75323 -2.15421 0.649689 2.51105 -1.59106 0.0553589 -0.392334 1.37 -0.766418 -1.30392 -1.31876 -0.395966 -0.682373 1.38745 -1.15582 -0.381134 3.26532 1.30963 2.17264 -1.42374 -2.09531 -1.38455 0.434937 0.364685 0.821442 -0.68988 -1.25165 1.72223 -0.750671 0.956055 -0.307281 -1.53519 -1.97083 -1.02939 -0.746613 0.930115 -0.0252991 0.00332642 0.272125 0.511871 1.30042 -1.64636 2.13724 0.31781 -0.625336 1.34323\n", + "-0.297791 -0.0542297 -0.421967 0.377991 0.33136 -0.276672 -0.584595 -0.589386 -0.61087 0.089325 0.108276 1.55051 0.152466 -0.31958 -0.56311 -1.14154 0.46759 -0.0978394 -0.0210571 -0.273438 -0.0992432 -0.0896606 -0.181854 0.239166 -0.0159607 0.559845 0.0929871 0.0160828 -0.0780334 0.329193 -1.19391 0.456177 0.419342 0.134827 0.417358 0.215637 -0.904572 0.654877 0.206909 -0.490723 0.756378 0.880402 -0.431183 -0.639526 1.38986 -0.458832 -0.257294 -0.341492 -0.0736694 -0.0177002 0.14328 0.58609 0.213898 0.227386 0.0162964 -0.25885 0.131012 -0.534271\n", + "-1.07837 -2.76547 0.940796 -0.729126 3.11826 0.677246 -1.08603 2.66486 -3.05392 -0.840271 1.66382 4.35934 0.728119 2.46014 3.83932 -4.6106 -0.720123 0.853088 -1.25714 0.7742 1.36703 1.08792 0.258148 -2.40692 0.125763 -0.370117 0.324188 0.0307617 -3.09845 -0.555359 3.27686 -0.433197 0.768158 -0.330872 0.119568 -2.81259 -3.87338 -2.55499 1.81772 -1.29462 -0.677063 0.129822 -0.724213 0.238708 6.18018 -0.725708 2.29901 -0.713348 0.0305481 2.88123 4.07993 3.17639 -0.880188 -0.998779 0.550385 -6.078 1.58862 -0.791077\n", + "-0.352692 -0.123871 -0.140686 0.629395 -0.181274 -0.507294 -0.0348511 0.694122 0.0849609 -0.181335 0.509308 0.662842 -0.762207 0.34845 -0.111298 0.0539551 -0.118164 -0.159271 -0.269135 -0.332458 0.706512 0.362366 -0.0500183 -0.550354 0.380554 0.656769 0.409119 0.0969849 -0.261322 -0.124084 -0.421356 0.229858 -0.0316162 -0.237946 0.0209351 -0.412384 -0.30127 0.22998 0.286469 0.137421 -0.09198 0.33432 -0.155609 -0.387848 -0.0738831 -0.390228 -0.428528 -0.829102 0.116241 -0.484253 0.519897 -0.421021 -0.10968 -0.103424 -0.484741 0.29187 0.556793 0.333221\n", + "-0.162445 0.0309143 0.125549 -0.0300293 0.0450134 -1.13913 -0.0758667 0.275879 0.794281 0.0881042 0.380554 0.0776367 -0.933777 0.427887 -0.19986 0.154388 -0.594482 0.0630493 -0.650543 -0.012207 0.217621 -0.694641 0.0815125 -0.118408 1.10532 0.687561 -0.491455 -0.00396729 -0.158844 -0.0246887 -0.276917 0.192322 -0.363495 0.453033 0.381927 0.418457 0.388306 0.253693 0.44696 -0.814514 0.158539 0.274017 0.486603 -0.285004 -0.059021 -0.0265198 -0.458191 -0.589203 0.575958 -0.394592 0.453003 -0.183075 0.0177002 -0.622681 -0.22998 0.146179 -0.155975 0.0854492\n", + "0.079895 0.153564 -0.131256 -0.0319214 0.26416 0.155884 -0.161804 -0.324768 0.48056 -0.00808716 1.11765 -0.396973 -0.837555 -0.374847 -0.432983 0.612366 0.647095 0.160004 -0.150421 0.396759 -0.655365 -0.591919 -0.119141 0.65152 0.180359 0.567444 0.0383911 -0.313995 -0.0793762 0.350403 -0.548767 -0.223083 -0.900665 0.363403 -0.214539 -0.177673 -0.431244 -0.144073 -0.849945 -0.0571594 0.611542 1.03403 -0.827972 -0.548645 1.00226 -0.533691 -0.52887 -0.0626221 0.0395203 -0.377808 0.33139 0.812775 -0.253296 0.11673 0.20929 -0.436493 -0.0305481 -0.268433\n", + "-0.0627441 -0.202271 0.394012 -0.0518494 0.171661 0.359009 0.0279236 0.432312 -0.84433 -0.0555725 0.204254 1.52335 0.0863647 0.410248 0.178314 -0.158386 -0.364655 0.13913 -0.221771 -0.0316467 -0.229004 0.500793 0.593781 0.0852356 0.124359 -0.194336 0.226746 0.145874 -0.245056 -0.260254 0.22525 0.210419 0.951813 -0.580078 -0.0593262 -0.567352 0.24295 -0.728729 0.411987 -0.50116 -0.691711 -0.137939 -0.0970154 -0.459991 0.168732 0.536407 0.901733 0.608124 -0.247681 -0.0584717 -0.390686 0.273499 0.332764 -0.0638428 -0.600098 -0.61377 -0.153625 -0.305725\n", + "-0.792389 -0.803314 0.398102 2.13715 -0.910889 1.04382 -0.65918 0.722504 -1.43613 -1.52966 7.22067 0.763214 0.40567 0.995483 -2.25424 -3.10666 2.05148 -1.49142 -0.136749 0.377533 1.89157 -0.865662 0.394043 0.460602 0.234558 0.152039 -1.50177 -1.42294 -3.26114 -1.10718 -3.26883 2.55048 -1.39178 -4.60999 -0.371002 -0.0978699 -2.67279 1.96872 0.513184 -2.01129 1.86374 -1.56012 -2.2868 -1.0426 0.343842 -1.35406 -1.90848 -1.0343 -0.17395 -5.3721 0.730438 -0.585571 -2.34402 7.10355 -2.46097 -0.640778 3.4906 0.114929\n", + "0.0104675 -0.0874023 0.0974731 -0.0449829 -0.0600281 0.319855 0.206818 -0.0050354 0.204926 0.116547 0.392883 0.00308228 -0.495575 0.321289 -0.488922 0.175568 0.0588074 -0.164276 0.20929 -0.319336 0.0320129 0.574982 0.171844 -0.0144348 0.221039 0.0230713 -0.0635986 -0.0613098 -0.0340576 -0.0597839 0.202179 0.129639 0.0372314 -0.16922 -0.283325 -0.667816 -0.39917 -0.239288 -0.0992737 -0.0805054 -0.212524 0.13324 0.0897827 0.00366211 0.142059 0.085144 0.287994 0.0312805 -0.215576 -0.0093689 0.452087 -0.199158 -0.0496216 -0.203674 -0.313751 -0.254852 -0.15152 0.304932\n", + "1.34329 -1.28287 -1.12827 3.79785 -1.79947 0.647461 -0.528198 0.872894 1.60904 -0.615753 -0.829926 5.33163 -1.27249 3.46289 -2.61871 0.0675964 -2.08609 -0.188538 -1.01871 3.43811 -1.68066 -3.92615 3.53134 -3.07449 -0.546997 -3.25143 2.48495 -2.46268 -3.66678 -0.630096 -6.37961 0.920929 1.03818 0.284821 1.50647 3.54846 0.109436 0.241394 3.13211 0.0311279 5.35309 5.76132 -5.69952 0.395264 -1.57275 1.37912 -2.25897 -1.64563 2.53143 -5.8222 -3.64178 -1.07065 0.227264 2.05499 -0.0279541 -3.70917 4.30847 -1.87357\n", + "0.404785 -0.0836792 -0.0130005 -0.358673 0.372437 0.660767 -0.448303 0.209015 -0.779663 -0.0976562 0.639038 1.32236 -0.612823 0.132568 -0.49881 -0.404846 -0.053009 0.243225 -0.140045 0.644287 -0.432892 -0.462097 0.306274 0.244049 0.0644226 -0.113281 0.428711 0.267578 -0.29184 -0.0840454 -0.819366 -0.223022 0.372803 -0.219116 -0.0837708 -0.583893 -0.212585 -0.579529 -0.403381 -0.301331 -0.148468 0.034668 -0.884735 0.110291 0.493896 0.681824 0.679138 0.53598 0.0961304 0.117523 -0.621613 0.683929 0.738556 0.791168 -0.322906 -0.809479 0.530579 -0.735626\n", + "2.57928 -1.04907 3.24918 -3.22861 2.28308 -3.08331 -2.94229 4.28549 -1.7785 -1.68216 -0.634491 6.57773 -1.63971 -2.57605 1.61075 -0.791473 -7.32532 3.4346 -3.08353 -0.358307 -1.39688 4.26144 0.263733 2.6774 -0.256561 3.84384 2.97147 0.395355 4.24841 2.79126 4.30096 -4.90915 -0.884186 -1.32922 0.227325 -7.05237 1.11023 -1.02087 -1.16449 4.49664 -4.1109 -1.87335 -3.29999 -1.17505 3.04425 -1.9996 2.97501 -0.466309 -3.03323 0.799042 1.49243 0.720245 2.80359 -1.61151 2.36536 -0.23056 1.29117 2.41824\n", + "0.464752 -0.0552673 -0.969849 -0.379639 -0.0131836 0.106598 -0.59613 -0.784943 -0.956757 0.301086 0.606964 1.73239 -0.2659 -0.709137 -0.262695 -0.0877686 -0.297516 0.571167 -0.494446 0.42453 0.466797 -0.751038 0.200134 0.365356 -0.785583 0.331207 -0.142487 -0.401215 0.583893 0.498993 -0.70462 0.020752 0.230865 -0.30722 0.633728 0.0812988 -0.55423 0.285706 -0.706146 0.12561 0.15329 0.718689 -0.67453 -1.02264 -0.220825 -0.200226 -0.186218 0.455597 -0.0488281 -0.975311 -0.745758 0.653442 -0.0880432 0.427002 -0.132385 0.315887 0.291748 -0.5466\n", + "-0.349701 -0.984467 -1.50107 -3.62067 3.3129 3.44931 2.30103 -1.59415 -3.47668 4.11908 5.79288 4.38483 -7.1333 8.71185 -5.53717 -0.999634 -0.933716 -4.33572 -5.82562 -3.49008 3.83344 3.06989 0.00860596 4.00421 2.52966 -1.52396 4.39224 0.0692139 -2.42319 0.35022 -3.56467 1.78284 3.81573 6.6377 -3.78204 -3.53177 -1.99298 -3.60541 -3.17026 -4.19589 1.9053 -4.57309 3.0802 1.51938 6.68381 3.22186 9.87927 2.23587 0.529083 1.20386 -3.5105 1.49005 3.58292 -0.500549 -3.0267 -4.3931 0.647797 -7.03854\n", + "-0.290161 0.250153 0.690918 0.0443115 -0.920441 -0.750214 0.73941 0.178772 0.713074 0.12793 -0.936188 1.59717 -0.99411 -0.14209 -0.307739 0.738861 -1.14981 0.453766 0.217987 -0.542053 -0.465149 0.781189 0.386597 -1.41928 0.218231 0.29422 -0.0434875 0.715881 0.021698 0.266602 -0.184906 -1.52173 -0.433563 0.503906 0.186157 -0.992676 0.135925 0.294647 0.526764 0.624481 -0.485382 1.23364 -0.454254 -0.425079 0.403412 0.33136 -0.656158 -0.267273 -0.47403 -0.221802 -0.0628357 -1.21777 0.440857 -1.67603 1.34821 0.0334167 -0.142822 0.747253\n", + "-0.233459 -0.280518 0.14975 0.313324 -0.507965 -0.248047 0.249451 0.137146 -0.271362 -0.408875 -0.0521545 1.27454 0.0393372 0.185699 0.0946655 0.0571289 -0.215576 0.126312 0.182465 0.105835 0.226685 -0.152008 -0.101532 -0.661713 -0.449066 0.0214233 -0.193329 -0.0296021 0.126953 -0.611298 0.0100098 0.010437 -0.295105 -0.466064 -0.0827332 -0.268921 -0.217377 0.316467 0.432129 0.0915833 0.182495 0.577057 -0.183167 -0.636475 -0.364838 -0.383209 -0.363861 0.174866 -0.0255737 -0.547211 0.1008 -0.320282 0.22229 0.307007 0.175812 1.25931 0.653137 -0.299225\n", + "0.279846 -1.16803 -0.33255 0.655823 0.270081 -0.072937 0.0192566 0.178528 -0.0359192 0.646881 1.37521 0.972473 -1.22327 0.479004 -0.377625 -0.443939 0.48941 1.18347 0.0610962 0.921265 0.966461 0.827271 -0.101562 0.336578 1.90829 0.211975 -0.266174 0.70108 -0.488861 -0.348633 -0.813843 0.763885 -0.850464 0.0134583 -0.204681 -1.12814 -1.57031 -1.40936 0.0976868 -1.13181 -0.572388 0.150024 0.175995 -1.15738 1.58459 -0.50592 0.443115 -0.104187 0.76123 0.495667 0.953461 -0.260101 1.36896 0.0508118 -0.685303 -0.461975 0.472748 0.176117\n", + "0.364044 -0.11673 -0.16217 0.0873413 -0.0254517 0.572784 0.00457764 -0.126251 -0.433197 0.256195 0.243683 0.210999 -0.403625 -0.201752 -0.383179 -0.478119 -0.0983887 -0.545563 0.18338 -0.0863037 0.259216 -0.00216675 0.194702 0.513885 -0.229095 -0.143494 -0.126251 -0.367035 -0.0326843 0.180328 -0.408112 0.172668 0.61557 -0.0272217 -0.168396 -0.0761108 -0.325775 -0.29187 -0.207977 -0.0967102 -0.00360107 0.0433655 -0.185547 0.120361 0.101288 -0.0417786 0.507538 0.145935 -0.350983 -0.442535 -0.432037 0.203339 -0.119476 0.621704 -0.175354 -0.0480957 0.12558 -0.204102\n", + "-4.18976 -2.15021 1.30432 4.71851 0.316223 -1.0358 -2.76596 2.60397 -4.00879 -2.49783 -3.88272 6.12576 6.30438 4.25308 -1.96408 -7.57401 2.46304 1.43237 2.0076 -0.90918 0.774933 -8.27258 0.260864 -7.69278 3.05444 -2.50192 -4.94275 -3.50507 -7.01157 -6.836 -0.565521 4.61499 -2.91653 -1.6055 -1.07877 4.22363 -4.25534 2.18069 13.6614 -5.44159 3.8317 1.95255 -4.54453 -5.49881 2.05154 -4.23203 -6.11353 -1.76819 1.05444 -3.5708 5.97385 2.16995 -3.89539 4.34207 1.18945 7.16541 11.5857 -1.44257\n", + "-0.251007 -0.23999 0.0907898 0.37677 -0.789948 0.128326 0.367462 0.230499 0.201721 -0.15744 0.991608 -0.241821 -0.601746 0.276978 -0.447083 0.126678 0.25473 -0.344269 -0.140381 -0.248932 0.500061 0.211639 0.312164 -0.422119 0.025177 -0.0189819 -0.25589 -0.743469 -0.497375 -0.119049 -0.565918 0.271027 -0.353973 0.111694 -0.111603 -0.0343018 -0.655487 -0.0682678 0.626617 0.207092 0.255615 0.0359192 -0.074585 0.109161 0.0733643 0.163971 -0.465302 -0.265717 -0.194946 -0.882416 -0.0744019 -0.538116 -0.306671 0.135254 0.101379 -0.187836 0.554321 0.156158\n", + "1.78082 3.29858 1.40051 -4.3208 -1.57013 -2.40311 3.62238 -0.9151 3.29327 0.381378 1.65826 0.208282 -5.47647 -4.49625 0.550171 6.79865 -3.43661 -1.42984 -1.29715 2.1489 -3.03409 -2.65906 -1.43152 -0.628235 -2.04892 1.84805 -0.794098 -0.871643 8.38638 -0.605835 1.06735 -3.61374 -3.55383 1.03513 0.328552 1.05011 1.77292 0.314728 -3.58331 2.51358 0.763916 2.87424 0.396423 -1.62634 -2.53314 0.206329 -0.635803 1.44247 -0.261993 0.178497 -2.01465 -1.16446 2.55002 -3.39957 3.82147 0.810913 -1.16608 1.4556\n", + "-0.154938 -0.668518 0.0223389 0.188629 0.298584 -0.0791321 -0.418884 0.725983 0.124847 0.0571594 0.0874023 1.40341 0.118958 0.607025 0.0968628 -0.261261 -0.364166 0.473022 -0.250732 0.214294 -0.0818176 -0.530701 0.568634 -0.373138 0.601044 0.0871277 0.368713 0.0381775 -1.0499 0.103058 -0.513428 0.419342 0.130463 -0.274078 0.350067 -0.232758 -0.20224 -0.0462952 0.71228 -0.317719 0.109222 0.549469 -0.678284 -0.472046 0.389496 0.200073 0.0909729 -0.147339 0.622192 -0.118134 0.0678101 -0.0141296 0.263275 0.203522 -0.035675 -1.39487 0.425476 -0.754913\n", + "0.324036 -2.59756 -1.00558 -0.53183 3.59903 2.09775 -2.19473 -0.115417 -4.19873 -0.714294 0.903229 8.08517 1.24405 0.867615 2.78857 -5.47485 1.29633 0.691223 -0.170013 2.207 1.27814 -0.0498047 0.745575 -1.24988 0.0418701 -2.23856 0.397675 0.448486 -2.62283 -0.903229 0.920959 0.789337 1.61868 -0.10498 0.944305 -1.55115 -3.76102 -1.88477 -0.4664 -1.83575 -1.09918 1.43506 -0.868835 -0.109192 6.96436 -1.47934 0.0200195 -0.0190735 -1.18066 3.11383 4.01483 1.86725 -1.59503 1.49048 -2.42633 -5.23734 0.97406 -1.20486\n", + "0.0716553 0.105042 0.355072 -0.211273 0.596832 -0.725433 0.268341 1.68408 1.02744 0.0823669 0.141815 0.232727 -0.268799 -0.40387 0.536591 -0.584106 -0.943329 1.29367 -0.0310364 -0.202698 -0.251007 -0.579071 0.219604 0.00839233 -0.111877 1.18237 0.0269775 -0.193359 0.472382 1.23001 0.455475 -0.718231 -0.464417 -1.25995 0.0334473 -0.940033 -0.612823 -0.301788 -0.51297 1.05249 -0.109009 0.471497 -0.934753 -0.627502 -0.297821 -0.334747 0.368958 -0.60141 0.0742188 -0.599518 0.0855408 0.848633 0.495331 -0.364563 0.117462 -0.797058 0.173828 0.496857\n", + "0.195251 0.0027771 0.597534 -0.904327 0.0638123 -1.21124 -0.166107 0.736786 0.149567 -0.271088 0.682983 -0.697235 -0.823883 0.990723 -0.809662 0.945892 -1.30371 -0.199066 -1.0903 -0.547516 -0.1315 -0.202423 -0.689209 0.371674 1.45367 0.808136 0.207886 -0.0493469 0.516937 -0.65802 0.115784 0.439056 -0.384674 0.242523 -0.0957031 0.166504 1.09451 0.0159302 0.477081 0.0945435 0.094574 -0.582886 0.800568 -0.185364 -0.462402 0.0653076 0.462158 0.384674 -0.117004 -0.42691 -0.51712 0.123322 0.198669 -0.0711975 -0.0377197 0.533325 -0.0383606 -0.251251\n", + "0.870422 -1.71893 -1.19711 -0.304993 -0.16687 0.729462 -0.751404 0.270721 -0.605927 -0.561798 1.39423 3.55905 -0.924683 0.390228 -0.229767 -0.846771 -0.397522 0.613739 -0.65567 1.23819 1.06137 -0.741486 0.78006 -0.388123 0.0171204 -0.420807 0.196686 -0.920166 0.0435791 0.0263062 -0.96698 0.355804 0.660309 -0.582336 0.134796 -0.342957 -0.793457 -0.427673 -0.0650024 -0.212036 0.584473 0.68927 -1.14221 0.0220337 1.30997 0.166473 1.53534 1.14905 0.337921 -0.946411 -0.529022 0.521637 0.931976 0.508087 0.0103149 -1.7171 1.23199 -1.57013\n", + "-0.103638 0.047821 0.152954 0.0017395 -0.0967407 0.167816 0.579071 -0.456757 -0.703247 0.481812 0.557587 1.75128 -0.466583 1.12033 -0.400574 -0.368622 -0.541016 -0.74234 -0.630188 -0.431732 0.334412 0.0240173 0.830475 -0.267426 0.109039 -0.611572 0.41095 0.565186 -0.886536 0.113861 -0.588989 -0.22525 0.867523 0.853943 0.0455627 -0.446655 0.453186 -0.343414 -0.0935974 -0.819946 -0.334229 -0.453217 0.29834 0.0518799 0.569092 0.26004 0.295349 0.565857 0.284637 0.135101 0.0370483 -0.597626 0.184296 -0.610535 -0.640198 -0.597076 0.18573 -0.766205\n", + "0.504761 -0.814758 -0.439728 0.779541 0.14743 -0.22113 -0.732056 0.450836 -0.189758 0.0542297 2.8157 0.763916 -1.42169 -0.316589 -0.0619812 0.377106 0.539825 -0.0682983 -0.663025 0.719849 -0.196564 -0.157227 0.909515 0.394745 1.17004 1.1051 0.526703 0.268799 -0.484528 -0.303253 -1.37503 1.13998 -1.24194 -1.15814 0.762085 -0.532166 0.10611 -0.950928 -1.04321 0.154114 -0.323608 0.532013 -0.895233 -1.61566 0.00439453 0.0808716 -0.602203 -0.299316 -0.13501 -1.03595 1.38052 -0.70816 -0.478271 0.853394 -0.912292 -0.380371 0.646637 0.356018\n", + "-0.0307922 -0.188324 -0.183868 0.0914001 0.0119934 0.0293579 0.0515747 0.300812 0.0392151 -0.0205688 0.0651855 0.339508 -0.622742 0.267914 -0.325287 -0.00280762 -0.320374 0.200714 -0.074707 -0.199341 0.251343 0.645355 -0.051239 0.306915 0.426605 0.270782 0.514984 0.185181 0.092804 -0.00106812 -0.00778198 0.36084 0.307465 -0.206268 -0.0572815 -0.757812 -0.438202 -0.431488 0.098175 -0.261536 0.270508 0.305573 -0.44632 0.00823975 0.429413 0.0526428 1.05814 0.109344 0.0201721 0.153748 -0.258667 -0.0142822 0.27301 0.0938721 0.00430298 -0.494904 -0.0994263 -0.237213\n", + "-0.43454 0.749664 0.428986 -0.70462 0.222626 -0.497711 0.132141 0.655609 -0.0159607 -0.975525 0.74884 -1.01273 -0.595367 0.456879 -0.174072 0.350433 0.0593262 -0.150177 -0.678802 0.168823 -0.566223 -0.469666 -0.660248 -0.227539 0.426575 0.817535 -0.15744 0.283234 0.250336 -0.727142 -0.153503 -0.731018 0.316223 0.19873 -0.281799 0.341461 -0.019928 -0.117035 0.423126 -0.364899 0.243774 0.514954 0.296417 -0.425385 0.256683 -0.0461121 -0.0142212 -0.224457 -0.0508728 0.950562 0.114685 0.540833 0.0301208 -0.233704 0.831146 -0.317352 0.271515 0.26059\n", + "-0.239044 -0.320984 -0.0515442 0.027832 0.359314 0.313049 0.0908508 0.114441 -0.518616 -0.292023 0.806396 1.17679 0.354156 -0.093811 -0.185974 -0.694061 0.455109 0.394165 0.348755 -0.115448 0.388275 -0.0960388 0.0374451 -0.00228882 -0.30423 -0.256744 -0.613312 -0.16684 -0.274231 -0.183777 -0.0188904 -0.0885925 0.589874 -0.771881 -0.00445557 -0.323608 -0.655273 0.328735 0.127991 -0.303284 -0.0161133 0.059021 0.143219 -0.42691 0.827454 -0.636261 -0.53183 0.225647 -0.740387 -0.564789 0.402954 0.348267 -0.559052 0.672424 -0.35144 -0.187378 0.469452 -0.0166016\n", + "0.582214 0.0616455 0.2276 0.66684 0.237061 0.595917 -0.679596 -0.25116 -0.891022 -0.308472 0.251465 1.45465 -0.132538 0.21994 -0.241364 -1.27344 0.210663 0.0537415 -0.405884 0.100739 -0.129272 -0.987183 -0.318787 0.308441 0.295319 0.263794 -0.304321 -0.0135193 -0.548676 -0.13559 -0.88147 -0.151001 0.453583 -0.325073 0.259705 -0.233185 -0.19455 0.0861816 -0.271484 -0.982178 0.611969 0.272339 0.0963135 -0.397003 0.823517 -0.566193 -0.272522 0.162079 -0.437866 -0.72644 0.0291443 0.35788 -0.148376 0.674072 0.107697 -0.0837097 0.479034 -0.313232\n", + "-0.750092 -0.346649 0.992706 0.0149231 0.825836 -0.67865 0.0672913 1.76581 -0.221375 -0.837219 0.230072 1.19656 0.187927 0.977386 1.00317 -1.48431 -0.825989 -0.190277 -0.268402 -0.0446167 0.424896 -0.140747 0.131226 -0.733246 -0.195526 0.314758 -0.902985 0.798035 -0.920685 -0.29776 0.675293 0.517914 -0.0801392 -0.783356 0.00387573 -1.25488 -1.13266 -0.759888 1.73395 -0.0971069 -0.0378418 -0.802948 0.115662 -0.34494 0.753937 -0.796204 -0.111053 -0.980042 0.384979 -0.281036 0.997833 -0.419312 -0.931549 0.538696 0.292084 -0.557129 0.988617 0.786987\n", + "0.173889 -0.0111084 -0.0697327 -0.372986 0.658508 -0.293213 -0.489349 0.367981 -0.547516 -0.0986328 0.36026 1.43234 -0.0679932 0.0918274 0.320953 -0.677795 -0.654114 0.631622 -0.666016 0.302551 -0.0819397 -0.406342 -0.295044 -0.173706 -0.146271 0.483337 -0.326996 0.114502 0.200348 0.246338 0.299713 -0.483398 -0.294647 -0.611389 -0.018219 -0.736053 -0.747314 0.0341187 -0.210968 0.373779 -0.259125 0.0966492 -0.200653 -0.474609 0.317352 -0.767853 0.0154114 -0.226776 0.22641 -0.343079 0.173035 0.832764 0.292572 0.0951538 -0.27066 -0.0137024 0.623108 0.0141602\n", + "-0.192078 0.103363 -0.487396 -0.626678 0.542816 0.034729 0.182465 -0.142029 -0.529755 -0.0874939 0.349945 1.62656 0.247559 0.00762939 0.429535 -0.933105 0.0613098 0.519073 0.575897 -0.0791931 0.778046 -0.241272 0.122131 0.601685 -0.0702515 0.278107 -1.4957 -0.0530701 0.188538 0.102448 0.354004 0.604675 0.483521 -0.772156 0.277069 -0.374359 -0.298676 0.594086 0.360931 -0.935028 -0.06073 0.333954 -0.0166626 -1.61002 0.813782 -0.790222 -0.237122 0.54184 0.101654 -0.108582 1.2475 -0.112427 -0.676819 0.217804 -0.346344 0.334686 0.129822 0.00405884\n", + "-0.197662 0.204254 0.330109 -0.0847473 0.0732422 -0.147339 -0.171173 0.273254 -0.16333 -0.147522 0.0973816 0.085022 -0.00637817 0.27536 -0.0137024 -0.0191956 -0.00592041 0.0462952 -0.195465 -0.324463 0.0985413 0.101868 -0.265778 0.0513916 0.187683 0.523193 -0.084137 -0.292389 0.0731812 -0.267029 0.217072 0.0383911 -0.125763 -0.0100098 0.140594 0.0106506 -0.0295105 0.0458984 0.458099 0.103699 0.11908 0.173248 0.132233 -0.570618 0.391174 -0.410706 0.0386353 -0.114899 -0.108887 -0.144409 0.114014 0.18576 -0.33139 -0.0829773 0.00454712 0.199402 0.194855 -0.0548401\n", + "-0.340363 -0.234192 -0.103271 0.58786 0.205078 0.675171 0.457123 0.567291 -1.05426 -0.183411 1.28253 0.855896 0.362518 1.7265 -0.469452 -1.08704 -0.371521 -0.176605 0.0597534 1.01138 -1.04324 -0.296173 0.599548 -0.501617 1.09052 -1.3595 -1.06635 -0.401611 -1.67453 -0.92981 -0.121155 0.842163 0.164978 -0.689606 -0.104706 0.119263 -1.36765 -1.46121 1.52859 -1.86877 0.281342 0.193787 -1.27225 -0.261566 1.43155 -0.0647278 -0.0447998 -0.380005 0.768829 -0.295898 0.689789 -0.126556 -1.09119 1.47684 0.273804 -1.7963 1.86743 0.744934\n", + "0.050293 -0.0556641 -0.207092 -0.055481 0.233124 -0.207703 -0.243103 0.264862 -0.0139771 -0.0428162 0.146729 0.0707092 -0.284149 -0.00842285 -0.167389 -0.0117493 -0.132812 0.161896 -0.0355835 -0.0278625 -0.00479126 -0.0370789 -0.259644 0.286011 0.269501 0.154785 -0.0540161 -0.333557 0.494171 -0.00167847 -0.0210876 0.133453 0.0437012 0.022522 -0.218811 -0.00970459 -0.20874 -0.0039978 0.00149536 -0.0443726 -0.00494385 0.435638 -0.0859375 -0.0488586 0.218658 -0.183807 0.118469 -0.0488892 -0.044342 -0.00509644 -0.172974 0.243073 0.179871 0.107788 -0.0660706 0.0974731 0.131348 -0.108185\n", + "-0.434845 -0.535431 0.915222 0.247894 -0.136536 -0.522247 0.179565 0.580566 0.314667 0.0986938 0.516144 0.821991 -0.033783 -0.219147 -0.294434 -0.339355 -1.06821 0.438354 0.12442 -0.00750732 -0.170715 -0.000152588 0.121277 0.285767 0.0629578 0.484131 -0.287781 0.581848 -0.495392 0.682312 -0.0767822 -0.317169 0.333649 -0.429474 0.0482788 -1.20749 -0.532349 -0.0267334 0.263977 0.0707092 0.389954 0.134613 -0.13501 -0.158386 0.665894 -1.46075 -0.291412 -0.625854 -0.301056 -1.05283 0.0799255 0.355835 -0.0302734 -0.57901 0.572479 0.0496826 0.352875 0.665222\n", + "0.21167 0.158936 -0.0798035 -0.0149231 0.37146 -0.0176697 0.129425 -0.0280151 0.0502319 -0.11853 0.0907593 0.469818 -0.233765 0.110687 -0.212585 -0.568207 -0.191162 -0.207428 0.0723572 0.0612793 0.307678 -0.0291138 0.0368347 0.171875 -0.123138 0.180298 -0.239807 -0.0748291 -0.158051 -0.00418091 -0.303925 -0.084137 0.410339 0.0366821 0.387146 -0.00305176 0.010376 0.237183 0.105865 -0.0912781 0.0515747 0.182892 -0.115295 0.0654297 0.258148 0.26828 0.177582 -0.0130615 -0.122589 -0.407806 -0.18692 0.107452 0.167542 0.41803 -0.149353 -0.168701 0.113556 -0.15509\n", + "0.389923 -0.452728 -0.592804 -0.618683 -0.214722 0.0758972 0.0376282 0.147034 -0.025177 0.447876 0.414948 0.992035 -0.570465 0.334106 -0.599762 0.10199 0.0826416 -0.00549316 -0.254669 1.52347 -0.209442 -1.36929 0.101593 -0.844788 0.153168 -0.366119 -0.627197 -0.0716248 -0.259857 -0.150909 -0.288757 -0.147614 0.126526 0.802399 0.108093 0.839172 -0.355316 -0.624542 -0.277649 0.0855103 -0.218414 1.048 -0.263702 -0.704895 0.531311 -0.181854 0.236145 0.345551 0.580841 0.148529 0.598511 0.756409 0.634918 -0.0735168 0.439819 -0.0782166 0.635406 -0.646515\n", + "-0.110291 0.0855713 0.23468 -0.373352 0.152954 -0.221954 -0.0886536 0.579956 -0.531189 -0.674408 -0.986694 1.44632 0.0810852 0.436279 -0.288452 -0.834961 -0.420776 0.0910034 0.0740967 -0.00732422 -0.437347 -0.641174 -0.481537 -0.528168 -0.380371 0.30069 -0.319733 0.0464172 -0.120819 -0.42157 0.169006 -0.362213 -0.122345 -0.105194 0.160767 -0.383362 -0.186249 0.0653076 1.10907 0.196594 0.170349 0.401276 -0.610077 -0.414062 0.906891 -0.427124 -0.0509338 -0.308807 -0.394379 -0.0992737 0.428802 0.641144 0.273834 0.509521 0.514496 1.15881 1.50693 -0.171082\n", + "0.108734 -0.0784302 0.0401306 -0.11322 0.145905 -0.216492 -0.223297 0.0438232 0.102722 0.151031 0.139557 -0.150513 -0.182068 -0.0906067 -0.280853 0.13385 -0.00289917 -0.00326538 -0.0613403 -0.359009 -0.100983 -0.0581665 -0.15976 0.389832 0.374298 0.31131 -0.108063 -0.093689 0.0387268 -0.0796814 -0.33371 -0.00152588 -0.0218811 -0.0603943 -0.159912 0.0667419 0.244507 0.242676 0.114929 0.0835571 0.022522 -0.0469666 0.346527 -0.169861 0.116302 -0.174072 -0.020813 -0.176453 -0.169617 -0.075592 -0.12146 0.0550232 -0.0839844 0.0254211 -0.293121 0.284241 0.0794067 0.121826\n", + "0.502747 0.597961 -0.431976 -0.555084 0.760742 -0.180573 0.404877 0.0437927 -0.515839 -0.62738 1.21857 0.789825 -0.411224 -0.84967 0.309143 -0.259155 -0.0377808 -0.193481 -0.855927 0.538788 0.105865 -0.493347 -0.51059 -0.303253 -0.00534058 0.400909 -0.567413 0.196503 0.868042 -0.319 -0.323059 -0.112152 -0.563782 -0.655945 0.23764 0.751953 0.0464478 -0.341278 -0.228424 -0.178253 -0.131683 0.5448 -0.10144 -0.795898 0.0756226 0.116974 -0.17688 0.176727 -0.153381 -0.217804 -0.0621948 0.0830688 0.13858 0.378998 -0.107452 -0.902344 0.246338 0.369476\n", + "0.269257 0.228546 0.0320129 0.0383911 0.0689392 0.257294 0.0683594 -0.294495 -0.191193 -0.0244141 0.169647 0.513519 -0.421906 -0.112976 -0.0328064 -0.0736694 0.00125122 -0.0727234 -0.0559692 0.306885 -0.0201111 -0.067749 -0.0225525 -0.04953 0.158661 0.0692749 -0.0652161 0.166168 0.0989685 -0.361969 -0.160797 0.0845032 -0.0183411 0.0323181 0.108612 -0.269318 -0.237976 -0.0344238 -0.150604 -0.295563 0.175995 0.372131 0.0604248 -0.352753 0.141449 -0.0065918 0.0686646 0.249268 0.196259 0.138062 0.085144 -0.113495 0.16748 -0.0447693 -0.137207 0.0169983 0.122803 -0.0394897\n", + "0.769897 0.95105 -0.981293 -0.345703 0.114105 0.416443 0.852051 -1.10477 -0.724518 0.70401 0.365356 1.63596 -0.537445 0.228058 -0.577393 -0.863281 -0.322937 -0.783417 -0.648712 0.781555 0.20697 -0.164551 -0.133972 0.319489 -0.686768 -0.37384 -0.372528 -0.768219 -0.270599 0.0642395 0.146271 -0.256104 -0.236328 -0.158813 0.531036 0.328033 -0.553741 -0.370392 0.264587 -0.906219 0.106659 1.03342 -0.727631 -1.28049 0.606354 -0.423157 0.351929 0.393951 -0.243256 -0.4263 0.742615 -0.0592957 -0.122406 0.626434 0.258484 0.209778 0.93396 0.0231018\n", + "0.030304 -0.0301208 -0.0245056 0.0229187 -0.0222168 -0.0392761 0.049408 -0.0853271 -0.0537109 0.0630188 -0.0562744 0.0404663 -0.00518799 -0.0519714 0.0481873 -0.0636902 -0.0232239 0.0264282 0.0823364 -0.0317078 0.0479736 -0.0276184 -0.0366211 -0.0304871 0.0238342 0.00860596 -0.0314026 0.0451965 0.0421753 -0.0149841 -0.0327454 -0.00408936 0.0519104 -0.0670776 0.0437012 -0.0358887 -0.0617676 -0.0241089 0.0730286 0.0516052 -0.0511169 0.0736694 0.0612183 -0.0513916 0.0444946 -0.0144043 0.0586548 -0.0126343 0.0351868 0.0583801 -0.0437012 -0.0205383 0.0706177 -0.0845642 -0.0387268 -0.0353394 0.0826416 0.0414124\n", + "-0.0747375 0.254547 -0.00363159 -0.365784 0.492554 -0.315552 -0.0103149 0.0491028 0.243896 0.0979919 -0.119659 -0.422241 -0.537354 0.0517883 -0.407349 0.184814 -0.249878 -0.0918579 -0.102142 -0.270294 0.195282 0.186707 -0.719971 0.117371 0.27536 0.257629 0.178223 -0.356445 0.382324 0.377808 -0.0570984 -0.475433 -0.15741 0.485504 -0.306061 0.221771 -0.0643005 0.255493 -0.370575 0.628723 0.144104 0.144653 -0.102997 0.107117 0.203369 -0.459045 -0.0101318 -0.647705 -0.0913391 -0.013855 -0.310181 0.293732 -0.0106201 -0.059082 -0.0960083 0.106506 0.104065 -0.0157166\n", + "0.0478821 -0.033783 0.012146 -0.000549316 -0.0426941 -0.0072937 0.0766907 -0.0657043 -0.0608521 0.0260315 -0.0220947 0.0325623 -0.0591736 -0.0652161 0.015686 -0.0557861 -0.0630798 0.0181274 0.105469 0.0352783 0.0142517 -0.101044 -0.0604248 -0.0678406 -0.0123291 -0.0621338 -0.0358582 -0.033783 0.0143127 -0.0519714 -0.00836182 0.0121155 0.0635071 -0.0783997 0.0610657 0.0554199 -0.0327759 -0.0525208 0.0906372 0.0714417 0.000366211 0.119965 0.0361328 -0.0605774 0.0339966 0.00289917 0.106659 0.0977478 0.00915527 -0.0103149 -0.0604248 0.075592 0.0823975 -0.0253906 0.0511475 -0.0787964 0.164001 -0.0314941\n", + "0.00109863 -0.0224304 -0.0946045 -0.0949097 -0.226776 -0.0460205 0.148315 -0.1716 -0.376526 -0.111115 0.227051 0.582214 0.0651855 0.149048 -0.133667 -0.0304871 -0.0670166 -0.216888 -0.158478 0.42099 -0.239807 -0.412445 -0.113861 -0.142761 0.0528564 -0.307068 -0.296661 0.119324 0.159851 -0.423828 -0.178864 -0.0879822 -0.127106 -0.126068 0.0345459 0.117889 -0.0469055 -0.360809 0.225952 -0.144196 0.340668 0.143158 -0.0900574 -0.103912 0.108246 0.0863647 0.294678 0.138 0.216705 0.0378723 -0.349518 -0.0236511 0.322968 0.482147 0.181183 -0.0898743 0.58551 -0.122253\n", + "-0.020813 0.0798645 -0.0566711 -0.0676575 0.0434875 -0.0661011 -0.00585938 0.00601196 -0.246124 0.0631409 -0.056366 0.142181 -0.0270691 0.148193 -0.0210571 -0.0614929 -0.106262 -0.0247803 -0.0894775 -0.00332642 0.096344 0.0697937 -0.0171509 0.0383911 0.111572 0.00708008 -0.0101013 -0.127686 0.0445251 -0.0817566 -0.0586548 0.0223694 0.0253601 -0.0761414 -0.0141907 -0.0757141 -0.0913696 -0.022522 0.230682 -0.0352783 0.00939941 0.123138 -0.142792 -0.186829 0.161255 0.0802002 0.217346 -0.00753784 0.161957 0.0698547 -0.204865 -0.010498 0.092865 0.124817 -0.0829468 -0.0240173 0.242126 -0.0472717\n", + "-0.0966492 -0.128418 -0.0380554 -0.177094 0.127411 -0.119568 0.106445 -0.153137 -0.0137634 0.0324402 0.0356445 0.0660706 0.0895386 -0.0310059 -0.0886841 0.201233 -0.0322571 0.125305 0.113708 -0.119446 -0.243958 0.0714111 -0.0638123 -0.0892029 -0.0727844 -0.0970459 0.200775 -0.031311 0.217163 -0.052002 0.0240479 -0.224274 0.0873718 -0.100616 -0.0689392 0.00326538 -0.131775 -0.0166321 -0.100647 0.360687 0.0579529 0.228302 -0.041748 0.148865 0.205566 -0.0418701 -0.0153809 -0.0840149 -0.215668 -0.00784302 -0.155029 0.0774231 0.00637817 -0.159058 -0.0740356 -0.165344 -0.0292358 0.0771484\n", + "0.0588684 0.0993958 -0.0613098 -0.0362244 0.211792 -0.0632019 0.0634155 -0.121979 -0.0594788 0.160706 -0.18161 0.427521 -0.0708923 -0.150482 0.160187 -0.238892 -0.076355 0.121033 0.0390625 0.0668945 0.144836 -0.0817871 -0.0430298 -0.276337 -0.0158997 0.0567932 -0.130402 0.121857 -0.00238037 -0.106232 -0.131805 -0.0701599 -0.16449 -0.0877686 0.15152 -0.00662231 -0.0346375 0.156982 0.135681 0.0716553 -0.051239 0.250793 -0.054657 -0.16629 0.14679 0.0166016 -0.0848083 -0.10965 0.0986938 0.0172119 0.13916 -0.0484619 0.0414429 -0.11319 -0.074646 0.0291443 0.0775452 0.0773926\n", + "0.00527954 -0.0418701 -0.0233765 0.00921631 0.0697021 -0.0925293 0.0618591 -0.0647888 -0.040863 0.0743103 -0.0383301 0.0393677 -0.0433655 0.0267334 0.0360718 -0.0683289 -0.0411987 0.0105591 0.022583 -0.0529785 0.0724487 0.0184021 -0.0578613 -0.0113831 0.084259 0.0175171 -0.0301208 -0.00985718 0.0396729 -0.00192261 -0.0201416 0.0184631 0.0404663 -0.0264282 0.0062561 -0.00738525 -0.0647583 -0.0939331 0.0878601 0.0675659 -0.0331421 0.0473328 0.047699 -0.0570984 0.0873108 0.0186768 0.118317 -0.0639343 0.09729 0.0264282 -0.0455322 0.000152588 0.114349 -0.114227 -0.080658 -0.0817871 0.07724 0.0496521\n", + "-0.0504761 -0.133331 0.0484924 -0.0062561 -0.0397339 -0.171631 0.135681 0.0847778 -0.0170898 0.0209351 -0.0357056 0.256378 -0.00350952 0.128723 0.00512695 -0.0880737 -0.0480652 0.178711 0.0877686 -0.0796509 0.0676575 -0.0479126 -0.110474 -0.033844 -0.0336914 0.073761 -0.0929871 -0.0583496 0.0273132 -0.0743103 0.0926514 0.0386353 0.0741577 -0.131805 -0.00845337 -0.150574 -0.151031 -0.122772 0.211945 -0.0188904 0.0246582 0.157349 -0.033783 -0.173767 0.262177 -0.106018 0.18811 0.032196 0.066803 -0.0592041 -0.037262 0.033905 0.0942383 -0.0420532 0.0930786 -0.0180969 0.192261 -0.0830078\n", + "0.0266418 -0.00817871 -0.0127869 0.0353394 -0.00326538 -0.0509644 0.0522461 -0.0682068 -0.0409851 0.0514526 -0.0707703 0.0253296 -0.0207214 -0.0411377 0.0562744 -0.0579224 -0.0311279 0.00283813 0.072113 -0.0614014 0.0541382 -0.0105896 -0.0317993 -0.0407715 0.019104 0.0153503 -0.0334778 0.0328064 0.0354309 -0.0187683 -0.0229492 -0.00939941 0.0735474 -0.0576782 0.0442505 -0.013855 -0.0473938 -0.0126953 0.0796204 0.0419617 -0.0657043 0.0629578 0.0843201 -0.035553 0.0279846 0.00308228 0.0389404 -0.0274353 0.0319214 0.0579224 -0.0379639 -0.0443726 0.0485535 -0.066925 -0.0480957 -0.0329895 0.0686646 0.0521851\n", + "0.00524902 -0.022583 -0.0017395 0.0343323 0.0210266 -0.0246582 0.0584717 -0.0751953 -0.0630798 0.0657349 -0.0645447 0.0535583 -0.00814819 -0.0263367 0.0675049 -0.0637512 -0.0296936 -0.00393677 0.0696716 -0.0683899 0.0424805 0.00796509 -0.0186462 -0.0682068 0.0231934 -0.0108337 -0.0197144 0.019165 0.0277405 -0.0162964 -0.0274353 0.000152588 0.0737305 -0.0432434 0.0409241 -0.0168762 -0.0742493 -0.00262451 0.0512695 0.0722961 -0.0792542 0.0419922 0.0805054 -0.0151367 0.0508728 0.00335693 0.0318604 -0.0327454 0.0179138 0.0820923 -0.0201416 -0.0455627 0.0639648 -0.0635986 -0.0623779 -0.0572815 0.0679626 0.0384827\n", + "0.0266113 -0.00814819 -0.0128174 0.0353699 -0.00326538 -0.0509644 0.0522461 -0.0682373 -0.0409851 0.0514526 -0.0707703 0.0253296 -0.0206909 -0.0411682 0.0562744 -0.0579224 -0.0311279 0.00286865 0.072113 -0.0614014 0.0541077 -0.0105896 -0.0318298 -0.0408325 0.0190735 0.0153198 -0.0334778 0.0327759 0.0354309 -0.0187378 -0.0229187 -0.0093689 0.0735474 -0.0576782 0.0442505 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419922 -0.0657349 0.0629272 0.0842896 -0.035553 0.0279541 0.00311279 0.0389099 -0.0274353 0.0319214 0.0578918 -0.0379639 -0.044342 0.0485535 -0.066925 -0.0480957 -0.0329895 0.0686951 0.0521851\n", + "0.0266113 -0.00817871 -0.0128174 0.0353394 -0.00326538 -0.0509644 0.0522461 -0.0682373 -0.0409851 0.0514221 -0.0708008 0.0253296 -0.0206604 -0.0411682 0.0562744 -0.0579224 -0.0310974 0.00283813 0.072113 -0.0614014 0.0541382 -0.0105896 -0.0318298 -0.0407715 0.019104 0.0153503 -0.0334778 0.0327759 0.0354309 -0.0187683 -0.0229187 -0.0093689 0.0735474 -0.0576782 0.0442505 -0.013855 -0.0474243 -0.0126648 0.0796204 0.0419922 -0.0657043 0.0629578 0.0842896 -0.0355225 0.0279846 0.00308228 0.0389099 -0.0274048 0.0319214 0.0578918 -0.0379639 -0.044342 0.0485535 -0.066925 -0.0480957 -0.0329895 0.0686646 0.0521851\n", + "0.0266418 -0.00817871 -0.0128479 0.0353699 -0.00326538 -0.0509949 0.0522461 -0.0682373 -0.0409851 0.0514526 -0.0707703 0.0252991 -0.0206909 -0.0411682 0.0562744 -0.0579529 -0.0311279 0.00283813 0.072113 -0.0614014 0.0541382 -0.0105896 -0.0317993 -0.040802 0.0190735 0.0153503 -0.0334473 0.0327454 0.0354309 -0.0187683 -0.0229187 -0.0093689 0.0735779 -0.0576782 0.0442505 -0.013855 -0.0474548 -0.0126953 0.0796204 0.0419922 -0.0657349 0.0629578 0.0842896 -0.0355225 0.0279541 0.00314331 0.0389099 -0.0274048 0.0319214 0.0579224 -0.0379639 -0.044342 0.0485535 -0.066925 -0.0481262 -0.0329895 0.0686646 0.0522156\n", + "0.0266418 -0.00817871 -0.0128174 0.0353394 -0.0032959 -0.0509644 0.0522461 -0.0682373 -0.0409851 0.0514526 -0.0707703 0.0252991 -0.0206604 -0.0411682 0.0562439 -0.0579224 -0.0310974 0.00283813 0.072113 -0.0614014 0.0541077 -0.0105896 -0.0317993 -0.040802 0.0190735 0.0153503 -0.0334778 0.0327454 0.0354309 -0.0187683 -0.0229492 -0.00939941 0.0735779 -0.0576782 0.0442505 -0.013855 -0.0474243 -0.0126953 0.0796204 0.0419922 -0.0657043 0.0629578 0.0843201 -0.0355225 0.0279846 0.00311279 0.0389099 -0.0274048 0.0318909 0.0579529 -0.0379333 -0.0443726 0.0485535 -0.066925 -0.0480652 -0.03302 0.0686646 0.0521851\n", + "0.0266418 -0.00817871 -0.0127869 0.0353394 -0.0032959 -0.0509644 0.0522461 -0.0682068 -0.0409851 0.0514526 -0.0707703 0.0253296 -0.0206909 -0.0411682 0.0562744 -0.0579529 -0.0310974 0.00286865 0.072113 -0.0614014 0.0541077 -0.0105896 -0.0318298 -0.040802 0.019104 0.0153198 -0.0335083 0.0327759 0.0354004 -0.0187683 -0.0229492 -0.0093689 0.0735779 -0.0576782 0.0442505 -0.013855 -0.0474548 -0.0126953 0.0796204 0.0419617 -0.0657043 0.0629578 0.0842896 -0.035553 0.0279541 0.00311279 0.0389404 -0.0274353 0.0318909 0.0579224 -0.0379639 -0.0443726 0.0485535 -0.066925 -0.0480957 -0.0329895 0.0686951 0.0521851\n", + "\n", + "=== COMPUTATION END ===\n", + "\n", + "Offline Communication = 175698065 bytes\n", + "Offline Time = 205.734 milliseconds\n", + "Online Rounds = 14\n", + "Online Communication = 90665623 bytes\n", + "Online Time = 16440.5 milliseconds\n", + "Total Eigen Time = 15683.1 milliseconds\n", + "\n", + "Conv + Matmul Time = 15696.5 milliseconds\n", + "Relu time = 436.247 milliseconds\n", + "ReluTruncate time = 0 milliseconds\n", + "MaxPool time = 0 milliseconds\n", + "Select/Bit operations Time = 0 milliseconds\n", + "Truncate time = 267.737 milliseconds\n", + "Total Time (including Key Read) = 30708.6 milliseconds\n", + "\n", + "Conv Online Communication = 0 bytes\n", + "MatMul Online Communication = 1052800 bytes\n", + "Select Online Communication = 0 bytes\n", + "ReLU Online Communication = 1080000 bytes\n", + "RT Online Communication = 0 bytes\n", + "ARS Online Communication = 1052800 bytes\n", + "=========\n" + ] + } + ], + "source": [ + "# Replace the path below with the path to your files\n", + "!./ezpc_run_on_single_machine.sh \"/home/user/path/to/input_volume_100batch.npy\" {batch_size}" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "gather": { + "logged": 1689970626620 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "# Replace the path below with the path to your files\n", + "ezpc_output_file=\"/home/user/EzPC/OnnxBridge/workdir/ezpc_prediction.dat\"" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "gather": { + "logged": 1689972886360 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([42, 42, 42, 42, 42, 42, 42, 6, 42, 32, 56, 44, 10, 56, 51, 42, 10, 34,\n", + " 49, 37, 29, 10, 11, 4, 11, 11, 20, 11, 46, 46, 11, 44, 42, 50, 2, 11,\n", + " 11, 10, 28, 11, 44, 20, 24, 10, 11, 10, 21, 41, 11, 11, 11, 46, 11, 11,\n", + " 24, 53, 38, 10, 28, 11, 11, 7, 24, 11, 11, 10, 46, 49, 11, 11, 7, 11,\n", + " 11, 25, 56, 28, 2, 11, 19, 56, 23, 10, 11, 11, 56, 39, 56, 56, 56, 39,\n", + " 11, 46, 44, 42, 49, 42, 42, 42, 42, 42])\n" + ] + } + ], + "source": [ + "with open(ezpc_output_file) as f:\n", + " lines = [[float(x) for x in line.strip().split(\" \")] for line in f]\n", + "\n", + "ezpc_probs = F.softmax(torch.as_tensor(lines), dim=1)\n", + "_, ezpc_predictions = ezpc_probs.max(1)\n", + "print(ezpc_predictions)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "gather": { + "logged": 1689971899909 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "def compare_tensor_outputs(actual, predicted):\n", + " # calculate absolute error across all classes\n", + " error = torch.abs(actual - predicted).flatten()\n", + " mean = torch.mean(error)\n", + " std_dev = torch.std(error)\n", + " ci = stats.norm.interval(alpha=0.95, loc=mean, scale=stats.sem(error))\n", + " print(f\"absolute error: mean: {mean}, standard deviation: {std_dev}, confidence interval: {ci}, max: {torch.max(error)}\")\n", + " print(f\"===== Mean \\u00b1 CI: {mean:.4E} \\u00b1 {(ci[1] - ci[0]) / 2.0:.2E} ======\")" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "gather": { + "logged": 1689972899922 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "absolute error: mean: 5.204777335166e-05, standard deviation: 0.00016560518997721374, confidence interval: (4.778582642261696e-05, 5.6309720280703034e-05), max: 0.0060277581214904785\n", + "===== Mean ± CI: 5.2048E-05 ± 4.26E-06 ======\n" + ] + } + ], + "source": [ + "# errors between original pyTorch outputs and EzPC \n", + "compare_tensor_outputs(probs, ezpc_probs)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "gather": { + "logged": 1689972948436 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "absolute error: mean: 5.20477224199567e-05, standard deviation: 0.0001656016247579828, confidence interval: (4.778586724392669e-05, 5.630957759598671e-05), max: 0.006027638912200928\n", + "===== Mean ± CI: 5.2048E-05 ± 4.26E-06 ======\n" + ] + } + ], + "source": [ + "# errors between EzPC and plain ONNX inference\n", + "compare_tensor_outputs(ort_probs, ezpc_probs)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "gather": { + "logged": 1689972960428 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "absolute error: mean: 4.411621290500989e-09, standard deviation: 2.207849369995074e-08, confidence interval: (3.8434182744279515e-09, 4.979824306574026e-09), max: 7.748603820800781e-07\n", + "===== Mean ± CI: 4.4116E-09 ± 5.68E-10 ======\n" + ] + } + ], + "source": [ + "# errors between original pyTorch outputs and plain ONNX inference\n", + "compare_tensor_outputs(probs, ort_probs)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "gather": { + "logged": 1689971479084 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [], + "source": [ + "def print_metrics(actual, predicted):\n", + " scores = precision_recall_fscore_support(actual, predicted, average=\"micro\")\n", + " print(f\"precision: {scores[0]}, recall: {scores[1]}, f1 score: {scores[2]}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "gather": { + "logged": 1689971481951 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "precision: 1.0, recall: 1.0, f1 score: 1.0\n" + ] + } + ], + "source": [ + "# Metrics for original pyTorch and EzPC predictions\n", + "print_metrics(predictions, ezpc_predictions)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "gather": { + "logged": 1689971484175 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "precision: 1.0, recall: 1.0, f1 score: 1.0\n" + ] + } + ], + "source": [ + "# Metrics for original pyTorch and plain ONNX predictions\n", + "print_metrics(predictions, ort_predictions)" + ] + } + ], + "metadata": { + "kernel_info": { + "name": "synapse_pyspark" + }, + "kernelspec": { + "display_name": "Synapse PySpark", + "language": "Python", + "name": "synapse_pyspark" + }, + "language_info": { + "codemirror_mode": "ipython", + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython", + "version": "3.8.0" + }, + "microsoft": { + "host": { + "AzureML": { + "notebookHasBeenCompleted": true + } + }, + "ms_spell_check": { + "ms_spell_check_language": "en" + } + }, + "nteract": { + "version": "nteract-front-end@1.0.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/OnnxBridge/Demo/mlp/extract_mlp_model.ipynb b/OnnxBridge/Demo/mlp/extract_mlp_model.ipynb new file mode 100644 index 00000000..545791c6 --- /dev/null +++ b/OnnxBridge/Demo/mlp/extract_mlp_model.ipynb @@ -0,0 +1,218 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "NZKUpjEb6wTZ", + "vscode": { + "languageId": "python" + } + }, + "outputs": [], + "source": [ + "!pip install nibabel\n", + "!pip install torchio\n", + "!pip install onnx\n", + "!pip install onnxruntime" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "B6KLtDsD7BOU", + "vscode": { + "languageId": "python" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "import torchvision\n", + "from torchvision import datasets,transforms, models\n", + "import torchvision.transforms.functional as TF\n", + "import nibabel as nib\n", + "from pathlib import Path\n", + "import onnxruntime\n", + "from sklearn.metrics import precision_recall_fscore_support\n", + "from scipy import stats\n", + "import onnx" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "CiBuxhgm7NMB", + "vscode": { + "languageId": "python" + } + }, + "outputs": [], + "source": [ + "# to match fMRI ICA 100 components\n", + "batch_size = 100" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "TnJ0C5rk7Nvd", + "vscode": { + "languageId": "python" + } + }, + "outputs": [], + "source": [ + "class MultilayerPerceptron2(nn.Module):\n", + " # whatever op layer is becomes num ip for next hidden layer\n", + " def __init__(self, input_size=45*54*45, output_size=58):\n", + " super().__init__()\n", + " N = 200\n", + " self.d1 = nn.Linear(input_size, N)\n", + " self.d2 = nn.Linear(N, N)\n", + " self.d3 = nn.Linear(N, N)\n", + " self.d4 = nn.Linear(N, N)\n", + " self.d5 = nn.Linear(N, output_size)\n", + " self.dropout = nn.Dropout(0.66)\n", + " self.flat = nn.Flatten()\n", + "\n", + "\n", + " def forward(self,X):\n", + "\n", + " X = self.flat(X) #X.view(-1,45*54*45)\n", + " X = F.relu(self.d1(X))\n", + " X = F.relu(self.d3(X))\n", + " X = self.dropout(X)\n", + " X = F.relu(self.d4(X))\n", + " X = self.d5(X)\n", + " #X = torch.squeeze(X)\n", + "\n", + " return X" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Download the mlp model weights from below link as provided in GitHub repo: https://github.com/AmmarPL/fMRI-Classification-JHU/
\n", + "Model Weights - https://livejohnshopkins-my.sharepoint.com/:f:/g/personal/apallik1_jh_edu/Eqo4DojG33pBquC3_zCNYhYBSTcUS6Ppfhl9OAVF_erlZQ?e=bfn0E7" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "vw5SBCfh7NzE", + "outputId": "c4a1696a-2109-4f78-e15f-08300250be3a", + "vscode": { + "languageId": "python" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Device is cpu\n" + ] + }, + { + "data": { + "text/plain": [ + "MultilayerPerceptron2(\n", + " (d1): Linear(in_features=109350, out_features=200, bias=True)\n", + " (d2): Linear(in_features=200, out_features=200, bias=True)\n", + " (d3): Linear(in_features=200, out_features=200, bias=True)\n", + " (d4): Linear(in_features=200, out_features=200, bias=True)\n", + " (d5): Linear(in_features=200, out_features=58, bias=True)\n", + " (dropout): Dropout(p=0.66, inplace=False)\n", + " (flat): Flatten(start_dim=1, end_dim=-1)\n", + ")" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "device = 'cuda' if torch.cuda.is_available() else \"cpu\"\n", + "print(f'Device is {device}')\n", + "model_final = torch.load('/content/drive/MyDrive/Colab Notebooks/model_mlp_final.pth', map_location=device)\n", + "\n", + "model = MultilayerPerceptron2()\n", + "\n", + "\n", + "model.load_state_dict(model_final['model'])\n", + "model = model.to(device)\n", + "model.eval()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below cell saves the mlp model as an ONNX file which we can then use with OnnxBridge." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "cKJt9Tmx7N2t", + "vscode": { + "languageId": "python" + } + }, + "outputs": [], + "source": [ + "output_onnx = str(Path(\"mlp_model.onnx\"))\n", + "input_volume = torch.randn(1, 1, 45, 54, 45)\n", + "\n", + "# Export an ONNX model.\n", + "with torch.no_grad():\n", + " torch.onnx.export(\n", + " model=model,\n", + " args=(input_volume),\n", + " f=output_onnx,\n", + " opset_version=13,\n", + " verbose=True,\n", + " input_names=[\"image\"],\n", + " output_names=[ \"score\"],\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Successfully saved mlp_model.onnx !!" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Xonsh", + "language": "xonsh", + "name": "xonsh" + }, + "language_info": { + "name": "xonsh" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/OnnxBridge/Demo/mlp/ezpc_run_on_single_machine.sh b/OnnxBridge/Demo/mlp/ezpc_run_on_single_machine.sh new file mode 100644 index 00000000..c3cc238d --- /dev/null +++ b/OnnxBridge/Demo/mlp/ezpc_run_on_single_machine.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +input_file=${1} +batch_size=${2:-"1"} +predictions_file=${3:-"ezpc_prediction.dat"} + +work_dir="EzPC/OnnxBridge/workdir" +cd $work_dir + +# ------------------CLIENT------------------ +case $input_file in + *.npy) + input_file_basename=$(basename $input_file) + preprocessed_file=${input_file_basename%".npy"}.inp + # Use below command to dump the numpy file as a custom .inp format file + python ../helper/convert_np_to_float_inp.py --inp $input_file --output $preprocessed_file + ;; + *) + preprocessed_file=$input_file + ;; +esac + +# ------------------SERVER------------------ +# run server +./mlp_model_LLAMA_15 2 mlp_model_input_weights.dat & + +# ------------------CLIENT------------------ +#run client +./mlp_model_LLAMA_15 3 127.0.0.1 < $preprocessed_file |& tee >(tail -n $batch_size > $predictions_file); sync + +#./mlp_model_LLAMA_15 3 127.0.0.1 < $preprocessed_file | tee ezpc_client.log +# tail -n 10 ezpc_client.log > "ezpc_prediction.dat" + +#tail 10 | tee ezpc_prediction.dat + +#./script.sh |& tee >(tail -10 >file.txt) +##tee ezpc_client.log +#tail -n 10 ezpc_client.log > ezpc_prediction.dat + + + diff --git a/OnnxBridge/Demo/mlp/ezpc_secure_compile.sh b/OnnxBridge/Demo/mlp/ezpc_secure_compile.sh new file mode 100644 index 00000000..11b579a4 --- /dev/null +++ b/OnnxBridge/Demo/mlp/ezpc_secure_compile.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +onnx_model_path=${1:-"mlp_model.onnx"} +work_dir="EzPC/OnnxBridge/workdir" + +model_basename=$(basename $onnx_model_path) +mkdir -p $work_dir +# TODO: use symbolic link instead +cp $onnx_model_path $work_dir/mlp_model.onnx +cd $work_dir + +# ------------------SERVER------------------ +# Compile the onnx model +python ../main.py --path $model_basename --generate "executable" --backend LLAMA --scale 15 --bitlength 64 + +# ------------------DEALER------------------ +# generate keys +./mlp_model_LLAMA_15 1 diff --git a/OnnxBridge/Demo/mlp/ezpc_setup.sh b/OnnxBridge/Demo/mlp/ezpc_setup.sh new file mode 100644 index 00000000..6dd90d39 --- /dev/null +++ b/OnnxBridge/Demo/mlp/ezpc_setup.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +sudo apt update +sudo apt install -y --no-install-recommends libeigen3-dev cmake build-essential git + +# upgrade cmake if version < 3.16 +wget -O /tmp/cmake.sh wget -O /tmp/cmake.sh https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-linux-x86_64.sh +sudo /bin/sh /tmp/cmake.sh --prefix=/usr/local --skip-license && rm /tmp/cmake.sh +echo $(cmake --version) + +git clone https://github.com/mpc-msri/EzPC.git +# git checkout 8b07f73e187c5eb6ab98b0bf09b9bd276cd43949 +cd EzPC/ +#python3 -m venv venv +#source venv/bin/activate +pip install -r OnnxBridge/requirements.txt \ No newline at end of file diff --git a/OnnxBridge/README.md b/OnnxBridge/README.md index 63e79c43..4f946116 100644 --- a/OnnxBridge/README.md +++ b/OnnxBridge/README.md @@ -1,3 +1,6 @@ + +![OnnxBridge](image.png) + # OnnxBridge An end-to-end compiler for converting Onnx Models to Secure Cryptographic backends : **Secfloat**(Floating Point) and **LLAMA**(FSS based). - [Setup](#setup) @@ -253,6 +256,16 @@ This completes the node implementation in backend. ``` ## Demo -Follow [Demo](Secfloat/demo/Readme.md) for OnnxBridge demo with Secfloat. +Below are the available demos: +- OnnxBridge with Secfloat. [link](/OnnxBridge/Secfloat/demo/Readme.md) +- OnnxBridge with LLAMA. [link](/OnnxBridge/Demo/hinet_cifar10-llama/README.md) +- Toy Example - Single Inference. [link](/sytorch/Toy%20example-%20single%20inference.md) +- Toy Example - Multiple Inference. [link](/sytorch/Toy%20example-%20multiple%20inference.md) +- Inference App - Chexpert. [link](/inference-app/README.md) +- Inference App - fMRI-MLP. [link](/OnnxBridge/Demo/mlp/README.md) + +## Helper Scripts +These [scripts](/OnnxBridge/helper/README.md) are useful during development and testing. + diff --git a/OnnxBridge/backend.py b/OnnxBridge/backend.py index 9b602042..cd25a544 100644 --- a/OnnxBridge/backend.py +++ b/OnnxBridge/backend.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import os, sys import onnx.checker diff --git a/OnnxBridge/helper/README.md b/OnnxBridge/helper/README.md new file mode 100644 index 00000000..88b8deaf --- /dev/null +++ b/OnnxBridge/helper/README.md @@ -0,0 +1,47 @@ +# OnnxBridge: Helper scripts + +These are some scripts to increase productivity while using, developing and testing OnnxBridge, they enable you to create an arbitrary onnx file, input for it and other major tasks. + +- **compare_np_arrs.py :** A script if two numpy array are similar and if they match upto which decimal place. +```bash +# usage +python .../helper/compare_np_arrs.py -i $expected.npy $output.npy + +# further add a `-v` flag to print the two array +``` + +- **convert_np_to_float_inp.py :** A script to dump a numpy array to `.inp` file as floating point values. +```bash +# usage +python .../helper/convert_np_to_float_inp.py --inp $actualFileName.npy --output ${actualFileName}_input.inp +``` + +- **create_np_array.py :** A script to create a numpy array of desired size, also prints the values which can then be saved in a `.inp` file for ezpc inference. +```bash +# usage +python .../helper/create_np_array.py > conv2d_input.inp +# saves conv2d_input.npy and conv2d_input.inp files +``` + +- **make_model.py :** A script to create custom ONNX files. +```bash +# examples given in the file +``` + +- **make_np_arr.py :** A script to extract output from th eoutput logs of inference from ezpc. +```bash +# usage +python .../helper/make_np_arr.py "output.txt" +``` + +- **pre_process.py :** A script to preprocess and save an input image file as numpy array. +```bash +# usage +python .../helper/pre_process.py $image_path +``` + +- **run_onnx.py :** A script to run ONNX files with a given numpy array. +```bash +# usage +python .../helper/run_onnx.py model.onnx "input.npy" +``` diff --git a/OnnxBridge/helper/create_np_array.py b/OnnxBridge/helper/create_np_array.py index 3223061f..a84cd0ae 100644 --- a/OnnxBridge/helper/create_np_array.py +++ b/OnnxBridge/helper/create_np_array.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import numpy as np import os diff --git a/OnnxBridge/helper/make_model.py b/OnnxBridge/helper/make_model.py index 9c4b6f87..ecea2541 100644 --- a/OnnxBridge/helper/make_model.py +++ b/OnnxBridge/helper/make_model.py @@ -1,24 +1,45 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import onnx_graphsurgeon as gs import numpy as np import onnx -W_val = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] -bias = [1, 2, 3] +# W_val = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] +# bias = [1, 2, 3] -X = gs.Variable(name="X", dtype=np.float32, shape=(1, 1, 1, 3)) -# Since W is a Constant, it will automatically be exported as an initializer -W = gs.Constant(name="W", values=np.array(W_val, dtype=np.float32)) -bias = gs.Constant(name="bias", values=np.array(bias, dtype=np.float32)) +# X = gs.Variable(name="X", dtype=np.float32, shape=(1, 1, 1, 3)) +# # Since W is a Constant, it will automatically be exported as an initializer +# W = gs.Constant(name="W", values=np.array(W_val, dtype=np.float32)) +# bias = gs.Constant(name="bias", values=np.array(bias, dtype=np.float32)) -Y = gs.Variable(name="Y", dtype=np.float32, shape=(1, 3)) -Z = gs.Variable(name="Z", dtype=np.float32, shape=(1, 3)) +# Y = gs.Variable(name="Y", dtype=np.float32, shape=(1, 3)) +# Z = gs.Variable(name="Z", dtype=np.float32, shape=(1, 3)) -node = gs.Node(op="Flatten", inputs=[X], outputs=[Y]) -node2 = gs.Node(op="Gemm", inputs=[Y, W, bias], outputs=[Z]) +# node = gs.Node(op="Flatten", inputs=[X], outputs=[Y]) +# node2 = gs.Node(op="Gemm", inputs=[Y, W, bias], outputs=[Z]) -# Note that initializers do not necessarily have to be graph inputs -graph = gs.Graph(nodes=[node, node2], inputs=[X], outputs=[Z]) -onnx.save(gs.export_onnx(graph), "onnx_new_files/fc_bias.onnx") +# # Note that initializers do not necessarily have to be graph inputs +# graph = gs.Graph(nodes=[node, node2], inputs=[X], outputs=[Z]) +# onnx.save(gs.export_onnx(graph), "onnx_new_files/fc_bias.onnx") # X = gs.Variable(name="X", dtype=np.float32, shape=(1, 1, 3, 3)) # # Since W is a Constant, it will automatically be exported as an initializer @@ -31,3 +52,84 @@ # # Note that initializers do not necessarily have to be graph inputs # graph = gs.Graph(nodes=[node], inputs=[X], outputs=[Y]) # onnx.save(gs.export_onnx(graph), "onnx_files/conv.onnx") + +# writing chexpert model node by node with initializers value as random + +# input = gs.Variable(name="input", dtype=np.float32, shape=(1, 3, 320, 320)) +# # Since W is a Constant, it will automatically be exported as an initializer +# W = gs.Constant(name="W", values=np.random.rand(64, 3, 7, 7).astype(np.float32)) +# bias = gs.Constant(name="bias", values=np.random.rand(64).astype(np.float32)) +# conv_out = gs.Variable(name="conv_out", dtype=np.float32, shape=(1, 64, 160, 160)) + +# node = gs.Node(op="Conv", inputs=[input, W, bias], attrs={"strides": [2, 2], "kernel_shape": [7, 7], "pads": [3, 3, 3, 3]}, outputs=[conv_out]) + +# relu_out = gs.Variable(name="relu_out", dtype=np.float32, shape=(1, 64, 160, 160)) +# node2 = gs.Node(op="Relu", inputs=[conv_out], outputs=[relu_out]) + +# pool_out = gs.Variable(name="pool_out", dtype=np.float32, shape=(1, 64, 80, 80)) +# node3 = gs.Node(op="AveragePool", inputs=[relu_out], attrs={"strides": [2, 2], "kernel_shape": [2, 2], "pads": [0, 0, 0, 0]}, outputs=[pool_out]) + +# concat_out = gs.Variable(name="concat_out", dtype=np.float32, shape=(1, 64, 80, 80)) +# node4 = gs.Node(op="Concat", inputs=[pool_out], attrs={"axis": 1}, outputs=[concat_out]) + +# batchnorm_out = gs.Variable(name="batchnorm_out", dtype=np.float32, shape=(1, 64, 80, 80)) +# scale = gs.Constant(name="scale", values=np.random.rand(64).astype(np.float32)) +# B = gs.Constant(name="bias1", values=np.random.rand(64).astype(np.float32)) +# mean = gs.Constant(name="mean", values=np.random.rand(64).astype(np.float32)) +# var = gs.Constant(name="var", values=np.random.rand(64).astype(np.float32)) +# node5 = gs.Node(op="BatchNormalization", inputs=[concat_out, scale, B, mean, var], outputs=[batchnorm_out]) + +# graph = gs.Graph(nodes=[node, node2, node3,], inputs=[input], outputs=[pool_out]) +# onnx.save(gs.export_onnx(graph), "mod_chexpert.onnx") + + +# writing a model with just one maxpool layer +# input = gs.Variable(name="input", dtype=np.float32, shape=(1, 3, 320, 320)) +# pool_out = gs.Variable(name="pool_out", dtype=np.float32, shape=(1, 3, 160, 160)) +# node = gs.Node(op="MaxPool", inputs=[input], attrs={"strides": [2, 2], "kernel_shape": [3, 3], "pads": [1, 1, 1, 1]}, outputs=[pool_out]) +# graph = gs.Graph(nodes=[node], inputs=[input], outputs=[pool_out]) +# onnx.save(gs.export_onnx(graph), "maxpool.onnx") + + +# #writing a model with just one transpose layer of shape 2,3,3 +# input = gs.Variable(name="input", dtype=np.float32, shape=(1, 2,3, 3)) +# transpose_out = gs.Variable(name="transpose_out", dtype=np.float32, shape=(3,1,2, 3)) +# node = gs.Node(op="Transpose", inputs=[input], attrs={"perm": [3, 0,1, 2]}, outputs=[transpose_out]) +# graph = gs.Graph(nodes=[node], inputs=[input], outputs=[transpose_out]) +# onnx.save(gs.export_onnx(graph), "transpose.onnx") + +# writing a model with just one relu layer of shape 3,3 +# input = gs.Variable(name="input", dtype=np.float32, shape=(3, 3)) +# transpose_out = gs.Variable(name="relu_out", dtype=np.float32, shape=(3, 3)) +# node = gs.Node(op="LeakyRelu", inputs=[input], outputs=[transpose_out]) +# graph = gs.Graph(nodes=[node], inputs=[input], outputs=[transpose_out]) +# onnx.save(gs.export_onnx(graph), "leakyrelu.onnx") + + +# #writing a model with just one convtranspose of shape 1,8,8,8 +# input = gs.Variable(name="input", dtype=np.float32, shape=(1, 1, 2, 2)) +# transpose_out = gs.Variable(name="transpose_out", dtype=np.float32, shape=(1, 1, 3, 3)) +# W = gs.Constant(name="W", values=np.random.rand(1, 1, 2, 2).astype(np.float32)) +# node = gs.Node(op="ConvTranspose", inputs=[input, W], attrs={"strides": [1, 1], "kernel_shape": [2,2], "pads": [0, 0, 0, 0], "group": 1, "dilations": [1, 1]}, outputs=[transpose_out]) +# graph = gs.Graph(nodes=[node], inputs=[input], outputs=[transpose_out]) +# onnx.save(gs.export_onnx(graph), "convtranspose.onnx") + + +# #writing a model with just one conv3d of shape 1,1,64,64,64 +input = gs.Variable(name="input", dtype=np.float32, shape=(1, 1, 6, 6)) +output = gs.Variable(name="output", dtype=np.float32, shape=(1, 2, 6, 6)) +W = gs.Constant(name="W", values=np.random.rand(2, 1, 3, 3).astype(np.float32)) +node = gs.Node( + op="Conv", + inputs=[input, W], + attrs={ + "strides": [1, 1], + "kernel_shape": [3, 3], + "pads": [1, 1, 1, 1], + "group": 1, + "dilations": [1, 1], + }, + outputs=[output], +) +graph = gs.Graph(nodes=[node], inputs=[input], outputs=[output]) +onnx.save(gs.export_onnx(graph), "conv2d.onnx") diff --git a/OnnxBridge/helper/make_np_arr.py b/OnnxBridge/helper/make_np_arr.py index 59a1a3f8..5260680d 100644 --- a/OnnxBridge/helper/make_np_arr.py +++ b/OnnxBridge/helper/make_np_arr.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import numpy as np import sys import os diff --git a/OnnxBridge/helper/pre_process.py b/OnnxBridge/helper/pre_process.py index 44568a8a..c5c5d074 100755 --- a/OnnxBridge/helper/pre_process.py +++ b/OnnxBridge/helper/pre_process.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + from PIL import Image import numpy as np import sys @@ -27,4 +48,4 @@ def get_arr_from_image(path): img_path = sys.argv[1] arr = get_arr_from_image(img_path) npy_path = os.path.splitext(img_path)[0] + ".npy" - np.save(npy_path, arr) \ No newline at end of file + np.save(npy_path, arr) diff --git a/OnnxBridge/helper/run_onnx.py b/OnnxBridge/helper/run_onnx.py index 24907688..afa84b55 100755 --- a/OnnxBridge/helper/run_onnx.py +++ b/OnnxBridge/helper/run_onnx.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import numpy as np import onnxruntime as rt import sys, os @@ -7,9 +28,10 @@ sess = rt.InferenceSession(sys.argv[1]) input_name = sess.get_inputs()[0].name pred_onx = sess.run(None, {input_name: input_np_arr})[0] - print("Output:\n", pred_onx.flatten()) + # print("Output:\n", pred_onx.flatten()) output_dir = "onnx_output" if not os.path.exists(output_dir): os.makedirs(output_dir) output_name = os.path.join(output_dir, os.path.basename("expected.npy")) np.save(output_name, pred_onx.flatten()) + print("\n".join(map(str, pred_onx.flatten()))) diff --git a/OnnxBridge/image.png b/OnnxBridge/image.png new file mode 100644 index 0000000000000000000000000000000000000000..7e90b1304de3da2049a4ead99e96d895dcaba496 GIT binary patch literal 16907 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 z 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 literal 0 HcmV?d00001 diff --git a/OnnxBridge/main.py b/OnnxBridge/main.py index ab318620..ad6030da 100644 --- a/OnnxBridge/main.py +++ b/OnnxBridge/main.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import argparse, sys, os from sys import argv from utils import logger diff --git a/OnnxBridge/utils/backend_helper.py b/OnnxBridge/utils/backend_helper.py index ba38f000..0b38625e 100644 --- a/OnnxBridge/utils/backend_helper.py +++ b/OnnxBridge/utils/backend_helper.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + from utils import VariableGen, Party diff --git a/OnnxBridge/utils/logger.py b/OnnxBridge/utils/logger.py index d06d37e0..99f4a642 100644 --- a/OnnxBridge/utils/logger.py +++ b/OnnxBridge/utils/logger.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import logging import sys diff --git a/OnnxBridge/utils/nodes.py b/OnnxBridge/utils/nodes.py index f8eadc7a..5004f7a1 100644 --- a/OnnxBridge/utils/nodes.py +++ b/OnnxBridge/utils/nodes.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + from onnx import ValueInfoProto, TensorProto from utils import Party diff --git a/OnnxBridge/utils/onnx2IR_helper.py b/OnnxBridge/utils/onnx2IR_helper.py index 280b700f..d0599e04 100644 --- a/OnnxBridge/utils/onnx2IR_helper.py +++ b/OnnxBridge/utils/onnx2IR_helper.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + from numbers import Number from onnx import TensorProto diff --git a/OnnxBridge/utils/onnx_nodes.py b/OnnxBridge/utils/onnx_nodes.py index 31754faf..d9b71e83 100644 --- a/OnnxBridge/utils/onnx_nodes.py +++ b/OnnxBridge/utils/onnx_nodes.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + from utils import logger from utils.nodes import Input, Output diff --git a/OnnxBridge/utils/optimizations.py b/OnnxBridge/utils/optimizations.py index 91696eeb..571c53c3 100644 --- a/OnnxBridge/utils/optimizations.py +++ b/OnnxBridge/utils/optimizations.py @@ -1,3 +1,24 @@ +""" +Authors: Saksham Gupta. +Copyright: +Copyright (c) 2021 Microsoft Research +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + import os import struct diff --git a/inference-app/app_3d.py b/inference-app/app_3d.py new file mode 100644 index 00000000..0b3dc23f --- /dev/null +++ b/inference-app/app_3d.py @@ -0,0 +1,314 @@ +import gradio as gr +import time, os +from PIL import Image +import numpy as np +import ftplib +import requests +from tqdm import tqdm +from dotenv import load_dotenv + +load_dotenv() + +from constants import ( + desc, + Input_Shape, + EXAMPLES, + preprocess, + dims, + scale, + mode, + labels_map, +) + +url = os.getenv("_URL") +user = os.getenv("_USER") +passwd = os.getenv("_PASSWORD") +file_name = os.getenv("_FILE_NAME") +client_ip = os.getenv("_CLIENT_IP") + + +print("Starting the demo...") +with gr.Blocks(theme=gr.themes.Monochrome()) as demo: + gr.Markdown( + f""" + + + + + +

+
+ EzPC +
+

+

Securely Inferencing a Machine Learning model using EzPC

+ + +

+ EzPC + — + Project +

+

+ +

+ +

+ +

+ {desc} +

+ +

+ Try out the below app, and see + tutorial + for more info! +

+ """ + ) + + gr.Markdown("## Client side") + + # Step 1 Input Image + gr.Markdown("### Step 1: Upload an image. ") + gr.Markdown( + f"The image will automatically be resized to shape {Input_Shape} as the input size for lenet model. " + ) + + with gr.Row(): + input_image = gr.Image( + value=None, + label="Upload an image here.", + shape=(dims["h"], dims["d"]), + source="upload", + interactive=True, + image_mode=mode, + type="pil", + ) + examples = gr.Examples( + examples=EXAMPLES, + inputs=[input_image], + examples_per_page=5, + label="Examples to use.", + ) + + # Step 2 Get Mask from Dealer + gr.Markdown( + "### Step 2: Click on the button below to get encryption keys from dealer." + ) + dealer_status = gr.Textbox( + label="Status", placeholder="Encryption Keys status will be shown here." + ) + get_mask_button = gr.Button(value="Get Encryption Keys", interactive=True) + + # Step 3 Mask Input Image + gr.Markdown("### Step 3: Click on the button below to encrypt the image.") + with gr.Row(): + in_image = gr.Image( + value=None, + label="Input Image", + shape=(dims["h"], dims["d"]), + interactive=False, + image_mode=mode, + type="pil", + ).style(width=256, height=256) + out_image = gr.Image( + value=None, + label="Encrypted Image", + shape=(dims["h"], dims["d"]), + interactive=False, + ).style(width=256, height=256) + mask_button = gr.Button(value="Encrypt Image", interactive=True) + + # Step 4 Start Secure Inference + gr.Markdown( + "### Step 4: Click on the button below to start secure inference with Encrypted Image." + ) + with gr.Column(): + inference_status = gr.Textbox( + show_label=False, + placeholder="Inference status will be shown here.", + interactive=False, + ) + inference_button = gr.Button(value="Start Secure Inference", interactive=True) + prediction = gr.Label("Prediction: ", interactive=False, visible=False) + + def show_progress(progress=gr.Progress()): + for i in range(10): + time.sleep(0.1) + progress(i / 10, desc="Encrypting Image") + return True + + def update_input_image(input_image): + return input_image + + def check_dealer_status(progress=gr.Progress()): + try: + progress(0.001, desc="Connecting with Dealer\n Please wait...") + progress(0.035, desc="Dealer is still generating keys\n Please wait...") + ftp = ftplib.FTP() + print(f"Connecting to {url}") + ftp.connect(url, 9000) + progress(0.05, desc="Authenticating with Dealer") + ftp.login(user=user, passwd=passwd) + progress(0.1, desc="Authenticated Successfully") + + # Switch to binary mode + ftp.sendcmd("TYPE i") + + # Get the size of the file on the server + file_size = ftp.size(file_name) + print(f"File size: {file_size}") + + xbar = 0.1 + # Download the file and display a progress bar + with open(file_name, "wb") as f: + with tqdm( + unit="B", unit_scale=True, unit_divisor=1024, total=file_size + ) as pbar: + + def callback(data): + f.write(data) + pbar.update(len(data)) + progress( + xbar + (1 - xbar) * pbar.n / file_size, + desc="Downloading Encryption Keys", + ) + + ftp.retrbinary(f"RETR {file_name}", callback) + + ftp.quit() + return { + dealer_status: gr.update( + value="Encryption Keys received from dealer.", visible=True + ) + } + + except Exception as e: + print(f"Error: {e}") + # print(f"Error: Dealer not ready.") + return { + dealer_status: gr.update( + value="Dealer not ready, please try again after some time.", + visible=True, + ) + } + + def mask_image(input_image, progress=gr.Progress()): + arr = preprocess(input_image) + + # Open the file for reading + with open("masks.dat", "r") as f: + # Read the contents of the file as a list of integers + data = [int(line.strip()) for line in f.readlines()] + + # Convert the list of integers to a numpy array + np_mask = np.array(data).reshape( + (1, dims["h"], dims["w"], dims["d"], dims["c"]) + ) + np_mask = np.transpose(np_mask, (0, 4, 1, 2, 3)) + + print("Masking Image") + arr_save = arr.copy() + arr_save = arr_save * (1 << scale) + arr_save = arr_save.astype(np.int64) + arr_save = arr_save + np_mask + np.save("masked_image.npy", arr_save) + + # for debugging + # with open("masked_inp.inp", "w") as f: + # for x in np.nditer(arr_save, order='C'): + # f.write(str(x) + "\n") + + if mode == "RGB": + arr_save = arr_save.reshape(Input_Shape[1:]) + print(arr_save.shape) + arr_converted = np.transpose(arr_save, (1, 2, 0)) + updated_image = Image.fromarray(arr_converted, mode=mode) + show_progress(progress) + print(updated_image.size) + elif mode == "L": + arr_save = arr_save[0, 0, :, 0, :] + print(arr_save.shape) + updated_image = Image.fromarray(arr_save, mode=mode) + show_progress(progress) + print(updated_image.size) + else: + print("Invalid Mode") + return None + return updated_image + + def start_inference(in_image, progress=gr.Progress()): + print("Starting Inference") + url = f"http://{client_ip}:5000/inference" + file_path = "masked_image.npy" + with open(file_path, "rb") as file: + try: + response = requests.get(url, files={"file": file}) + + if response.status_code == 200: + with open("output.txt", "wb") as file: + print(response.content) + file.write(response.content) + else: + print("Error:", response.status_code) + return { + inference_status: gr.update( + value=f"Error {response.status_code} \nClient in Setup Phase...", + visible=True, + ) + } + + except requests.Timeout: + print("Connection timeout.") + return { + prediction: gr.update( + value=f"Connection Timedout. \nClient in Setup Phase...", + visible=True, + ) + } + except requests.HTTPError as e: + print("HTTP Error:", e) + return { + prediction: gr.update( + value=f"Error {e} \nClient in Setup Phase...", visible=True + ) + } + except requests.RequestException as e: + print("Error:", e) + return { + prediction: gr.update( + value=f"Connection Refused. \nClient in Setup Phase...", + visible=True, + ) + } + + # Read the contents of the file as a list of integers and return the index of max value + with open("output.txt", "r") as f: + # Read the contents of the file as a list of integers + data_as_str = [line.strip() for line in f.readlines()] + data = data_as_str[0].split(" ") + data = [float(i) for i in data] + # find the index of max value + print(data) + print(type(data)) + print(type(data[0])) + index = data.index(max(data)) + print(f"Prediction: {labels_map[index]}") + return { + prediction: gr.update( + value=f"Prediction: {labels_map[index]}", visible=True + ) + } + + get_mask_button.click(fn=check_dealer_status, inputs=[], outputs=[dealer_status]) + + mask_button.click(fn=mask_image, inputs=[input_image], outputs=[out_image]) + + inference_button.click( + fn=start_inference, inputs=[out_image], outputs=[inference_status, prediction] + ) + + input_image.change(fn=update_input_image, inputs=[input_image], outputs=[in_image]) + +demo.queue(concurrency_count=20).launch(share=False)