aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2019-06-17 17:46:17 +0100
committerGeorgios Pinitas <georgios.pinitas@arm.com>2019-06-24 14:27:42 +0000
commitdb09b3783ff9af67c6d373b12aa9a6aff3c5d0f1 (patch)
tree270aaba4e8e1553a32bc3e492f480fdbbaec3bd3
parent3689fcd5915cd902cb4ea5f618f2a6e42f6dc4a1 (diff)
downloadComputeLibrary-db09b3783ff9af67c6d373b12aa9a6aff3c5d0f1.tar.gz
COMPMID-2392: Add documentation for import_memory interface
Change-Id: I943aefafe4131fc366d7ec336c9b94e89ce4fb8d Signed-off-by: Georgios Pinitas <georgios.pinitas@arm.com> Reviewed-on: https://review.mlplatform.org/c/1362 Reviewed-by: Michalis Spyrou <michalis.spyrou@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com>
-rw-r--r--arm_compute/runtime/CL/CLTensorAllocator.h1
-rw-r--r--arm_compute/runtime/TensorAllocator.h1
-rw-r--r--docs/01_library.dox24
-rw-r--r--tests/validation/NEON/UNIT/TensorAllocator.cpp53
4 files changed, 78 insertions, 1 deletions
diff --git a/arm_compute/runtime/CL/CLTensorAllocator.h b/arm_compute/runtime/CL/CLTensorAllocator.h
index f942478ada..a60594ca3e 100644
--- a/arm_compute/runtime/CL/CLTensorAllocator.h
+++ b/arm_compute/runtime/CL/CLTensorAllocator.h
@@ -114,6 +114,7 @@ public:
* @warning memory is expected to be aligned with the device requirements.
* @warning tensor shouldn't be memory managed.
* @warning ownership of memory is not transferred.
+ * @warning padding should be accounted by the client code.
* @note buffer size will be checked to be compliant with total_size reported by ITensorInfo.
*
* @param[in] buffer Buffer to be used as backing memory
diff --git a/arm_compute/runtime/TensorAllocator.h b/arm_compute/runtime/TensorAllocator.h
index f296bc2e3d..bf574fa0c9 100644
--- a/arm_compute/runtime/TensorAllocator.h
+++ b/arm_compute/runtime/TensorAllocator.h
@@ -98,6 +98,7 @@ public:
* @warning size is expected to be compliant with total_size reported by ITensorInfo.
* @warning ownership of memory is not transferred.
* @warning tensor shouldn't be memory managed.
+ * @warning padding should be accounted by the client code.
* @note buffer alignment will be checked to be compliant with alignment reported by ITensorInfo.
*
* @param[in] memory Raw memory pointer to be used as backing memory
diff --git a/docs/01_library.dox b/docs/01_library.dox
index 359ca4794a..85af8a0ded 100644
--- a/docs/01_library.dox
+++ b/docs/01_library.dox
@@ -449,7 +449,29 @@ conv1.run();
conv2.run();
@endcode
-@section S4_8_opencl_tuner OpenCL Tuner
+@section S4_8_import_memory Import Memory Interface
+
+The implemented @ref TensorAllocator and @ref CLTensorAllocator objects provide an interface capable of importing existing memory to a tensor as backing memory.
+
+A simple NEON example can be the following:
+@code{.cpp}
+// External backing memory
+void* external_ptr = ...;
+
+// Create and initialize tensor
+Tensor tensor;
+tensor.allocator()->init(tensor_info);
+
+// Import existing pointer as backing memory
+tensor.allocator()->import_memory(external_ptr);
+@endcode
+
+It is important to note the following:
+- Ownership of the backing memory is not transferred to the tensor itself.
+- The tensor mustn't be memory managed.
+- Padding requirements should be accounted by the client code. In other words, if padding is required by the tensor after the function configuration step, then the imported backing memory should account for it. Padding can be checked through the @ref TensorInfo::padding() interface.
+
+@section S4_9_opencl_tuner OpenCL Tuner
OpenCL kernels when dispatched to the GPU take two arguments:
- The Global Workgroup Size (GWS): That's the number of times to run an OpenCL kernel to process all the elements we want to process.
diff --git a/tests/validation/NEON/UNIT/TensorAllocator.cpp b/tests/validation/NEON/UNIT/TensorAllocator.cpp
index 217933da48..4764bf63ca 100644
--- a/tests/validation/NEON/UNIT/TensorAllocator.cpp
+++ b/tests/validation/NEON/UNIT/TensorAllocator.cpp
@@ -142,6 +142,59 @@ TEST_CASE(ImportMemoryMalloc, framework::DatasetMode::ALL)
ARM_COMPUTE_EXPECT(tensor.info()->is_resizable(), framework::LogLevel::ERRORS);
}
+TEST_CASE(ImportMemoryMallocPadded, framework::DatasetMode::ALL)
+{
+ // Create tensor
+ Tensor tensor;
+ tensor.allocator()->init(TensorInfo(TensorShape(24U, 16U, 3U), 1, DataType::F32));
+
+ // Enforce tensor padding and validate that meta-data were updated
+ // Note: Padding might be updated after the function configuration in case of increased padding requirements
+ const PaddingSize enforced_padding(3U, 5U, 2U, 4U);
+ tensor.info()->extend_padding(enforced_padding);
+ validate(tensor.info()->padding(), enforced_padding);
+
+ // Create and configure activation function
+ NEActivationLayer act_func;
+ act_func.configure(&tensor, nullptr, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+
+ // Allocate and import tensor
+ const size_t total_size_in_bytes = tensor.info()->total_size();
+ auto raw_data = support::cpp14::make_unique<uint8_t[]>(total_size_in_bytes);
+
+ ARM_COMPUTE_EXPECT(bool(tensor.allocator()->import_memory(raw_data.get())), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(!tensor.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Fill tensor while accounting padding
+ std::uniform_real_distribution<float> distribution(-5.f, 5.f);
+ std::mt19937 gen(library->seed());
+
+ Window tensor_window;
+ tensor_window.use_tensor_dimensions(tensor.info()->tensor_shape());
+ Iterator tensor_it(&tensor, tensor_window);
+
+ execute_window_loop(tensor_window, [&](const Coordinates &)
+ {
+ *reinterpret_cast<float *>(tensor_it.ptr()) = distribution(gen);
+ },
+ tensor_it);
+
+ // Execute function and sync
+ act_func.run();
+
+ // Validate result by checking that the input has no negative values
+ execute_window_loop(tensor_window, [&](const Coordinates &)
+ {
+ const float val = *reinterpret_cast<float *>(tensor_it.ptr());
+ ARM_COMPUTE_EXPECT(val >= 0, framework::LogLevel::ERRORS);
+ },
+ tensor_it);
+
+ // Release resources
+ tensor.allocator()->free();
+ ARM_COMPUTE_EXPECT(tensor.info()->is_resizable(), framework::LogLevel::ERRORS);
+}
+
#if !defined(BARE_METAL)
TEST_CASE(ImportMemoryMappedFile, framework::DatasetMode::ALL)
{