提交 1e95672a 编写于 作者: L Liangliang He

Merge branch 'out_of_resource' into 'out_of_resource'

Return status instead of abort when allocate failed.

See merge request !494
...@@ -29,9 +29,10 @@ class Allocator { ...@@ -29,9 +29,10 @@ class Allocator {
public: public:
Allocator() {} Allocator() {}
virtual ~Allocator() noexcept {} virtual ~Allocator() noexcept {}
virtual void *New(size_t nbytes) const = 0; virtual MaceStatus New(size_t nbytes, void **result) const = 0;
virtual void *NewImage(const std::vector<size_t> &image_shape, virtual MaceStatus NewImage(const std::vector<size_t> &image_shape,
const DataType dt) const = 0; const DataType dt,
void **result) const = 0;
virtual void Delete(void *data) const = 0; virtual void Delete(void *data) const = 0;
virtual void DeleteImage(void *data) const = 0; virtual void DeleteImage(void *data) const = 0;
virtual void *Map(void *buffer, size_t offset, size_t nbytes) const = 0; virtual void *Map(void *buffer, size_t offset, size_t nbytes) const = 0;
...@@ -40,22 +41,12 @@ class Allocator { ...@@ -40,22 +41,12 @@ class Allocator {
std::vector<size_t> *mapped_image_pitch) const = 0; std::vector<size_t> *mapped_image_pitch) const = 0;
virtual void Unmap(void *buffer, void *mapper_ptr) const = 0; virtual void Unmap(void *buffer, void *mapper_ptr) const = 0;
virtual bool OnHost() const = 0; virtual bool OnHost() const = 0;
template <typename T>
T *New(size_t num_elements) {
if (num_elements > (std::numeric_limits<size_t>::max() / sizeof(T))) {
return nullptr;
}
void *p = New(sizeof(T) * num_elements);
T *typed_p = reinterpret_cast<T *>(p);
return typed_p;
}
}; };
class CPUAllocator : public Allocator { class CPUAllocator : public Allocator {
public: public:
~CPUAllocator() override {} ~CPUAllocator() override {}
void *New(size_t nbytes) const override { MaceStatus New(size_t nbytes, void **result) const override {
VLOG(3) << "Allocate CPU buffer: " << nbytes; VLOG(3) << "Allocate CPU buffer: " << nbytes;
void *data = nullptr; void *data = nullptr;
#ifdef __ANDROID__ #ifdef __ANDROID__
...@@ -66,16 +57,19 @@ class CPUAllocator : public Allocator { ...@@ -66,16 +57,19 @@ class CPUAllocator : public Allocator {
MACE_CHECK_NOTNULL(data); MACE_CHECK_NOTNULL(data);
// TODO(heliangliang) This should be avoided sometimes // TODO(heliangliang) This should be avoided sometimes
memset(data, 0, nbytes); memset(data, 0, nbytes);
return data; *result = data;
return MaceStatus::MACE_SUCCESS;
} }
void *NewImage(const std::vector<size_t> &shape, MaceStatus NewImage(const std::vector<size_t> &shape,
const DataType dt) const override { const DataType dt,
void **status) const override {
LOG(FATAL) << "Allocate CPU image"; LOG(FATAL) << "Allocate CPU image";
return nullptr; return MaceStatus::MACE_SUCCESS;
} }
void Delete(void *data) const override { void Delete(void *data) const override {
MACE_CHECK_NOTNULL(data);
VLOG(3) << "Free CPU buffer"; VLOG(3) << "Free CPU buffer";
free(data); free(data);
} }
......
...@@ -25,6 +25,11 @@ class BufferBase { ...@@ -25,6 +25,11 @@ class BufferBase {
virtual void *raw_mutable_data() = 0; virtual void *raw_mutable_data() = 0;
virtual MaceStatus Allocate(index_t size) = 0;
virtual MaceStatus Allocate(const std::vector<size_t> &shape,
DataType data_type) = 0;
virtual void *Map(index_t offset, virtual void *Map(index_t offset,
index_t length, index_t length,
std::vector<size_t> *pitch) const = 0; std::vector<size_t> *pitch) const = 0;
...@@ -35,7 +40,7 @@ class BufferBase { ...@@ -35,7 +40,7 @@ class BufferBase {
virtual void UnMap() = 0; virtual void UnMap() = 0;
virtual void Resize(index_t size) = 0; virtual MaceStatus Resize(index_t size) = 0;
virtual void Copy(void *src, index_t offset, index_t length) = 0; virtual void Copy(void *src, index_t offset, index_t length) = 0;
...@@ -70,14 +75,6 @@ class Buffer : public BufferBase { ...@@ -70,14 +75,6 @@ class Buffer : public BufferBase {
mapped_buf_(nullptr), mapped_buf_(nullptr),
is_data_owner_(true) {} is_data_owner_(true) {}
Buffer(Allocator *allocator, index_t size)
: BufferBase(size),
allocator_(allocator),
mapped_buf_(nullptr),
is_data_owner_(true) {
buf_ = allocator->New(size);
}
Buffer(Allocator *allocator, void *data, index_t size) Buffer(Allocator *allocator, void *data, index_t size)
: BufferBase(size), : BufferBase(size),
allocator_(allocator), allocator_(allocator),
...@@ -94,6 +91,7 @@ class Buffer : public BufferBase { ...@@ -94,6 +91,7 @@ class Buffer : public BufferBase {
} }
} }
void *buffer() { void *buffer() {
MACE_CHECK_NOTNULL(buf_); MACE_CHECK_NOTNULL(buf_);
return buf_; return buf_;
...@@ -119,6 +117,28 @@ class Buffer : public BufferBase { ...@@ -119,6 +117,28 @@ class Buffer : public BufferBase {
} }
} }
MaceStatus Allocate(index_t size) {
if (size <= 0) {
return MaceStatus::MACE_SUCCESS;
}
MACE_CHECK(is_data_owner_,
"data is not owned by this buffer, cannot reallocate");
if (mapped_buf_ != nullptr) {
UnMap();
}
if (buf_ != nullptr) {
allocator_->Delete(buf_);
}
size_ = size;
return allocator_->New(size, &buf_);
}
MaceStatus Allocate(const std::vector<size_t> &shape,
DataType data_type) {
MACE_NOT_IMPLEMENTED;
return MACE_SUCCESS;
}
void *Map(index_t offset, index_t length, std::vector<size_t> *pitch) const { void *Map(index_t offset, index_t length, std::vector<size_t> *pitch) const {
MACE_CHECK_NOTNULL(buf_); MACE_CHECK_NOTNULL(buf_);
return allocator_->Map(buf_, offset, length); return allocator_->Map(buf_, offset, length);
...@@ -140,7 +160,7 @@ class Buffer : public BufferBase { ...@@ -140,7 +160,7 @@ class Buffer : public BufferBase {
mapped_buf_ = nullptr; mapped_buf_ = nullptr;
} }
void Resize(index_t size) { MaceStatus Resize(index_t size) {
MACE_CHECK(is_data_owner_, MACE_CHECK(is_data_owner_,
"data is not owned by this buffer, cannot resize"); "data is not owned by this buffer, cannot resize");
if (size != size_) { if (size != size_) {
...@@ -148,8 +168,9 @@ class Buffer : public BufferBase { ...@@ -148,8 +168,9 @@ class Buffer : public BufferBase {
allocator_->Delete(buf_); allocator_->Delete(buf_);
} }
size_ = size; size_ = size;
buf_ = allocator_->New(size); return allocator_->New(size, &buf_);
} }
return MaceStatus::MACE_SUCCESS;
} }
void Copy(void *src, index_t offset, index_t length) { void Copy(void *src, index_t offset, index_t length) {
...@@ -183,25 +204,35 @@ class Image : public BufferBase { ...@@ -183,25 +204,35 @@ class Image : public BufferBase {
buf_(nullptr), buf_(nullptr),
mapped_buf_(nullptr) {} mapped_buf_(nullptr) {}
Image(std::vector<size_t> shape, DataType data_type) virtual ~Image() {
: BufferBase( if (mapped_buf_ != nullptr) {
std::accumulate( UnMap();
shape.begin(), shape.end(), 1, std::multiplies<index_t>()) * }
GetEnumTypeSize(data_type)), if (buf_ != nullptr) {
allocator_(GetDeviceAllocator(OPENCL)), allocator_->DeleteImage(buf_);
mapped_buf_(nullptr) { }
shape_ = shape;
data_type_ = data_type;
buf_ = allocator_->NewImage(shape, data_type);
} }
virtual ~Image() { MaceStatus Allocate(index_t size) {
LOG(FATAL) << "Image should not call this allocate function";
return MaceStatus::MACE_SUCCESS;
}
MaceStatus Allocate(const std::vector<size_t> &shape,
DataType data_type) {
index_t size = std::accumulate(
shape.begin(), shape.end(), 1, std::multiplies<index_t>()) *
GetEnumTypeSize(data_type);
if (mapped_buf_ != nullptr) { if (mapped_buf_ != nullptr) {
UnMap(); UnMap();
} }
if (buf_ != nullptr) { if (buf_ != nullptr) {
allocator_->DeleteImage(buf_); allocator_->DeleteImage(buf_);
} }
size_ = size;
shape_ = shape;
data_type_ = data_type;
return allocator_->NewImage(shape, data_type, &buf_);
} }
void *buffer() { void *buffer() {
...@@ -244,7 +275,10 @@ class Image : public BufferBase { ...@@ -244,7 +275,10 @@ class Image : public BufferBase {
mapped_buf_ = nullptr; mapped_buf_ = nullptr;
} }
void Resize(index_t size) { MACE_NOT_IMPLEMENTED; } MaceStatus Resize(index_t size) {
MACE_NOT_IMPLEMENTED;
return MaceStatus::MACE_SUCCESS;
}
void Copy(void *src, index_t offset, index_t length) { MACE_NOT_IMPLEMENTED; } void Copy(void *src, index_t offset, index_t length) { MACE_NOT_IMPLEMENTED; }
...@@ -287,6 +321,17 @@ class BufferSlice : public BufferBase { ...@@ -287,6 +321,17 @@ class BufferSlice : public BufferBase {
} }
} }
MaceStatus Allocate(index_t size) {
LOG(FATAL) << "BufferSlice should not call allocate function";
return MaceStatus::MACE_SUCCESS;
}
MaceStatus Allocate(const std::vector<size_t> &shape,
DataType data_type) {
LOG(FATAL) << "BufferSlice should not call allocate function";
return MaceStatus::MACE_SUCCESS;
}
void *buffer() { void *buffer() {
MACE_CHECK_NOTNULL(buffer_); MACE_CHECK_NOTNULL(buffer_);
return buffer_->buffer(); return buffer_->buffer();
...@@ -326,7 +371,10 @@ class BufferSlice : public BufferBase { ...@@ -326,7 +371,10 @@ class BufferSlice : public BufferBase {
mapped_buf_ = nullptr; mapped_buf_ = nullptr;
} }
void Resize(index_t size) { MACE_NOT_IMPLEMENTED; } MaceStatus Resize(index_t size) {
MACE_NOT_IMPLEMENTED;
return MaceStatus::MACE_SUCCESS;
}
void Copy(void *src, index_t offset, index_t length) { MACE_NOT_IMPLEMENTED; } void Copy(void *src, index_t offset, index_t length) { MACE_NOT_IMPLEMENTED; }
......
...@@ -66,11 +66,12 @@ std::shared_ptr<float> MaceTensor::data() { return impl_->data; } ...@@ -66,11 +66,12 @@ std::shared_ptr<float> MaceTensor::data() { return impl_->data; }
// Mace Engine // Mace Engine
class MaceEngine::Impl { class MaceEngine::Impl {
public: public:
explicit Impl(const NetDef *net_def, explicit Impl(DeviceType device_type);
DeviceType device_type, ~Impl();
MaceStatus Init(const NetDef *net_def,
const std::vector<std::string> &input_nodes, const std::vector<std::string> &input_nodes,
const std::vector<std::string> &output_nodes); const std::vector<std::string> &output_nodes);
~Impl();
MaceStatus Run(const std::map<std::string, MaceTensor> &inputs, MaceStatus Run(const std::map<std::string, MaceTensor> &inputs,
std::map<std::string, MaceTensor> *outputs, std::map<std::string, MaceTensor> *outputs,
...@@ -86,15 +87,17 @@ class MaceEngine::Impl { ...@@ -86,15 +87,17 @@ class MaceEngine::Impl {
DISABLE_COPY_AND_ASSIGN(Impl); DISABLE_COPY_AND_ASSIGN(Impl);
}; };
MaceEngine::Impl::Impl(const NetDef *net_def, MaceEngine::Impl::Impl(DeviceType device_type)
DeviceType device_type,
const std::vector<std::string> &input_nodes,
const std::vector<std::string> &output_nodes)
: op_registry_(new OperatorRegistry()), : op_registry_(new OperatorRegistry()),
device_type_(device_type), device_type_(device_type),
ws_(new Workspace()), ws_(new Workspace()),
net_(nullptr), net_(nullptr),
hexagon_controller_(nullptr) { hexagon_controller_(nullptr) {}
MaceStatus MaceEngine::Impl::Init(
const NetDef *net_def,
const std::vector<std::string> &input_nodes,
const std::vector<std::string> &output_nodes) {
LOG(INFO) << "MACE version: " << MaceVersion(); LOG(INFO) << "MACE version: " << MaceVersion();
// Set storage path for internal usage // Set storage path for internal usage
for (auto input_name : input_nodes) { for (auto input_name : input_nodes) {
...@@ -105,7 +108,7 @@ MaceEngine::Impl::Impl(const NetDef *net_def, ...@@ -105,7 +108,7 @@ MaceEngine::Impl::Impl(const NetDef *net_def,
ws_->CreateTensor(MakeString("mace_output_node_", output_name, ":0"), ws_->CreateTensor(MakeString("mace_output_node_", output_name, ":0"),
GetDeviceAllocator(device_type_), DT_FLOAT); GetDeviceAllocator(device_type_), DT_FLOAT);
} }
if (device_type == HEXAGON) { if (device_type_ == HEXAGON) {
hexagon_controller_.reset(new HexagonControlWrapper()); hexagon_controller_.reset(new HexagonControlWrapper());
MACE_CHECK(hexagon_controller_->Config(), "hexagon config error"); MACE_CHECK(hexagon_controller_->Config(), "hexagon config error");
MACE_CHECK(hexagon_controller_->Init(), "hexagon init error"); MACE_CHECK(hexagon_controller_->Init(), "hexagon init error");
...@@ -120,16 +123,21 @@ MaceEngine::Impl::Impl(const NetDef *net_def, ...@@ -120,16 +123,21 @@ MaceEngine::Impl::Impl(const NetDef *net_def,
hexagon_controller_->PrintGraph(); hexagon_controller_->PrintGraph();
} }
} else { } else {
ws_->LoadModelTensor(*net_def, device_type); MaceStatus status = ws_->LoadModelTensor(*net_def, device_type_);
if (status != MaceStatus::MACE_SUCCESS) {
return status;
}
// Init model // Init model
auto net = CreateNet(op_registry_, *net_def, ws_.get(), device_type, auto net = CreateNet(op_registry_, *net_def, ws_.get(), device_type_,
NetMode::INIT); NetMode::INIT);
if (!net->Run()) { if (!net->Run()) {
LOG(FATAL) << "Net init run failed"; LOG(FATAL) << "Net init run failed";
} }
net_ = std::move(CreateNet(op_registry_, *net_def, ws_.get(), device_type)); net_ = std::move(CreateNet(op_registry_, *net_def,
ws_.get(), device_type_));
} }
return MaceStatus::MACE_SUCCESS;
} }
MaceEngine::Impl::~Impl() { MaceEngine::Impl::~Impl() {
...@@ -202,16 +210,19 @@ MaceStatus MaceEngine::Impl::Run( ...@@ -202,16 +210,19 @@ MaceStatus MaceEngine::Impl::Run(
return MACE_SUCCESS; return MACE_SUCCESS;
} }
MaceEngine::MaceEngine(const NetDef *net_def, MaceEngine::MaceEngine(DeviceType device_type) {
DeviceType device_type,
const std::vector<std::string> &input_nodes,
const std::vector<std::string> &output_nodes) {
impl_ = std::unique_ptr<MaceEngine::Impl>( impl_ = std::unique_ptr<MaceEngine::Impl>(
new MaceEngine::Impl(net_def, device_type, input_nodes, output_nodes)); new MaceEngine::Impl(device_type));
} }
MaceEngine::~MaceEngine() = default; MaceEngine::~MaceEngine() = default;
MaceStatus MaceEngine::Init(const NetDef *net_def,
const std::vector<std::string> &input_nodes,
const std::vector<std::string> &output_nodes) {
return impl_->Init(net_def, input_nodes, output_nodes);
}
MaceStatus MaceEngine::Run(const std::map<std::string, MaceTensor> &inputs, MaceStatus MaceEngine::Run(const std::map<std::string, MaceTensor> &inputs,
std::map<std::string, MaceTensor> *outputs, std::map<std::string, MaceTensor> *outputs,
RunMetadata *run_metadata) { RunMetadata *run_metadata) {
......
...@@ -34,18 +34,27 @@ static cl_channel_type DataTypeToCLChannelType(const DataType t) { ...@@ -34,18 +34,27 @@ static cl_channel_type DataTypeToCLChannelType(const DataType t) {
OpenCLAllocator::OpenCLAllocator() {} OpenCLAllocator::OpenCLAllocator() {}
OpenCLAllocator::~OpenCLAllocator() {} OpenCLAllocator::~OpenCLAllocator() {}
void *OpenCLAllocator::New(size_t nbytes) const { MaceStatus OpenCLAllocator::New(size_t nbytes, void **result) const {
VLOG(3) << "Allocate OpenCL buffer: " << nbytes; VLOG(3) << "Allocate OpenCL buffer: " << nbytes;
cl_int error; cl_int error;
cl::Buffer *buffer = new cl::Buffer(OpenCLRuntime::Global()->context(), cl::Buffer *buffer = new cl::Buffer(OpenCLRuntime::Global()->context(),
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
nbytes, nullptr, &error); nbytes, nullptr, &error);
MACE_CHECK_CL_SUCCESS(error); if (error != CL_SUCCESS) {
return static_cast<void *>(buffer); LOG(WARNING) << "Allocate OpenCL Buffer with "
<< nbytes << " bytes failed because of"
<< OpenCLErrorToString(error);
*result = nullptr;
return MaceStatus::MACE_OUT_OF_RESOURCES;
} else {
*result = buffer;
return MaceStatus::MACE_SUCCESS;
}
} }
void *OpenCLAllocator::NewImage(const std::vector<size_t> &image_shape, MaceStatus OpenCLAllocator::NewImage(const std::vector<size_t> &image_shape,
const DataType dt) const { const DataType dt,
void **result) const {
MACE_CHECK(image_shape.size() == 2) << "Image shape's size must equal 2"; MACE_CHECK(image_shape.size() == 2) << "Image shape's size must equal 2";
VLOG(3) << "Allocate OpenCL image: " << image_shape[0] << ", " VLOG(3) << "Allocate OpenCL image: " << image_shape[0] << ", "
<< image_shape[1]; << image_shape[1];
...@@ -57,11 +66,17 @@ void *OpenCLAllocator::NewImage(const std::vector<size_t> &image_shape, ...@@ -57,11 +66,17 @@ void *OpenCLAllocator::NewImage(const std::vector<size_t> &image_shape,
new cl::Image2D(OpenCLRuntime::Global()->context(), new cl::Image2D(OpenCLRuntime::Global()->context(),
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, img_format, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, img_format,
image_shape[0], image_shape[1], 0, nullptr, &error); image_shape[0], image_shape[1], 0, nullptr, &error);
MACE_CHECK_CL_SUCCESS(error) << " with image shape: [" if (error != CL_SUCCESS) {
LOG(WARNING) << "Allocate OpenCL image with shape: ["
<< image_shape[0] << ", " << image_shape[1] << image_shape[0] << ", " << image_shape[1]
<< "]"; << "] failed because of"
<< OpenCLErrorToString(error);
return cl_image; *result = nullptr;
return MaceStatus::MACE_OUT_OF_RESOURCES;
} else {
*result = cl_image;
return MaceStatus::MACE_SUCCESS;
}
} }
void OpenCLAllocator::Delete(void *buffer) const { void OpenCLAllocator::Delete(void *buffer) const {
......
...@@ -17,15 +17,16 @@ class OpenCLAllocator : public Allocator { ...@@ -17,15 +17,16 @@ class OpenCLAllocator : public Allocator {
~OpenCLAllocator() override; ~OpenCLAllocator() override;
void *New(size_t nbytes) const override; MaceStatus New(size_t nbytes, void **result) const override;
/* /*
* Use Image2D with RGBA (128-bit) format to represent the image. * Use Image2D with RGBA (128-bit) format to represent the image.
* *
* @ shape : [depth, ..., height, width ]. * @ shape : [depth, ..., height, width ].
*/ */
void *NewImage(const std::vector<size_t> &image_shape, MaceStatus NewImage(const std::vector<size_t> &image_shape,
const DataType dt) const override; const DataType dt,
void **result) const override;
void Delete(void *buffer) const override; void Delete(void *buffer) const override;
......
...@@ -171,15 +171,16 @@ class Tensor { ...@@ -171,15 +171,16 @@ class Tensor {
MACE_CHECK(raw_size() <= buffer_->size()); MACE_CHECK(raw_size() <= buffer_->size());
} }
inline void Resize(const std::vector<index_t> &shape) { inline MaceStatus Resize(const std::vector<index_t> &shape) {
shape_ = shape; shape_ = shape;
image_shape_.clear(); image_shape_.clear();
if (buffer_ != nullptr) { if (buffer_ != nullptr) {
MACE_CHECK(!has_opencl_image(), "Cannot resize image, use ResizeImage."); MACE_CHECK(!has_opencl_image(), "Cannot resize image, use ResizeImage.");
buffer_->Resize(raw_size()); return buffer_->Resize(raw_size());
} else { } else {
MACE_CHECK(is_buffer_owner_); MACE_CHECK(is_buffer_owner_);
buffer_ = new Buffer(allocator_, raw_size()); buffer_ = new Buffer(allocator_);
return buffer_->Allocate(raw_size());
} }
} }
...@@ -195,13 +196,14 @@ class Tensor { ...@@ -195,13 +196,14 @@ class Tensor {
is_buffer_owner_ = false; is_buffer_owner_ = false;
} }
inline void ResizeImage(const std::vector<index_t> &shape, inline MaceStatus ResizeImage(const std::vector<index_t> &shape,
const std::vector<size_t> &image_shape) { const std::vector<size_t> &image_shape) {
shape_ = shape; shape_ = shape;
image_shape_ = image_shape; image_shape_ = image_shape;
if (buffer_ == nullptr) { if (buffer_ == nullptr) {
MACE_CHECK(is_buffer_owner_); MACE_CHECK(is_buffer_owner_);
buffer_ = new Image(image_shape, dtype_); buffer_ = new Image();
return buffer_->Allocate(image_shape, dtype_);
} else { } else {
MACE_CHECK(has_opencl_image(), "Cannot ResizeImage buffer, use Resize."); MACE_CHECK(has_opencl_image(), "Cannot ResizeImage buffer, use Resize.");
Image *image = dynamic_cast<Image *>(buffer_); Image *image = dynamic_cast<Image *>(buffer_);
...@@ -211,24 +213,27 @@ class Tensor { ...@@ -211,24 +213,27 @@ class Tensor {
"): current physical image shape: ", image->image_shape()[0], "): current physical image shape: ", image->image_shape()[0],
", ", image->image_shape()[1], " < logical image shape: ", ", ", image->image_shape()[1], " < logical image shape: ",
image_shape[0], ", ", image_shape[1]); image_shape[0], ", ", image_shape[1]);
return MaceStatus::MACE_SUCCESS;
} }
} }
inline void ResizeLike(const Tensor &other) { ResizeLike(&other); } inline MaceStatus ResizeLike(const Tensor &other) {
return ResizeLike(&other);
}
inline void ResizeLike(const Tensor *other) { inline MaceStatus ResizeLike(const Tensor *other) {
if (other->has_opencl_image()) { if (other->has_opencl_image()) {
if (is_buffer_owner_ && buffer_ != nullptr && !has_opencl_image()) { if (is_buffer_owner_ && buffer_ != nullptr && !has_opencl_image()) {
delete buffer_; delete buffer_;
buffer_ = nullptr; buffer_ = nullptr;
} }
ResizeImage(other->shape(), other->image_shape_); return ResizeImage(other->shape(), other->image_shape_);
} else { } else {
if (is_buffer_owner_ && buffer_ != nullptr && has_opencl_image()) { if (is_buffer_owner_ && buffer_ != nullptr && has_opencl_image()) {
delete buffer_; delete buffer_;
buffer_ = nullptr; buffer_ = nullptr;
} }
Resize(other->shape()); return Resize(other->shape());
} }
} }
......
...@@ -48,7 +48,7 @@ std::vector<std::string> Workspace::Tensors() const { ...@@ -48,7 +48,7 @@ std::vector<std::string> Workspace::Tensors() const {
return names; return names;
} }
void Workspace::LoadModelTensor(const NetDef &net_def, DeviceType type) { MaceStatus Workspace::LoadModelTensor(const NetDef &net_def, DeviceType type) {
MACE_LATENCY_LOGGER(1, "Load model tensors"); MACE_LATENCY_LOGGER(1, "Load model tensors");
index_t model_data_size = 0; index_t model_data_size = 0;
unsigned char *model_data_ptr = nullptr; unsigned char *model_data_ptr = nullptr;
...@@ -74,7 +74,11 @@ void Workspace::LoadModelTensor(const NetDef &net_def, DeviceType type) { ...@@ -74,7 +74,11 @@ void Workspace::LoadModelTensor(const NetDef &net_def, DeviceType type) {
new Buffer(GetDeviceAllocator(type), model_data_ptr, model_data_size))); new Buffer(GetDeviceAllocator(type), model_data_ptr, model_data_size)));
} else { } else {
tensor_buffer_ = std::move(std::unique_ptr<Buffer>( tensor_buffer_ = std::move(std::unique_ptr<Buffer>(
new Buffer(GetDeviceAllocator(type), model_data_size))); new Buffer(GetDeviceAllocator(type))));
MaceStatus status = tensor_buffer_->Allocate(model_data_size);
if (status != MaceStatus::MACE_SUCCESS) {
return status;
}
tensor_buffer_->Map(nullptr); tensor_buffer_->Map(nullptr);
tensor_buffer_->Copy(model_data_ptr, 0, model_data_size); tensor_buffer_->Copy(model_data_ptr, 0, model_data_size);
tensor_buffer_->UnMap(); tensor_buffer_->UnMap();
...@@ -104,13 +108,15 @@ void Workspace::LoadModelTensor(const NetDef &net_def, DeviceType type) { ...@@ -104,13 +108,15 @@ void Workspace::LoadModelTensor(const NetDef &net_def, DeviceType type) {
} }
if (type == DeviceType::OPENCL) { if (type == DeviceType::OPENCL) {
CreateImageOutputTensor(net_def); MaceStatus status = CreateImageOutputTensor(net_def);
if (status != MaceStatus::MACE_SUCCESS) return status;
} }
return MaceStatus::MACE_SUCCESS;
} }
void Workspace::CreateImageOutputTensor(const NetDef &net_def) { MaceStatus Workspace::CreateImageOutputTensor(const NetDef &net_def) {
if (!net_def.has_mem_arena() || net_def.mem_arena().mem_block_size() == 0) { if (!net_def.has_mem_arena() || net_def.mem_arena().mem_block_size() == 0) {
return; return MaceStatus::MACE_SUCCESS;
} }
DataType dtype = DataType::DT_INVALID; DataType dtype = DataType::DT_INVALID;
...@@ -133,7 +139,12 @@ void Workspace::CreateImageOutputTensor(const NetDef &net_def) { ...@@ -133,7 +139,12 @@ void Workspace::CreateImageOutputTensor(const NetDef &net_def) {
MACE_CHECK(dtype != DataType::DT_INVALID, "data type is invalid."); MACE_CHECK(dtype != DataType::DT_INVALID, "data type is invalid.");
for (auto &mem_block : net_def.mem_arena().mem_block()) { for (auto &mem_block : net_def.mem_arena().mem_block()) {
std::unique_ptr<BufferBase> image_buf( std::unique_ptr<BufferBase> image_buf(
new Image({mem_block.x(), mem_block.y()}, dtype)); new Image());
MaceStatus status = image_buf->Allocate(
{mem_block.x(), mem_block.y()}, dtype);
if (status != MaceStatus::MACE_SUCCESS) {
return status;
}
preallocated_allocator_.SetBuffer(mem_block.mem_id(), std::move(image_buf)); preallocated_allocator_.SetBuffer(mem_block.mem_id(), std::move(image_buf));
} }
VLOG(3) << "Preallocate image to tensors"; VLOG(3) << "Preallocate image to tensors";
...@@ -157,6 +168,7 @@ void Workspace::CreateImageOutputTensor(const NetDef &net_def) { ...@@ -157,6 +168,7 @@ void Workspace::CreateImageOutputTensor(const NetDef &net_def) {
} }
} }
} }
return MaceStatus::MACE_SUCCESS;
} }
} // namespace mace } // namespace mace
...@@ -37,10 +37,10 @@ class Workspace { ...@@ -37,10 +37,10 @@ class Workspace {
std::vector<std::string> Tensors() const; std::vector<std::string> Tensors() const;
void LoadModelTensor(const NetDef &net_def, DeviceType type); MaceStatus LoadModelTensor(const NetDef &net_def, DeviceType type);
private: private:
void CreateImageOutputTensor(const NetDef &net_def); MaceStatus CreateImageOutputTensor(const NetDef &net_def);
TensorMap tensor_map_; TensorMap tensor_map_;
......
...@@ -387,7 +387,7 @@ void TestNEONNxNS12(const index_t height, ...@@ -387,7 +387,7 @@ void TestNEONNxNS12(const index_t height,
} }
TEST_F(DepthwiseConv2dOpTest, NEONTest) { TEST_F(DepthwiseConv2dOpTest, NEONTest) {
TestNEONNxNS12(4, 4, 32, 1); TestNEONNxNS12(5, 5, 32, 1);
TestNEONNxNS12(64, 64, 32, 1); TestNEONNxNS12(64, 64, 32, 1);
TestNEONNxNS12(112, 112, 32, 1); TestNEONNxNS12(112, 112, 32, 1);
TestNEONNxNS12(128, 128, 15, 1); TestNEONNxNS12(128, 128, 15, 1);
......
...@@ -20,7 +20,11 @@ const char *MaceVersion(); ...@@ -20,7 +20,11 @@ const char *MaceVersion();
enum DeviceType { CPU = 0, NEON = 1, OPENCL = 2, HEXAGON = 3 }; enum DeviceType { CPU = 0, NEON = 1, OPENCL = 2, HEXAGON = 3 };
enum MaceStatus { MACE_SUCCESS = 0, MACE_INVALID_ARGS = 1 }; enum MaceStatus {
MACE_SUCCESS = 0,
MACE_INVALID_ARGS = 1,
MACE_OUT_OF_RESOURCES = 2,
};
// MACE input/output tensor // MACE input/output tensor
class MaceTensor { class MaceTensor {
...@@ -51,11 +55,13 @@ class RunMetadata; ...@@ -51,11 +55,13 @@ class RunMetadata;
class MaceEngine { class MaceEngine {
public: public:
explicit MaceEngine(const NetDef *net_def, explicit MaceEngine(DeviceType device_type);
DeviceType device_type,
~MaceEngine();
MaceStatus Init(const NetDef *net_def,
const std::vector<std::string> &input_nodes, const std::vector<std::string> &input_nodes,
const std::vector<std::string> &output_nodes); const std::vector<std::string> &output_nodes);
~MaceEngine();
MaceStatus Run(const std::map<std::string, MaceTensor> &inputs, MaceStatus Run(const std::map<std::string, MaceTensor> &inputs,
std::map<std::string, MaceTensor> *outputs); std::map<std::string, MaceTensor> *outputs);
......
...@@ -231,7 +231,11 @@ bool RunModel(const std::vector<std::string> &input_names, ...@@ -231,7 +231,11 @@ bool RunModel(const std::vector<std::string> &input_names,
std::shared_ptr<KVStorageFactory> storage_factory( std::shared_ptr<KVStorageFactory> storage_factory(
new FileStorageFactory(kernel_file_path)); new FileStorageFactory(kernel_file_path));
ConfigKVStorageFactory(storage_factory); ConfigKVStorageFactory(storage_factory);
mace::MaceEngine engine(&net_def, device_type, input_names, output_names); mace::MaceEngine engine(device_type);
MaceStatus status = engine.Init(&net_def, input_names, output_names);
if (status != MaceStatus::MACE_SUCCESS) {
LOG(FATAL) << "Engine init failed with status: " << status;
}
if (device_type == DeviceType::OPENCL || device_type == DeviceType::HEXAGON) { if (device_type == DeviceType::OPENCL || device_type == DeviceType::HEXAGON) {
mace::MACE_MODEL_TAG::UnloadModelData(model_data); mace::MACE_MODEL_TAG::UnloadModelData(model_data);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册