aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2017-11-07 13:24:57 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:35:24 +0000
commit84b51ad1aaa530d397761f2b6da65add9dc8a6b0 (patch)
tree4f0150ef15c6bbff287658c517e3257513e4dc3e
parentc5d54397f6da490442f93ae880b361c45969f6b1 (diff)
downloadComputeLibrary-84b51ad1aaa530d397761f2b6da65add9dc8a6b0.tar.gz
COMPMID-666: Adds the ability to import backing memory in a Tensor(CPU).
Change-Id: I62b843b544fe9048837fd64c22e970fc6a0aaf23 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/94881 Reviewed-by: Anthony Barbier <anthony.barbier@arm.com> Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
-rw-r--r--arm_compute/runtime/Memory.h83
-rw-r--r--arm_compute/runtime/MemoryGroupBase.h1
-rw-r--r--arm_compute/runtime/TensorAllocator.h16
-rwxr-xr-xscripts/clang_tidy_rules.py1
-rw-r--r--src/runtime/Memory.cpp62
-rw-r--r--src/runtime/TensorAllocator.cpp53
-rw-r--r--support/ToolchainSupport.h4
-rw-r--r--tests/validation/NEON/UNIT/MemoryManager.cpp96
-rw-r--r--tests/validation/NEON/UNIT/TensorAllocator.cpp92
9 files changed, 380 insertions, 28 deletions
diff --git a/arm_compute/runtime/Memory.h b/arm_compute/runtime/Memory.h
new file mode 100644
index 0000000000..98bbb70239
--- /dev/null
+++ b/arm_compute/runtime/Memory.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_MEMORY_H__
+#define __ARM_COMPUTE_MEMORY_H__
+
+#include <cstddef>
+#include <memory>
+
+namespace arm_compute
+{
+/** CPU implementation of memory object */
+class Memory
+{
+public:
+ /** Default Constructor */
+ Memory();
+ /** Default Constructor
+ *
+ * @note Ownership of the memory is transferred to this object
+ *
+ * @param[in] memory Memory to be imported
+ */
+ Memory(std::shared_ptr<uint8_t> memory);
+ /** Default Constructor
+ *
+ * @note Ownership of the memory is not transferred to this object.
+ * Thus management (allocate/free) should be done by the client.
+ *
+ * @param[in] memory Memory to be imported
+ */
+ Memory(uint8_t *memory);
+ /** Allow instances of this class to be copied */
+ Memory(const Memory &) = default;
+ /** Allow instances of this class to be copy assigned */
+ Memory &operator=(const Memory &) = default;
+ /** Allow instances of this class to be moved */
+ Memory(Memory &&) noexcept = default;
+ /** Allow instances of this class to be move assigned */
+ Memory &operator=(Memory &&) noexcept = default;
+
+ /** Returns the pointer to the allocated data.
+ *
+ * @return Pointer to the allocated data
+ */
+ uint8_t *buffer();
+ /** Returns the pointer to the allocated data.
+ *
+ * @return Pointer to the allocated data
+ */
+ uint8_t *buffer() const;
+ /** Handle of internal memory
+ *
+ * @return Handle of memory
+ */
+ uint8_t **handle();
+
+private:
+ uint8_t *_memory;
+ std::shared_ptr<uint8_t> _memory_owned;
+};
+}
+#endif /* __ARM_COMPUTE_MEMORY_H__ */
diff --git a/arm_compute/runtime/MemoryGroupBase.h b/arm_compute/runtime/MemoryGroupBase.h
index ab8acb3494..19e9834923 100644
--- a/arm_compute/runtime/MemoryGroupBase.h
+++ b/arm_compute/runtime/MemoryGroupBase.h
@@ -26,6 +26,7 @@
#include "arm_compute/runtime/IMemoryGroup.h"
+#include "arm_compute/core/Error.h"
#include "arm_compute/runtime/IMemoryManager.h"
#include "arm_compute/runtime/IMemoryPool.h"
diff --git a/arm_compute/runtime/TensorAllocator.h b/arm_compute/runtime/TensorAllocator.h
index 40704c0a17..5e00cc0cc7 100644
--- a/arm_compute/runtime/TensorAllocator.h
+++ b/arm_compute/runtime/TensorAllocator.h
@@ -25,6 +25,7 @@
#define __ARM_COMPUTE_TENSORALLOCATOR_H__
#include "arm_compute/runtime/ITensorAllocator.h"
+#include "arm_compute/runtime/Memory.h"
#include <cstdint>
#include <memory>
@@ -86,6 +87,19 @@ public:
*
*/
void free() override;
+ /** Import an existing memory as a tensor's backing memory
+ *
+ * @warning If the tensor is flagged to be managed by a memory manager,
+ * this call will lead to an error.
+ * @warning Ownership of memory depends on the way the @ref Memory object was constructed
+ * @note Calling free on a tensor with imported memory will just clear
+ * the internal pointer value.
+ *
+ * @param[in] memory Memory to import
+ *
+ * @return error status
+ */
+ arm_compute::Error import_memory(Memory memory);
/** Associates the tensor with a memory group
*
* @param[in] associated_memory_group Memory group to associate the tensor with
@@ -104,7 +118,7 @@ protected:
private:
MemoryGroup *_associated_memory_group; /**< Registered memory manager */
- uint8_t *_buffer; /**< CPU memory allocation. */
+ Memory _memory; /**< CPU memory */
Tensor *_owner; /**< Owner of the allocator */
};
}
diff --git a/scripts/clang_tidy_rules.py b/scripts/clang_tidy_rules.py
index c70395fae8..9c012680d4 100755
--- a/scripts/clang_tidy_rules.py
+++ b/scripts/clang_tidy_rules.py
@@ -65,6 +65,7 @@ def filter_clang_tidy_lines( lines ):
(any(f in line for f in ["Error.cpp","Error.h"]) and "uninitialized record type: 'args'" in line) or
(any(f in line for f in ["Error.cpp","Error.h"]) and "do not call c-style vararg functions" in line) or
(any(f in line for f in ["Error.cpp","Error.h"]) and "do not define a C-style variadic function" in line) or
+ ("TensorAllocator.cpp" in line and "warning: pointer parameter 'ptr' can be pointer to const" in line) or
("NEMinMaxLocationKernel.cpp" in line and "move constructors should be marked noexcept" in line) or
("NEMinMaxLocationKernel.cpp" in line and "move assignment operators should be marked noexcept" in line) or
("CLMinMaxLocationKernel.cpp" in line and "Forming reference to null pointer" in line) or
diff --git a/src/runtime/Memory.cpp b/src/runtime/Memory.cpp
new file mode 100644
index 0000000000..35d0c824bb
--- /dev/null
+++ b/src/runtime/Memory.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/runtime/Memory.h"
+
+#include "arm_compute/core/Error.h"
+
+using namespace arm_compute;
+
+Memory::Memory()
+ : _memory(nullptr), _memory_owned(nullptr)
+{
+}
+
+Memory::Memory(std::shared_ptr<uint8_t> memory)
+ : _memory(nullptr), _memory_owned(std::move(memory))
+{
+ ARM_COMPUTE_ERROR_ON(_memory_owned.get() == nullptr);
+ _memory = _memory_owned.get();
+}
+
+Memory::Memory(uint8_t *memory)
+ : _memory(memory), _memory_owned(nullptr)
+{
+ ARM_COMPUTE_ERROR_ON(memory == nullptr);
+}
+
+uint8_t *Memory::buffer()
+{
+ return _memory;
+}
+
+uint8_t *Memory::buffer() const
+{
+ return _memory;
+}
+
+uint8_t **Memory::handle()
+{
+ ARM_COMPUTE_ERROR_ON(_memory_owned.get() != nullptr);
+ return &_memory;
+} \ No newline at end of file
diff --git a/src/runtime/TensorAllocator.cpp b/src/runtime/TensorAllocator.cpp
index 272b9f5695..25bd479c84 100644
--- a/src/runtime/TensorAllocator.cpp
+++ b/src/runtime/TensorAllocator.cpp
@@ -27,6 +27,7 @@
#include "arm_compute/core/Error.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/runtime/MemoryGroup.h"
+#include "support/ToolchainSupport.h"
#include <cstddef>
@@ -65,28 +66,23 @@ bool validate_subtensor_shape(const TensorInfo &parent_info, const TensorInfo &c
} // namespace
TensorAllocator::TensorAllocator(Tensor *owner)
- : _associated_memory_group(nullptr), _buffer(nullptr), _owner(owner)
+ : _associated_memory_group(nullptr), _memory(), _owner(owner)
{
}
TensorAllocator::~TensorAllocator()
{
- if((_associated_memory_group == nullptr) && (_buffer != nullptr))
- {
- delete[] _buffer;
- _buffer = nullptr;
- info().set_is_resizable(true);
- }
+ info().set_is_resizable(true);
}
TensorAllocator::TensorAllocator(TensorAllocator &&o) noexcept
: ITensorAllocator(std::move(o)),
_associated_memory_group(o._associated_memory_group),
- _buffer(o._buffer),
+ _memory(std::move(o._memory)),
_owner(o._owner)
{
o._associated_memory_group = nullptr;
- o._buffer = nullptr;
+ o._memory = Memory();
o._owner = nullptr;
}
@@ -97,8 +93,8 @@ TensorAllocator &TensorAllocator::operator=(TensorAllocator &&o) noexcept
_associated_memory_group = o._associated_memory_group;
o._associated_memory_group = nullptr;
- _buffer = o._buffer;
- o._buffer = nullptr;
+ _memory = std::move(o._memory);
+ o._memory = Memory();
_owner = o._owner;
o._owner = nullptr;
@@ -118,7 +114,7 @@ void TensorAllocator::init(const TensorAllocator &allocator, const Coordinates &
ARM_COMPUTE_UNUSED(validate_subtensor_shape);
// Copy pointer to buffer
- _buffer = allocator._buffer;
+ _memory = Memory(allocator._memory.buffer());
// Init tensor info with new dimensions
size_t total_size = parent_info.offset_element_in_bytes(coords) + sub_info.total_size() - sub_info.offset_first_element_in_bytes();
@@ -130,44 +126,53 @@ void TensorAllocator::init(const TensorAllocator &allocator, const Coordinates &
uint8_t *TensorAllocator::data() const
{
- return _buffer;
+ return _memory.buffer();
}
void TensorAllocator::allocate()
{
- ARM_COMPUTE_ERROR_ON(_buffer != nullptr);
+ ARM_COMPUTE_ERROR_ON(_memory.buffer() != nullptr);
if(_associated_memory_group == nullptr)
{
- _buffer = new uint8_t[info().total_size()]();
+ _memory = Memory(std::shared_ptr<uint8_t>(new uint8_t[info().total_size()](), [](uint8_t *ptr)
+ {
+ delete[] ptr;
+ }));
}
else
{
- _associated_memory_group->finalize_memory(_owner, reinterpret_cast<void **>(&_buffer), info().total_size());
+ _associated_memory_group->finalize_memory(_owner, reinterpret_cast<void **>(_memory.handle()), info().total_size());
}
info().set_is_resizable(false);
}
void TensorAllocator::free()
{
- if((_associated_memory_group == nullptr) && (_buffer != nullptr))
- {
- delete[] _buffer;
- _buffer = nullptr;
- info().set_is_resizable(true);
- }
+ _memory = Memory();
+ info().set_is_resizable(true);
+}
+
+arm_compute::Error TensorAllocator::import_memory(Memory memory)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON(memory.buffer() == nullptr);
+ ARM_COMPUTE_RETURN_ERROR_ON(_associated_memory_group != nullptr);
+ _memory = memory;
+ info().set_is_resizable(false);
+
+ return Error{};
}
void TensorAllocator::set_associated_memory_group(MemoryGroup *associated_memory_group)
{
ARM_COMPUTE_ERROR_ON(associated_memory_group == nullptr);
ARM_COMPUTE_ERROR_ON(_associated_memory_group != nullptr);
- ARM_COMPUTE_ERROR_ON(_buffer != nullptr);
+ ARM_COMPUTE_ERROR_ON(_memory.buffer() != nullptr);
_associated_memory_group = associated_memory_group;
}
uint8_t *TensorAllocator::lock()
{
- return _buffer;
+ return _memory.buffer();
}
void TensorAllocator::unlock()
diff --git a/support/ToolchainSupport.h b/support/ToolchainSupport.h
index ad09c6535a..e3c0c2761d 100644
--- a/support/ToolchainSupport.h
+++ b/support/ToolchainSupport.h
@@ -337,9 +337,7 @@ inline bool isfinite(half_float::half value)
namespace cpp14
{
-/** make_unqiue is missing in CPP11. Reimplement it according to the standard
- * proposal.
- */
+/** make_unique is missing in CPP11. Re-implement it according to the standard proposal. */
template <class T>
struct _Unique_if
{
diff --git a/tests/validation/NEON/UNIT/MemoryManager.cpp b/tests/validation/NEON/UNIT/MemoryManager.cpp
new file mode 100644
index 0000000000..27b05ed55a
--- /dev/null
+++ b/tests/validation/NEON/UNIT/MemoryManager.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/runtime/Allocator.h"
+#include "arm_compute/runtime/BlobLifetimeManager.h"
+#include "arm_compute/runtime/MemoryGroup.h"
+#include "arm_compute/runtime/MemoryManagerOnDemand.h"
+#include "arm_compute/runtime/NEON/functions/NENormalizationLayer.h"
+#include "arm_compute/runtime/PoolManager.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "support/ToolchainSupport.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/Utils.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(UNIT)
+TEST_SUITE(MemoryManager)
+
+TEST_CASE(BlobMemoryManagerSimpleWithinFunctionLevel, framework::DatasetMode::ALL)
+{
+ Allocator allocator{};
+ auto lifetime_mgr = std::make_shared<BlobLifetimeManager>();
+ auto pool_mgr = std::make_shared<PoolManager>();
+ auto mm = std::make_shared<MemoryManagerOnDemand>(lifetime_mgr, pool_mgr);
+
+ // Create tensors
+ Tensor src = create_tensor<Tensor>(TensorShape(27U, 11U, 3U), DataType::F32, 1);
+ Tensor dst = create_tensor<Tensor>(TensorShape(27U, 11U, 3U), DataType::F32, 1);
+
+ // Create and configure function
+ NENormalizationLayer norm_layer_1(mm);
+ NENormalizationLayer norm_layer_2(mm);
+ norm_layer_1.configure(&src, &dst, NormalizationLayerInfo(NormType::CROSS_MAP, 3));
+ norm_layer_2.configure(&src, &dst, NormalizationLayerInfo(NormType::IN_MAP_1D, 3));
+
+ ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Allocate tensors
+ src.allocator()->allocate();
+ dst.allocator()->allocate();
+
+ ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Finalize memory manager
+ mm->set_allocator(&allocator);
+ mm->set_num_pools(1);
+ mm->finalize();
+ ARM_COMPUTE_EXPECT(mm->is_finalized(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(mm->lifetime_manager()->are_all_finalized(), framework::LogLevel::ERRORS);
+
+ // Fill tensors
+ arm_compute::test::library->fill_tensor_uniform(Accessor(src), 0);
+
+ // Compute functions
+ norm_layer_1.run();
+ norm_layer_2.run();
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/UNIT/TensorAllocator.cpp b/tests/validation/NEON/UNIT/TensorAllocator.cpp
new file mode 100644
index 0000000000..069831880a
--- /dev/null
+++ b/tests/validation/NEON/UNIT/TensorAllocator.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/runtime/TensorAllocator.h"
+
+#include "arm_compute/runtime/MemoryGroup.h"
+#include "support/ToolchainSupport.h"
+#include "tests/Utils.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(UNIT)
+TEST_SUITE(TensorAllocator)
+
+TEST_CASE(ImportMemory, framework::DatasetMode::ALL)
+{
+ // Init tensor info
+ TensorInfo info(TensorShape(24U, 16U, 3U), 1, DataType::F32);
+
+ // Allocate memory buffer
+ std::shared_ptr<uint8_t> buf(new uint8_t[info.total_size()](), [](uint8_t *ptr)
+ {
+ delete[] ptr;
+ });
+
+ // Negative case : Import empty memory
+ Tensor t1;
+ t1.allocator()->init(info);
+ ARM_COMPUTE_EXPECT(bool(t1.allocator()->import_memory(Memory())), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(t1.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Negative case : Import memory to a tensor that is memory managed
+ Tensor t2;
+ MemoryGroup mg;
+ t2.allocator()->set_associated_memory_group(&mg);
+ ARM_COMPUTE_EXPECT(bool(t2.allocator()->import_memory(Memory(buf.get()))), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(t2.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Positive case : Set raw pointer
+ Tensor t3;
+ t3.allocator()->init(info);
+ ARM_COMPUTE_EXPECT(!bool(t3.allocator()->import_memory(Memory(buf.get()))), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(!t3.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(t3.buffer() == buf.get(), framework::LogLevel::ERRORS);
+ t3.allocator()->free();
+ ARM_COMPUTE_EXPECT(t3.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(t3.buffer() == nullptr, framework::LogLevel::ERRORS);
+
+ // Positive case : Set managed pointer
+ Tensor t4;
+ t4.allocator()->init(info);
+ ARM_COMPUTE_EXPECT(!bool(t4.allocator()->import_memory(Memory(buf))), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(!t4.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(t4.buffer() == buf.get(), framework::LogLevel::ERRORS);
+ t4.allocator()->free();
+ ARM_COMPUTE_EXPECT(t4.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(t4.buffer() == nullptr, framework::LogLevel::ERRORS);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute