diff options
author | Gian Marco Iodice <gianmarco.iodice@arm.com> | 2023-07-07 11:25:57 +0100 |
---|---|---|
committer | Viet-Hoa Do <viet-hoa.do@arm.com> | 2023-07-20 08:48:15 +0000 |
commit | ebfdb5a1ea73c2269eec5af492970c2174ab7d0f (patch) | |
tree | 5c60d083100118f0a40e629dfa69b7a7373dd7fd /compute_kernel_writer/src/cl/CLTensorArgument.cpp | |
parent | 29dc9fc1d3d6e90746ba1173e3318b774dcf7bed (diff) | |
download | ComputeLibrary-ebfdb5a1ea73c2269eec5af492970c2174ab7d0f.tar.gz |
Integrate CLTensorArgument
- Add CLTensorArgument to query the components and storages as OpenCL
variables (or by values when possible)
- Add caching mechanism in CLTensorArgument to keep track of the components and storages used
- Add unit tests
Resolves COMPMID-5787
Signed-off-by: Gian Marco Iodice <gianmarco.iodice@arm.com>
Signed-off-by: Viet-Hoa Do <viet-hoa.do@arm.com>
Change-Id: Ib39e1f77b097e5b907a296fe6b0d41bb4bcd4ffc
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/9908
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Benchmark: Arm Jenkins <bsgcomp@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Gunes Bayir <gunes.bayir@arm.com>
Reviewed-by: Jakub Sujak <jakub.sujak@arm.com>
Diffstat (limited to 'compute_kernel_writer/src/cl/CLTensorArgument.cpp')
-rw-r--r-- | compute_kernel_writer/src/cl/CLTensorArgument.cpp | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/compute_kernel_writer/src/cl/CLTensorArgument.cpp b/compute_kernel_writer/src/cl/CLTensorArgument.cpp new file mode 100644 index 0000000000..ed1c5bd687 --- /dev/null +++ b/compute_kernel_writer/src/cl/CLTensorArgument.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2023 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 "src/cl/CLTensorArgument.h" +#include "ckw/Error.h" +#include "src/cl/CLHelpers.h" +#include "src/types/TensorComponentType.h" + +#include <algorithm> +#include <vector> + +namespace ckw +{ +CLTensorArgument::CLTensorArgument(const std::string &name, const TensorInfo &info, bool return_dims_by_value) +{ + _return_dims_by_value = return_dims_by_value; + _basename = name; + _info = info; +} + +TileVariable CLTensorArgument::component(TensorComponentType x) +{ + if(_return_dims_by_value) + { + uint32_t component_type = static_cast<uint32_t>(x); + + const bool is_dimension = (component_type & static_cast<uint32_t>(TensorComponentBitmask::Dimension)) != 0; + const bool is_folded_dimensions = (component_type & static_cast<uint32_t>(TensorComponentBitmask::FoldedDimensions)) != 0; + + constexpr auto bitmask_all = static_cast<uint32_t>(TensorComponentIndexBitmask::All); + constexpr auto bitmask_index_0 = static_cast<uint32_t>(TensorComponentIndexBitmask::Index0); +#ifdef COMPUTE_KERNEL_WRITER_ASSERTS_ENABLED + constexpr auto bitmask_index_1 = static_cast<uint32_t>(TensorComponentIndexBitmask::Index1); + constexpr auto bitmask_index_2 = static_cast<uint32_t>(TensorComponentIndexBitmask::Index2); + constexpr auto bitmask_index_3 = static_cast<uint32_t>(TensorComponentIndexBitmask::Index3); +#endif // COMPUTE_KERNEL_WRITER_ASSERTS_ENABLED + + // Make sure that the encoding of component type hasn't changed and each nibble is 4 bits apart. + CKW_ASSERT(bitmask_all == (bitmask_index_0 | bitmask_index_1 | bitmask_index_2 | bitmask_index_3)); + CKW_ASSERT(bitmask_index_0 == bitmask_index_1 >> 4); + CKW_ASSERT(bitmask_index_1 == bitmask_index_2 >> 4); + CKW_ASSERT(bitmask_index_2 == bitmask_index_3 >> 4); + + // If we have a dimension or folded dimensions, we can return the corresponding value if it is not dynamic (not equal to -1) + if(is_dimension == true || is_folded_dimensions == true) + { + component_type = component_type & bitmask_all; + + int32_t idx = 1; + for(int32_t i = 0; i < tensor_component_index_max_count; ++i) + { + uint32_t dim_idx = component_type & bitmask_index_0; + + if(dim_idx == 0) + { + // Stop at the first nibble containing 0 + break; + } + + // Subtract - 1. Please refer to the TensorComponentIndexBitmask documentation + dim_idx -= 1; + + // Get the dimension value + const int32_t dim_val = _info.shape()[dim_idx]; + + if(dim_val == kDynamicTensorDimensionValue) + { + // We cannot return the dimension by value if it is dynamic. + // Therefore, force the idx variable to kDynamicTensorDimensionValue and break the loop. + idx = kDynamicTensorDimensionValue; + break; + } + + idx *= dim_val; + + // Go to the next nibble + component_type >>= 4; + } + + if(idx != kDynamicTensorDimensionValue) + { + TileVariable t; + t.str = std::to_string(idx); + t.desc.dt = DataType::Uint32; + t.desc.len = 1; + return t; + } + } + } + + auto it = std::find(_components_used.begin(), _components_used.end(), x); + + // Add to the list of used components if not present yet + if(it == _components_used.end()) + { + _components_used.push_back(x); + } + + TileVariable t; + t.str = create_component_name(x); + t.desc.dt = DataType::Int32; + t.desc.len = 1; + return t; +} + +TensorStorageVariable CLTensorArgument::storage(TensorStorageType x) +{ + if(std::find(_storages_used.begin(), _storages_used.end(), x) == _storages_used.end()) + { + _storages_used.push_back(x); + } + + TensorStorageVariable t; + t.val = create_storage_name(x); + t.type = cl_get_variable_storagetype_as_string(x); + + return t; +} + +std::string CLTensorArgument::create_storage_name(TensorStorageType x) const +{ + std::string var_name = _basename; + + switch(x) + { + case TensorStorageType::BufferUint8Ptr: + var_name += "_ptr"; + break; + case TensorStorageType::Texture2dReadOnly: + case TensorStorageType::Texture2dWriteOnly: + var_name += "_img2d"; + break; + default: + CKW_ASSERT_FAILED_MSG("Unsupported tensor storage"); + return ""; + } + + return var_name; +} + +std::string CLTensorArgument::create_component_name(TensorComponentType x) const +{ + std::string var_name = _basename; + + switch(x) + { + case TensorComponentType::OffsetFirstElement: + var_name += "_offset_first_element"; + break; + case TensorComponentType::Stride0: + var_name += "_stride0"; + break; + case TensorComponentType::Stride1: + var_name += "_stride1"; + break; + case TensorComponentType::Stride2: + var_name += "_stride2"; + break; + case TensorComponentType::Stride3: + var_name += "_stride3"; + break; + case TensorComponentType::Stride4: + var_name += "_stride4"; + break; + case TensorComponentType::Dim0: + var_name += "_dim0"; + break; + case TensorComponentType::Dim1: + var_name += "_dim1"; + break; + case TensorComponentType::Dim2: + var_name += "_dim2"; + break; + case TensorComponentType::Dim3: + var_name += "_dim3"; + break; + case TensorComponentType::Dim4: + var_name += "_dim4"; + break; + case TensorComponentType::Dim1xDim2: + var_name += "_dim1xdim2"; + break; + case TensorComponentType::Dim2xDim3: + var_name += "_dim2xdim3"; + break; + case TensorComponentType::Dim1xDim2xDim3: + var_name += "_dim1xdim2xdim3"; + break; + default: + COMPUTE_KERNEL_WRITER_ERROR_ON_MSG("Unsupported tensor component"); + return ""; + } + + return var_name; +} + +std::vector<TensorStorageVariable> CLTensorArgument::storages() const +{ + std::vector<TensorStorageVariable> storages; + for(auto &val : _storages_used) + { + TensorStorageVariable t; + t.val = create_storage_name(val); + t.type = cl_get_variable_storagetype_as_string(val); + storages.push_back(t); + } + + return storages; +} + +std::vector<TileVariable> CLTensorArgument::components() const +{ + std::vector<TileVariable> components; + + for(auto &val : _components_used) + { + TileVariable t; + t.str = create_component_name(val); + t.desc.dt = DataType::Int32; + t.desc.len = 1; + components.push_back(t); + } + + return components; +} +} // namespace ckw |