How do i use the get_properties method on the server side?

This question was migrated from the Slack channel #questions.

Original Question:
Hi. How do i use the get_properties method on the server side. I have sent some properties from the client to server in a dict format {"prop1": "lorem", "prop2": "ipsum"} but I’m not sure how to retrieve/use it on the server side.


Answer:
Hi! You can use it in your strategy by calling the get_properties function of the ClientProxy objects. Here is a working example in a fork of a Flower contributor: flower/examples/quickstart-pytorch-slurm/strategy.py at 339e95daabd999355c3ce1dca8a5df9d937557d1 · jafermarq/flower · GitHub


Question:
Thanks for replying. In the example, get_properties is used inside the configure_fit or configure_eval because it stops sending instructions to clients not participating in the training.My use case is somewhat different: I want to send some hardware properties of all the clients before any training starts. So, I’m not sure how to use get_properties in my strategy since it does not really go inside configure_fit or configure_eval


Answer:
But configure_fit is called every time before the training starts. You could use it to call the get_properties function of the clients without removing clients from the training.


Question:
I actually meant that I want the client properties just once and before the very first round of training


Answer:
Then you could do it in the initialize_parameters function of your strategy, which is only called once before the start of the training


Question:
Thanks for sticking in this discussion. Let me tell you a bit more about my use case:
I want to send some CPU/GPU properties such as CPU family name, available VRAM in a dict format using get_properties in client. As far as my knowledge, initialize_parameters is used to ask any one client what are its global model params before starting training, In my case, I just want to communicate the hardware properties to the server from all the clients. Later on, I can use that information and ask the client with the most available VRAM (or the most powerful CPU) for its param using initialize_paramters .
In summary, I don’t need model parameters. I only need some hardware info/properties.
Thanks for all the help :slightly_smiling_face:


Answer:
Well the initialize_parameters function has access to the ClientManager , with it you can sample all of your clients, call their get_properties functions, and then do what you need with the results. I might be wrong, but I think it should work as you need it to.

Maybe what I said wasn’t really clear, I meant that you could write a custom initialize_parameters function that does what you want because this function is called before the training starts and has access to the ClientManager


Question:
initialize_parameters is invoked even before the clients are connected. ccording to the docs “If no parameters are returned from initialize_parameters (i.e., None), the server will randomly select one client and ask it to provide its parameters”
Therefore I passed None in the initial_parameter in strategy declaration so that the func call directly goes to initialize_parameters .
This was my code:


def initialize_parameters(self, client_manager: ClientManager):
        # Get a list of all connected clients
        clients = client_manager.all()
        # Create an instance of GetPropertiesIns
        ins = GetPropertiesIns({})
        # Call get_properties on each client and store the results
        client_properties = {}
        for cid, client in clients.items():
            properties = client.get_properties(ins, timeout=30)
            client_properties[cid] = properties.properties
        print(f"CLIENT PROPS: {client_properties}")
        initial_parameters = self.set_initial_parameters()  # this is a helper func to load checkpoints
        return initial_parameters

Answer:
You can use the wait_for function of the ClientManager in order to make sure that all clients are connected before you call get_properties: flower/src/py/flwr/server/client_manager.py at 88f8e434489e7b99030664429d88bf66e0ecae66 · adap/flower · GitHub


Question:
Thanks. This is what I was looking for. I can now send client info to server before the any training starts. Thanks for the help :slightly_smiling_face:

Solution:
Client side:

def get_properties(self, config : Config) -> Dict[str, Scalar]:
       properties = {"value1": "lorem", "value2": "ipsum"}
        return properties

Server side:

def initialize_parameters(self, client_manager: ClientManager):   
       client_manager.wait_for(num_clients  =  2)
        client_properties = {}
        for cid, client in client_manager.all().items():
            ins = GetPropertiesIns({})
            client_properties[cid] = client.get_properties(ins, timeout = 30)
        print(self._filter(client_properties)) # helper filter function
        initial_parameters = self._set_initial_parameters() # for loading saved model checkpoints
        return initial_parameters