Skip to content
This repository has been archived by the owner on Apr 16, 2024. It is now read-only.

CPP example #26

Merged
merged 69 commits into from
Mar 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
adb9a3b
Init CPP project
Jan 13, 2022
f342fb7
working C++ training
Jan 14, 2022
b0529f4
add ssh
Jan 14, 2022
1ecfd42
remove json
Jan 17, 2022
6442886
Ignore devcontainer.json
Jan 17, 2022
c8e1dc5
ignore some stuff from docker ctx
Jan 17, 2022
3a8de19
Add NumCpp
Jan 17, 2022
bc52b1e
Import NumCpp
Jan 17, 2022
cfd922c
rollback numcpp
Jan 17, 2022
0065b27
params
Jan 19, 2022
47786ff
Env
Jan 19, 2022
6d99fea
Add conda
Jan 19, 2022
6173eb2
pin ipykernel
Jan 19, 2022
7db9a52
add packages
Jan 19, 2022
5dafe02
Splitting
Jan 19, 2022
c8f8643
remove test
Jan 20, 2022
e1b879a
install fedn
Jan 20, 2022
07684cc
Add compose
Jan 20, 2022
5a37141
conda entrypoint
Jan 20, 2022
2a03506
refactory
Jan 20, 2022
ff7cdbb
no need to change user
Jan 20, 2022
2498a94
Docker compose
Jan 20, 2022
0ea532c
Compose working
Jan 20, 2022
d43bb68
Reducer code
Jan 21, 2022
ad5482a
Merge branch 'dev/mnist-cpp' of github.com:scaleoutsystems/examples i…
Jan 21, 2022
237c94e
compose working
Jan 21, 2022
6b02481
minor refactory
Jan 21, 2022
d266d38
Binaries working
Jan 24, 2022
eef1ee1
fix
Jan 24, 2022
3266f4f
ignore
Jan 24, 2022
82f9de3
build package
Jan 24, 2022
7c73994
refining package
Jan 25, 2022
042744c
configure app dir
Jan 26, 2022
549982c
Working with one combiner
Jan 26, 2022
9673904
multicontainer support
Jan 27, 2022
283ae16
consolidate build script
Jan 27, 2022
1513fba
vscode settings
Jan 27, 2022
5ed3035
Linting/formatting
Jan 27, 2022
4735bea
fixes
Jan 28, 2022
cee907f
fix
Jan 28, 2022
f36510f
add env
Jan 28, 2022
dd03e2f
delete
Jan 28, 2022
3fe24a5
Example working with lanch
Jan 28, 2022
3234be1
docs
Jan 28, 2022
b91b257
Docker compose
Jan 28, 2022
21d1f85
minor
Jan 31, 2022
0296f91
typo
Jan 31, 2022
a0da0eb
gramine deps
Jan 31, 2022
8768a21
separate fedn env
Feb 1, 2022
44520eb
change version and add numpy
Feb 1, 2022
3230339
fixed gramine in conda
Feb 2, 2022
c4c29e8
fix conda prefix
Feb 2, 2022
6382181
generage gramine files
Feb 2, 2022
2b60d6e
add gramine templates
Feb 2, 2022
fc6426f
change gramine head
Feb 3, 2022
1486456
Merge branch 'dev/gramine' of github.com:scaleoutsystems/examples int…
Feb 3, 2022
ece6835
fix manifest
Feb 4, 2022
1409a33
limit threads
Feb 7, 2022
e1cff47
train on 2 threads only
Feb 7, 2022
3775bcb
change tmpdir
Feb 8, 2022
21955ac
fix template data path
Feb 8, 2022
e41c401
fix template for SGX
Feb 8, 2022
ed7af23
increasing threads
Feb 8, 2022
d5b41f8
bumpi gramine
Feb 9, 2022
80e4db2
Merge branch 'dev/gramine' of github.com:scaleoutsystems/examples int…
Feb 9, 2022
3106652
training in enclave working
Feb 9, 2022
a38ccf0
add TEE to docs
Feb 9, 2022
8184be6
improve guide
Feb 9, 2022
738097b
minor fix
Feb 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mnist-cpp/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
BasedOnStyle: Google
23 changes: 23 additions & 0 deletions mnist-cpp/.devcontainer/devcontainer.json.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "devcontainer",
"dockerFile": "../Dockerfile",
"context": "..",
"remoteUser": "default",
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.cpptools-themes",
"exiasr.hadolint",
"yzhang.markdown-all-in-one",
"ms-python.python",
"ms-toolsai.jupyter",
"ms-azuretools.vscode-docker"
],
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind,consistency=default",
],
"runArgs": [
"--net=host"
],
"forwardPorts": [8090, 9000, 9001, 8081],
}
4 changes: 4 additions & 0 deletions mnist-cpp/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build
data
net.pt
devcontainer.json
15 changes: 15 additions & 0 deletions mnist-cpp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
build
*.pt
/**/*.json
train
validate
package
*.npz
src/fedn
!.vscode/settings.json
data
.env
*.sgx
*.manifest
*.sig
*.token
8 changes: 8 additions & 0 deletions mnist-cpp/.hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ignored:
- DL3008
- DL4001
- SC2046
- DL4006
- SC2164
- DL3004
- SC2086
79 changes: 79 additions & 0 deletions mnist-cpp/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"cinttypes": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"netfwd": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp"
},
"python.languageServer": "None",
"python.pythonPath": "/opt/conda/envs/default/bin/python",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
}
14 changes: 14 additions & 0 deletions mnist-cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(mnist-cpp)

