Repository: cupy/cupy

Issue:
Cupyx.profiler benchmark implicitly converts from micro to milliseconds depending on object methods.
### Description

When reading the official CuPY documentation, a note on benchmarking says that it is important to use the built-in ```cupyx.profiler``` benchmark tool. However, this function returns a type ```_PerfCaseResult```. This object has several, very sparsely documented methods. If one calls ```print()``` on the entire object, the object is printed to console and runs are reported in microseconds. This is fairly standard for benchmarking. However, what is also extremely important in benchmarking is that the units stay consistent. If one wishes to access the ```cpu_times``` or ```gpu_times``` directly from the object, an array containing the run-times is printed containing the run-times in MILLIseconds.  There are no warnings or documentation of this implicit conversion, as the official documentation is:

```
cpu_times

    Returns an array of CPU times of size n_repeat.

gpu_times

    Returns an array of GPU times of size n_repeat.
```

### To Reproduce

```py
import cupy as cp
import sys
from helpers import *
from cupyx.profiler import benchmark

def generate_array(size, work_units):                          #Split this function up for timing the work only
    rand = cp.random.default_rng()                             #This is the fast way of creating large arrays with cp
    x = rand.integers(0, 100_000, (size, work_units))          #Create array
    return x                                     


def minmax(size, work_units):
    x_min = cp.min(arr)
    x_max = cp.max(arr)
    y = (arr-x_min)/(x_max-x_min)
    size = len(y) #Force execution
    return size
    
if __name__ == '__main__':
    sz = int(sys.argv[1])
    wk = int(sys.argv[2])
    arr = generate_array(sz, wk)  
    y = benchmark(minmax, (sz, wk), n_repeat=1, n_warmup=0)
    
    print(y.cpu_times)
    print(y)
```


### Installation

_No response_

### Environment

```
OS                           : Linux-5.15.0-52-generic-x86_64-with-glibc2.35
Python Version               : 3.9.13
CuPy Version                 : 10.6.0
CuPy Platform                : NVIDIA CUDA
NumPy Version                : 1.22.4
SciPy Version                : 1.9.1
Cython Build Version         : 0.29.30
Cython Runtime Version       : None
CUDA Root                    : /home/joachim/anaconda3/envs/rps
nvcc PATH                    : None
CUDA Build Version           : 11020
CUDA Driver Version          : 11070
CUDA Runtime Version         : 11050
cuBLAS Version               : (available)
cuFFT Version                : 10600
cuRAND Version               : 10207
cuSOLVER Version             : (11, 3, 2)
cuSPARSE Version             : (available)
NVRTC Version                : (11, 5)
Thrust Version               : 101000
CUB Build Version            : 101000
Jitify Build Version         : 87d8ccd
cuDNN Build Version          : None
cuDNN Version                : None
NCCL Build Version           : 21212
NCCL Runtime Version         : 21403
cuTENSOR Version             : None
cuSPARSELt Build Version     : None
Device 0 Name                : NVIDIA GeForce GTX 1660 SUPER
Device 0 Compute Capability  : 75
Device 0 PCI Bus ID          : 0000:01:00.0
```


### Additional Information

Printed to console:

python3 minmax.py 100 100
[0.00204923]
minmax              :    CPU: 2049.225 us     GPU-0: 2057.504 us


Discussion:

Resolving patch:
diff --git a/cupyx/profiler/_time.py b/cupyx/profiler/_time.py
--- a/cupyx/profiler/_time.py
+++ b/cupyx/profiler/_time.py
@@ -35,13 +35,23 @@ def __repr__(self) -> str:
         return self.to_str(show_gpu=True)
 
     @property
-    def cpu_times(self):
-        """ Returns an array of CPU times of size ``n_repeat``. """
+    def cpu_times(self) -> _numpy.ndarray:
+        """A :class:`numpy.ndarray` of shape ``(n_repeat,)``, holding times spent
+        on CPU in milliseconds.
+
+        These values are delta of the host-side performance counter
+        (:func:`time.perf_counter`) between each repeat step.
+        """
         return self._ts[0]
 
     @property
-    def gpu_times(self):
-        """ Returns an array of GPU times of size ``n_repeat``. """
+    def gpu_times(self) -> _numpy.ndarray:
+        """A :class:`numpy.ndarray` of shape ``(len(devices), n_repeat)``,
+        holding times spent on GPU in milliseconds.
+
+        These values are measured using ``cudaEventElapsedTime`` with events
+        recoreded before/after each repeat step.
+        """
         return self._ts[1:]
 
     @staticmethod
@@ -159,9 +169,6 @@ def _repeat(
         finally:
             runtime.setDevice(prev_device)
 
-    ev1 = _cupy.cuda.stream.Event()
-    ev2 = _cupy.cuda.stream.Event()
-
     for i in range(n_warmup):
         func(*args, **kwargs)
 


Test patch: