Skip to content

Commit 53df64c

Browse files
author
zxy.monado
committed
test(base): cover IO and container ownership
1 parent 03b074a commit 53df64c

5 files changed

Lines changed: 211 additions & 42 deletions

File tree

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
11
#include <ATen/core/tensor_buffer.h>
2-
32
#include <base/core/cpu_allocator.h>
43
#include <base/macros/macros.h>
54

65
#if defined(__CUDA) || defined(__ROCM)
76
#include <base/core/gpu_allocator.h>
87
#endif
98

10-
namespace container {
9+
namespace container
10+
{
1111

1212
// Construct a new TensorBuffer object.
13-
TensorBuffer::TensorBuffer(base::core::Allocator* alloc, void* data_ptr) : alloc_(alloc), data_(data_ptr), owns_memory_(true) {}
13+
TensorBuffer::TensorBuffer(base::core::Allocator* alloc, void* data_ptr)
14+
: alloc_(alloc), data_(data_ptr), owns_memory_(true)
15+
{
16+
}
1417

1518
// Construct a new TensorBuffer object.
1619
// Note, this is a reference TensorBuffer, does not own memory itself.
17-
TensorBuffer::TensorBuffer(void* data_ptr) : alloc_(), data_(data_ptr), owns_memory_(false) {}
20+
TensorBuffer::TensorBuffer(void* data_ptr) : alloc_(), data_(data_ptr), owns_memory_(false)
21+
{
22+
}
1823

19-
// Class members are initialized in the order of their declaration,
24+
// Class members are initialized in the order of their declaration,
2025
// rather than the order they appear in the initialization list!
21-
TensorBuffer::TensorBuffer(base::core::Allocator* alloc, size_t size) {
22-
alloc_ = alloc;
23-
if (size > 0) {
26+
TensorBuffer::TensorBuffer(base::core::Allocator* alloc, size_t size)
27+
{
28+
alloc_ = alloc;
29+
if (size > 0)
30+
{
2431
data_ = alloc_->allocate(size);
2532
owns_memory_ = true;
2633
allocated_bytes_ = size;
@@ -29,106 +36,142 @@ TensorBuffer::TensorBuffer(base::core::Allocator* alloc, size_t size) {
2936

3037
// Move constructor.
3138
TensorBuffer::TensorBuffer(TensorBuffer&& other) noexcept
32-
: alloc_(other.alloc_),
33-
data_(other.data_),
34-
owns_memory_(other.owns_memory_),
35-
allocated_bytes_(other.allocated_bytes_)
39+
: alloc_(other.alloc_), data_(other.data_), owns_memory_(other.owns_memory_),
40+
allocated_bytes_(other.allocated_bytes_)
3641
{
3742
// Reset the other TensorBuffer.
43+
other.alloc_ = nullptr;
3844
other.data_ = nullptr;
3945
other.owns_memory_ = false;
4046
other.allocated_bytes_ = 0;
4147
}
4248

4349
// Destroy the TensorBuffer object.
44-
TensorBuffer::~TensorBuffer() {
45-
if (this->OwnsMemory() && data_ != nullptr) {
50+
TensorBuffer::~TensorBuffer()
51+
{
52+
if (this->OwnsMemory() && data_ != nullptr)
53+
{
4654
alloc_->free(data_);
4755
}
48-
if (alloc_ != nullptr) {
56+
if (alloc_ != nullptr)
57+
{
4958
delete alloc_;
5059
}
5160
}
5261

5362
// Get the raw data pointer.
54-
void* TensorBuffer::data() const { return data_; }
63+
void* TensorBuffer::data() const
64+
{
65+
return data_;
66+
}
5567

5668
// Get the total number of bytes allocated for the buffer.
5769
// This method returns the total number of bytes allocated for the buffer by the allocator
5870
// associated with the TensorBuffer. If the buffer is not yet allocated, the function returns 0.
59-
size_t TensorBuffer::GetAllocatedBytes() const {
71+
size_t TensorBuffer::GetAllocatedBytes() const
72+
{
6073
return allocated_bytes_;
6174
}
6275

6376
// Get the root TensorBuffer object.
6477
// If this TensorBuffer is a sub-buffer of another TensorBuffer, returns that
6578
// TensorBuffer. Otherwise, returns this.
66-
TensorBuffer* TensorBuffer::root_buffer() { return this; } // Implementation goes here.
79+
TensorBuffer* TensorBuffer::root_buffer()
80+
{
81+
return this;
82+
} // Implementation goes here.
6783

6884
// Get the Allocator object used in this class.
69-
base::core::Allocator* TensorBuffer::allocator() const {
85+
base::core::Allocator* TensorBuffer::allocator() const
86+
{
7087
return alloc_;
7188
}
7289

7390
// Check whether this TensorBuffer owns the underlying memory.
74-
bool TensorBuffer::OwnsMemory() const { return this->owns_memory_; }
91+
bool TensorBuffer::OwnsMemory() const
92+
{
93+
return this->owns_memory_;
94+
}
7595

7696
// Get the type of device used by the TensorBuffer.
77-
DeviceType TensorBuffer::GetDeviceType() const {
78-
if (alloc_ != nullptr) {
97+
DeviceType TensorBuffer::GetDeviceType() const
98+
{
99+
if (alloc_ != nullptr)
100+
{
79101
return alloc_->GetDeviceType();
80102
}
81103
return DeviceType::UnKnown;
82104
}
83105

84-
void TensorBuffer::resize(size_t size) {
106+
void TensorBuffer::resize(size_t size)
107+
{
85108
// Allocate a new buffer.
86109
void* new_data = this->alloc_->allocate(size);
87110

88111
// Free the old buffer.
89-
if (this->OwnsMemory()) {
112+
if (this->OwnsMemory())
113+
{
90114
this->alloc_->free(data_);
91115
}
92116

93117
// Update the internal state.
94118
this->data_ = new_data;
95119
this->owns_memory_ = true;
120+
this->allocated_bytes_ = size;
96121
}
122+
TensorBuffer& TensorBuffer::operator=(const TensorBuffer& other)
123+
{
124+
if (this == &other)
125+
{
126+
return *this;
127+
}
97128

98-
TensorBuffer& TensorBuffer::operator=(const TensorBuffer& other) {
99-
if (this->OwnsMemory()) {
129+
if (this->OwnsMemory())
130+
{
100131
this->alloc_->free(data_);
101132
}
102133

103134
delete this->alloc_;
104-
if (other.GetDeviceType() == DeviceType::CpuDevice) {
135+
if (other.GetDeviceType() == DeviceType::CpuDevice)
136+
{
105137
this->alloc_ = new base::core::CPUAllocator();
106138
}
107-
#if defined(__CUDA) || defined(__ROCM)
108-
else if (other.GetDeviceType() == DeviceType::GpuDevice) {
139+
#if defined(__CUDA) || defined(__ROCM)
140+
else if (other.GetDeviceType() == DeviceType::GpuDevice)
141+
{
109142
this->alloc_ = new base::core::GPUAllocator();
110143
}
111-
#endif // __CUDA || __ROCM
112-
144+
#endif // __CUDA || __ROCM
113145

114146
this->data_ = this->alloc_->allocate(other.GetAllocatedBytes());
115147
this->owns_memory_ = true;
148+
this->allocated_bytes_ = other.GetAllocatedBytes();
116149
return *this;
117150
}
118151

119-
TensorBuffer& TensorBuffer::operator=(TensorBuffer&& other) noexcept {
120-
if (this->OwnsMemory()) {
152+
TensorBuffer& TensorBuffer::operator=(TensorBuffer&& other) noexcept
153+
{
154+
if (this == &other)
155+
{
156+
return *this;
157+
}
158+
159+
if (this->OwnsMemory())
160+
{
121161
this->alloc_->free(data_);
122162
}
123163
delete this->alloc_;
124164
this->alloc_ = other.alloc_;
125165
this->data_ = other.data_;
126166
this->owns_memory_ = other.owns_memory_;
167+
this->allocated_bytes_ = other.allocated_bytes_;
127168

128169
// Reset the other TensorBuffer.
170+
other.alloc_ = nullptr;
129171
other.data_ = nullptr;
130172
other.owns_memory_ = false;
173+
other.allocated_bytes_ = 0;
131174
return *this;
132175
}
133176

134-
} // namespace container
177+
} // namespace container

source/source_base/module_container/test/allocator_test.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ TEST(CPUAllocator, AllocateAndFree) {
2525
}
2626

2727
TEST(CPUAllocator, AllocatedSize) {
28-
base::core::CPUAllocator alloc;
28+
base::core::Allocator* alloc = new base::core::CPUAllocator();
2929
// Allocate memory of size 100 and check its size.
30-
void* ptr = alloc.allocate(100);
30+
void* ptr = alloc->allocate(100);
3131
EXPECT_NE(nullptr, ptr);
32-
alloc.free(ptr);
32+
EXPECT_EQ(alloc->AllocatedSize(ptr), 100);
33+
alloc->free(ptr);
34+
EXPECT_EQ(alloc->AllocatedSize(ptr), 0);
35+
delete alloc;
3336
}
3437

3538
TEST(CPUAllocator, GetDeviceType) {
@@ -49,3 +52,32 @@ TEST(LoggingDeathTest, AbortsWithContext)
4952
EXPECT_DEATH(base::utils::check_exit_impl("allocate", "allocator_test.cpp", 42, "allocation failed"),
5053
"Fatal error.*allocation failed");
5154
}
55+
56+
namespace
57+
{
58+
class TestCounted : public base::core::counted_base
59+
{
60+
public:
61+
explicit TestCounted(bool* destroyed) : destroyed_(destroyed) {}
62+
63+
~TestCounted() override
64+
{
65+
*destroyed_ = true;
66+
}
67+
68+
private:
69+
bool* destroyed_;
70+
};
71+
} // namespace
72+
73+
TEST(RefCount, TracksReferencesAndDeletes)
74+
{
75+
bool destroyed = false;
76+
TestCounted* counted = new TestCounted(&destroyed);
77+
EXPECT_TRUE(counted->ref_count_is_one());
78+
counted->ref();
79+
EXPECT_EQ(counted->ref_count(), 2);
80+
EXPECT_FALSE(counted->unref());
81+
EXPECT_TRUE(counted->unref());
82+
EXPECT_TRUE(destroyed);
83+
}

source/source_base/module_container/test/tensor_buffer_test.cpp

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ TEST(TensorBuffer, resize) {
4040
// Resize the buffer.
4141
const size_t new_buffer_size = 200;
4242
tensor_buffer.resize(new_buffer_size);
43+
EXPECT_EQ(tensor_buffer.GetAllocatedBytes(), new_buffer_size);
4344

4445
// Free the memory.
4546
// auto free by the destructor
@@ -82,4 +83,55 @@ TEST(TensorBuffer, empty_allocator) {
8283

8384
// Free the memory.
8485
alloc.free(buffer);
85-
}
86+
}
87+
88+
TEST(TensorBuffer, OwningPointerConstructor)
89+
{
90+
base::core::Allocator* alloc = new base::core::CPUAllocator();
91+
void* data = alloc->allocate(16);
92+
container::TensorBuffer buffer(alloc, data);
93+
94+
EXPECT_EQ(buffer.allocator(), alloc);
95+
EXPECT_EQ(buffer.data(), data);
96+
EXPECT_TRUE(buffer.OwnsMemory());
97+
}
98+
99+
TEST(TensorBuffer, MoveConstructor)
100+
{
101+
container::TensorBuffer source(new base::core::CPUAllocator(), 16);
102+
void* data = source.data();
103+
104+
container::TensorBuffer destination(std::move(source));
105+
106+
EXPECT_EQ(destination.data(), data);
107+
EXPECT_EQ(destination.GetAllocatedBytes(), 16);
108+
EXPECT_TRUE(destination.OwnsMemory());
109+
EXPECT_EQ(source.data(), nullptr);
110+
EXPECT_FALSE(source.OwnsMemory());
111+
}
112+
113+
TEST(TensorBuffer, CopyAssignment)
114+
{
115+
container::TensorBuffer source(new base::core::CPUAllocator(), 16);
116+
container::TensorBuffer destination(new base::core::CPUAllocator(), 8);
117+
118+
destination = source;
119+
120+
EXPECT_NE(destination.data(), source.data());
121+
EXPECT_EQ(destination.GetDeviceType(), container::DeviceType::CpuDevice);
122+
EXPECT_TRUE(destination.OwnsMemory());
123+
}
124+
125+
TEST(TensorBuffer, MoveAssignment)
126+
{
127+
container::TensorBuffer source(new base::core::CPUAllocator(), 16);
128+
void* data = source.data();
129+
container::TensorBuffer destination(new base::core::CPUAllocator(), 8);
130+
131+
destination = std::move(source);
132+
133+
EXPECT_EQ(destination.data(), data);
134+
EXPECT_TRUE(destination.OwnsMemory());
135+
EXPECT_EQ(source.data(), nullptr);
136+
EXPECT_FALSE(source.OwnsMemory());
137+
}

source/source_base/module_container/test/tensor_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ TEST(Tensor, Constructor) {
4343
EXPECT_EQ(t4.data(), vec.data());
4444
}
4545

46+
TEST(Tensor, CopyAssignment)
47+
{
48+
container::Tensor source({1, 2, 3, 4});
49+
source.reshape({2, 2});
50+
container::Tensor destination;
51+
52+
destination = source;
53+
54+
EXPECT_EQ(destination, source);
55+
EXPECT_NE(destination.data(), source.data());
56+
}
57+
4658

4759
TEST(Tensor, GetDataPointer) {
4860
// Create a 1x1 float tensor with data [1.0, 2.0, 3.0, 4.0].

0 commit comments

Comments
 (0)