| 32 | */ |
| 33 | template<class _T, class _Index = size_t> |
| 34 | class Memory { |
| 35 | public: |
| 36 | typedef _T Data; |
| 37 | typedef _Index Index; |
| 38 | |
| 39 | int device_id; |
| 40 | Index count = 0, capacity = 0; |
| 41 | cudaStream_t stream; |
| 42 | int *refer_count = nullptr; |
| 43 | Data *host_ptr = nullptr, *device_ptr = nullptr; |
| 44 | |
| 45 | /** |
| 46 | * @brief Construct a memory space |
| 47 | * @param _device_id GPU id, -1 for CPU |
| 48 | * @param _count number of data |
| 49 | * @param _stream CUDA stream |
| 50 | */ |
| 51 | Memory(int _device_id, Index _count = 0, cudaStream_t _stream = 0) : |
| 52 | device_id(_device_id), stream(_stream) { |
| 53 | resize(_count); |
| 54 | } |
| 55 | |
| 56 | /** Shallow copy constructor */ |
| 57 | Memory(const Memory &m) : |
| 58 | device_id(m.device_id), count(m.count), capacity(m.capacity), stream(m.stream), refer_count(m.refer_count), |
| 59 | host_ptr(m.host_ptr), device_ptr(m.device_ptr) { |
| 60 | if (capacity) |
| 61 | (*refer_count)++; |
| 62 | } |
| 63 | |
| 64 | Memory &operator=(const Memory &) = delete; |
| 65 | |
| 66 | ~Memory() { reallocate(0); } |
| 67 | |
| 68 | /** Swap two memory spaces */ |
| 69 | void swap(Memory &m) { |
| 70 | std::swap(device_id, m.device_id); |
| 71 | std::swap(count, m.count); |
| 72 | std::swap(capacity, m.capacity); |
| 73 | std::swap(stream, m.stream); |
| 74 | std::swap(refer_count, m.refer_count); |
| 75 | std::swap(host_ptr, m.host_ptr); |
| 76 | std::swap(device_ptr, m.device_ptr); |
| 77 | } |
| 78 | |
| 79 | __host__ __device__ Data &operator[](Index index) { |
| 80 | #ifdef __CUDA_ARCH__ |
| 81 | return device_ptr[index]; |
| 82 | #else |
| 83 | return host_ptr[index]; |
| 84 | #endif |
| 85 | } |
| 86 | |
| 87 | __host__ __device__ Data &operator[](Index index) const { |
| 88 | #ifdef __CUDA_ARCH__ |
| 89 | return device_ptr[index]; |
| 90 | #else |
| 91 | return host_ptr[index]; |
nothing calls this directly
no outgoing calls
no test coverage detected