Metric update method is called twice in a row
Why method update is called twice in a row when a metric is used?
Code
For instance, in the Precision metric below
import torch
from torch import nn
from pytorch_lightning.metrics.metric import Metric
from pytorch_lightning.metrics.utils import to_onehot, METRIC_EPS, _input_format_classification_one_hot


class Precision(Metric):

    def __init__(
        self,
        num_classes: int = 1,
        threshold: float = 0.5,
        average: str = 'micro',
        multilabel: bool = False,
        compute_on_step: bool = True,
        dist_sync_on_step: bool = False,
        process_group: Optional[Any] = None,
    ):
        super().__init__(
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
        )

        self.num_classes = num_classes
        self.threshold = threshold
        self.average = average
        self.multilabel = multilabel

        assert self.average in ('micro', 'macro'), \
            "average passed to the function must be either `micro` or `macro`"

        self.add_state("true_positives", default=torch.zeros(num_classes), dist_reduce_fx="sum")
        self.add_state("predicted_positives", default=torch.zeros(num_classes), dist_reduce_fx="sum")

    def update(self, preds: torch.Tensor, target: torch.Tensor):

        print("call update")
        preds, target = _input_format_classification_one_hot(
            self.num_classes, preds, target, self.threshold, self.multilabel
        )

        # multiply because we are counting (1, 1) pair for true positives
        self.true_positives += torch.sum(preds * target, dim=1)
        self.predicted_positives += torch.sum(preds, dim=1)


    def compute(self):
        if self.average == 'micro':
            return self.true_positives.sum().float() / (self.predicted_positives.sum() + METRIC_EPS)
        elif self.average == 'macro':
            return (self.true_positives.float() / (self.predicted_positives + METRIC_EPS)).mean()
when called, it produces the following output:
predictions = torch.rand(2,3)
targets = torch.rand(2,3)

mrr = Precision()
mrr(predictions, targets)
# call update
# call update
# tensor(0.4187)