Skip to content

Commit

Permalink
Merge branch 'main' into fds-rename-size-partitioner
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-narozniak authored Sep 10, 2024
2 parents 5447b9b + 8f8639f commit ff7ecca
Show file tree
Hide file tree
Showing 121 changed files with 2,658 additions and 1,868 deletions.
11 changes: 10 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
README.md @jafermarq @tanertopal @danieljanes

# Flower Baselines
/baselines @jafermarq @tanertopal @danieljanes
/baselines @jafermarq @danieljanes

# Flower Benchmarks
/benchmarks @jafermarq @danieljanes

# Flower Datasets
/datasets @jafermarq @tanertopal @danieljanes
Expand All @@ -27,3 +30,9 @@ README.md @jafermarq @tanertopal @danieljanes
# GitHub Actions and Workflows
/.github/workflows @Robert-Steiner @tanertopal @danieljanes
/.github/actions @Robert-Steiner @tanertopal @danieljanes

# Docker-related files
/.devcontainer @Robert-Steiner @Moep90
**/Dockerfile @Robert-Steiner @Moep90
**/*.Dockerfile @Robert-Steiner @Moep90
src/docker @Robert-Steiner @Moep90
18 changes: 5 additions & 13 deletions .github/workflows/_docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,16 @@ permissions:
jobs:
build:
name: Build image
runs-on: ubuntu-22.04
runs-on: ${{ matrix.platform.runner-os }}
timeout-minutes: 180
outputs:
build-id: ${{ steps.build-id.outputs.id }}
strategy:
fail-fast: true
matrix:
platform: [
# build-push action and qemu use different platform names
# therefore we create a map
{ name: "amd64", qemu: "", docker: "linux/amd64" },
{ name: "arm64", qemu: "arm64", docker: "linux/arm64" },
{ name: "amd64", docker: "linux/amd64", runner-os: "ubuntu-22.04" },
{ name: "arm64", docker: "linux/arm64", runner-os: "ubuntu-4-core-arm64" },
]
steps:
- name: Create build id
Expand Down Expand Up @@ -79,12 +77,6 @@ jobs:
print(build_args, file=fh)
print("EOF", file=fh)
- name: Set up QEMU
if: matrix.platform.qemu != ''
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
with:
platforms: ${{ matrix.platform.qemu }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
Expand All @@ -104,7 +96,7 @@ jobs:
uses: Wandalen/wretry.action@6feedb7dedadeb826de0f45ff482b53b379a7844 # v3.5.0
id: build
with:
action: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
action: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
attempt_limit: 60 # 60 attempts * (9 secs delay + 1 sec retry) = ~10 mins
attempt_delay: 9000 # 9 secs
with: |
Expand All @@ -122,7 +114,7 @@ jobs:
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: digests-${{ steps.build-id.outputs.id }}-${{ matrix.platform.name }}
path: /tmp/digests/*
Expand Down
69 changes: 69 additions & 0 deletions .github/workflows/docker-build-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Build Docker Images Main Branch

on:
push:
branches:
- 'main'

jobs:
parameters:
if: github.repository == 'adap/flower'
name: Collect docker build parameters
runs-on: ubuntu-22.04
timeout-minutes: 10
outputs:
pip-version: ${{ steps.versions.outputs.pip-version }}
setuptools-version: ${{ steps.versions.outputs.setuptools-version }}
flwr-version-ref: ${{ steps.versions.outputs.flwr-version-ref }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- uses: ./.github/actions/bootstrap
id: bootstrap

- id: versions
run: |
echo "pip-version=${{ steps.bootstrap.outputs.pip-version }}" >> "$GITHUB_OUTPUT"
echo "setuptools-version=${{ steps.bootstrap.outputs.setuptools-version }}" >> "$GITHUB_OUTPUT"
echo "flwr-version-ref=git+${{ github.server_url }}/${{ github.repository }}.git@${{ github.sha }}" >> "$GITHUB_OUTPUT"
build-docker-base-images:
name: Build base images
if: github.repository == 'adap/flower'
uses: ./.github/workflows/_docker-build.yml
needs: parameters
with:
namespace-repository: flwr/base
file-dir: src/docker/base/ubuntu
build-args: |
PIP_VERSION=${{ needs.parameters.outputs.pip-version }}
SETUPTOOLS_VERSION=${{ needs.parameters.outputs.setuptools-version }}
FLWR_VERSION_REF=${{ needs.parameters.outputs.flwr-version-ref }}
tags: unstable
secrets:
dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}

build-docker-binary-images:
name: Build binary images
if: github.repository == 'adap/flower'
uses: ./.github/workflows/_docker-build.yml
needs: build-docker-base-images
strategy:
fail-fast: false
matrix:
images: [
{ repository: "flwr/superlink", file_dir: "src/docker/superlink" },
{ repository: "flwr/supernode", file_dir: "src/docker/supernode" },
{ repository: "flwr/serverapp", file_dir: "src/docker/serverapp" },
{ repository: "flwr/superexec", file_dir: "src/docker/superexec" },
{ repository: "flwr/clientapp", file_dir: "src/docker/clientapp" }
]
with:
namespace-repository: ${{ matrix.images.repository }}
file-dir: ${{ matrix.images.file_dir }}
build-args: BASE_IMAGE=unstable
tags: unstable
secrets:
dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
51 changes: 51 additions & 0 deletions .github/workflows/docker-readme.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Update Docker READMEs

on:
push:
branches:
- 'main'
paths:
- 'src/docker/**/README.md'