list(APPEND CMAKE_PREFIX_PATH "$ENV{TORCH_DIR}/libtorch")
find_package(Torch REQUIRED)

set(HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/net.h")

foreach(_target
train validate)
add_executable(${_target} "${_target}.cpp" "${HEADER_FILES}")
target_link_libraries(${_target} "${TORCH_LIBRARIES}")
set_property(TARGET ${_target} PROPERTY CXX_STANDARD 14)
endforeach()
169 changes: 169 additions & 0 deletions mnist-cpp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Base image
FROM debian:bookworm

# Env versioning
ARG HADOLINT_VERSION=v2.8.0
ARG CMAKE_VERSION=3.16.9
ARG TORCH_VERSION=1.10.1
ARG NUMCPP_VERSION=2.6.2
ARG DOCKER_VERSION=19.03.9
ARG CONDA_VERSION=4.9.2
ARG COMPOSE_VERSION=1.29.2
ARG SGX_SDK_VERSION=2.15.101.1
ARG SGX_PSW_VERSION=2.15.1
ARG GRAMINE_HEAD=v1.1

# Non-root user with sudo access
ARG USERNAME=default
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

# Other env
ENV TORCH_DIR=/opt/torch
ENV DATA_DIR=/app/data

# Install apt deps
SHELL ["/bin/bash", "-c"]
RUN apt-get update \
&& apt-get -y install --no-install-recommends \
apt-utils \
dialog 2>&1 \
#
# More apt deps
&& apt-get install -y --no-install-recommends \
sudo \
ca-certificates \
wget \
curl \
git \
vim \
openssh-client \
build-essential \
autoconf \
libtool \
pkg-config \
googletest \
libgtest-dev \
autoconf \
gawk \
libcurl4-openssl-dev \
libprotobuf-c-dev \
protobuf-c-compiler \
linux-headers-amd64 \
unzip \
bison \
#
# Hadolint
&& wget --progress=dot:giga -O /bin/hadolint \
https://github.com/hadolint/hadolint/releases/download/${HADOLINT_VERSION}/hadolint-Linux-x86_64 \
&& chmod +x /bin/hadolint \
#
# Install docker binaries
&& curl -L https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz | tar xvz docker/docker \
&& cp docker/docker /usr/local/bin \
&& rm -R docker \
&& curl -L https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose \
&& chmod +x /usr/local/bin/docker-compose \
#
# Install cmake
&& wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-Linux-x86_64.sh \
&& sh cmake-linux.sh -- --skip-license \
&& rm cmake-linux.sh \
#
# Install libtorch
&& mkdir $TORCH_DIR \
&& pushd $TORCH_DIR \
&& wget --progress=dot:giga https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-${TORCH_VERSION}%2Bcpu.zip \
&& unzip libtorch-cxx11-abi-shared-with-deps-${TORCH_VERSION}+cpu.zip \
&& rm -r libtorch-cxx11-abi-shared-with-deps-${TORCH_VERSION}+cpu.zip \
&& popd \
#
# SGX SDK
&& wget --progress=dot:giga https://download.01.org/intel-sgx/latest/linux-latest/distro/ubuntu20.04-server/sgx_linux_x64_sdk_${SGX_SDK_VERSION}.bin \
&& chmod +x sgx_linux_x64_sdk_${SGX_SDK_VERSION}.bin \
&& ./sgx_linux_x64_sdk_${SGX_SDK_VERSION}.bin --prefix /opt/sgx-sdk \
&& rm sgx_linux_x64_sdk_${SGX_SDK_VERSION}.bin \
#
# SGX PSW
&& wget --progress=dot:giga https://download.01.org/intel-sgx/sgx-linux/${SGX_PSW_VERSION}/distro/ubuntu20.04-server/sgx_debian_local_repo.tgz \
&& tar xzvf sgx_debian_local_repo.tgz \
&& mv sgx_debian_local_repo /opt \
&& echo 'deb [trusted=yes] file:///opt/sgx_debian_local_repo focal main' >> /etc/apt/sources.list \
&& echo 'deb [trusted=yes] http://archive.ubuntu.com/ubuntu focal main' >> /etc/apt/sources.list \
&& apt-get update \
&& sudo apt-get install -y --no-install-recommends \
ubuntu-keyring \
libsgx-urts \
libsgx-launch \
libsgx-epid \
libsgx-quote-ex \
libsgx-dcap-ql \
#
# Install conda
&& wget --progress=dot:giga https://repo.anaconda.com/miniconda/Miniconda3-py39_${CONDA_VERSION}-Linux-x86_64.sh \
&& bash Miniconda3-py39_${CONDA_VERSION}-Linux-x86_64.sh -b -p /opt/conda \
&& rm -f Miniconda3-py39_${CONDA_VERSION}-Linux-x86_64.sh \
&& ln -s /opt/conda/bin/conda /bin/conda \
&& ln -s /opt/conda/bin/conda-env /bin/conda-env \
#
# Create a non-root user to use if preferred
&& groupadd --gid $USER_GID $USERNAME \
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME \
#
# Configure FEDn directories
&& mkdir -p /app/certs \
&& mkdir -p /app/client/package \
&& mkdir -p /app/config \
&& chown -R $USERNAME /app \
#
# Configure data dir
&& mkdir -p $DATA_DIR \
&& chown $USERNAME $DATA_DIR \
#
# Configure for gramine
&& mkdir -p /usr/include/asm \
&& ln -s /usr/src/linux-headers-*/arch/x86/include/uapi/asm/sgx.h /usr/include/asm/sgx.h \
&& mkdir -p /opt/gramine \
&& chown -R $USERNAME /opt/gramine \
#
# Cleanup
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*

# Copy FEDn config
COPY config/*.yaml /app/config/

# Setup default environment
COPY environment.yaml /tmp/environment.yaml
RUN conda env create -f /tmp/environment.yaml \
&& rm /tmp/environment.yaml \
&& conda run -n default python -m ipykernel install --name default \
&& chown $USERNAME /opt/conda/envs/default

# Init conda for non-root user
USER $USERNAME
RUN conda init bash \
&& conda config --set auto_activate_base false \
&& echo "conda activate default" >> ~/.bashrc

# Gramine
RUN git clone https://github.com/gramineproject/gramine.git /opt/gramine \
&& pushd /opt/gramine \
&& git checkout $GRAMINE_HEAD \
&& conda run -n default meson setup build/ \
--buildtype=release -Ddirect=enabled -Dsgx=enabled --prefix=/opt/conda/envs/default \
&& conda run -n default ninja -C build/ \
&& sudo /opt/conda/envs/default/bin/ninja -C build/ install \
&& popd

# Switch back to dialog for any ad-hoc use of apt-get
ENV DEBIAN_FRONTEND=dialog

# Add entrypoint to conda environment for commands
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "default"]
51 changes: 51 additions & 0 deletions mnist-cpp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# MNIST example - Pytorch C++
This is an example of the classic MNIST hand-written text recognition task using FEDn with the PyTorch C++ API.

## Table of Contents
- [MNIST example - Pytorch C++](#mnist-example---pytorch-c)
- [Table of Contents](#table-of-contents)
- [Prerequisites](#prerequisites)
- [Running the example](#running-the-example)
- [Clean up](#clean-up)
- [Running in Truested Execution Environment (TEE)](#running-in-truested-execution-environment-tee)

## Prerequisites
The only prerequisite to run this example is [Docker](https://www.docker.com).

## Running the example

Start the Docker environment:
```
bin/launch.sh
```
> This may take a few minutes.

Download the data:
```
bin/download_data.sh
```

Build the compute package and train the seed model:
```
bin/build.sh
```
> This may take a few minutes. After completion `package/package.tgz` and `seed.npz` should be built in your current working directory.

Start reducer and combiner network:
```
sudo docker-compose up -d
```
> This may take a few minutes. After this is done you should be able to access the reducer interface at https://localhost:8090.

Now navigate to https://localhost:8090 and upload `package/package.tgz` and `seed.npz`. After you are done you can deploy two clients by running:
```
sudo docker-compose up -d --scale client=2
```

Finally, you can navigate again to https://localhost:8090 and start the experiment from the "control" tab.

## Clean up
To clean up you can run: `sudo docker-compose down`. To exit the Docker environment simply run `exit`.

## Running in Truested Execution Environment (TEE)
The compute package in this example supports running training and validation in [Intel SGX TEE](https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/overview.html) via [Gramine](https://grapheneproject.io). The code was tested using [Azure Confidential Computing](https://azure.microsoft.com/en-us/solutions/confidential-compute). To enable this running mode, after starting the development container with `bin/launch.sh` you can run: `echo "LOADER=gramine-sgx" >> .env` and repeat all of the subsequent seps.
Loading