Repository: ivy-llc/ivy
Pull request: Fixing the randint function when using the torch backend
Closes #10369

Problem statement:
[Bug]: ivy.randint with torch backend produces undesired values.
### Bug Explanation

When using ivy.randint with the torch backend, the values that are returned are wrong. 

It should return a random uniform distribution between low and high, but it returns just the lower value. 

### Steps to Reproduce Bug

E.g.: `ivy.randint(2, 10, shape=(10, 2))`

### Environment

Arch Linux, Ipython

### Ivy Version

v1.1.9 

### Backend

- [ ] NumPy
- [ ] TensorFlow
- [X] PyTorch
- [ ] JAX

### Device

CPU

Hints from issue discussion:
#10371 should resolve the issue

Commit message: when no shape is given the default is a scalar

Patch to review:
diff --git a/ivy/functional/backends/torch/random.py b/ivy/functional/backends/torch/random.py
index bcfa4d05a6114..b157c177ce068 100644
--- a/ivy/functional/backends/torch/random.py
+++ b/ivy/functional/backends/torch/random.py
@@ -96,21 +96,18 @@ def randint(
     high: Union[int, torch.Tensor],
     /,
     *,
-    shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None,
+    shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = (1,),
     device: torch.device,
-    dtype: Optional[Union[torch.dtype, ivy.Dtype]] = None,
+    dtype: Optional[Union[torch.dtype, ivy.Dtype]] = ivy.default_int_dtype(),
     seed: Optional[int] = None,
     out: Optional[torch.Tensor] = None,
 ) -> torch.Tensor:
-    if not dtype:
-        dtype = ivy.default_int_dtype()
     dtype = ivy.as_native_dtype(dtype)
     _randint_check_dtype_and_bound(low, high, dtype)
     shape = _check_bounds_and_get_shape(low, high, shape)
-    rand_range = high - low
     if seed:
         torch.manual_seed(seed)
-    return torch.rand(shape, device=device).to(dtype) * rand_range + low
+    return torch.randint(low=low, high=high, size=shape, device=device, dtype=dtype)
 
 
 def seed(*, seed_value: int = 0) -> None:


Code review comments:
diff_hunk: @@ -96,21 +96,18 @@ def randint(
     high: Union[int, torch.Tensor],
     /,
     *,
-    shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None,
+    shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = (1,),
     device: torch.device,
-    dtype: Optional[Union[torch.dtype, ivy.Dtype]] = None,
+    dtype: Optional[Union[torch.dtype, ivy.Dtype]] = ivy.default_int_dtype(),
path: ivy/functional/backends/torch/random.py
text: @user1:
This should be kept none and add a condition to check when `dtype` is `None`

diff_hunk: @@ -96,21 +96,18 @@ def randint(
     high: Union[int, torch.Tensor],
     /,
     *,
-    shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None,
+    shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = (1,),
path: ivy/functional/backends/torch/random.py
text: @user1:
This one also should be kept as `None`

@author:
@user2-nshuti , thanks it's done. 

Why do you think `None` makes more sense in this case? 
Is it the convention for backend functions? 

@user1:
It's because we have explicitly stated it in the functional API🙂
https://lets-unify.ai/ivy/functional/ivy/random/randint.html

@author:
Thank you :)