Repository: PennyLaneAI/pennylane

Issue:
[BUG] Finite diff changes incompatible with floats
### Expected behavior

The following quantum function should be able to be run:

```python
import pennylane as qml

def f(x):
    qml.RX(x, wires=0)
    return qml.expval(qml.PauliY(0))

def interpretted_grad_default(x):
    device = qml.device("default.qubit", wires=1)
    g = qml.QNode(f, device, diff_method="finite-diff")
    h = qml.grad(g, argnum=0)
    return h(x)

print(interpretted_grad_default(1.0))
```

### Actual behavior

There's an assertion: `ImportError: autoray couldn't find function 'get_dtype_name' for backend 'autograd'.`

### Additional information

Catalyst tests are failing due to [a change made to finite diff](https://github.com/PennyLaneAI/pennylane/pull/4415#discussion_r1290048575). This needs to be addressed before the v0.32 release.

### Source code

See above

### Tracebacks

```
Traceback (most recent call last):
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autoray/autoray.py", line 953, in get_dtype_name
    return x.dtype.name
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autograd/numpy/numpy_boxes.py", line 19, in <lambda>
    dtype = property(lambda self: self._value.dtype)
AttributeError: 'float' object has no attribute 'dtype'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autoray/autoray.py", line 462, in get_lib_fn
    lib_fn = _FUNCS[backend, fn]
KeyError: ('autograd', 'get_dtype_name')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autoray/autoray.py", line 429, in import_lib_fn
    lib_fn = _FUNCS[backend, fn] = wrapper(getattr(lib, fn_name))
