Repository: Lightning-AI/torchmetrics

Issue:
Thresholds not working?
## 🐛 Bug

Using `torchmetrics.PrecisionRecallCurve` / `torchmetrics.ROC` produce an error when setting `thresholds` to something other than `None`.

### To Reproduce

```py
import torch
import torchmetrics
x = torch.zeros(5, 2)
y = torch.zeros(5, 2)
thresholds = torch.linspace(0, 1, 100)
prc = torchmetrics.PrecisionRecallCurve(task="multilabel", num_labels=2, thresholds=thresholds)
prc(x, y)
```

Output:
```
File .../torchmetrics/utilities/data.py:228, in _bincount(x, minlength)
    226         output[i] = (x == i).sum()
    227     return output
--> 228 return torch.bincount(x, minlength=minlength)

RuntimeError: "bincount_cpu" not implemented for 'Float'
```

#### Code sample

See above.

### Expected behavior

Works as documented, where a `List` or `Tensor` of thresholds can be manually provided, rather than using the autobin feature.

### Environment

- TorchMetrics version (and how you installed TM, e.g. `conda`, `pip`, build from source): conda, 0.11
- Python & PyTorch Version (e.g., 1.0): Python 3.10, PyTorch 1.13.1
- Any other relevant information such as OS (e.g., Linux): LUbuntu 22.04

### Additional context

N/A


Discussion:
Hi! thanks for your contribution!, great first issue!

Resolving patch:
diff --git a/src/torchmetrics/functional/classification/precision_recall_curve.py b/src/torchmetrics/functional/classification/precision_recall_curve.py
--- a/src/torchmetrics/functional/classification/precision_recall_curve.py
+++ b/src/torchmetrics/functional/classification/precision_recall_curve.py
@@ -132,6 +132,12 @@ def _binary_precision_recall_curve_tensor_validation(
     """
     _check_same_shape(preds, target)
 
+    if target.is_floating_point():
+        raise ValueError(
+            "Expected argument `target` to be an int or long tensor with ground truth labels"
+            f" but got tensor with dtype {target.dtype}"
+        )
+
     if not preds.is_floating_point():
         raise ValueError(
             "Expected argument `preds` to be an floating tensor with probability/logit scores,"
@@ -334,6 +340,10 @@ def _multiclass_precision_recall_curve_tensor_validation(
         raise ValueError(
             f"Expected `preds` to have one more dimension than `target` but got {preds.ndim} and {target.ndim}"
         )
+    if target.is_floating_point():
+        raise ValueError(
+            f"Expected argument `target` to be an int or long tensor, but got tensor with dtype {target.dtype}"
+        )
     if not preds.is_floating_point():
         raise ValueError(f"Expected `preds` to be a float tensor, but got {preds.dtype}")
     if preds.shape[1] != num_classes:


Test patch:
diff --git a/tests/unittests/classification/test_precision_recall_curve.py b/tests/unittests/classification/test_precision_recall_curve.py
--- a/tests/unittests/classification/test_precision_recall_curve.py
+++ b/tests/unittests/classification/test_precision_recall_curve.py
@@ -132,6 +132,16 @@ def test_binary_precision_recall_curve_threshold_arg(self, input, threshold_fn):
             assert torch.allclose(r1, r2)
             assert torch.allclose(t1, t2)
 
+    def test_binary_error_on_wrong_dtypes(self, input):
+        """Test that error are raised on wrong dtype."""
+        preds, target = input
+
+        with pytest.raises(ValueError, match="Expected argument `target` to be an int or long tensor with ground.*"):
+            binary_precision_recall_curve(preds[0], target[0].to(torch.float32))
+
+        with pytest.raises(ValueError, match="Expected argument `preds` to be an floating tensor with probability.*"):
+            binary_precision_recall_curve(preds[0].long(), target[0])
+
 
 def _sklearn_precision_recall_curve_multiclass(preds, target, ignore_index=None):
     preds = np.moveaxis(preds.numpy(), 1, -1).reshape((-1, preds.shape[1]))
@@ -243,6 +253,16 @@ def test_multiclass_precision_recall_curve_threshold_arg(self, input, threshold_
                 assert torch.allclose(r1[i], r2[i])
                 assert torch.allclose(t1[i], t2)
 
+    def test_multiclass_error_on_wrong_dtypes(self, input):
+        """Test that error are raised on wrong dtype."""
+        preds, target = input
+
+        with pytest.raises(ValueError, match="Expected argument `target` to be an int or long tensor, but got.*"):
+            multiclass_precision_recall_curve(preds[0], target[0].to(torch.float32), num_classes=NUM_CLASSES)
+
+        with pytest.raises(ValueError, match="Expected `preds` to be a float tensor, but got.*"):
+            multiclass_precision_recall_curve(preds[0].long(), target[0], num_classes=NUM_CLASSES)
+
 
 def _sklearn_precision_recall_curve_multilabel(preds, target, ignore_index=None):
     precision, recall, thresholds = [], [], []
@@ -345,6 +365,16 @@ def test_multilabel_precision_recall_curve_threshold_arg(self, input, threshold_
                 assert torch.allclose(r1[i], r2[i])
                 assert torch.allclose(t1[i], t2)
 
+    def test_multilabel_error_on_wrong_dtypes(self, input):
+        """Test that error are raised on wrong dtype."""
+        preds, target = input
+
+        with pytest.raises(ValueError, match="Expected argument `target` to be an int or long tensor with ground.*"):
+            multilabel_precision_recall_curve(preds[0], target[0].to(torch.float32), num_labels=NUM_CLASSES)
+
+        with pytest.raises(ValueError, match="Expected argument `preds` to be an floating tensor with probability.*"):
+            multilabel_precision_recall_curve(preds[0].long(), target[0], num_labels=NUM_CLASSES)
+
 
 @pytest.mark.parametrize(
     "metric",