flwr-nightly 1.10.0.dev20240712__py3-none-any.whl → 1.10.0.dev20240714__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flwr-nightly might be problematic. Click here for more details.
- flwr/cli/new/templates/app/code/client.hf.py.tpl +6 -2
- flwr/cli/new/templates/app/code/client.jax.py.tpl +2 -1
- flwr/cli/new/templates/app/code/client.mlx.py.tpl +5 -2
- flwr/cli/new/templates/app/code/client.numpy.py.tpl +2 -1
- flwr/cli/new/templates/app/code/client.pytorch.py.tpl +5 -2
- flwr/cli/new/templates/app/code/client.sklearn.py.tpl +4 -2
- flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +5 -2
- flwr/cli/new/templates/app/code/server.hf.py.tpl +13 -11
- flwr/cli/new/templates/app/code/server.jax.py.tpl +12 -8
- flwr/cli/new/templates/app/code/server.mlx.py.tpl +8 -7
- flwr/cli/new/templates/app/code/server.numpy.py.tpl +12 -8
- flwr/cli/new/templates/app/code/server.pytorch.py.tpl +13 -14
- flwr/cli/new/templates/app/code/server.sklearn.py.tpl +13 -10
- flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +13 -13
- flwr/cli/new/templates/app/code/task.hf.py.tpl +2 -2
- flwr/cli/new/templates/app/code/task.mlx.py.tpl +2 -2
- flwr/cli/new/templates/app/code/task.pytorch.py.tpl +1 -1
- flwr/cli/run/run.py +1 -1
- flwr/client/app.py +4 -7
- flwr/client/client_app.py +28 -8
- flwr/client/message_handler/message_handler.py +1 -1
- flwr/client/node_state.py +3 -3
- flwr/client/node_state_tests.py +1 -1
- flwr/client/typing.py +2 -2
- flwr/common/constant.py +3 -0
- flwr/common/context.py +1 -8
- flwr/server/superlink/fleet/vce/backend/raybackend.py +2 -1
- flwr/server/superlink/fleet/vce/vce_api.py +14 -3
- flwr/simulation/app.py +4 -3
- flwr/simulation/ray_transport/ray_client_proxy.py +20 -9
- flwr/superexec/app.py +11 -5
- flwr/superexec/deployment.py +85 -21
- flwr/superexec/exec_grpc.py +5 -2
- flwr/superexec/executor.py +18 -1
- {flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/METADATA +1 -1
- {flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/RECORD +39 -39
- {flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""$project_name: A Flower / HuggingFace Transformers app."""
|
|
2
2
|
|
|
3
3
|
from flwr.client import ClientApp, NumPyClient
|
|
4
|
+
from flwr.common import Context
|
|
4
5
|
from transformers import AutoModelForSequenceClassification
|
|
5
6
|
|
|
6
7
|
from $import_name.task import (
|
|
@@ -38,12 +39,15 @@ class FlowerClient(NumPyClient):
|
|
|
38
39
|
return float(loss), len(self.testloader), {"accuracy": accuracy}
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
def client_fn(
|
|
42
|
+
def client_fn(context: Context):
|
|
42
43
|
# Load model and data
|
|
43
44
|
net = AutoModelForSequenceClassification.from_pretrained(
|
|
44
45
|
CHECKPOINT, num_labels=2
|
|
45
46
|
).to(DEVICE)
|
|
46
|
-
|
|
47
|
+
|
|
48
|
+
partition_id = int(context.node_config['partition-id'])
|
|
49
|
+
num_partitions = int(context.node_config['num-partitions])
|
|
50
|
+
trainloader, valloader = load_data(partition_id, num_partitions)
|
|
47
51
|
|
|
48
52
|
# Return Client instance
|
|
49
53
|
return FlowerClient(net, trainloader, valloader).to_client()
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import jax
|
|
4
4
|
from flwr.client import NumPyClient, ClientApp
|
|
5
|
+
from flwr.common import Context
|
|
5
6
|
|
|
6
7
|
from $import_name.task import (
|
|
7
8
|
evaluation,
|
|
@@ -44,7 +45,7 @@ class FlowerClient(NumPyClient):
|
|
|
44
45
|
)
|
|
45
46
|
return float(loss), num_examples, {"loss": float(loss)}
|
|
46
47
|
|
|
47
|
-
def client_fn(
|
|
48
|
+
def client_fn(context: Context):
|
|
48
49
|
# Return Client instance
|
|
49
50
|
return FlowerClient().to_client()
|
|
50
51
|
|
|
@@ -4,6 +4,7 @@ import mlx.core as mx
|
|
|
4
4
|
import mlx.nn as nn
|
|
5
5
|
import mlx.optimizers as optim
|
|
6
6
|
from flwr.client import NumPyClient, ClientApp
|
|
7
|
+
from flwr.common import Context
|
|
7
8
|
|
|
8
9
|
from $import_name.task import (
|
|
9
10
|
batch_iterate,
|
|
@@ -57,8 +58,10 @@ class FlowerClient(NumPyClient):
|
|
|
57
58
|
return loss.item(), len(self.test_images), {"accuracy": accuracy.item()}
|
|
58
59
|
|
|
59
60
|
|
|
60
|
-
def client_fn(
|
|
61
|
-
|
|
61
|
+
def client_fn(context: Context):
|
|
62
|
+
partition_id = int(context.node_config["partition-id"])
|
|
63
|
+
num_partitions = int(context.node_config["num-partitions"])
|
|
64
|
+
data = load_data(partition_id, num_partitions)
|
|
62
65
|
|
|
63
66
|
# Return Client instance
|
|
64
67
|
return FlowerClient(data).to_client()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""$project_name: A Flower / NumPy app."""
|
|
2
2
|
|
|
3
3
|
from flwr.client import NumPyClient, ClientApp
|
|
4
|
+
from flwr.common import Context
|
|
4
5
|
import numpy as np
|
|
5
6
|
|
|
6
7
|
|
|
@@ -15,7 +16,7 @@ class FlowerClient(NumPyClient):
|
|
|
15
16
|
return float(0.0), 1, {"accuracy": float(1.0)}
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def client_fn(
|
|
19
|
+
def client_fn(context: Context):
|
|
19
20
|
return FlowerClient().to_client()
|
|
20
21
|
|
|
21
22
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""$project_name: A Flower / PyTorch app."""
|
|
2
2
|
|
|
3
3
|
from flwr.client import NumPyClient, ClientApp
|
|
4
|
+
from flwr.common import Context
|
|
4
5
|
|
|
5
6
|
from $import_name.task import (
|
|
6
7
|
Net,
|
|
@@ -31,10 +32,12 @@ class FlowerClient(NumPyClient):
|
|
|
31
32
|
return loss, len(self.valloader.dataset), {"accuracy": accuracy}
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
def client_fn(
|
|
35
|
+
def client_fn(context: Context):
|
|
35
36
|
# Load model and data
|
|
36
37
|
net = Net().to(DEVICE)
|
|
37
|
-
|
|
38
|
+
partition_id = int(context.node_config["partition-id"])
|
|
39
|
+
num_partitions = int(context.node_config["num-partitions"])
|
|
40
|
+
trainloader, valloader = load_data(partition_id, num_partitions)
|
|
38
41
|
|
|
39
42
|
# Return Client instance
|
|
40
43
|
return FlowerClient(net, trainloader, valloader).to_client()
|
|
@@ -4,6 +4,7 @@ import warnings
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
from flwr.client import NumPyClient, ClientApp
|
|
7
|
+
from flwr.common import Context
|
|
7
8
|
from flwr_datasets import FederatedDataset
|
|
8
9
|
from sklearn.linear_model import LogisticRegression
|
|
9
10
|
from sklearn.metrics import log_loss
|
|
@@ -68,8 +69,9 @@ class FlowerClient(NumPyClient):
|
|
|
68
69
|
|
|
69
70
|
fds = FederatedDataset(dataset="mnist", partitioners={"train": 2})
|
|
70
71
|
|
|
71
|
-
def client_fn(
|
|
72
|
-
|
|
72
|
+
def client_fn(context: Context):
|
|
73
|
+
partition_id = int(context.node_config["partition-id"])
|
|
74
|
+
dataset = fds.load_partition(partition_id, "train").with_format("numpy")
|
|
73
75
|
|
|
74
76
|
X, y = dataset["image"].reshape((len(dataset), -1)), dataset["label"]
|
|
75
77
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""$project_name: A Flower / TensorFlow app."""
|
|
2
2
|
|
|
3
3
|
from flwr.client import NumPyClient, ClientApp
|
|
4
|
+
from flwr.common import Context
|
|
4
5
|
|
|
5
6
|
from $import_name.task import load_data, load_model
|
|
6
7
|
|
|
@@ -28,10 +29,12 @@ class FlowerClient(NumPyClient):
|
|
|
28
29
|
return loss, len(self.x_test), {"accuracy": accuracy}
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
def client_fn(
|
|
32
|
+
def client_fn(context: Context):
|
|
32
33
|
# Load model and data
|
|
33
34
|
net = load_model()
|
|
34
|
-
|
|
35
|
+
|
|
36
|
+
partition_id = int(context.node_config["partition-id"])
|
|
37
|
+
x_train, y_train, x_test, y_test = load_data(partition_id, 2)
|
|
35
38
|
|
|
36
39
|
# Return Client instance
|
|
37
40
|
return FlowerClient(net, x_train, y_train, x_test, y_test).to_client()
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"""$project_name: A Flower / HuggingFace Transformers app."""
|
|
2
2
|
|
|
3
|
+
from flwr.common import Context
|
|
3
4
|
from flwr.server.strategy import FedAvg
|
|
4
|
-
from flwr.server import ServerApp, ServerConfig
|
|
5
|
+
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def server_fn(context: Context):
|
|
9
|
+
# Define strategy
|
|
10
|
+
strategy = FedAvg(
|
|
11
|
+
fraction_fit=1.0,
|
|
12
|
+
fraction_evaluate=1.0,
|
|
13
|
+
)
|
|
14
|
+
config = ServerConfig(num_rounds=3)
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
)
|
|
16
|
+
return ServerAppComponents(strategy=strategy, config=config)
|
|
17
|
+
|
|
18
|
+
# Create ServerApp
|
|
19
|
+
app = ServerApp(server_fn=server_fn)
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"""$project_name: A Flower / JAX app."""
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
from flwr.common import Context
|
|
4
|
+
from flwr.server.strategy import FedAvg
|
|
5
|
+
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
4
6
|
|
|
5
|
-
# Configure the strategy
|
|
6
|
-
strategy = fl.server.strategy.FedAvg()
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
def server_fn(context: Context):
|
|
9
|
+
# Define strategy
|
|
10
|
+
strategy = FedAvg()
|
|
11
|
+
config = ServerConfig(num_rounds=3)
|
|
12
|
+
|
|
13
|
+
return ServerAppComponents(strategy=strategy, config=config)
|
|
14
|
+
|
|
15
|
+
# Create ServerApp
|
|
16
|
+
app = ServerApp(server_fn=server_fn)
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
"""$project_name: A Flower / MLX app."""
|
|
2
2
|
|
|
3
|
-
from flwr.
|
|
3
|
+
from flwr.common import Context
|
|
4
|
+
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
4
5
|
from flwr.server.strategy import FedAvg
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
def server_fn(context: Context):
|
|
9
|
+
# Define strategy
|
|
10
|
+
strategy = FedAvg()
|
|
11
|
+
config = ServerConfig(num_rounds=3)
|
|
9
12
|
|
|
13
|
+
return ServerAppComponents(strategy=strategy, config=config)
|
|
10
14
|
|
|
11
15
|
# Create ServerApp
|
|
12
|
-
app = ServerApp(
|
|
13
|
-
config=ServerConfig(num_rounds=3),
|
|
14
|
-
strategy=strategy,
|
|
15
|
-
)
|
|
16
|
+
app = ServerApp(server_fn=server_fn)
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"""$project_name: A Flower / NumPy app."""
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
from flwr.common import Context
|
|
4
|
+
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
5
|
+
from flwr.server.strategy import FedAvg
|
|
4
6
|
|
|
5
|
-
# Configure the strategy
|
|
6
|
-
strategy = fl.server.strategy.FedAvg()
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
def server_fn(context: Context):
|
|
9
|
+
# Define strategy
|
|
10
|
+
strategy = FedAvg()
|
|
11
|
+
config = ServerConfig(num_rounds=3)
|
|
12
|
+
|
|
13
|
+
return ServerAppComponents(strategy=strategy, config=config)
|
|
14
|
+
|
|
15
|
+
# Create ServerApp
|
|
16
|
+
app = ServerApp(server_fn=server_fn)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""$project_name: A Flower / PyTorch app."""
|
|
2
2
|
|
|
3
|
-
from flwr.common import ndarrays_to_parameters
|
|
4
|
-
from flwr.server import ServerApp, ServerConfig
|
|
3
|
+
from flwr.common import Context, ndarrays_to_parameters
|
|
4
|
+
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
5
5
|
from flwr.server.strategy import FedAvg
|
|
6
6
|
|
|
7
7
|
from $import_name.task import Net, get_weights
|
|
@@ -11,18 +11,17 @@ from $import_name.task import Net, get_weights
|
|
|
11
11
|
ndarrays = get_weights(Net())
|
|
12
12
|
parameters = ndarrays_to_parameters(ndarrays)
|
|
13
13
|
|
|
14
|
+
def server_fn(context: Context):
|
|
15
|
+
# Define strategy
|
|
16
|
+
strategy = FedAvg(
|
|
17
|
+
fraction_fit=1.0,
|
|
18
|
+
fraction_evaluate=1.0,
|
|
19
|
+
min_available_clients=2,
|
|
20
|
+
initial_parameters=parameters,
|
|
21
|
+
)
|
|
22
|
+
config = ServerConfig(num_rounds=3)
|
|
14
23
|
|
|
15
|
-
|
|
16
|
-
strategy = FedAvg(
|
|
17
|
-
fraction_fit=1.0,
|
|
18
|
-
fraction_evaluate=1.0,
|
|
19
|
-
min_available_clients=2,
|
|
20
|
-
initial_parameters=parameters,
|
|
21
|
-
)
|
|
22
|
-
|
|
24
|
+
return ServerAppComponents(strategy=strategy, config=config)
|
|
23
25
|
|
|
24
26
|
# Create ServerApp
|
|
25
|
-
app = ServerApp(
|
|
26
|
-
config=ServerConfig(num_rounds=3),
|
|
27
|
-
strategy=strategy,
|
|
28
|
-
)
|
|
27
|
+
app = ServerApp(server_fn=server_fn)
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"""$project_name: A Flower / Scikit-Learn app."""
|
|
2
2
|
|
|
3
|
-
from flwr.
|
|
3
|
+
from flwr.common import Context
|
|
4
|
+
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
4
5
|
from flwr.server.strategy import FedAvg
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def server_fn(context: Context):
|
|
9
|
+
# Define strategy
|
|
10
|
+
strategy = FedAvg(
|
|
11
|
+
fraction_fit=1.0,
|
|
12
|
+
fraction_evaluate=1.0,
|
|
13
|
+
min_available_clients=2,
|
|
14
|
+
)
|
|
15
|
+
config = ServerConfig(num_rounds=3)
|
|
16
|
+
|
|
17
|
+
return ServerAppComponents(strategy=strategy, config=config)
|
|
12
18
|
|
|
13
19
|
# Create ServerApp
|
|
14
|
-
app = ServerApp(
|
|
15
|
-
config=ServerConfig(num_rounds=3),
|
|
16
|
-
strategy=strategy,
|
|
17
|
-
)
|
|
20
|
+
app = ServerApp(server_fn=server_fn)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""$project_name: A Flower / TensorFlow app."""
|
|
2
2
|
|
|
3
|
-
from flwr.common import ndarrays_to_parameters
|
|
4
|
-
from flwr.server import ServerApp, ServerConfig
|
|
3
|
+
from flwr.common import Context, ndarrays_to_parameters
|
|
4
|
+
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
|
|
5
5
|
from flwr.server.strategy import FedAvg
|
|
6
6
|
|
|
7
7
|
from $import_name.task import load_model
|
|
@@ -11,17 +11,17 @@ config = ServerConfig(num_rounds=3)
|
|
|
11
11
|
|
|
12
12
|
parameters = ndarrays_to_parameters(load_model().get_weights())
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
def server_fn(context: Context):
|
|
15
|
+
# Define strategy
|
|
16
|
+
strategy = strategy = FedAvg(
|
|
17
|
+
fraction_fit=1.0,
|
|
18
|
+
fraction_evaluate=1.0,
|
|
19
|
+
min_available_clients=2,
|
|
20
|
+
initial_parameters=parameters,
|
|
21
|
+
)
|
|
22
|
+
config = ServerConfig(num_rounds=3)
|
|
21
23
|
|
|
24
|
+
return ServerAppComponents(strategy=strategy, config=config)
|
|
22
25
|
|
|
23
26
|
# Create ServerApp
|
|
24
|
-
app = ServerApp(
|
|
25
|
-
config=config,
|
|
26
|
-
strategy=strategy,
|
|
27
|
-
)
|
|
27
|
+
app = ServerApp(server_fn=server_fn)
|
|
@@ -16,9 +16,9 @@ DEVICE = torch.device("cpu")
|
|
|
16
16
|
CHECKPOINT = "distilbert-base-uncased" # transformer model checkpoint
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def load_data(partition_id,
|
|
19
|
+
def load_data(partition_id: int, num_partitions: int):
|
|
20
20
|
"""Load IMDB data (training and eval)"""
|
|
21
|
-
fds = FederatedDataset(dataset="imdb", partitioners={"train":
|
|
21
|
+
fds = FederatedDataset(dataset="imdb", partitioners={"train": num_partitions})
|
|
22
22
|
partition = fds.load_partition(partition_id)
|
|
23
23
|
# Divide data: 80% train, 20% test
|
|
24
24
|
partition_train_test = partition.train_test_split(test_size=0.2, seed=42)
|
|
@@ -43,8 +43,8 @@ def batch_iterate(batch_size, X, y):
|
|
|
43
43
|
yield X[ids], y[ids]
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
def load_data(partition_id,
|
|
47
|
-
fds = FederatedDataset(dataset="mnist", partitioners={"train":
|
|
46
|
+
def load_data(partition_id: int, num_partitions: int):
|
|
47
|
+
fds = FederatedDataset(dataset="mnist", partitioners={"train": num_partitions})
|
|
48
48
|
partition = fds.load_partition(partition_id)
|
|
49
49
|
partition_splits = partition.train_test_split(test_size=0.2, seed=42)
|
|
50
50
|
|
|
@@ -34,7 +34,7 @@ class Net(nn.Module):
|
|
|
34
34
|
return self.fc3(x)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def load_data(partition_id, num_partitions):
|
|
37
|
+
def load_data(partition_id: int, num_partitions: int):
|
|
38
38
|
"""Load partition CIFAR10 data."""
|
|
39
39
|
fds = FederatedDataset(dataset="cifar10", partitioners={"train": num_partitions})
|
|
40
40
|
partition = fds.load_partition(partition_id)
|
flwr/cli/run/run.py
CHANGED
flwr/client/app.py
CHANGED
|
@@ -28,7 +28,7 @@ from grpc import RpcError
|
|
|
28
28
|
from flwr.client.client import Client
|
|
29
29
|
from flwr.client.client_app import ClientApp, LoadClientAppError
|
|
30
30
|
from flwr.client.typing import ClientFnExt
|
|
31
|
-
from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, Message, event
|
|
31
|
+
from flwr.common import GRPC_MAX_MESSAGE_LENGTH, Context, EventType, Message, event
|
|
32
32
|
from flwr.common.address import parse_address
|
|
33
33
|
from flwr.common.constant import (
|
|
34
34
|
MISSING_EXTRA_REST,
|
|
@@ -138,8 +138,8 @@ def start_client(
|
|
|
138
138
|
|
|
139
139
|
Starting an SSL-enabled gRPC client using system certificates:
|
|
140
140
|
|
|
141
|
-
>>> def client_fn(
|
|
142
|
-
>>> return FlowerClient()
|
|
141
|
+
>>> def client_fn(context: Context):
|
|
142
|
+
>>> return FlowerClient().to_client()
|
|
143
143
|
>>>
|
|
144
144
|
>>> start_client(
|
|
145
145
|
>>> server_address=localhost:8080,
|
|
@@ -253,8 +253,7 @@ def _start_client_internal(
|
|
|
253
253
|
if client_fn is None:
|
|
254
254
|
# Wrap `Client` instance in `client_fn`
|
|
255
255
|
def single_client_factory(
|
|
256
|
-
|
|
257
|
-
partition_id: Optional[int], # pylint: disable=unused-argument
|
|
256
|
+
context: Context, # pylint: disable=unused-argument
|
|
258
257
|
) -> Client:
|
|
259
258
|
if client is None: # Added this to keep mypy happy
|
|
260
259
|
raise ValueError(
|
|
@@ -349,7 +348,6 @@ def _start_client_internal(
|
|
|
349
348
|
node_state = NodeState(
|
|
350
349
|
node_id=-1,
|
|
351
350
|
node_config={},
|
|
352
|
-
partition_id=None,
|
|
353
351
|
)
|
|
354
352
|
else:
|
|
355
353
|
# Call create_node fn to register node
|
|
@@ -361,7 +359,6 @@ def _start_client_internal(
|
|
|
361
359
|
node_state = NodeState(
|
|
362
360
|
node_id=node_id,
|
|
363
361
|
node_config=node_config,
|
|
364
|
-
partition_id=None,
|
|
365
362
|
)
|
|
366
363
|
|
|
367
364
|
app_state_tracker.register_signal_handler()
|
flwr/client/client_app.py
CHANGED
|
@@ -30,21 +30,41 @@ from flwr.common.logger import warn_deprecated_feature, warn_preview_feature
|
|
|
30
30
|
from .typing import ClientAppCallable
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
def _alert_erroneous_client_fn() -> None:
|
|
34
|
+
raise ValueError(
|
|
35
|
+
"A `ClientApp` cannot make use of a `client_fn` that does "
|
|
36
|
+
"not have a signature in the form: `def client_fn(context: "
|
|
37
|
+
"Context)`. You can import the `Context` like this: "
|
|
38
|
+
"`from flwr.common import Context`"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
33
42
|
def _inspect_maybe_adapt_client_fn_signature(client_fn: ClientFnExt) -> ClientFnExt:
|
|
34
43
|
client_fn_args = inspect.signature(client_fn).parameters
|
|
44
|
+
first_arg = list(client_fn_args.keys())[0]
|
|
45
|
+
|
|
46
|
+
if len(client_fn_args) != 1:
|
|
47
|
+
_alert_erroneous_client_fn()
|
|
48
|
+
|
|
49
|
+
first_arg_type = client_fn_args[first_arg].annotation
|
|
35
50
|
|
|
36
|
-
if
|
|
51
|
+
if first_arg_type is str or first_arg == "cid":
|
|
52
|
+
# Warn previous signature for `client_fn` seems to be used
|
|
37
53
|
warn_deprecated_feature(
|
|
38
|
-
"`client_fn` now expects a signature `def client_fn(
|
|
39
|
-
"
|
|
40
|
-
f"{dict(client_fn_args.items())}"
|
|
54
|
+
"`client_fn` now expects a signature `def client_fn(context: Context)`."
|
|
55
|
+
"The provided `client_fn` has signature: "
|
|
56
|
+
f"{dict(client_fn_args.items())}. You can import the `Context` like this:"
|
|
57
|
+
" `from flwr.common import Context`"
|
|
41
58
|
)
|
|
42
59
|
|
|
43
60
|
# Wrap depcreated client_fn inside a function with the expected signature
|
|
44
61
|
def adaptor_fn(
|
|
45
|
-
|
|
46
|
-
) -> Client:
|
|
47
|
-
|
|
62
|
+
context: Context,
|
|
63
|
+
) -> Client: # pylint: disable=unused-argument
|
|
64
|
+
# if patition-id is defined, pass it. Else pass node_id that should
|
|
65
|
+
# always be defined during Context init.
|
|
66
|
+
cid = context.node_config.get("partition-id", context.node_id)
|
|
67
|
+
return client_fn(str(cid)) # type: ignore
|
|
48
68
|
|
|
49
69
|
return adaptor_fn
|
|
50
70
|
|
|
@@ -71,7 +91,7 @@ class ClientApp:
|
|
|
71
91
|
>>> class FlowerClient(NumPyClient):
|
|
72
92
|
>>> # ...
|
|
73
93
|
>>>
|
|
74
|
-
>>> def client_fn(
|
|
94
|
+
>>> def client_fn(context: Context):
|
|
75
95
|
>>> return FlowerClient().to_client()
|
|
76
96
|
>>>
|
|
77
97
|
>>> app = ClientApp(client_fn)
|
|
@@ -92,7 +92,7 @@ def handle_legacy_message_from_msgtype(
|
|
|
92
92
|
client_fn: ClientFnExt, message: Message, context: Context
|
|
93
93
|
) -> Message:
|
|
94
94
|
"""Handle legacy message in the inner most mod."""
|
|
95
|
-
client = client_fn(
|
|
95
|
+
client = client_fn(context)
|
|
96
96
|
|
|
97
97
|
# Check if NumPyClient is returend
|
|
98
98
|
if isinstance(client, NumPyClient):
|
flwr/client/node_state.py
CHANGED
|
@@ -36,12 +36,13 @@ class NodeState:
|
|
|
36
36
|
"""State of a node where client nodes execute runs."""
|
|
37
37
|
|
|
38
38
|
def __init__(
|
|
39
|
-
self,
|
|
39
|
+
self,
|
|
40
|
+
node_id: int,
|
|
41
|
+
node_config: Dict[str, str],
|
|
40
42
|
) -> None:
|
|
41
43
|
self.node_id = node_id
|
|
42
44
|
self.node_config = node_config
|
|
43
45
|
self.run_infos: Dict[int, RunInfo] = {}
|
|
44
|
-
self._partition_id = partition_id
|
|
45
46
|
|
|
46
47
|
def register_context(
|
|
47
48
|
self,
|
|
@@ -59,7 +60,6 @@ class NodeState:
|
|
|
59
60
|
node_config=self.node_config,
|
|
60
61
|
state=RecordSet(),
|
|
61
62
|
run_config=initial_run_config.copy(),
|
|
62
|
-
partition_id=self._partition_id,
|
|
63
63
|
),
|
|
64
64
|
)
|
|
65
65
|
|
flwr/client/node_state_tests.py
CHANGED
|
@@ -41,7 +41,7 @@ def test_multirun_in_node_state() -> None:
|
|
|
41
41
|
expected_values = {0: "1", 1: "1" * 3, 2: "1" * 2, 3: "1", 5: "1"}
|
|
42
42
|
|
|
43
43
|
# NodeState
|
|
44
|
-
node_state = NodeState(node_id=0, node_config={}
|
|
44
|
+
node_state = NodeState(node_id=0, node_config={})
|
|
45
45
|
|
|
46
46
|
for task in tasks:
|
|
47
47
|
run_id = task.run_id
|
flwr/client/typing.py
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"""Custom types for Flower clients."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
from typing import Callable
|
|
18
|
+
from typing import Callable
|
|
19
19
|
|
|
20
20
|
from flwr.common import Context, Message
|
|
21
21
|
|
|
@@ -23,7 +23,7 @@ from .client import Client as Client
|
|
|
23
23
|
|
|
24
24
|
# Compatibility
|
|
25
25
|
ClientFn = Callable[[str], Client]
|
|
26
|
-
ClientFnExt = Callable[[
|
|
26
|
+
ClientFnExt = Callable[[Context], Client]
|
|
27
27
|
|
|
28
28
|
ClientAppCallable = Callable[[Message, Context], Message]
|
|
29
29
|
Mod = Callable[[Message, Context, ClientAppCallable], Message]
|
flwr/common/constant.py
CHANGED
|
@@ -57,6 +57,9 @@ APP_DIR = "apps"
|
|
|
57
57
|
FAB_CONFIG_FILE = "pyproject.toml"
|
|
58
58
|
FLWR_HOME = "FLWR_HOME"
|
|
59
59
|
|
|
60
|
+
# Constants entries in Node config for Simulation
|
|
61
|
+
PARTITION_ID_KEY = "partition-id"
|
|
62
|
+
NUM_PARTITIONS_KEY = "num-partitions"
|
|
60
63
|
|
|
61
64
|
GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY = "flower-version"
|
|
62
65
|
GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY = "should-exit"
|
flwr/common/context.py
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
from dataclasses import dataclass
|
|
19
|
-
from typing import Dict
|
|
19
|
+
from typing import Dict
|
|
20
20
|
|
|
21
21
|
from .record import RecordSet
|
|
22
22
|
|
|
@@ -43,17 +43,12 @@ class Context:
|
|
|
43
43
|
A config (key/value mapping) held by the entity in a given run and that will
|
|
44
44
|
stay local. It can be used at any point during the lifecycle of this entity
|
|
45
45
|
(e.g. across multiple rounds)
|
|
46
|
-
partition_id : Optional[int] (default: None)
|
|
47
|
-
An index that specifies the data partition that the ClientApp using this Context
|
|
48
|
-
object should make use of. Setting this attribute is better suited for
|
|
49
|
-
simulation or proto typing setups.
|
|
50
46
|
"""
|
|
51
47
|
|
|
52
48
|
node_id: int
|
|
53
49
|
node_config: Dict[str, str]
|
|
54
50
|
state: RecordSet
|
|
55
51
|
run_config: Dict[str, str]
|
|
56
|
-
partition_id: Optional[int]
|
|
57
52
|
|
|
58
53
|
def __init__( # pylint: disable=too-many-arguments
|
|
59
54
|
self,
|
|
@@ -61,10 +56,8 @@ class Context:
|
|
|
61
56
|
node_config: Dict[str, str],
|
|
62
57
|
state: RecordSet,
|
|
63
58
|
run_config: Dict[str, str],
|
|
64
|
-
partition_id: Optional[int] = None,
|
|
65
59
|
) -> None:
|
|
66
60
|
self.node_id = node_id
|
|
67
61
|
self.node_config = node_config
|
|
68
62
|
self.state = state
|
|
69
63
|
self.run_config = run_config
|
|
70
|
-
self.partition_id = partition_id
|
|
@@ -21,6 +21,7 @@ from typing import Callable, Dict, List, Tuple, Union
|
|
|
21
21
|
import ray
|
|
22
22
|
|
|
23
23
|
from flwr.client.client_app import ClientApp
|
|
24
|
+
from flwr.common.constant import PARTITION_ID_KEY
|
|
24
25
|
from flwr.common.context import Context
|
|
25
26
|
from flwr.common.logger import log
|
|
26
27
|
from flwr.common.message import Message
|
|
@@ -168,7 +169,7 @@ class RayBackend(Backend):
|
|
|
168
169
|
|
|
169
170
|
Return output message and updated context.
|
|
170
171
|
"""
|
|
171
|
-
partition_id = context.
|
|
172
|
+
partition_id = context.node_config[PARTITION_ID_KEY]
|
|
172
173
|
|
|
173
174
|
try:
|
|
174
175
|
# Submit a task to the pool
|
|
@@ -29,7 +29,12 @@ from typing import Callable, Dict, Optional
|
|
|
29
29
|
|
|
30
30
|
from flwr.client.client_app import ClientApp, ClientAppException, LoadClientAppError
|
|
31
31
|
from flwr.client.node_state import NodeState
|
|
32
|
-
from flwr.common.constant import
|
|
32
|
+
from flwr.common.constant import (
|
|
33
|
+
NUM_PARTITIONS_KEY,
|
|
34
|
+
PARTITION_ID_KEY,
|
|
35
|
+
PING_MAX_INTERVAL,
|
|
36
|
+
ErrorCode,
|
|
37
|
+
)
|
|
33
38
|
from flwr.common.logger import log
|
|
34
39
|
from flwr.common.message import Error
|
|
35
40
|
from flwr.common.object_ref import load_app
|
|
@@ -73,7 +78,7 @@ def worker(
|
|
|
73
78
|
task_ins: TaskIns = taskins_queue.get(timeout=1.0)
|
|
74
79
|
node_id = task_ins.task.consumer.node_id
|
|
75
80
|
|
|
76
|
-
# Register and retrieve
|
|
81
|
+
# Register and retrieve context
|
|
77
82
|
node_states[node_id].register_context(run_id=task_ins.run_id)
|
|
78
83
|
context = node_states[node_id].retrieve_context(run_id=task_ins.run_id)
|
|
79
84
|
|
|
@@ -283,9 +288,15 @@ def start_vce(
|
|
|
283
288
|
|
|
284
289
|
# Construct mapping of NodeStates
|
|
285
290
|
node_states: Dict[int, NodeState] = {}
|
|
291
|
+
# Number of unique partitions
|
|
292
|
+
num_partitions = len(set(nodes_mapping.values()))
|
|
286
293
|
for node_id, partition_id in nodes_mapping.items():
|
|
287
294
|
node_states[node_id] = NodeState(
|
|
288
|
-
node_id=node_id,
|
|
295
|
+
node_id=node_id,
|
|
296
|
+
node_config={
|
|
297
|
+
PARTITION_ID_KEY: str(partition_id),
|
|
298
|
+
NUM_PARTITIONS_KEY: str(num_partitions),
|
|
299
|
+
},
|
|
289
300
|
)
|
|
290
301
|
|
|
291
302
|
# Load backend config
|
flwr/simulation/app.py
CHANGED
|
@@ -111,9 +111,9 @@ def start_simulation(
|
|
|
111
111
|
Parameters
|
|
112
112
|
----------
|
|
113
113
|
client_fn : ClientFnExt
|
|
114
|
-
A function creating Client instances. The function must have the signature
|
|
115
|
-
`client_fn(
|
|
116
|
-
a single client instance of type Client
|
|
114
|
+
A function creating `Client` instances. The function must have the signature
|
|
115
|
+
`client_fn(context: Context). It should return
|
|
116
|
+
a single client instance of type `Client`. Note that the created client
|
|
117
117
|
instances are ephemeral and will often be destroyed after a single method
|
|
118
118
|
invocation. Since client instances are not long-lived, they should not attempt
|
|
119
119
|
to carry state over method invocations. Any state required by the instance
|
|
@@ -327,6 +327,7 @@ def start_simulation(
|
|
|
327
327
|
client_fn=client_fn,
|
|
328
328
|
node_id=node_id,
|
|
329
329
|
partition_id=partition_id,
|
|
330
|
+
num_partitions=num_clients,
|
|
330
331
|
actor_pool=pool,
|
|
331
332
|
)
|
|
332
333
|
initialized_server.client_manager().register(client=client_proxy)
|
|
@@ -24,7 +24,12 @@ from flwr.client import ClientFnExt
|
|
|
24
24
|
from flwr.client.client_app import ClientApp
|
|
25
25
|
from flwr.client.node_state import NodeState
|
|
26
26
|
from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
|
|
27
|
-
from flwr.common.constant import
|
|
27
|
+
from flwr.common.constant import (
|
|
28
|
+
NUM_PARTITIONS_KEY,
|
|
29
|
+
PARTITION_ID_KEY,
|
|
30
|
+
MessageType,
|
|
31
|
+
MessageTypeLegacy,
|
|
32
|
+
)
|
|
28
33
|
from flwr.common.logger import log
|
|
29
34
|
from flwr.common.recordset_compat import (
|
|
30
35
|
evaluateins_to_recordset,
|
|
@@ -43,11 +48,12 @@ from flwr.simulation.ray_transport.ray_actor import VirtualClientEngineActorPool
|
|
|
43
48
|
class RayActorClientProxy(ClientProxy):
|
|
44
49
|
"""Flower client proxy which delegates work using Ray."""
|
|
45
50
|
|
|
46
|
-
def __init__(
|
|
51
|
+
def __init__( # pylint: disable=too-many-arguments
|
|
47
52
|
self,
|
|
48
53
|
client_fn: ClientFnExt,
|
|
49
54
|
node_id: int,
|
|
50
55
|
partition_id: int,
|
|
56
|
+
num_partitions: int,
|
|
51
57
|
actor_pool: VirtualClientEngineActorPool,
|
|
52
58
|
):
|
|
53
59
|
super().__init__(cid=str(node_id))
|
|
@@ -60,7 +66,11 @@ class RayActorClientProxy(ClientProxy):
|
|
|
60
66
|
self.app_fn = _load_app
|
|
61
67
|
self.actor_pool = actor_pool
|
|
62
68
|
self.proxy_state = NodeState(
|
|
63
|
-
node_id=node_id,
|
|
69
|
+
node_id=node_id,
|
|
70
|
+
node_config={
|
|
71
|
+
PARTITION_ID_KEY: str(partition_id),
|
|
72
|
+
NUM_PARTITIONS_KEY: str(num_partitions),
|
|
73
|
+
},
|
|
64
74
|
)
|
|
65
75
|
|
|
66
76
|
def _submit_job(self, message: Message, timeout: Optional[float]) -> Message:
|
|
@@ -70,18 +80,19 @@ class RayActorClientProxy(ClientProxy):
|
|
|
70
80
|
# Register state
|
|
71
81
|
self.proxy_state.register_context(run_id=run_id)
|
|
72
82
|
|
|
73
|
-
# Retrieve
|
|
74
|
-
|
|
83
|
+
# Retrieve context
|
|
84
|
+
context = self.proxy_state.retrieve_context(run_id=run_id)
|
|
85
|
+
partition_id_str = context.node_config[PARTITION_ID_KEY]
|
|
75
86
|
|
|
76
87
|
try:
|
|
77
88
|
self.actor_pool.submit_client_job(
|
|
78
|
-
lambda a, a_fn, mssg, partition_id,
|
|
79
|
-
a_fn, mssg, partition_id,
|
|
89
|
+
lambda a, a_fn, mssg, partition_id, context: a.run.remote(
|
|
90
|
+
a_fn, mssg, partition_id, context
|
|
80
91
|
),
|
|
81
|
-
(self.app_fn, message,
|
|
92
|
+
(self.app_fn, message, partition_id_str, context),
|
|
82
93
|
)
|
|
83
94
|
out_mssg, updated_context = self.actor_pool.get_client_result(
|
|
84
|
-
|
|
95
|
+
partition_id_str, timeout
|
|
85
96
|
)
|
|
86
97
|
|
|
87
98
|
# Update state
|
flwr/superexec/app.py
CHANGED
|
@@ -24,6 +24,7 @@ import grpc
|
|
|
24
24
|
|
|
25
25
|
from flwr.common import EventType, event, log
|
|
26
26
|
from flwr.common.address import parse_address
|
|
27
|
+
from flwr.common.config import parse_config_args
|
|
27
28
|
from flwr.common.constant import SUPEREXEC_DEFAULT_ADDRESS
|
|
28
29
|
from flwr.common.exit_handlers import register_exit_handlers
|
|
29
30
|
from flwr.common.object_ref import load_app, validate
|
|
@@ -55,6 +56,7 @@ def run_superexec() -> None:
|
|
|
55
56
|
address=address,
|
|
56
57
|
executor=_load_executor(args),
|
|
57
58
|
certificates=certificates,
|
|
59
|
+
config=parse_config_args(args.executor_config),
|
|
58
60
|
)
|
|
59
61
|
|
|
60
62
|
grpc_servers = [superexec_server]
|
|
@@ -74,21 +76,25 @@ def _parse_args_run_superexec() -> argparse.ArgumentParser:
|
|
|
74
76
|
parser = argparse.ArgumentParser(
|
|
75
77
|
description="Start a Flower SuperExec",
|
|
76
78
|
)
|
|
77
|
-
parser.add_argument(
|
|
78
|
-
"executor",
|
|
79
|
-
help="For example: `deployment:exec` or `project.package.module:wrapper.exec`.",
|
|
80
|
-
default="flwr.superexec.deployment:executor",
|
|
81
|
-
)
|
|
82
79
|
parser.add_argument(
|
|
83
80
|
"--address",
|
|
84
81
|
help="SuperExec (gRPC) server address (IPv4, IPv6, or a domain name)",
|
|
85
82
|
default=SUPEREXEC_DEFAULT_ADDRESS,
|
|
86
83
|
)
|
|
84
|
+
parser.add_argument(
|
|
85
|
+
"--executor",
|
|
86
|
+
help="For example: `deployment:exec` or `project.package.module:wrapper.exec`.",
|
|
87
|
+
default="flwr.superexec.deployment:executor",
|
|
88
|
+
)
|
|
87
89
|
parser.add_argument(
|
|
88
90
|
"--executor-dir",
|
|
89
91
|
help="The directory for the executor.",
|
|
90
92
|
default=".",
|
|
91
93
|
)
|
|
94
|
+
parser.add_argument(
|
|
95
|
+
"--executor-config",
|
|
96
|
+
help="Key-value pairs for the executor config, separated by commas.",
|
|
97
|
+
)
|
|
92
98
|
parser.add_argument(
|
|
93
99
|
"--insecure",
|
|
94
100
|
action="store_true",
|
flwr/superexec/deployment.py
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import subprocess
|
|
18
18
|
import sys
|
|
19
19
|
from logging import ERROR, INFO
|
|
20
|
+
from pathlib import Path
|
|
20
21
|
from typing import Dict, Optional
|
|
21
22
|
|
|
22
23
|
from typing_extensions import override
|
|
@@ -33,25 +34,73 @@ from .executor import Executor, RunTracker
|
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
class DeploymentEngine(Executor):
|
|
36
|
-
"""Deployment engine executor.
|
|
37
|
+
"""Deployment engine executor.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
superlink: str (default: "0.0.0.0:9091")
|
|
42
|
+
Address of the SuperLink to connect to.
|
|
43
|
+
root_certificates: Optional[str] (default: None)
|
|
44
|
+
Specifies the path to the PEM-encoded root certificate file for
|
|
45
|
+
establishing secure HTTPS connections.
|
|
46
|
+
flwr_dir: Optional[str] (default: None)
|
|
47
|
+
The path containing installed Flower Apps.
|
|
48
|
+
"""
|
|
37
49
|
|
|
38
50
|
def __init__(
|
|
39
51
|
self,
|
|
40
|
-
|
|
41
|
-
root_certificates: Optional[
|
|
52
|
+
superlink: str = DEFAULT_SERVER_ADDRESS_DRIVER,
|
|
53
|
+
root_certificates: Optional[str] = None,
|
|
54
|
+
flwr_dir: Optional[str] = None,
|
|
42
55
|
) -> None:
|
|
43
|
-
self.
|
|
44
|
-
|
|
56
|
+
self.superlink = superlink
|
|
57
|
+
if root_certificates is None:
|
|
58
|
+
self.root_certificates = None
|
|
59
|
+
self.root_certificates_bytes = None
|
|
60
|
+
else:
|
|
61
|
+
self.root_certificates = root_certificates
|
|
62
|
+
self.root_certificates_bytes = Path(root_certificates).read_bytes()
|
|
63
|
+
self.flwr_dir = flwr_dir
|
|
45
64
|
self.stub: Optional[DriverStub] = None
|
|
46
65
|
|
|
66
|
+
@override
|
|
67
|
+
def set_config(
|
|
68
|
+
self,
|
|
69
|
+
config: Dict[str, str],
|
|
70
|
+
) -> None:
|
|
71
|
+
"""Set executor config arguments.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
config : Dict[str, str]
|
|
76
|
+
A dictionary for configuration values.
|
|
77
|
+
Supported configuration key/value pairs:
|
|
78
|
+
- "superlink": str
|
|
79
|
+
The address of the SuperLink Driver API.
|
|
80
|
+
- "root-certificates": str
|
|
81
|
+
The path to the root certificates.
|
|
82
|
+
- "flwr-dir": str
|
|
83
|
+
The path to the Flower directory.
|
|
84
|
+
"""
|
|
85
|
+
if not config:
|
|
86
|
+
return
|
|
87
|
+
if superlink_address := config.get("superlink"):
|
|
88
|
+
self.superlink = superlink_address
|
|
89
|
+
if root_certificates := config.get("root-certificates"):
|
|
90
|
+
self.root_certificates = root_certificates
|
|
91
|
+
self.root_certificates_bytes = Path(root_certificates).read_bytes()
|
|
92
|
+
if flwr_dir := config.get("flwr-dir"):
|
|
93
|
+
self.flwr_dir = flwr_dir
|
|
94
|
+
|
|
47
95
|
def _connect(self) -> None:
|
|
48
|
-
if self.stub is None:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
96
|
+
if self.stub is not None:
|
|
97
|
+
return
|
|
98
|
+
channel = create_channel(
|
|
99
|
+
server_address=self.superlink,
|
|
100
|
+
insecure=(self.root_certificates_bytes is None),
|
|
101
|
+
root_certificates=self.root_certificates_bytes,
|
|
102
|
+
)
|
|
103
|
+
self.stub = DriverStub(channel)
|
|
55
104
|
|
|
56
105
|
def _create_run(
|
|
57
106
|
self,
|
|
@@ -74,7 +123,9 @@ class DeploymentEngine(Executor):
|
|
|
74
123
|
|
|
75
124
|
@override
|
|
76
125
|
def start_run(
|
|
77
|
-
self,
|
|
126
|
+
self,
|
|
127
|
+
fab_file: bytes,
|
|
128
|
+
override_config: Dict[str, str],
|
|
78
129
|
) -> Optional[RunTracker]:
|
|
79
130
|
"""Start run using the Flower Deployment Engine."""
|
|
80
131
|
try:
|
|
@@ -84,7 +135,7 @@ class DeploymentEngine(Executor):
|
|
|
84
135
|
|
|
85
136
|
# Install FAB Python package
|
|
86
137
|
subprocess.check_call(
|
|
87
|
-
[sys.executable, "-m", "pip", "install", str(fab_path)],
|
|
138
|
+
[sys.executable, "-m", "pip", "install", "--no-deps", str(fab_path)],
|
|
88
139
|
stdout=subprocess.DEVNULL,
|
|
89
140
|
stderr=subprocess.DEVNULL,
|
|
90
141
|
)
|
|
@@ -93,14 +144,27 @@ class DeploymentEngine(Executor):
|
|
|
93
144
|
run_id: int = self._create_run(fab_id, fab_version, override_config)
|
|
94
145
|
log(INFO, "Created run %s", str(run_id))
|
|
95
146
|
|
|
96
|
-
|
|
147
|
+
command = [
|
|
148
|
+
"flower-server-app",
|
|
149
|
+
"--run-id",
|
|
150
|
+
str(run_id),
|
|
151
|
+
"--superlink",
|
|
152
|
+
str(self.superlink),
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
if self.flwr_dir:
|
|
156
|
+
command.append("--flwr-dir")
|
|
157
|
+
command.append(self.flwr_dir)
|
|
158
|
+
|
|
159
|
+
if self.root_certificates is None:
|
|
160
|
+
command.append("--insecure")
|
|
161
|
+
else:
|
|
162
|
+
command.append("--root-certificates")
|
|
163
|
+
command.append(self.root_certificates)
|
|
164
|
+
|
|
165
|
+
# Execute the command
|
|
97
166
|
proc = subprocess.Popen( # pylint: disable=consider-using-with
|
|
98
|
-
|
|
99
|
-
"flower-server-app",
|
|
100
|
-
"--run-id",
|
|
101
|
-
str(run_id),
|
|
102
|
-
"--insecure",
|
|
103
|
-
],
|
|
167
|
+
command,
|
|
104
168
|
stdout=subprocess.PIPE,
|
|
105
169
|
stderr=subprocess.PIPE,
|
|
106
170
|
text=True,
|
flwr/superexec/exec_grpc.py
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"""SuperExec gRPC API."""
|
|
16
16
|
|
|
17
17
|
from logging import INFO
|
|
18
|
-
from typing import Optional, Tuple
|
|
18
|
+
from typing import Dict, Optional, Tuple
|
|
19
19
|
|
|
20
20
|
import grpc
|
|
21
21
|
|
|
@@ -32,8 +32,11 @@ def run_superexec_api_grpc(
|
|
|
32
32
|
address: str,
|
|
33
33
|
executor: Executor,
|
|
34
34
|
certificates: Optional[Tuple[bytes, bytes, bytes]],
|
|
35
|
+
config: Dict[str, str],
|
|
35
36
|
) -> grpc.Server:
|
|
36
37
|
"""Run SuperExec API (gRPC, request-response)."""
|
|
38
|
+
executor.set_config(config)
|
|
39
|
+
|
|
37
40
|
exec_servicer: grpc.Server = ExecServicer(
|
|
38
41
|
executor=executor,
|
|
39
42
|
)
|
|
@@ -45,7 +48,7 @@ def run_superexec_api_grpc(
|
|
|
45
48
|
certificates=certificates,
|
|
46
49
|
)
|
|
47
50
|
|
|
48
|
-
log(INFO, "Flower
|
|
51
|
+
log(INFO, "Starting Flower SuperExec gRPC server on %s", address)
|
|
49
52
|
superexec_grpc_server.start()
|
|
50
53
|
|
|
51
54
|
return superexec_grpc_server
|
flwr/superexec/executor.py
CHANGED
|
@@ -31,9 +31,24 @@ class RunTracker:
|
|
|
31
31
|
class Executor(ABC):
|
|
32
32
|
"""Execute and monitor a Flower run."""
|
|
33
33
|
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def set_config(
|
|
36
|
+
self,
|
|
37
|
+
config: Dict[str, str],
|
|
38
|
+
) -> None:
|
|
39
|
+
"""Register provided config as class attributes.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
config : Optional[Dict[str, str]]
|
|
44
|
+
A dictionary for configuration values.
|
|
45
|
+
"""
|
|
46
|
+
|
|
34
47
|
@abstractmethod
|
|
35
48
|
def start_run(
|
|
36
|
-
self,
|
|
49
|
+
self,
|
|
50
|
+
fab_file: bytes,
|
|
51
|
+
override_config: Dict[str, str],
|
|
37
52
|
) -> Optional[RunTracker]:
|
|
38
53
|
"""Start a run using the given Flower FAB ID and version.
|
|
39
54
|
|
|
@@ -44,6 +59,8 @@ class Executor(ABC):
|
|
|
44
59
|
----------
|
|
45
60
|
fab_file : bytes
|
|
46
61
|
The Flower App Bundle file bytes.
|
|
62
|
+
override_config: Dict[str, str]
|
|
63
|
+
The config overrides dict sent by the user (using `flwr run`).
|
|
47
64
|
|
|
48
65
|
Returns
|
|
49
66
|
-------
|
{flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/RECORD
RENAMED
|
@@ -14,13 +14,13 @@ flwr/cli/new/templates/app/README.md.tpl,sha256=_qGtgpKYKoCJVjQnvlBMKvFs_1gzTcL9
|
|
|
14
14
|
flwr/cli/new/templates/app/__init__.py,sha256=DU7QMY7IhMQyuwm_tja66xU0KXTWQFqzfTqwg-_NJdE,729
|
|
15
15
|
flwr/cli/new/templates/app/code/__init__.py,sha256=EM6vfvgAILKPaPn7H1wMV1Wi01WyZCP_Eg6NxD6oWg8,736
|
|
16
16
|
flwr/cli/new/templates/app/code/__init__.py.tpl,sha256=olwrBeJemHNBWvjc6gJURloFRqW40dAy7FRQA5pDqHU,21
|
|
17
|
-
flwr/cli/new/templates/app/code/client.hf.py.tpl,sha256=
|
|
18
|
-
flwr/cli/new/templates/app/code/client.jax.py.tpl,sha256=
|
|
19
|
-
flwr/cli/new/templates/app/code/client.mlx.py.tpl,sha256=
|
|
20
|
-
flwr/cli/new/templates/app/code/client.numpy.py.tpl,sha256=
|
|
21
|
-
flwr/cli/new/templates/app/code/client.pytorch.py.tpl,sha256=
|
|
22
|
-
flwr/cli/new/templates/app/code/client.sklearn.py.tpl,sha256=
|
|
23
|
-
flwr/cli/new/templates/app/code/client.tensorflow.py.tpl,sha256=
|
|
17
|
+
flwr/cli/new/templates/app/code/client.hf.py.tpl,sha256=cqq2M-l8yrsw6kZZLIjum2g-0uKg4Pyh3YGhgpQKQrw,1636
|
|
18
|
+
flwr/cli/new/templates/app/code/client.jax.py.tpl,sha256=i_SZykD42vqEvv2ZyX655szuikXJXLc6uV1T-LWiYLU,1479
|
|
19
|
+
flwr/cli/new/templates/app/code/client.mlx.py.tpl,sha256=Ntpbz9fcw-87FPBZmhns1NbJJXOQxnssJ_lStAqGuaQ,2299
|
|
20
|
+
flwr/cli/new/templates/app/code/client.numpy.py.tpl,sha256=ov9mtWJGjaQ9ZVlQ5jsuCjHDeETf13GFla5jbP3KimE,561
|
|
21
|
+
flwr/cli/new/templates/app/code/client.pytorch.py.tpl,sha256=bmmplNEVk3uHERFGlDP6FmBJQ7IBFw-OQ8otueAmOX0,1358
|
|
22
|
+
flwr/cli/new/templates/app/code/client.sklearn.py.tpl,sha256=C2PfCn0w8MpXmY4tuIIJ7fF2Mv-YW37YmMf0knIEARo,2905
|
|
23
|
+
flwr/cli/new/templates/app/code/client.tensorflow.py.tpl,sha256=D8h_RSWk2GGazW2-fLle1dIz9ABWuC_1aczxNbKHfOA,1390
|
|
24
24
|
flwr/cli/new/templates/app/code/flwr_tune/__init__.py,sha256=JgNgBtKdm1jKM9625WxappCAVUGtYAmcjKSsXJ1u3ZQ,748
|
|
25
25
|
flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl,sha256=KXqCaD2NSEaLHT08fgQTzWlrtOdfxRYs0fsLw9yecCY,2647
|
|
26
26
|
flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl,sha256=MvQ5tt1r7CBUR8y-nBcZs4as2m1YimxegLYw_nHmXzc,4048
|
|
@@ -29,17 +29,17 @@ flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl,sha256=kPG4AIXQfNNHZGYC
|
|
|
29
29
|
flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl,sha256=cEq9ZWM3zImJVceNtxHC_bYBLE8OChK0BdjpWs5Wz-0,1881
|
|
30
30
|
flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl,sha256=Z_JC7-YdjCnnUJPKILwT5Iqc70byJpthbye8RsQp9L0,1548
|
|
31
31
|
flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl,sha256=cBPpBVN_N7p4T2a3rqChlngmE0dB_jveOLHesNcEHvs,268
|
|
32
|
-
flwr/cli/new/templates/app/code/server.hf.py.tpl,sha256=
|
|
33
|
-
flwr/cli/new/templates/app/code/server.jax.py.tpl,sha256=
|
|
34
|
-
flwr/cli/new/templates/app/code/server.mlx.py.tpl,sha256=
|
|
35
|
-
flwr/cli/new/templates/app/code/server.numpy.py.tpl,sha256=
|
|
36
|
-
flwr/cli/new/templates/app/code/server.pytorch.py.tpl,sha256=
|
|
37
|
-
flwr/cli/new/templates/app/code/server.sklearn.py.tpl,sha256=
|
|
38
|
-
flwr/cli/new/templates/app/code/server.tensorflow.py.tpl,sha256=
|
|
39
|
-
flwr/cli/new/templates/app/code/task.hf.py.tpl,sha256=
|
|
32
|
+
flwr/cli/new/templates/app/code/server.hf.py.tpl,sha256=BQmQy7UR8B1mNojUaTNVM4ci1pdKCk1Znw4bH_3nE1c,510
|
|
33
|
+
flwr/cli/new/templates/app/code/server.jax.py.tpl,sha256=stWCaIZCqdw-RnLtpa7hdz24JaiG65z2OSTB1yz6NdA,427
|
|
34
|
+
flwr/cli/new/templates/app/code/server.mlx.py.tpl,sha256=P1Odp3SYl0CQt5tX4fcrY4nxOBOejOMMerRvbrOq-KA,427
|
|
35
|
+
flwr/cli/new/templates/app/code/server.numpy.py.tpl,sha256=oZ_KBcvv0NRINjCKbwNCnSz7xcquDRQEgSh7yOEWZ5E,429
|
|
36
|
+
flwr/cli/new/templates/app/code/server.pytorch.py.tpl,sha256=wcekFyR4qMc3zfi39_AmSps8ahL_NpIzfvfI5iKj_vE,744
|
|
37
|
+
flwr/cli/new/templates/app/code/server.sklearn.py.tpl,sha256=SmlGeCnpPlfx0x0P3RgO2jPlablovp0ugMDcPDgXVmk,531
|
|
38
|
+
flwr/cli/new/templates/app/code/server.tensorflow.py.tpl,sha256=DHTIcUzA0XbtUVWvZ8LYABpzwdubsyxkNk42OiWG7vs,762
|
|
39
|
+
flwr/cli/new/templates/app/code/task.hf.py.tpl,sha256=B5CrA7L5PSOWnluYoAAL7LCeKvP8t-Rhwt6t2ZTYP3g,2873
|
|
40
40
|
flwr/cli/new/templates/app/code/task.jax.py.tpl,sha256=u4o3V019EH79szOw2xzVeC5r9xgQiayPi9ZTIopV2TA,1519
|
|
41
|
-
flwr/cli/new/templates/app/code/task.mlx.py.tpl,sha256=
|
|
42
|
-
flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=
|
|
41
|
+
flwr/cli/new/templates/app/code/task.mlx.py.tpl,sha256=nrfZ1aGOs_ayb70j7XdAmwFYa-rN10d9GIMIKLzctUE,2614
|
|
42
|
+
flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=TU4uNtJ9wtxeVvoHD3_K89EFWmrIvdECdASzRX-4Uvk,3694
|
|
43
43
|
flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=cPOUUS07QbblT9PGFucwu9lY1clRA4-W4DQGA7cpcao,1044
|
|
44
44
|
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=5kAtRcTvn2-s2i2_WGoDNJQ__ALADQjabX7lQlCNOGA,899
|
|
45
45
|
flwr/cli/new/templates/app/pyproject.hf.toml.tpl,sha256=O3-dgH8_knk9uM49IzX06CYC2Ev5xdPuITB40Phvewc,759
|
|
@@ -50,12 +50,12 @@ flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=wxN6I8uvWZ4MErvTbQJ
|
|
|
50
50
|
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=wFeJuhqnBPQtKCBvnE3ySBpxmbeNdxcsq2Eb_RmSDIg,655
|
|
51
51
|
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=zkxLTQRvujF76sIlzNNGPVU7Y9nVCwNBxAx82AOBaJY,654
|
|
52
52
|
flwr/cli/run/__init__.py,sha256=oCd6HmQDx-sqver1gecgx-uMA38BLTSiiKpl7RGNceg,789
|
|
53
|
-
flwr/cli/run/run.py,sha256=
|
|
53
|
+
flwr/cli/run/run.py,sha256=b_TcqJAGOiF0RDO5f25HCWYYdG54CxSjtsXwcRYN_J8,4973
|
|
54
54
|
flwr/cli/utils.py,sha256=l65Ul0YsSBPuypk0uorAtEDmLEYiUrzpCXi6zCg9mJ4,4506
|
|
55
55
|
flwr/client/__init__.py,sha256=wzJZsYJIHf_8-PMzvfbinyzzjgh1UP1vLrAw2_yEbKI,1345
|
|
56
|
-
flwr/client/app.py,sha256=
|
|
56
|
+
flwr/client/app.py,sha256=5v5EsA1zbViJAp998dCVRXvsyigZ-x3JEIKQ_fLeA48,26102
|
|
57
57
|
flwr/client/client.py,sha256=Vp9UkOkoHdNfn6iMYZsj_5m_GICiFfUlKEVaLad-YhM,8183
|
|
58
|
-
flwr/client/client_app.py,sha256=
|
|
58
|
+
flwr/client/client_app.py,sha256=WcO4r6wrdfaus__3s22D2sYjfcptdgmVujUAYdNE6HU,10393
|
|
59
59
|
flwr/client/dpfedavg_numpy_client.py,sha256=ylZ-LpBIKmL1HCiS8kq4pkp2QGalc8rYEzDHdRG3VRQ,7435
|
|
60
60
|
flwr/client/grpc_adapter_client/__init__.py,sha256=QyNWIbsq9DpyMk7oemiO1P3TBFfkfkctnJ1JoAkTl3s,742
|
|
61
61
|
flwr/client/grpc_adapter_client/connection.py,sha256=fM6QTIrcDGIXux7nzxOY3qNUfBGxVl1W7861iGSy5wA,3873
|
|
@@ -67,7 +67,7 @@ flwr/client/grpc_rere_client/connection.py,sha256=nC4Usb1qok2liVxwlbQokUNwRRRD10
|
|
|
67
67
|
flwr/client/grpc_rere_client/grpc_adapter.py,sha256=woljH8yr1pyLH4W4Azogyy7Nafn6y9DHBnDCIIVKwCw,4711
|
|
68
68
|
flwr/client/heartbeat.py,sha256=cx37mJBH8LyoIN4Lks85wtqT1mnU5GulQnr4pGCvAq0,2404
|
|
69
69
|
flwr/client/message_handler/__init__.py,sha256=QxxQuBNpFPTHx3KiUNvQSlqMKlEnbRR1kFfc1KVje08,719
|
|
70
|
-
flwr/client/message_handler/message_handler.py,sha256=
|
|
70
|
+
flwr/client/message_handler/message_handler.py,sha256=q1fiWQob4TCaSHxvIklEtqsz-TwupXNYK-yKV9LubWY,6531
|
|
71
71
|
flwr/client/message_handler/task_handler.py,sha256=ZDJBKmrn2grRMNl1rU1iGs7FiMHL5VmZiSp_6h9GHVU,1824
|
|
72
72
|
flwr/client/mod/__init__.py,sha256=37XeXZLFq_tzFVKVtC9JaigM2bSAU7BrGQvMPCE3Q28,1159
|
|
73
73
|
flwr/client/mod/centraldp_mods.py,sha256=UGwNuqpmOWfLdfJITFgdi1TG-nLjuSb-cbEyoyfDgxQ,5415
|
|
@@ -77,19 +77,19 @@ flwr/client/mod/secure_aggregation/__init__.py,sha256=A7DzZ3uvXTUkuHBzrxJMWQQD4R
|
|
|
77
77
|
flwr/client/mod/secure_aggregation/secagg_mod.py,sha256=wI9tuIEvMUETz-wVIEbPYvh-1nK9CEylBLGoVpNhL94,1095
|
|
78
78
|
flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=fZTfIELkYS64lpgxQKL66s-QHjCn-159qfLoNoIMJjc,19699
|
|
79
79
|
flwr/client/mod/utils.py,sha256=UAJXiB0wwVyLkCkpW_i5BXikdBR65p8sNFr7VNHm2nk,1226
|
|
80
|
-
flwr/client/node_state.py,sha256=
|
|
81
|
-
flwr/client/node_state_tests.py,sha256
|
|
80
|
+
flwr/client/node_state.py,sha256=_qgoNJXay25maUmcBwUcSVYpKTiW0RaoiWDSL4oFvJE,2864
|
|
81
|
+
flwr/client/node_state_tests.py,sha256=-4fVsn7y-z9NYBuhq-cjepgxgVuPqqQgDOL4SofrdIo,2239
|
|
82
82
|
flwr/client/numpy_client.py,sha256=u76GWAdHmJM88Agm2EgLQSvO8Jnk225mJTk-_TmPjFE,10283
|
|
83
83
|
flwr/client/rest_client/__init__.py,sha256=5KGlp7pjc1dhNRkKlaNtUfQmg8wrRFh9lS3P3uRS-7Q,735
|
|
84
84
|
flwr/client/rest_client/connection.py,sha256=aY_UzrNyE8g-xPAK_POZZZ93mERHTe-pOhNP-uZ8GyU,12147
|
|
85
85
|
flwr/client/supernode/__init__.py,sha256=SUhWOzcgXRNXk1V9UgB5-FaWukqqrOEajVUHEcPkwyQ,865
|
|
86
86
|
flwr/client/supernode/app.py,sha256=cg8momLzMnFrDBNJsSRDYrn8zHuJ-4UC3wIHf51aBXQ,15385
|
|
87
|
-
flwr/client/typing.py,sha256=
|
|
87
|
+
flwr/client/typing.py,sha256=dxoTBnTMfqXr5J7G3y-uNjqxYCddvxhu89spfj4Lm2U,1048
|
|
88
88
|
flwr/common/__init__.py,sha256=4cBLNNnNTwHDnL_HCxhU5ILCSZ6fYh3A_aMBtlvHTVw,3721
|
|
89
89
|
flwr/common/address.py,sha256=wRu1Luezx1PWadwV9OA_KNko01oVvbRnPqfzaDn8QOk,1882
|
|
90
90
|
flwr/common/config.py,sha256=7OF4R43st8teFXBWmV92noGEYVe00wT29QMs6od8mlI,4994
|
|
91
|
-
flwr/common/constant.py,sha256=
|
|
92
|
-
flwr/common/context.py,sha256=
|
|
91
|
+
flwr/common/constant.py,sha256=1XxuRezsr9fl3xvQNPR2kyFkwNeG_f5vZayv0PFh0kY,3012
|
|
92
|
+
flwr/common/context.py,sha256=CQt4uzCDvCIr2WdkrWq0obAz92k2_ucXGrWtBZCxP_M,2256
|
|
93
93
|
flwr/common/date.py,sha256=OcQuwpb2HxcblTqYm6H223ufop5UZw5N_fzalbpOVzY,891
|
|
94
94
|
flwr/common/differential_privacy.py,sha256=WZWrL7C9XaB9l9NDkLDI5PvM7jwcoTTFu08ZVG8-M5Q,6113
|
|
95
95
|
flwr/common/differential_privacy_constants.py,sha256=c7b7tqgvT7yMK0XN9ndiTBs4mQf6d3qk6K7KBZGlV4Q,1074
|
|
@@ -238,8 +238,8 @@ flwr/server/superlink/fleet/rest_rere/rest_api.py,sha256=yoSU-6nCJF9ASHGNpSY69nZ
|
|
|
238
238
|
flwr/server/superlink/fleet/vce/__init__.py,sha256=36MHKiefnJeyjwMQzVUK4m06Ojon3WDcwZGQsAcyVhQ,783
|
|
239
239
|
flwr/server/superlink/fleet/vce/backend/__init__.py,sha256=oBIzmnrSSRvH_H0vRGEGWhWzQQwqe3zn6e13RsNwlIY,1466
|
|
240
240
|
flwr/server/superlink/fleet/vce/backend/backend.py,sha256=iG3KSIY7DzNfcxmuLfTs7VdQJnqPCvvn5DFkTWKG5lI,2227
|
|
241
|
-
flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=
|
|
242
|
-
flwr/server/superlink/fleet/vce/vce_api.py,sha256=
|
|
241
|
+
flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=SnjZ1WOcrfMZNgiDdTHcFeXJqrY7UHx8kvO62mqU9S4,7489
|
|
242
|
+
flwr/server/superlink/fleet/vce/vce_api.py,sha256=jSMmo3AXN_6XlYyzasu5yZ2jir8_Avj2zD9qtMzun6Q,12055
|
|
243
243
|
flwr/server/superlink/state/__init__.py,sha256=Gj2OTFLXvA-mAjBvwuKDM3rDrVaQPcIoybSa2uskMTE,1003
|
|
244
244
|
flwr/server/superlink/state/in_memory_state.py,sha256=fb-f4RGiqXON0DC7aSEMNuNIjH406BhBYrNNX5Kza2g,13061
|
|
245
245
|
flwr/server/superlink/state/sqlite_state.py,sha256=dO374mTkvhWQSiwbqwUXVnAYHev-j2mHaX9v8wFmmMA,29044
|
|
@@ -257,20 +257,20 @@ flwr/server/workflow/secure_aggregation/__init__.py,sha256=3XlgDOjD_hcukTGl6Bc1B
|
|
|
257
257
|
flwr/server/workflow/secure_aggregation/secagg_workflow.py,sha256=wpAkYPId0nfK6SgpUAtsCni4_MQLd-uqJ81tUKu3xlI,5838
|
|
258
258
|
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=BRqhlnVe8CYNoUvb_KCfRXay02NTT6a-pCrMaOqAxGc,29038
|
|
259
259
|
flwr/simulation/__init__.py,sha256=9x8OCkK3jpFAPJB1aeEMOddz6V58bExQPtwE8Z3q-RY,1359
|
|
260
|
-
flwr/simulation/app.py,sha256=
|
|
260
|
+
flwr/simulation/app.py,sha256=te3dQB3eodPwzsv1y4daPyaskIAaOtgoHaQLobrqoqY,15163
|
|
261
261
|
flwr/simulation/ray_transport/__init__.py,sha256=wzcEEwUUlulnXsg6raCA1nGpP3LlAQDtJ8zNkCXcVbA,734
|
|
262
262
|
flwr/simulation/ray_transport/ray_actor.py,sha256=3j0HgzjrlYjnzdTRy8aA4Nf6VoUvxi1hGRQkGSU5z6c,19020
|
|
263
|
-
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=
|
|
263
|
+
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=4KWWGSnfEBe3aGc0Ln5_1yRcZ52wKmOA7gXJKkMglvM,7302
|
|
264
264
|
flwr/simulation/ray_transport/utils.py,sha256=TYdtfg1P9VfTdLMOJlifInGpxWHYs9UfUqIv2wfkRLA,2392
|
|
265
265
|
flwr/simulation/run_simulation.py,sha256=qGP8sHKAzJT9nGeqMw36iCsVXm4ZFMBisCORuTswr-g,17277
|
|
266
266
|
flwr/superexec/__init__.py,sha256=9h94ogLxi6eJ3bUuJYq3E3pApThSabTPiSmPAGlTkHE,800
|
|
267
|
-
flwr/superexec/app.py,sha256=
|
|
268
|
-
flwr/superexec/deployment.py,sha256=
|
|
269
|
-
flwr/superexec/exec_grpc.py,sha256=
|
|
267
|
+
flwr/superexec/app.py,sha256=Zh9I64XfCoghWoT1k2DKDrcVCXIGOpw03v0WKCOg-mg,6402
|
|
268
|
+
flwr/superexec/deployment.py,sha256=o_FYkB_vamBPjeVpPbqvzr4kBYID26sXVDrLO3Ac4R0,6130
|
|
269
|
+
flwr/superexec/exec_grpc.py,sha256=vYbZyV89MuvYDH1XzVYHkKmGfOcU6FWh8rTcIJk2TIQ,1910
|
|
270
270
|
flwr/superexec/exec_servicer.py,sha256=4R1f_9v0vly_bXpIYaXAeV1tO5LAy1AYygGGGNZmlQk,2194
|
|
271
|
-
flwr/superexec/executor.py,sha256=
|
|
272
|
-
flwr_nightly-1.10.0.
|
|
273
|
-
flwr_nightly-1.10.0.
|
|
274
|
-
flwr_nightly-1.10.0.
|
|
275
|
-
flwr_nightly-1.10.0.
|
|
276
|
-
flwr_nightly-1.10.0.
|
|
271
|
+
flwr/superexec/executor.py,sha256=5ua0AU2cfisyD79dosP-POF3w0FRH2I5Wko_PPKLWqU,2153
|
|
272
|
+
flwr_nightly-1.10.0.dev20240714.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
273
|
+
flwr_nightly-1.10.0.dev20240714.dist-info/METADATA,sha256=9aI10DHtz4gZbec9re5g_yizKlPUjDQptMpkYOShtHE,15632
|
|
274
|
+
flwr_nightly-1.10.0.dev20240714.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
275
|
+
flwr_nightly-1.10.0.dev20240714.dist-info/entry_points.txt,sha256=7qBQcA-bDGDxnJmLd9FYqglFQubjCNqyg9M8a-lukps,336
|
|
276
|
+
flwr_nightly-1.10.0.dev20240714.dist-info/RECORD,,
|
{flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/LICENSE
RENAMED
|
File without changes
|
{flwr_nightly-1.10.0.dev20240712.dist-info → flwr_nightly-1.10.0.dev20240714.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|