Revert D9076734: Split storage from tensor
Differential Revision:
D9076734
Original commit changeset: ea9e1094ecf8
fbshipit-source-id: 3fa9b65b7265fce6207d9e1d9ef4707dbb29704b
diff --git a/caffe2/core/storage.h b/caffe2/core/storage.h
deleted file mode 100644
index aeebad4..0000000
--- a/caffe2/core/storage.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef CAFFE2_CORE_STORAGE_H_
-#define CAFFE2_CORE_STORAGE_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <fstream>
-#include <sstream>
-#include <type_traits>
-#include <typeinfo>
-#include <vector>
-
-#include "caffe2/core/allocator.h"
-#include "caffe2/core/common.h"
-#include "caffe2/core/context.h"
-#include "caffe2/core/flags.h"
-#include "caffe2/core/logging.h"
-#include "caffe2/core/typeid.h"
-
-namespace caffe2 {
-
-using DataType = TypeMeta;
-
-class StorageImpl;
-using Storage = std::shared_ptr<StorageImpl>;
-
-class StorageImpl {
- public:
- StorageImpl() = delete;
- StorageImpl(const StorageImpl&) = delete;
- StorageImpl& operator=(const StorageImpl&) = delete;
-
- explicit StorageImpl(DeviceType device_type) : device_type_(device_type) {}
- StorageImpl(DeviceType device_type, TypeMeta data_type)
- : data_type_(data_type), device_type_(device_type) {}
-
- void reset() {
- data_ptr_.reset();
- capacity_ = 0;
- }
-
- template <typename T>
- inline bool IsType() const {
- return data_type_.Match<T>();
- }
-
- const void* data_ptr() const {
- return data_ptr_.get();
- }
-
- void* data_ptr() {
- return data_ptr_.get();
- }
-
- const DataType& dtype() const {
- return data_type_;
- }
-
- size_t capacity() const {
- return capacity_;
- }
-
- int64_t numel() const {
- return capacity_ / itemsize();
- }
-
- inline void set_device_type(DeviceType device_type) {
- device_type_ = device_type;
- }
-
- inline DeviceType device_type() const {
- return device_type_;
- }
-
- inline size_t itemsize() const {
- return data_type_.itemsize();
- }
-
- // Rule of Five
- StorageImpl(StorageImpl&&) = default;
- ~StorageImpl() = default;
- StorageImpl& operator=(StorageImpl&&) = default;
-
- protected:
- template <typename Deleter = MemoryDeleter>
- void ShareExternalPointer(
- void* src,
- const DataType& data_type,
- size_t capacity = 0,
- Deleter d = nullptr) {
- // Check if the deleter is a MemoryDeleter and is a simple nullptr.
- if (std::is_same<MemoryDeleter, Deleter>::value &&
- reinterpret_cast<MemoryDeleter*>(&d)[0] == nullptr) {
- // Use aliasing constructor trick to avoid calling the destructor.
- data_ptr_ = std::shared_ptr<void>(std::shared_ptr<void>(), src);
- } else {
- data_ptr_.reset(src, d);
- }
- // Sets capacity. If not specified, we will implicitly assume that
- // the capacity is the current size.
- if (capacity) {
- capacity_ = capacity;
- }
- }
-
- // TODO: changed to DataPtr in Aten when shared folder
- // is ready
- using DataPtr = std::shared_ptr<void>;
- int64_t capacity_ = 0;
- DataType data_type_;
- DataPtr data_ptr_;
- // allocator_ takes precedence over StaticContext from device_type_
- // Allocator* allocator_;
- DeviceType device_type_ = CPU;
-
- friend class Tensor;
-};
-
-} // namespace caffe2
-
-#endif // CAFFE2_CORE_STORAGE_H_
diff --git a/caffe2/core/tensor.h b/caffe2/core/tensor.h
index ad39ab6..2e011ef 100644
--- a/caffe2/core/tensor.h
+++ b/caffe2/core/tensor.h
@@ -1,7 +1,19 @@
#ifndef CAFFE2_CORE_TENSOR_H_
#define CAFFE2_CORE_TENSOR_H_
-#include "caffe2/core/storage.h"
+#include <cstddef>
+#include <cstdint>
+#include <fstream>
+#include <sstream>
+#include <type_traits>
+#include <typeinfo>
+#include <vector>
+
+#include "caffe2/core/common.h"
+#include "caffe2/core/flags.h"
+#include "caffe2/core/context.h"
+#include "caffe2/core/typeid.h"
+#include "caffe2/core/logging.h"
// A global boolean variable to control whether we free memory when a Tensor
// is shrinked to a smaller size. As a result, a Tensor is always going to
@@ -80,8 +92,7 @@
class Tensor {
public:
Tensor() = delete;
- explicit Tensor(DeviceType device_type)
- : storage_(std::make_shared<StorageImpl>(device_type)) {}
+ explicit Tensor(DeviceType type) : device_type_(type) {}
/**
* @brief Creates a tensor of the given dimension.
@@ -89,27 +100,20 @@
* Note that the actual data allocation is not going to be carried out until
* the first time mutable_data() is called.
*/
- // TODO: here, we create a Storage
- // and immediately discard it in Resize() since
- // reset_tensor will be true and FreeMemory will be called,
- // we might want to avoid creating Storage twice?
- explicit Tensor(const vector<TIndex>& dims, DeviceType device_type)
- : storage_(std::make_shared<StorageImpl>(device_type)) {
+ explicit Tensor(const vector<TIndex>& dims, DeviceType type)
+ : device_type_(type) {
Resize(dims);
}
- explicit Tensor(const vector<int>& dims, DeviceType device_type)
- : storage_(std::make_shared<StorageImpl>(device_type)) {
+ explicit Tensor(const vector<int>& dims, DeviceType type)
+ : device_type_(type) {
Resize(dims);
}
/* Now we require that context_for_copy has the same device type as src since
* template is removed
*/
- Tensor(
- const Tensor& src,
- BaseContext* context_for_copy,
- DeviceType device_type)
- : storage_(std::make_shared<StorageImpl>(device_type)) {
+ Tensor(const Tensor& src, BaseContext* context_for_copy, DeviceType type)
+ : device_type_(type) {
CopyFrom(src, context_for_copy);
}
@@ -117,8 +121,7 @@
* @brief: Create a Tensor of DeviceType `type` and initialize it with
* src Tensor
*/
- Tensor(const Tensor& src, DeviceType device_type)
- : storage_(std::make_shared<StorageImpl>(device_type)) {
+ Tensor(const Tensor& src, DeviceType type) : device_type_(type) {
CopyFrom(src);
}
@@ -131,13 +134,11 @@
const vector<TIndex>& dims,
const vector<T>& values,
BaseContext* context)
- : storage_(std::make_shared<StorageImpl>(
- context->GetDevicetype(),
- TypeMeta::Make<T>())) {
+ : meta_(TypeMeta::Make<T>()) {
Resize(dims);
CAFFE_ENFORCE_EQ_WITH_CALLER(values.size(), size_);
- context->CopyItemsFromCPU(
- storage_->dtype(), size_, values.data(), mutable_data<T>());
+ device_type_ = context->GetDevicetype();
+ context->CopyItemsFromCPU(meta_, size_, values.data(), mutable_data<T>());
}
/**
@@ -147,13 +148,10 @@
template <
typename T,
typename = typename std::enable_if<std::is_scalar<T>::value>::type>
- Tensor(const T& value, BaseContext* context)
- : storage_(std::make_shared<StorageImpl>(
- context->GetDevicetype(),
- TypeMeta::Make<T>())) {
+ Tensor(const T& value, BaseContext* context) : meta_(TypeMeta::Make<T>()) {
Resize(vector<TIndex>{});
- context->CopyItemsFromCPU(
- storage_->dtype(), size_, &value, mutable_data<T>());
+ device_type_ = context->GetDevicetype();
+ context->CopyItemsFromCPU(meta_, size_, &value, mutable_data<T>());
}
/*
@@ -161,7 +159,7 @@
* context pointer in tensor, which indicates the type of the tensor.
*/
BaseStaticContext* GetStaticContext() const {
- return GET_STATIC_CONTEXT(GetDeviceType());
+ return GET_STATIC_CONTEXT(device_type_);
}
/* @brief
@@ -176,9 +174,8 @@
}
DeviceType GetDeviceType() const {
- return storage_->device_type();
+ return device_type_;
}
-
/**
* @brief Copies the data from a source tensor, with a contex provided to
* carry out the underlying memcpy operation.
@@ -187,23 +184,25 @@
if ((void*)&src == (void*)this) {
return;
}
- storage_->data_type_ = src.storage()->dtype();
+ meta_ = src.meta();
if (src.size() == -1) {
dims_.clear();
size_ = -1;
- storage_->reset();
+ data_.reset();
+ capacity_ = 0;
+ reserved_ = false;
return;
}
Resize(src.dims());
if (size() > 0) {
- if (storage_->dtype().copy()) {
+ if (meta_.copy()) {
CAFFE_ENFORCE(
GetDeviceType() == CPU,
"In CopyFrom source and dest tensors must both be CPU for meta copy");
CAFFE_ENFORCE(
src.GetDeviceType() == CPU,
"In CopyFrom source and dest tensors must both be CPU for meta copy");
- storage_->dtype().copy()(src.raw_data(), raw_mutable_data(), size());
+ meta_.copy()(src.raw_data(), raw_mutable_data(), size());
} else {
// We'll need to use a non-CPU context to perform the copy if
// one of the context is not CPU since only non-CPU context
@@ -256,12 +255,9 @@
CAFFE_ENFORCE_GE_WITH_CALLER(dims_.size(), 1);
CAFFE_ENFORCE_GE_WITH_CALLER(
num, 0, "`num` must be non-negative for Extend");
- CAFFE_ENFORCE(
- storage_.use_count() == 1,
- "Can't call Extend on shared storage, please call Resize instead");
auto newDims = dims_;
newDims[0] += num;
- if (!storage_->data_ptr()) {
+ if (!data_) {
Resize(newDims);
return;
}
@@ -270,7 +266,7 @@
newDims.end(),
static_cast<TIndex>(1),
std::multiplies<TIndex>());
- if (newSize * storage_->itemsize() <= storage_->capacity()) {
+ if (newSize * meta_.itemsize() <= capacity_) {
dims_ = newDims;
size_ = newSize;
return;
@@ -278,15 +274,14 @@
auto newCapacity = dims_;
newCapacity[0] = std::max<size_t>(
newDims[0], std::ceil(dims_[0] * (growthPct + 100) / 100));
- auto oldData = std::move(storage_->data_ptr_);
+ auto oldData = std::move(data_);
auto oldSize = size_;
auto oldDims = dims_;
Resize(newCapacity);
- auto* newData = raw_mutable_data(storage_->dtype());
+ auto* newData = raw_mutable_data(meta_);
CAFFE_ENFORCE(
context != nullptr, "Context must be provided to Extend the tensor");
- context->CopyItemsSameDevice(
- storage_->dtype(), oldSize, oldData.get(), newData);
+ context->CopyItemsSameDevice(meta_, oldSize, oldData.get(), newData);
reserved_ = true;
dims_ = newDims;
size_ = newSize;
@@ -303,9 +298,6 @@
CAFFE_ENFORCE_WITH_CALLER(
outer_dim <= dims_[0],
"New outer dimension must be smaller than current.");
- CAFFE_ENFORCE(
- storage_.use_count() == 1,
- "Can't call ShrinkTo on shared storage, please call Resize instead.");
dims_[0] = outer_dim;
size_ = std::accumulate(
dims_.begin(),
@@ -324,9 +316,6 @@
void ReserveSpace(const T& outer_dim) {
CAFFE_ENFORCE(
size_ != -1, "size should be initialized before calling ReserveSpace");
- CAFFE_ENFORCE(
- storage_.use_count() == 1,
- "Can't call ReserveSpace on shared storage.");
auto newCapacity = dims_;
newCapacity[0] = outer_dim;
auto newSize = std::accumulate(
@@ -334,16 +323,16 @@
newCapacity.end(),
static_cast<TIndex>(1),
std::multiplies<TIndex>());
- if (newSize * storage_->itemsize() <= storage_->capacity()) {
+ if (newSize * meta_.itemsize() <= capacity_) {
return;
}
// Old data is discarded
- storage_->data_ptr_.reset();
+ data_.reset();
auto oldSize = size_;
auto oldDims = dims_;
Resize(newCapacity);
- // Allocate new memory but don't copy over the data
- raw_mutable_data(storage_->dtype());
+ // Allocate new memory and don't copy over the data
+ raw_mutable_data(meta_);
dims_ = oldDims;
size_ = oldSize;
reserved_ = true;
@@ -368,16 +357,15 @@
if (size_changed) {
// If needed, we will free the data. the next mutable_data() call
// will create the data storage.
+ int64_t new_size = size_ * meta_.itemsize();
bool reset_tensor = false;
if (reserved_) {
- // If tensor is reserved then don't claim its memeory unless capacity()
+ // If tensor is reserved then don't claim its memeory unless capacity_
// is smaller than new size
- reset_tensor = storage_->capacity() < size_ * storage_->itemsize();
+ reset_tensor = capacity_ < new_size;
} else {
- reset_tensor = storage_->capacity() < size_ * storage_->itemsize() ||
- !FLAGS_caffe2_keep_on_shrink ||
- storage_->capacity() - size_ * storage_->itemsize() >
- FLAGS_caffe2_max_keep_on_shrink_memory;
+ reset_tensor = capacity_ < new_size || !FLAGS_caffe2_keep_on_shrink ||
+ capacity_ - new_size > FLAGS_caffe2_max_keep_on_shrink_memory;
}
if (reset_tensor) {
@@ -429,9 +417,12 @@
* allocation.
*/
inline void FreeMemory() {
- // We'll detach from the old Storage and create a new one
- storage_ = std::make_shared<StorageImpl>(
- storage_->device_type(), storage_->dtype());
+ data_.reset();
+ capacity_ = 0;
+ // If reserved is true and we changed tensor memory then it is fine
+ // to switch it to false, if Resize is called from Reserve and it triggers
+ // FreeMemory() then reserved_ will be set to true at end of ReserveSpace()
+ reserved_ = false;
}
/**
@@ -441,8 +432,8 @@
*/
string DebugString() const {
std::stringstream ss;
- ss << "A Tensor of item size " << storage_->itemsize() << " and type "
- << storage_->dtype().name() << " and dimension (";
+ ss << "A Tensor of item size " << itemsize() << " and type "
+ << meta_.name() << " and dimension (";
for (int d : dims_) {
ss << d << ",";
}
@@ -453,7 +444,11 @@
void swap(Tensor& other) noexcept {
std::swap(dims_, other.dims_);
std::swap(size_, other.size_);
- std::swap(storage_, other.storage_);
+ std::swap(meta_, other.meta_);
+ std::swap(data_, other.data_);
+ std::swap(capacity_, other.capacity_);
+ std::swap(reserved_, other.reserved_);
+ std::swap(device_type_, other.device_type_);
}
/**
@@ -469,10 +464,7 @@
* The source tensor should already have its data allocated.
*/
void ShareData(const Tensor& src) {
- CAFFE_ENFORCE(
- storage_.use_count() == 1,
- "Can't share data if underlying storage used by more than one tensor");
- storage_->data_type_ = src.storage()->data_type_;
+ meta_ = src.meta();
CAFFE_ENFORCE_EQ_WITH_CALLER(
src.size_,
size_,
@@ -481,11 +473,11 @@
// in which case ShareData() doesn't make much sense since we don't really
// know what to share yet.
CAFFE_ENFORCE_WITH_CALLER(
- src.storage()->data_ptr() || src.size_ == 0,
+ src.data_.get() || src.size_ == 0,
"Source tensor has no content and has size > 0");
// Finally, do sharing.
- storage_->data_ptr_ = src.storage()->data_ptr_;
- storage_->capacity_ = src.storage()->capacity_;
+ data_ = src.data_;
+ capacity_ = src.capacity_;
}
/**
@@ -497,36 +489,40 @@
* using it. If a Deleter object is passed in, when this tensor is reallocated
* or freed, the deleter function is going to be called.
*/
- // TODO: Change to ShareExternalStorage
template <typename T, typename Deleter = MemoryDeleter>
void ShareExternalPointer(T* src, size_t capacity = 0, Deleter d = nullptr) {
ShareExternalPointer(src, TypeMeta::Make<T>(), capacity, d);
- // Sets capacity. If not specified, we will implicitly assume that
- // the capacity is the current size.
- if (!capacity) {
- capacity = size_ * storage_->itemsize();
- }
- storage_->capacity_ = capacity;
}
template <typename Deleter = MemoryDeleter>
void ShareExternalPointer(
void* src,
- const TypeMeta& data_type,
+ const TypeMeta& meta,
size_t capacity = 0,
Deleter d = nullptr) {
- CAFFE_ENFORCE(
- storage_.use_count() == 1,
- "Can't share external pointer if underlying storage used by more than one tensor");
- storage_->data_type_ = data_type;
+ meta_ = meta;
CAFFE_ENFORCE_WITH_CALLER(
- storage_->data_type_.id() != TypeIdentifier::uninitialized(),
+ meta_.id() != TypeIdentifier::uninitialized(),
"To share with a raw external pointer you need to have meta "
"already set.");
CAFFE_ENFORCE_WITH_CALLER(
size_ >= 0,
"To share data with a raw pointer, you need to set shape first.");
- storage_->ShareExternalPointer(src, data_type, capacity, d);
+ // Check if the deleter is a MemoryDeleter and is a simple nullptr.
+ if (std::is_same<MemoryDeleter, Deleter>::value &&
+ reinterpret_cast<MemoryDeleter*>(&d)[0] == nullptr) {
+ // Use aliasing constructor trick to avoid calling the destructor.
+ data_ = std::shared_ptr<void>(std::shared_ptr<void>(), src);
+ } else {
+ data_.reset(src, d);
+ }
+ // Sets capacity. If not specified, we will implicitly assume that
+ // the capacity is the current size.
+ if (capacity) {
+ capacity_ = capacity;
+ } else {
+ capacity_ = nbytes();
+ }
}
/**
@@ -534,8 +530,8 @@
* or raw_mutable_data() must have been called prior to this function call.
*/
inline const void* raw_data() const {
- CAFFE_ENFORCE_WITH_CALLER(storage_->data_ptr() || size_ == 0);
- return storage_->data_ptr();
+ CAFFE_ENFORCE_WITH_CALLER(data_.get() || size_ == 0);
+ return data_.get();
}
/**
@@ -547,7 +543,7 @@
template <typename T>
inline const T* data() const {
CAFFE_ENFORCE_WITH_CALLER(
- storage_->data_ptr() || size_ == 0,
+ data_.get() || size_ == 0,
"The tensor is of non-zero shape, but its data is not allocated yet. "
"Caffe2 uses a lazy allocation, so you will need to call "
"mutable_data() or raw_mutable_data() to actually allocate memory.");
@@ -556,8 +552,8 @@
"Tensor type mismatch, caller expects elements to be ",
TypeMeta::TypeName<T>(),
" while tensor contains ",
- storage_->dtype().name());
- return static_cast<T*>(storage_->data_ptr());
+ meta_.name());
+ return static_cast<T*>(data_.get());
}
/**
@@ -573,12 +569,11 @@
*/
inline void* raw_mutable_data(const TypeMeta& meta) {
// For 0-size tensors it's fine to return any pointer (including nullptr)
- if (storage_->dtype() == meta && (storage_->data_ptr() || size_ == 0)) {
- return storage_->data_ptr();
+ if (meta_ == meta && (data_.get() || size_ == 0)) {
+ return data_.get();
} else {
- bool had_special_dtor = storage_->dtype().dtor() != nullptr;
- // TODO: we should create a new Storage here.
- storage_->data_type_ = meta;
+ bool had_special_dtor = meta_.dtor() != nullptr;
+ meta_ = meta;
CAFFE_ENFORCE_WITH_CALLER(
size_ >= 0,
"Tensor is not initialized. You probably need to call Resize() "
@@ -589,33 +584,32 @@
// constructor.
if (size_ == 0 ||
(meta.ctor() == nullptr && !had_special_dtor &&
- storage_->capacity() >= size_ * storage_->itemsize())) {
- return storage_->data_ptr();
+ capacity_ >= size_ * meta_.itemsize())) {
+ return data_.get();
}
if (meta.ctor()) {
// For types that need placement new, we will call it, as well as
// making sure that when the data is freed, it calls the right
// destruction procedure.
auto size = size_;
- auto dtor = storage_->dtype().dtor();
+ auto dtor = meta_.dtor();
auto ptr_and_deleter =
- GetStaticContext()->New(size_ * storage_->itemsize());
+ GetStaticContext()->New(size_ * meta_.itemsize());
auto deleter = ptr_and_deleter.second;
- storage_->data_ptr_.reset(
+ data_.reset(
ptr_and_deleter.first, [size, dtor, deleter](void* ptr) -> void {
dtor(ptr, size);
deleter(ptr);
});
- storage_->dtype().ctor()(storage_->data_ptr(), size_);
+ meta_.ctor()(data_.get(), size_);
} else {
// For fundamental type, new and delete is easier.
auto ptr_and_deleter =
- GetStaticContext()->New(size_ * storage_->itemsize());
- storage_->data_ptr_.reset(
- ptr_and_deleter.first, ptr_and_deleter.second);
+ GetStaticContext()->New(size_ * meta_.itemsize());
+ data_.reset(ptr_and_deleter.first, ptr_and_deleter.second);
}
- storage_->capacity_ = size_ * storage_->itemsize();
- return storage_->data_ptr();
+ capacity_ = size_ * meta_.itemsize();
+ return data_.get();
}
}
@@ -630,10 +624,10 @@
*/
inline void* raw_mutable_data() {
CAFFE_ENFORCE_WITH_CALLER(
- storage_->dtype().id() != TypeIdentifier::uninitialized(),
+ meta_.id() != TypeIdentifier::uninitialized(),
"Calling raw_mutable_data() without meta, but the current meta is "
"of unknown type.");
- return raw_mutable_data(storage_->dtype());
+ return raw_mutable_data(meta_);
}
/**
@@ -642,60 +636,41 @@
* For fundamental types, we reuse possible existing storage if there
* is sufficient capacity.
*/
- template <typename T>
- inline T* mutable_data() {
- if ((size_ == 0 || storage_->data_ptr()) && IsType<T>()) {
- return static_cast<T*>(storage_->data_ptr());
+ template <typename T>
+ inline T* mutable_data() {
+ if ((size_ == 0 || data_.get()) && IsType<T>()) {
+ return static_cast<T*>(data_.get());
+ }
+ // Check it here statically - otherwise TypeMeta would throw the runtime
+ // error in attempt to invoke TypeMeta::ctor()
+ static_assert(
+ std::is_default_constructible<T>::value,
+ "Tensor can't hold non-default-constructible types");
+ return static_cast<T*>(raw_mutable_data(TypeMeta::Make<T>()));
}
- // Check it here statically - otherwise TypeMeta would throw the runtime
- // error in attempt to invoke TypeMeta::ctor()
- static_assert(
- std::is_default_constructible<T>::value,
- "Tensor can't hold non-default-constructible types");
- return static_cast<T*>(raw_mutable_data(TypeMeta::Make<T>()));
- }
- /**
- * Returns the underlying Stoarge for the Tensor
- */
- inline Storage storage() {
- return storage_;
- }
-
- inline Storage storage() const {
- return storage_;
- }
/**
* Returns the number of dimensions of the data.
*/
- inline int ndim() const {
- return dims_.size();
- }
+ inline int ndim() const { return dims_.size(); }
/**
* Returns the size (i.e. the number of items) of the tensor.
*/
- inline TIndex size() const {
- return size_;
- }
+ inline TIndex size() const { return size_; }
/**
* Return the number of bytes each item takes in the tensor.
*/
- inline size_t itemsize() const {
- return storage_->itemsize();
- }
+ inline size_t itemsize() const { return meta_.itemsize(); }
/**
* Returns the total number of bytes of the storage.
*
* This is equivalent to calling size() * itemsize().
*/
- inline size_t nbytes() const {
- return size_ * itemsize();
- ;
- }
+ inline size_t nbytes() const { return size_ * meta_.itemsize(); }
inline size_t capacity_nbytes() const {
- return storage_->capacity();
+ return capacity_;
}
/**
* Returns the dimensions of the tensor as a vector.
@@ -733,15 +708,11 @@
* Checks if the tensor content is of the given data type.
*/
template <typename T>
- inline bool IsType() const {
- return storage_->IsType<T>();
- }
+ inline bool IsType() const { return meta_.Match<T>(); }
/**
* Returns the TypeMeta object associated with the current data type.
*/
- inline const TypeMeta& meta() const {
- return storage_->dtype();
- }
+ inline const TypeMeta& meta() const { return meta_; }
/**
* Returns the i-th dimension of the tensor in int.
@@ -796,16 +767,18 @@
}
protected:
- using DimVector = std::vector<TIndex>;
- DimVector dims_; // sizes_
- TIndex size_ = -1; // numel_
- // we decide to keep reserved_ and it will
+ vector<TIndex> dims_;
+ TIndex size_ = -1;
+ TypeMeta meta_;
+ std::shared_ptr<void> data_;
+ size_t capacity_ = 0;
+ // we decide to keep reserved and it will
// live in Tensor after the split
// The logic is that if Extend() or ReserveSpace() were ever called,
// then subsequent Resize()s will not free up Storage.
bool reserved_ = false;
- Storage storage_;
- // int64_t storage_offset_;
+ DeviceType device_type_ = CPU;
+ // In case of chunk load we store how much data was already loaded
private:
template <