{"record":{"id":"f00cc76528e6aa6d","repo":"Lightning-AI/pytorch-lightning","slug":"devices-selected-with-cpuaccelerator-should-be","errorCode":null,"errorMessage":"`devices` selected with `CPUAccelerator` should be an int > 0.","messagePattern":"`devices` selected with `CPUAccelerator` should be an int > 0\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/lightning/fabric/accelerators/cpu.py","lineNumber":99,"sourceCode":"    \"\"\"Parses the cpu_cores given in the format as accepted by the ``devices`` argument in the\n    :class:`~lightning.pytorch.trainer.trainer.Trainer`.\n\n    Args:\n        cpu_cores: An int > 0 or a string that can be converted to an int > 0.\n\n    Returns:\n        An int representing the number of processes\n\n    Raises:\n        MisconfigurationException:\n            If cpu_cores is not an int > 0\n\n    \"\"\"\n    if isinstance(cpu_cores, str) and cpu_cores.strip().isdigit():\n        cpu_cores = int(cpu_cores)\n\n    if not isinstance(cpu_cores, int) or cpu_cores <= 0:\n        raise TypeError(\"`devices` selected with `CPUAccelerator` should be an int > 0.\")\n\n    return cpu_cores\n","sourceCodeStart":81,"sourceCodeEnd":102,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/fabric/accelerators/cpu.py#L81-L102","documentation":"When a logged metric has sync_dist=True (or is otherwise a torchmetrics Metric), Lightning calls the metric's .compute() and expects a single torch.Tensor back. This ValueError is thrown in _get_cache when the computed cache exists but is not a Tensor (e.g. a tuple, dict, list, or number).","triggerScenarios":"Logging a torchmetrics Metric whose compute() returns a tuple (like returning (loss, acc)) or a dict; logging a custom Metric subclass whose compute() returns a Python float or a collection; metrics with enable_graph/sync_dist paths that read result_metric._computed in _get_cache (used by metrics(), tests like test_metric_result_computed_check).","commonSituations":"Wrapping a model that returns multiple outputs into one Metric.compute(); using ClassificationTask-style metrics returning dicts; upgrading torchmetrics where compute() signatures changed; writing custom metrics without returning a tensor.","solutions":["Make the custom Metric.compute() return a single torch.Tensor (stack/cat or index into the collection)","Split multi-output metrics into separate Metric instances, one per scalar, each logged with its own name","Return a scalar tensor: e.g. return loss.item() -> return torch.tensor(loss) is wrong; return loss if loss is already a tensor"],"exampleFix":"# before\nclass MyMetric(Metric):\n    def compute(self):\n        return self.tp, self.fp  # tuple -> raises\n\n# after\nclass MyMetric(Metric):\n    def compute(self):\n        return torch.stack([self.tp.float(), self.fp.float()])\n# or two separate metrics logged under distinct names","handlingStrategy":"validation","validationCode":"import torch\nfrom torchmetrics import Metric\n\ndef compute_is_tensor(metric: Metric) -> bool:\n    out = metric.compute()\n    return isinstance(out, torch.Tensor)","typeGuard":"from torch import Tensor\nfrom torchmetrics import Metric\n\ndef metric_returns_tensor(m: Metric) -> bool:\n    try:\n        return isinstance(m.compute(), Tensor)\n    except Exception:\n        return False","tryCatchPattern":"try:\n    value = trainer.callback_metrics[\"my_metric\"]\nexcept (ValueError, KeyError) as e:\n    # metric.compute() did not return a tensor\n    logger.warning(\"skipping metric: %s\", e)\n    value = None","preventionTips":["Always return a single Tensor from custom Metric.compute()","Keep one Metric per scalar value; never return tuples or dicts from compute()","Add a unit test asserting isinstance(my_metric.compute(), torch.Tensor)"],"tags":["pytorch-lightning","torchmetrics","compute","type-mismatch"],"backgroundTag":"metric-compute-wrong-return-type","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}