Repository: Lightning-AI/torchmetrics

Issue:
raise ValueError(f"Rank {rank} and Rank 0 have different values for the list to gather.")
Please help me to check the following code in "torchmetrics/detection/mean_ap.py" is right?

I think list_gathered[rank] should not be equal to list_gathered[0]

#1743 
#1763 

```
for rank in range(1, world_size):
            if list_gathered[rank] != list_gathered[0]:
                raise ValueError(f"Rank {rank} and Rank 0 have different values for the list to gather.")
```


Discussion:
The following is the test code.

```
import lightning
import torch
import torch.nn as nn
from torchmetrics.detection import MeanAveragePrecision


class ToyNet(lightning.LightningModule):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(1, 1)
        self.metric = MeanAveragePrecision(iou_type="segm")

    def training_step(self, batch, batch_idx):
        return None

    def validation_step(self, batch, batch_idx):
        preds = []
        targets = []
        for _ in range(2):
            result = dict()
            num_preds = torch.randint(0, 10, (1,)).item()
            # result['boxes'] = torch.rand((num_preds, 4), device=self.device)
            result['scores'] = torch.rand((num_preds,), device=self.device)
            result['labels'] = torch.randint(0, 10, (num_preds,),  device=self.device)
            result['masks'] = torch.randint(0, 2, (num_preds, 10, 10),  device=self.device).bool()
            preds.append(result)
            # parse gt
            gt = dict()
            num_gt = torch.randint(0, 10, (1,)).item()
            # gt['boxes'] = torch.rand((num_gt, 4), device=self.device)
            gt['labels'] = torch.randint(0, 10, (num_gt,),  device=self.device)
            gt['masks'] = torch.randint(0, 2, (num_gt, 10, 10),  device=self.device).bool()
            targets.append(gt)
        self.metric.update(preds, targets)

    def on_validation_epoch_end(self) -> None:
        self.log_dict(self.metric.compute(), prog_bar=True)

    def configure_optimizers(self):
        return torch.optim.Adam(self.parameters(), lr=0.02)


if __name__ == '__main__':
    model = ToyNet()
    trainer = lightning.Trainer(accelerator='gpu', devices=2, max_epochs=1)
    val_dataloader = torch.utils.data.DataLoader(torch.utils.data.TensorDataset(torch.rand((10, 1)), torch.rand((10, 1))))
    trainer.validate(model, val_dataloader)

```

Resolving patch:
diff --git a/src/torchmetrics/detection/mean_ap.py b/src/torchmetrics/detection/mean_ap.py
--- a/src/torchmetrics/detection/mean_ap.py
+++ b/src/torchmetrics/detection/mean_ap.py
@@ -900,12 +900,11 @@ def _sync_dist(self, dist_sync_fn: Optional[Callable] = None, process_group: Opt
     def _gather_tuple_list(list_to_gather: List[Tuple], process_group: Optional[Any] = None) -> List[Any]:
         """Gather a list of tuples over multiple devices."""
         world_size = dist.get_world_size(group=process_group)
-        list_gathered = [None] * world_size
+        dist.barrier(group=process_group)
+
+        list_gathered = [None for _ in range(world_size)]
         dist.all_gather_object(list_gathered, list_to_gather, group=process_group)
 
-        for rank in range(1, world_size):
-            if list_gathered[rank] != list_gathered[0]:
-                raise ValueError(f"Rank {rank} and Rank 0 have different values for the list to gather.")
         list_merged = []
         for idx in range(len(list_gathered[0])):
             for rank in range(world_size):


Test patch: