Args: input_dict (dict): all the values will be reduced average (bool): whether to do average or sum Reduce the values in the dictionary from all processes so that all processes have the averaged results. Returns a dict with the same fields as input_dict, after reduc
(input_dict, average=True)
| 155 | |
| 156 | |
| 157 | def reduce_dict(input_dict, average=True): |
| 158 | """ |
| 159 | Args: |
| 160 | input_dict (dict): all the values will be reduced |
| 161 | average (bool): whether to do average or sum |
| 162 | Reduce the values in the dictionary from all processes so that all processes |
| 163 | have the averaged results. Returns a dict with the same fields as |
| 164 | input_dict, after reduction. |
| 165 | """ |
| 166 | world_size = get_world_size() |
| 167 | if world_size < 2: |
| 168 | return input_dict |
| 169 | with torch.no_grad(): |
| 170 | names = [] |
| 171 | values = [] |
| 172 | # sort the keys so that they are consistent across processes |
| 173 | # import pdb; pdb.set_trace() |
| 174 | for k in sorted(input_dict.keys()): |
| 175 | |
| 176 | names.append(k) |
| 177 | values.append(input_dict[k]) |
| 178 | # pdb.set_trace() |
| 179 | values = torch.stack(values, dim=0) |
| 180 | |
| 181 | try: |
| 182 | dist.all_reduce(values) |
| 183 | rank = dist.get_rank() |
| 184 | # logging.info(f'Rank {rank} after all_reduce') |
| 185 | except Exception as e: |
| 186 | rank = dist.get_rank() |
| 187 | print(f'Exception in rank {rank}: {e}') |
| 188 | # print(f'values: {values}') |
| 189 | # print(f'names: {names}') |
| 190 | logging.info(f'Rank {rank} after all_reduce') |
| 191 | if average: |
| 192 | values /= world_size |
| 193 | reduced_dict = {k: v for k, v in zip(names, values)} |
| 194 | return reduced_dict |
| 195 | |
| 196 | def setup_logging(): |
| 197 | logging.basicConfig(level=logging.INFO) |
nothing calls this directly
no test coverage detected