AttributeError: module 'pennylane.numpy' has no attribute 'get_dtype_name'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/erick.ochoalopez/Code/catalyst-latest/test.py", line 29, in <module>
    print(interpretted_grad_default(1.0))
  File "/home/erick.ochoalopez/Code/catalyst-latest/test.py", line 27, in interpretted_grad_default
    return h(x)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/_grad.py", line 120, in __call__
    grad_value, ans = grad_fn(*args, **kwargs)  # pylint: disable=not-callable
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autograd/wrap_util.py", line 20, in nary_f
    return unary_operator(unary_f, x, *nary_op_args, **nary_op_kwargs)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/_grad.py", line 146, in _grad_with_forward
    grad_value = vjp(vspace(ans).ones())
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autograd/core.py", line 14, in vjp
    def vjp(g): return backward_pass(g, end_node)
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autograd/core.py", line 21, in backward_pass
    ingrads = node.vjp(outgrad[0])
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autograd/core.py", line 67, in <lambda>
    return lambda g: (vjp(g),)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/interfaces/autograd.py", line 497, in grad_fn
    vjp_tapes, processing_fn = qml.gradients.batch_vjp(
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/gradients/vjp.py", line 521, in batch_vjp
    g_tapes, fn = vjp(tape, dy, gradient_fn, gradient_kwargs=gradient_kwargs)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/gradients/vjp.py", line 381, in vjp
    gradient_tapes, fn = gradient_fn(tape, **gradient_kwargs)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/transforms/batch_transform.py", line 359, in __call__
    return self._tape_wrapper(*targs, **tkwargs)(qnode)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/transforms/batch_transform.py", line 452, in <lambda>
    return lambda tape: self.construct(tape, *targs, **tkwargs)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/transforms/batch_transform.py", line 434, in construct
    tapes, processing_fn = self.transform_fn(tape, *targs, **tkwargs)
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/gradients/finite_difference.py", line 334, in finite_diff
    if any(qml.math.get_dtype_name(p) == "float32" for p in tape.get_parameters()):
  File "/home/erick.ochoalopez/Code/pennylane/pennylane/gradients/finite_difference.py", line 334, in <genexpr>
    if any(qml.math.get_dtype_name(p) == "float32" for p in tape.get_parameters()):
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autoray/autoray.py", line 956, in get_dtype_name
    return do("get_dtype_name", x, like=x)
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autoray/autoray.py", line 79, in do
    return get_lib_fn(backend, fn)(*args, **kwargs)
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autoray/autoray.py", line 464, in get_lib_fn
    lib_fn = import_lib_fn(backend, fn)
  File "/home/erick.ochoalopez/Code/catalyst-latest/env/lib/python3.10/site-packages/autoray/autoray.py", line 437, in import_lib_fn
    raise ImportError(
ImportError: autoray couldn't find function 'get_dtype_name' for backend 'autograd'.

```

### System information

```shell
*
```


### Existing GitHub issues

- [X] I have searched existing GitHub issues to make sure the issue does not already exist.


Discussion:
quick note for readers/fixers: it's `ArrayBox` instances, not `pennylane.numpy.tensor` instances, that cause this issue

Resolving patch:
diff --git a/pennylane/math/__init__.py b/pennylane/math/__init__.py
--- a/pennylane/math/__init__.py
+++ b/pennylane/math/__init__.py
@@ -95,7 +95,16 @@
 sum = ar.numpy.sum
 toarray = ar.numpy.to_numpy
 T = ar.numpy.transpose
-get_dtype_name = ar.get_dtype_name
+
+
+def get_dtype_name(x) -> str:
+    """An interface independent way of getting the name of the datatype.
+
+    >>> x = tf.Variable(0.1)
+    >>> qml.math.get_dtype_name(tf.Variable(0.1))
+    'float32'
+    """
+    return ar.get_dtype_name(x)
 
 
 class NumpyMimic(ar.autoray.NumpyMimic):
@@ -142,6 +151,7 @@ def __getattr__(name):
     "fidelity",
     "fidelity_statevector",
     "frobenius_inner_product",
+    "get_dtype_name",
     "get_interface",
     "get_trainable_indices",
     "in_backprop",
diff --git a/pennylane/math/single_dispatch.py b/pennylane/math/single_dispatch.py
--- a/pennylane/math/single_dispatch.py
+++ b/pennylane/math/single_dispatch.py
@@ -116,6 +116,15 @@ def _cond(pred, true_fn, false_fn, args):
 ar.register_function("autograd", "unstack", list)
 
 
+def autograd_get_dtype_name(x):
+    """A autograd version of get_dtype_name that can handle array boxes."""
+    # this function seems to only get called with x is an arraybox.
+    return ar.get_dtype_name(x._value)
+
+
+ar.register_function("autograd", "get_dtype_name", autograd_get_dtype_name)
+
+
 def _block_diag_autograd(tensors):
     """Autograd implementation of scipy.linalg.block_diag"""
     _np = _i("qml").numpy


Test patch:
diff --git a/tests/math/test_functions.py b/tests/math/test_functions.py
--- a/tests/math/test_functions.py
+++ b/tests/math/test_functions.py
@@ -11,7 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-"""Unit tests for the TensorBox functional API in pennylane.fn.fn
+"""Unit tests for pennylane.math.single_dispatch
 """
 # pylint: disable=import-outside-toplevel
 import itertools
@@ -1327,6 +1327,29 @@ def test_shape(shape, interface, create_array):
     assert fn.shape(t) == shape
 
 
+@pytest.mark.parametrize(
+    "x, expected",
+    (
+        (1.0, "float64"),
+        (1, "int64"),
+        (onp.array(0.5), "float64"),
+        (onp.array(1.0, dtype="float32"), "float32"),
+        (ArrayBox(1, "a", "b"), "int64"),
+        (np.array(0.5), "float64"),
+        (np.array(0.5, dtype="complex64"), "complex64"),
+        # skip jax as output is dependent on global configuration
+        (tf.Variable(0.1, dtype="float32"), "float32"),
+        (tf.Variable(0.1, dtype="float64"), "float64"),
+        (torch.tensor(0.1, dtype=torch.float32), "float32"),
+        (torch.tensor(0.5, dtype=torch.float64), "float64"),
+        (torch.tensor(0.1, dtype=torch.complex128), "complex128"),
+    ),
+)
+def test_get_dtype_name(x, expected):
+    """Test that get_dtype_name returns the a string for the datatype."""
+    assert fn.get_dtype_name(x) == expected
+
+
 @pytest.mark.parametrize("t", test_data)
 def test_sqrt(t):
     """Test that the square root function works for a variety