aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiCong Li <sicong.li@arm.com>2022-11-23 09:58:18 +0000
committerGunes Bayir <gunes.bayir@arm.com>2022-12-22 17:42:47 +0000
commit81fdaddaf36cb4c7ff0d2c52a370dd977a13dc72 (patch)
treec9e25c9e4b69db153c9594b751ada977594cab8b
parent8ee689312a64e10d9e39d745fe79b9c5ecb96820 (diff)
downloadComputeLibrary-81fdaddaf36cb4c7ff0d2c52a370dd977a13dc72.tar.gz
Add is_supported_op interface
* This retains the behaviors of the current library's validate() method. I.e. is_supported_op() is used to check the support level and validity of an operator configuration without any consideration of fusion. - validate_op() interface still checks both the op validity and the fusion validity - This arrangement ensures that any users of the original validate() interface can expect to use is_supported_op() in exactly the same way with no performance or behavioral difference. * Force adding const tensors to ArgumentPack when adding to OperatorGroup. This is because OperatorGroup is only for validating fusion, and does not mutate TensorInfos at all Partially resolves COMPMID-5736 Change-Id: I4157677f55848d66a08ec00e6a76d13a24b722b7 Signed-off-by: SiCong Li <sicong.li@arm.com> Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/8687 Benchmark: Arm Jenkins <bsgcomp@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: Gian Marco Iodice <gianmarco.iodice@arm.com>
-rw-r--r--arm_compute/dynamic_fusion/sketch/gpu/operators/GpuConv2d.h14
-rw-r--r--src/dynamic_fusion/sketch/gpu/operators/GpuConv2d.cpp102
2 files changed, 76 insertions, 40 deletions
diff --git a/arm_compute/dynamic_fusion/sketch/gpu/operators/GpuConv2d.h b/arm_compute/dynamic_fusion/sketch/gpu/operators/GpuConv2d.h
index fe9108d356..76decfd6cf 100644
--- a/arm_compute/dynamic_fusion/sketch/gpu/operators/GpuConv2d.h
+++ b/arm_compute/dynamic_fusion/sketch/gpu/operators/GpuConv2d.h
@@ -34,6 +34,7 @@ namespace experimental
namespace dynamic_fusion
{
/** Forward declaration */
+class GpuWorkloadContext;
class GpuWorkloadSketch;
/** Operator interface. */
@@ -59,7 +60,7 @@ public:
* @param[in] src Source tensor
* @param[in] wei Weight tensor
* @param[in] bia (Optional) Bias tensor
- * @param[out] dst Destination tensor
+ * @param[out] dst Destination tensor. If an uninitialized ITensorInfo is passed in, it will be auto-initialized
* @param[in] attributes Operator attributes
*/
static void create_op(GpuWorkloadSketch &sketch,
@@ -68,7 +69,16 @@ public:
ITensorInfo *bia,
ITensorInfo *dst,
const Attributes &attributes);
- /** Validate the operator and check if it can be fused into the workload sketch.
+ /** Check if the operator configuration is supported, irrespective of fusion
+ * Similar to @ref GpuConv2d::create_op()
+ */
+ static Status is_supported_op(const GpuWorkloadContext &context,
+ const ITensorInfo *src,
+ const ITensorInfo *wei,
+ const ITensorInfo *bia,
+ const ITensorInfo *dst,
+ const Attributes &attributes);
+ /** Check if the operator configuration is supported and if it can be fused into the workload sketch.
* Similar to @ref GpuConv2d::create_op()
*/
static Status validate_op(const GpuWorkloadSketch &sketch,
diff --git a/src/dynamic_fusion/sketch/gpu/operators/GpuConv2d.cpp b/src/dynamic_fusion/sketch/gpu/operators/GpuConv2d.cpp
index 048ee01f35..00b4fbccb2 100644
--- a/src/dynamic_fusion/sketch/gpu/operators/GpuConv2d.cpp
+++ b/src/dynamic_fusion/sketch/gpu/operators/GpuConv2d.cpp
@@ -98,23 +98,30 @@ DirectConvComputeKernelInfo config_direct_convolution_nhwc(const ITensorInfo *sr
return t->configure(src, weights, conv_info);
}
+void calculate_and_init_dst_if_empty(ITensorInfo *dst, const ITensorInfo *src, const ITensorInfo *wei, const Conv2dAttributes &attributes)
+{
+ if(dst->total_size() == 0U)
+ {
+ const auto shape = misc::shape_calculator::compute_deep_convolution_shape(src->tensor_shape(), src->data_layout(), wei->tensor_shape(),
+ PadStrideInfo(attributes.stride().x(), attributes.stride().y(), attributes.pad().left,
+ attributes.pad().right,
+ attributes.pad().top, attributes.pad().bottom, DimensionRoundingType::FLOOR)); // use the default DimensionRoundingType
+
+ auto_init_if_empty(*dst, src->clone()->set_tensor_shape(shape));
+ }
+}
+
constexpr GpuOperatorType operator_type = GpuOperatorType::Complex;
} // namespace
-Status GpuConv2d::validate_op(const GpuWorkloadSketch &sketch,
- const ITensorInfo *src,
- const ITensorInfo *wei,
- const ITensorInfo *bia,
- const ITensorInfo *dst,
- const Conv2dAttributes &attributes)
+Status GpuConv2d::is_supported_op(const GpuWorkloadContext &context,
+ const ITensorInfo *src,
+ const ITensorInfo *wei,
+ const ITensorInfo *bia,
+ const ITensorInfo *dst,
+ const Conv2dAttributes &attributes)
{
ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src, wei, dst);
- ARM_COMPUTE_RETURN_ERROR_ON(
- !src->has_valid_id() || !wei->has_valid_id() || !dst->has_valid_id());
- if(bia != nullptr)
- {
- ARM_COMPUTE_RETURN_ERROR_ON(!bia->has_valid_id());
- }
// Auto initialize dst tensor info
TensorInfo dst_info_to_validate = *dst;
const auto data_layout = src->data_layout();
@@ -133,30 +140,17 @@ Status GpuConv2d::validate_op(const GpuWorkloadSketch &sketch,
auto_init_if_empty(dst_info_to_validate, src->clone()->set_tensor_shape(shape));
}
- // Perform fusion test
- // Pack tensor infos
- ArgumentPack<ITensorInfo> tensors;
- tensors.add_const_tensor(ACL_SRC_0, src);
- tensors.add_const_tensor(ACL_SRC_1, wei);
- tensors.add_const_tensor(ACL_SRC_2, bia);
- tensors.add_const_tensor(ACL_DST_0, &dst_info_to_validate);
- const auto op = sketch.implementation().operator_group().new_operator(operator_type, tensors);
- ARM_COMPUTE_RETURN_ERROR_ON_MSG(!sketch.implementation().operator_group().try_add_operator(op),
- "Operator fusion test failed. This operator cannot be fused into the workload");
-
// Check support level
// Data type
ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(src, 1, DataType::F16, DataType::F32);
// Data layout
ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(src, DataLayout::NHWC);
- const auto sketch_ctx = sketch.implementation().context();
-
- const auto gpu_target = sketch_ctx->gpu_target();
-
- if(sketch_ctx->gpu_language() == GpuLanguage::OpenCL)
+ // Check components
+ const auto gpu_target = context.gpu_target();
+ if(context.gpu_language() == GpuLanguage::OpenCL)
{
- const auto cl_compile_ctx = sketch_ctx->cl_compile_context();
+ const auto cl_compile_ctx = context.cl_compile_context();
ARM_COMPUTE_RETURN_ERROR_ON(cl_compile_ctx == nullptr);
// Validate Direct Conv2d Component
{
@@ -185,6 +179,42 @@ Status GpuConv2d::validate_op(const GpuWorkloadSketch &sketch,
return Status{};
}
+Status GpuConv2d::validate_op(const GpuWorkloadSketch &sketch,
+ const ITensorInfo *src,
+ const ITensorInfo *wei,
+ const ITensorInfo *bia,
+ const ITensorInfo *dst,
+ const Conv2dAttributes &attributes)
+{
+ ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src, wei, dst);
+
+ // Check if tensors have valid id. I.e. they are created from a sketch
+ ARM_COMPUTE_RETURN_ERROR_ON(
+ !src->has_valid_id() || !wei->has_valid_id() || !dst->has_valid_id());
+ if(bia != nullptr)
+ {
+ ARM_COMPUTE_RETURN_ERROR_ON(!bia->has_valid_id());
+ }
+
+ // Auto initialize dst tensor info
+ TensorInfo dst_info_to_validate = *dst;
+ calculate_and_init_dst_if_empty(&dst_info_to_validate, src, wei, attributes);
+
+ // Perform fusion test
+ // Check if operator meets fusion constraints
+ ArgumentPack<ITensorInfo> tensors;
+ tensors.add_const_tensor(ACL_SRC_0, src);
+ tensors.add_const_tensor(ACL_SRC_1, wei);
+ tensors.add_const_tensor(ACL_SRC_2, bia);
+ tensors.add_const_tensor(ACL_DST_0, &dst_info_to_validate);
+ const auto op = sketch.implementation().operator_group().new_operator(operator_type, tensors);
+ ARM_COMPUTE_RETURN_ERROR_ON_MSG(!sketch.implementation().operator_group().try_add_operator(op),
+ "Operator fusion test failed. This operator cannot be fused into the workload");
+
+ // Check if configuration is supported
+ return is_supported_op(*sketch.gpu_context(), src, wei, bia, &dst_info_to_validate, attributes);
+}
+
void GpuConv2d::create_op(GpuWorkloadSketch &sketch,
ITensorInfo *src,
ITensorInfo *wei,
@@ -202,21 +232,17 @@ void GpuConv2d::create_op(GpuWorkloadSketch &sketch,
// Assert validation
ARM_COMPUTE_ERROR_THROW_ON(GpuConv2d::validate_op(sketch, src, wei, bia, dst, attributes));
ARM_COMPUTE_ERROR_ON_NULLPTR(src, wei, dst);
- const auto data_layout = src->data_layout();
// Auto initialize dst tensor
- {
- auto shape = misc::shape_calculator::compute_deep_convolution_shape(src->tensor_shape(), data_layout, wei->tensor_shape(), conv_info); // use the default DimensionRoundingType
-
- auto_init_if_empty(*dst, src->clone()->set_tensor_shape(shape));
- }
+ calculate_and_init_dst_if_empty(dst, src, wei, attributes);
// Translate into components and add to component graph
auto &comp_graph = sketch.implementation().component_graph();
const auto sketch_ctx = sketch.implementation().context();
- const auto gpu_target = sketch_ctx->gpu_target();
+ const auto data_layout = src->data_layout();
+ const auto gpu_target = sketch_ctx->gpu_target();
if(sketch_ctx->gpu_language() == GpuLanguage::OpenCL)
{
@@ -263,9 +289,9 @@ void GpuConv2d::create_op(GpuWorkloadSketch &sketch,
// Pack tensor infos
ArgumentPack<ITensorInfo> tensors;
tensors.add_const_tensor(ACL_SRC_0, src);
- tensors.add_tensor(ACL_SRC_1, wei);
+ tensors.add_const_tensor(ACL_SRC_1, wei);
tensors.add_const_tensor(ACL_SRC_2, bia);
- tensors.add_tensor(ACL_DST_0, dst);
+ tensors.add_const_tensor(ACL_DST_0, dst);
const auto op = sketch.implementation().operator_group().new_operator(operator_type, tensors);
sketch.implementation().operator_group().add_operator(op);