I wanted to avoid this. In the documentation 1 it says: " If you have a numpy array and want to avoid a copy, use torch.as_tensor()". Then, what is wrong here?.

As I wrote above, torch.as_tensor([a])  forces a slow copy because you wrap the NumPy array in a Python list. It’s not the same as torch.as_tensor(a) – type(a) is a NumPy ndarray; type([a]) is Python list.
I’m not sure what your use-case is. If you’re doing an element-wise multiplication of two arrays only once, it never makes sense to copy it to the GPU and back. Modern CPUs can multiply integers and floating point numbers faster than they can copy them to and from RAM (or the GPU). You’re going to be primarily measuring the time it takes to copy. If you want measure copy time, just measure copy time.
Regard asynchronous execution, see:
https://pytorch.org/docs/stable/notes/cuda.html#asynchronous-execution 19.
https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#using-cpu-timers 10