Repository: pytorch
Issue: [Bug]need check for duplicate malloc calls in CUDAPluggableAllocator
Labels: module: cuda,triaged,module: CUDACachingAllocator

### 🐛 Describe the bug

Noticing that CUDAPluggableAllocator checks for duplicate free calls on the same pointer, but there is no check for duplicate malloc calls in CUDAPluggableAllocator.

Duplicate call of malloc  in the same pointer would occur if the statically allocated PluggableAllocator is used.

Suppose there are two sets of memory allocation requests, representing Tensor-0 and Tensor-1, respectively. If Tensor-0 is allocated first and not released until the end of the entire training task, while Tensor-1 uses the same address as Tensor-0, memory corruption has already occurred. However, since the second free operation on this address happens at the very end of the process, the error might not be detected during the training process.

It's worth noting that some Tensors might not be explicitly released; instead, they are automatically freed when the process ends, thus bypassing the call to CUDAPluggableAllocator's raw_delete(). This will even cause this Duplicate malloc behavior to not get any Error report.

## Code
file-path : `torch/csrc/cuda/CUDAPluggableAllocator.cpp`
check for duplicate free calls in `CUDAPluggableAllocator::raw_delete()`
```c++
void CUDAPluggableAllocator::raw_delete(void* ptr) {
  cudaStream_t stream{};
  c10::DeviceIndex device_idx = -1;
  size_t size = 0;
  {
    const std::lock_guard<std::mutex> lock(allocator_mutex_);
    TORCH_CHECK(
        allocation_metadata_.count(ptr),
        "Trying to free a pointer not allocated here");
    _AllocationMetadata& metadata = allocation_metadata_[ptr];
    size = metadata.size;
    device_idx = metadata.device_idx;
    stream = metadata.stream;
    allocation_metadata_.erase(ptr);
  }
  free_fn_(ptr, size, device_idx, stream);
}
```

no check for duplicate alloc calls in `CUDAPluggableAllocator::malloc()`
```c++
void* CUDAPluggableAllocator::malloc(
    size_t size,
    c10::DeviceIndex device,
    cudaStream_t stream) {
  void* r = alloc_fn_(size, device, stream);
  {
    const std::lock_guard<std::mutex> lock(allocator_mutex_);
    allocation_metadata_.emplace(r, _AllocationMetadata(size, device, stream));
  }
  return r;
}
```

### Versions

Collecting environment information...
PyTorch version: N/A
Is debug build: N/A
CUDA used to build PyTorch: N/A
ROCM used to build PyTorch: N/A

OS: macOS 14.5 (arm64)
GCC version: Could not collect
Clang version: 16.0.0 (clang-1600.0.26.4)
CMake version: Could not collect
Libc version: N/A

Python version: 3.9.6 (default, Oct  4 2024, 08:01:31)  [Clang 16.0.0 (clang-1600.0.26.4)] (64-bit runtime)
Python platform: macOS-14.5-arm64-arm-64bit
Is CUDA available: N/A
CUDA runtime version: Could not collect
CUDA_MODULE_LOADING set to: N/A
GPU models and configuration: Could not collect
Nvidia driver version: Could not collect
cuDNN version: Could not collect
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: N/A

CPU:
Apple M2

Versions of relevant libraries:
[pip3] numpy==2.0.2
[conda] Could not collect

cc @ptrblck @msaroufim @eqy