jobs:
collect:
if: ${{ github.repository == 'adap/flower' }}
name: Collect Docker READMEs
runs-on: ubuntu-22.04
timeout-minutes: 10
outputs:
readme_files: ${{ steps.filter.outputs.readme_files }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
list-files: "json"
filters: |
readme:
- 'src/docker/**/README.md'
update:
if: ${{ needs.collect.outputs.readme_files != '' && toJson(fromJson(needs.collect.outputs.readme_files)) != '[]' }}
name: Update Docker READMEs
runs-on: ubuntu-22.04
timeout-minutes: 10
needs: collect
strategy:
matrix:
readme_path: ${{ fromJSON(needs.collect.outputs.readme_files) }}

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- id: repository
run: echo "name=$(basename $(dirname ${{ matrix.readme_path }}))" >> "$GITHUB_OUTPUT"

- name: Docker Hub Description
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4.0.0
with:
repository: flwr/${{ steps.repository.outputs.name }}
readme-filepath: ${{ matrix.readme_path }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
4 changes: 1 addition & 3 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ jobs:
if: ${{ github.repository == 'adap/flower' && !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }}
run: |
python -m pip install https://${{ env.ARTIFACT_BUCKET }}/py/${{ needs.wheel.outputs.dir }}/${{ needs.wheel.outputs.short_sha }}/${{ needs.wheel.outputs.whl_path }}
- name: Install e2e components
run: pip install .
- name: Download dataset
if: ${{ matrix.dataset }}
run: python -c "${{ matrix.dataset }}"
Expand All @@ -172,7 +170,7 @@ jobs:
run: ./../test_superlink.sh bare sqlite
- name: Run driver test with client authentication
if: ${{ matrix.directory == 'e2e-bare-auth' }}
run: ./../test_superlink.sh bare client-auth
run: ./../test_superlink.sh "${{ matrix.directory }}" client-auth
- name: Run reconnection test with SQLite database
if: ${{ matrix.directory == 'e2e-bare' }}
run: ./../test_reconnection.sh sqlite
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/framework-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
if: ${{ github.repository == 'adap/flower' }}
name: Publish release
runs-on: ubuntu-22.04
outputs:
flwr-version: ${{ steps.publish.outputs.flwr-version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -26,10 +28,12 @@ jobs:
uses: ./.github/actions/bootstrap

- name: Get artifacts and publish
id: publish
env:
GITHUB_REF: ${{ github.ref }}
run: |
TAG_NAME=$(echo "${GITHUB_REF_NAME}" | cut -c2-)
echo "flwr-version=$TAG_NAME" >> "$GITHUB_OUTPUT"
wheel_name="flwr-${TAG_NAME}-py3-none-any.whl"
tar_name="flwr-${TAG_NAME}.tar.gz"
Expand Down Expand Up @@ -67,8 +71,7 @@ jobs:
- id: matrix
run: |
FLWR_VERSION=$(poetry version -s)
python dev/build-docker-image-matrix.py --flwr-version "${FLWR_VERSION}" > matrix.json
python dev/build-docker-image-matrix.py --flwr-version "${{ needs.publish.outputs.flwr-version }}" > matrix.json
echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT
build-base-images:
Expand Down
34 changes: 16 additions & 18 deletions baselines/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# Flower Baselines


> [!NOTE]
> We are changing the way we structure the Flower baselines. While we complete the transition to the new format, you can still find the existing baselines in the `flwr_baselines` directory. Currently, you can make use of baselines for [FedAvg](https://github.com/adap/flower/tree/main/baselines/flwr_baselines/flwr_baselines/publications/fedavg_mnist), [FedOpt](https://github.com/adap/flower/tree/main/baselines/flwr_baselines/flwr_baselines/publications/adaptive_federated_optimization), and [LEAF-FEMNIST](https://github.com/adap/flower/tree/main/baselines/flwr_baselines/flwr_baselines/publications/leaf/femnist).
> The documentation below has been updated to reflect the new way of using Flower baselines.

## Structure

Expand All @@ -15,17 +14,15 @@ baselines/<baseline-name>/
├── README.md
├── pyproject.toml
└── <baseline-name>
├── *.py # several .py files including main.py and __init__.py
└── conf
└── *.yaml # one or more Hydra config files
└── *.py # several .py files
```
Please note that some baselines might include additional files (e.g. a `requirements.txt`) or a hierarchy of `.yaml` files for [Hydra](https://hydra.cc/).

## Running the baselines

Each baseline is self-contained in its own directory. Furthermore, each baseline defines its own Python environment using [Poetry](https://python-poetry.org/docs/) via a `pyproject.toml` file and [`pyenv`](https://github.com/pyenv/pyenv). If you haven't setup `Poetry` and `pyenv` already on your machine, please take a look at the [Documentation](https://flower.ai/docs/baselines/how-to-use-baselines.html#setting-up-your-machine) for a guide on how to do so.
> [!NOTE]
> We are in the process of migrating all baselines to use `flwr run`. Those baselines that remain using the previous system (i.e. using [Poetry](https://python-poetry.org/), [Hydra](https://hydra.cc/) and [start_simulation](https://flower.ai/docs/framework/ref-api/flwr.simulation.start_simulation.html)) might require you to first setup `Poetry` and `pyenv` already on your machine, please take a look at the [Documentation](https://flower.ai/docs/baselines/how-to-use-baselines.html#setting-up-your-machine) for a guide on how to do so.
Assuming `pyenv` and `Poetry` are already installed on your system. Running a baseline can be done by:
Each baseline is self-contained in its own directory. To run a baseline:

1. Cloning the flower repository

Expand All @@ -34,29 +31,30 @@ Assuming `pyenv` and `Poetry` are already installed on your system. Running a ba
```

2. Navigate inside the directory of the baseline you'd like to run.
3. Follow the `[Environment Setup]` instructions in the `README.md`. In most cases this will require you to just do:
```bash
poetry install
```
3. Follow the `[Environment Setup]` instructions in the `README.md`.
4. Run the baseline as indicated in the `[Running the Experiments]` section in the `README.md` or in the `[Expected Results]` section to reproduce the experiments in the paper.
## Contributing a new baseline
Do you have a new federated learning paper and want to add a new baseline to Flower? Or do you want to add an experiment to an existing baseline paper? Great, we really appreciate your contribution !!
> [!TIP]
> A more verbose version of these steps can be found in the [Flower Baselines documentation](https://flower.ai/docs/baselines/how-to-contribute-baselines.html).
The steps to follow are:
1. Create a new Python 3.10 environment and install Flower (`pip install flwr`)
1. Fork the Flower repo and clone it into your machine.
2. Navigate to the `baselines/` directory, choose a single-word (and **lowercase**) name for your baseline, and from there run:
2. Navigate to the `baselines/` directory, from there and with your environment activated, run:
```bash
# This will create a new directory with the same structure as `baseline_template`.
./dev/create-baseline.sh <baseline-name>
# Choose option "Flower Baseline" when prompted
flwr new <baseline-name>
```
3. Then, go inside your baseline directory and continue with the steps detailed in `EXTENDED_README.md` and `README.md`.
4. Once your code is ready and you have checked that following the instructions in your `README.md` the Python environment can be created correctly and that running the code following your instructions can reproduce the experiments in the paper, you just need to create a Pull Request (PR). Then, the process to merge your baseline into the Flower repo will begin!
3. Then, go inside your baseline directory and continue with the steps detailed in the `README.md`.
4. Once your code is ready, check that you have completed all the sections in the `README.md` and that, if a new environment is created, your baseline still runs (i.e. play the role of a person running the baseline you want to contribute).
5. Create a Pull Request (PR). Then, the process to merge your baseline into the Flower repo will begin!
Further resources:
Expand Down
Loading

0 comments on commit ff7ecca

Please sign in to comment.