diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.cc b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.cc index bb44866e19d..023d2f80ee3 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.cc +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.cc @@ -20,20 +20,25 @@ namespace mindspore { namespace kernel { -void BoundingBoxDecodeCpuKernelMod::InitKernel(const CNodePtr &kernel_node) { - MS_EXCEPTION_IF_NULL(kernel_node); - kernel_name_ = common::AnfAlgo::GetCNodeName(kernel_node); - size_t input_num = common::AnfAlgo::GetInputTensorNum(kernel_node); - if (input_num != INPUT_NUMS) { - MS_LOG(ERROR) << "For '" << kernel_name_ << "', the number of inputs must be 2, but got " << input_num; - } +namespace { +const size_t kInputRank = 2; +const size_t kLastDim = 4; +} // namespace + +bool BoundingBoxDecodeCpuKernelMod::Init(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs) { + MS_EXCEPTION_IF_NULL(base_operator); + kernel_name_ = base_operator->name(); + constexpr size_t input_num = 2; + CHECK_KERNEL_INPUTS_NUM(inputs.size(), input_num, kernel_name_); const size_t coordinate_size = 4; - if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa() || - common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa()) { - means_ = common::AnfAlgo::GetNodeAttr>(kernel_node, "means"); - } else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa()) { - float mean = common::AnfAlgo::GetNodeAttr(kernel_node, "means"); + auto means = base_operator->GetAttr("means"); + if (means->isa()) { + means_ = api::GetValue>(means); + } else if (means->isa()) { + float mean = api::GetValue(means); for (size_t i = 0; i < coordinate_size; i++) { (void)means_.emplace_back(mean); } @@ -42,11 +47,11 @@ void BoundingBoxDecodeCpuKernelMod::InitKernel(const CNodePtr &kernel_node) { << "', the input 'means' must be a tuple or a list, and dtype must be float, but got is not."; } - if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa() || - common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa()) { - stds_ = common::AnfAlgo::GetNodeAttr>(kernel_node, "stds"); - } else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa()) { - float std = common::AnfAlgo::GetNodeAttr(kernel_node, "stds"); + auto stds = base_operator->GetAttr("stds"); + if (stds->isa()) { + stds_ = api::GetValue>(stds); + } else if (stds->isa()) { + float std = api::GetValue(stds); for (size_t i = 0; i < coordinate_size; i++) { (void)stds_.emplace_back(std); } @@ -62,17 +67,68 @@ void BoundingBoxDecodeCpuKernelMod::InitKernel(const CNodePtr &kernel_node) { << means_.size() << ", and the length of 'stds': " << stds_.size(); } - std::vector max_shape_me = common::AnfAlgo::GetNodeAttr>(kernel_node, "max_shape"); + auto max_shape = base_operator->GetAttr("max_shape"); + std::vector max_shape_me = api::GetValue>(max_shape); (void)std::transform(max_shape_me.begin(), max_shape_me.end(), std::back_inserter(max_shape_), [](const int64_t &value) { return LongToInt(value); }); - wh_ratio_clip_ = common::AnfAlgo::GetNodeAttr(kernel_node, "wh_ratio_clip"); + auto wh_ratio_clip = base_operator->GetAttr("wh_ratio_clip"); + wh_ratio_clip_ = api::GetValue(wh_ratio_clip); if (max_shape_.size() < MIN_MAX_SHAPE_SIZE) { MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the length of 'max_shape' must be at least 2, but got: " << max_shape_.size(); } - InitTaskFunc(kernel_node); + auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs); + auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport()); + if (!is_match) { + MS_LOG(ERROR) << "For '" << kernel_name_ << "' does not support this kernel type: " << kernel_attr; + return false; + } + kernel_func_ = func_list_[index].second; + return true; +} + +int BoundingBoxDecodeCpuKernelMod::Resize(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs, + const std::map &inputsOnHost) { + if (auto ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost); ret != KRET_OK) { + return ret; + } + + auto anchor_box_shape = LongVecToSizeVec(inputs[kIndex0]->GetShapeVector()); + auto deltas_shape = LongVecToSizeVec(inputs[kIndex1]->GetShapeVector()); + + auto it_x = std::find_if(anchor_box_shape.begin(), anchor_box_shape.end(), [](int64_t sh) { return sh <= 0; }); + if (it_x != anchor_box_shape.end()) { + return KRET_UNKNOWN_SHAPE; + } + + size_t anchor_box_rank = anchor_box_shape.size(); + size_t deltas_rank = deltas_shape.size(); + + if (anchor_box_rank != kInputRank) { + MS_LOG(ERROR) << "The rank of anchor box must be 2, but got " << anchor_box_rank; + return KRET_RESIZE_FAILED; + } + + if (deltas_rank != kInputRank) { + MS_LOG(ERROR) << "The rank of deltas must be 2, but got " << deltas_rank; + return KRET_RESIZE_FAILED; + } + + if (anchor_box_shape[1] != kLastDim) { + MS_LOG(ERROR) << "The shape of anchor box must be (n, 4), but got the second dimension of " << anchor_box_shape[1]; + return KRET_RESIZE_FAILED; + } + + if (deltas_shape[1] != kLastDim) { + MS_LOG(ERROR) << "The shape of deltas must be (n, 4), but got the second dimension of " << deltas_shape[1]; + return KRET_RESIZE_FAILED; + } + + return KRET_OK; } template @@ -165,15 +221,6 @@ std::vector}}; -void BoundingBoxDecodeCpuKernelMod::InitTaskFunc(const CNodePtr &kernel_node) { - auto kernel_attr = GetKernelAttrFromNode(kernel_node); - auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport()); - if (!is_match) { - MS_LOG(EXCEPTION) << "BoundingBoxDecode does not support this kernel data type: " << kernel_attr; - } - kernel_func_ = func_list_[index].second; -} - std::vector BoundingBoxDecodeCpuKernelMod::GetOpSupport() { std::vector support_list; (void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list), diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.h b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.h index 446ce4f8eef..b45474be842 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.h +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_decode_cpu_kernel.h @@ -14,12 +14,13 @@ * limitations under the License. */ -#ifndef MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_BOUNDINGBOX_DECODE_CPU_KERNEL_H_ -#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_BOUNDINGBOX_DECODE_CPU_KERNEL_H_ +#ifndef MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_BOUNDINGBOX_DECODE_CPU_KERNEL_H_ +#define MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_BOUNDINGBOX_DECODE_CPU_KERNEL_H_ #include #include #include +#include #include "plugin/device/cpu/kernel/cpu_kernel.h" #include "plugin/factory/ms_factory.h" @@ -27,23 +28,25 @@ namespace mindspore { namespace kernel { constexpr size_t MIN_MAX_SHAPE_SIZE = 2; -constexpr size_t INPUT_NUMS = 2; -class BoundingBoxDecodeCpuKernelMod : public DeprecatedNativeCpuKernelMod { +class BoundingBoxDecodeCpuKernelMod : public NativeCpuKernelMod { public: BoundingBoxDecodeCpuKernelMod() = default; ~BoundingBoxDecodeCpuKernelMod() override = default; - void InitKernel(const CNodePtr &kernel_node) override; + bool Init(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs) override; bool Launch(const std::vector &inputs, const std::vector &workspace, const std::vector &outputs) override { return kernel_func_(this, inputs, workspace, outputs); } + int Resize(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs, const std::map &) override; + std::vector GetOpSupport() override; private: - void InitTaskFunc(const CNodePtr &kernel_node); template bool LaunchKernel(const std::vector &inputs, const std::vector &workspace, const std::vector &outputs); @@ -55,10 +58,10 @@ class BoundingBoxDecodeCpuKernelMod : public DeprecatedNativeCpuKernelMod { std::vector means_; std::vector stds_; - std::vector max_shape_; + std::vector max_shape_; float wh_ratio_clip_{0.016}; }; } // namespace kernel } // namespace mindspore -#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_BOUNDINGBOX_DECODE_CPU_KERNEL_H_ +#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_BOUNDINGBOX_DECODE_CPU_KERNEL_H_ diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.cc b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.cc index 871569d52fa..f6f1c7b9536 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.cc +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.cc @@ -20,43 +20,25 @@ namespace mindspore { namespace kernel { -std::vector> - BoundingBoxEncodeCpuKernelMod::func_list_ = { - {KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), - &BoundingBoxEncodeCpuKernelMod::LaunchKernel}, - {KernelAttr().AddInputAttr(kNumberTypeFloat16).AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16), - &BoundingBoxEncodeCpuKernelMod::LaunchKernel}}; +namespace { +const size_t kInputRank = 2; +const size_t kLastDim = 4; +} // namespace -void BoundingBoxEncodeCpuKernelMod::InitTaskFunc(const CNodePtr &kernel_node) { - auto kernel_attr = GetKernelAttrFromNode(kernel_node); - auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport()); - if (!is_match) { - MS_LOG(EXCEPTION) << "BoundingBoxEncode does not support this kernel data type: " << kernel_attr; - } - kernel_func_ = func_list_[index].second; -} - -std::vector BoundingBoxEncodeCpuKernelMod::GetOpSupport() { - std::vector support_list; - (void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list), - [](const std::pair &pair) { return pair.first; }); - return support_list; -} - -void BoundingBoxEncodeCpuKernelMod::InitKernel(const CNodePtr &kernel_node) { - MS_EXCEPTION_IF_NULL(kernel_node); - kernel_name_ = common::AnfAlgo::GetCNodeName(kernel_node); - size_t input_num = common::AnfAlgo::GetInputTensorNum(kernel_node); - if (input_num != INPUT_NUMS) { - MS_LOG(ERROR) << "For '" << kernel_name_ << "', the number of inputs must be 2, but got " << input_num; - } +bool BoundingBoxEncodeCpuKernelMod::Init(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs) { + MS_EXCEPTION_IF_NULL(base_operator); + kernel_name_ = base_operator->name(); + constexpr size_t input_num = 2; + CHECK_KERNEL_INPUTS_NUM(inputs.size(), input_num, kernel_name_); const size_t coordinate_size = 4; - if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa() || - common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa()) { - means_ = common::AnfAlgo::GetNodeAttr>(kernel_node, "means"); - } else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa()) { - float mean = common::AnfAlgo::GetNodeAttr(kernel_node, "means"); + auto means = base_operator->GetAttr("means"); + if (means->isa()) { + means_ = api::GetValue>(means); + } else if (means->isa()) { + float mean = api::GetValue(means); for (size_t i = 0; i < coordinate_size; i++) { (void)means_.emplace_back(mean); } @@ -65,11 +47,11 @@ void BoundingBoxEncodeCpuKernelMod::InitKernel(const CNodePtr &kernel_node) { << "', the input 'means' must be a tuple or a list, and dtype must be float, but got is not."; } - if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa() || - common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa()) { - stds_ = common::AnfAlgo::GetNodeAttr>(kernel_node, "stds"); - } else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa()) { - float std = common::AnfAlgo::GetNodeAttr(kernel_node, "stds"); + auto stds = base_operator->GetAttr("stds"); + if (stds->isa()) { + stds_ = api::GetValue>(stds); + } else if (stds->isa()) { + float std = api::GetValue(stds); for (size_t i = 0; i < coordinate_size; i++) { (void)stds_.emplace_back(std); } @@ -84,7 +66,15 @@ void BoundingBoxEncodeCpuKernelMod::InitKernel(const CNodePtr &kernel_node) { "but got the length of 'means': " << means_.size() << ", and the length of 'stds': " << stds_.size(); } - InitTaskFunc(kernel_node); + + auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs); + auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport()); + if (!is_match) { + MS_LOG(ERROR) << "For '" << kernel_name_ << "' does not support this kernel type: " << kernel_attr; + return false; + } + kernel_func_ = func_list_[index].second; + return true; } template @@ -152,6 +142,62 @@ bool BoundingBoxEncodeCpuKernelMod::LaunchKernel(const std::vector & return true; } +int BoundingBoxEncodeCpuKernelMod::Resize(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs, + const std::map &inputsOnHost) { + if (auto ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost); ret != KRET_OK) { + return ret; + } + + auto anchor_box_shape = LongVecToSizeVec(inputs[kIndex0]->GetShapeVector()); + auto groundtruth_box_shape = LongVecToSizeVec(inputs[kIndex1]->GetShapeVector()); + + auto it_x = std::find_if(anchor_box_shape.begin(), anchor_box_shape.end(), [](int64_t sh) { return sh <= 0; }); + if (it_x != anchor_box_shape.end()) { + return KRET_UNKNOWN_SHAPE; + } + + auto anchor_box_rank = anchor_box_shape.size(); + auto groundtruth_box_rank = groundtruth_box_shape.size(); + + if (anchor_box_rank != kInputRank) { + MS_LOG(ERROR) << "The rank of anchor box must be 2, but got " << anchor_box_rank; + return KRET_RESIZE_FAILED; + } + + if (groundtruth_box_rank != kInputRank) { + MS_LOG(ERROR) << "The rank of groundtruth box must be 2, but got " << groundtruth_box_rank; + return KRET_RESIZE_FAILED; + } + + if (anchor_box_shape[1] != kLastDim) { + MS_LOG(ERROR) << "The shape of anchor box must be (n, 4), but got the second dimension of " << anchor_box_shape[1]; + return KRET_RESIZE_FAILED; + } + + if (groundtruth_box_shape[1] != kLastDim) { + MS_LOG(ERROR) << "The shape of groundtruth box must be (n, 4), but got the second dimension of " + << groundtruth_box_shape[1]; + return KRET_RESIZE_FAILED; + } + + return KRET_OK; +} + +std::vector> + BoundingBoxEncodeCpuKernelMod::func_list_ = { + {KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), + &BoundingBoxEncodeCpuKernelMod::LaunchKernel}, + {KernelAttr().AddInputAttr(kNumberTypeFloat16).AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16), + &BoundingBoxEncodeCpuKernelMod::LaunchKernel}}; + +std::vector BoundingBoxEncodeCpuKernelMod::GetOpSupport() { + std::vector support_list; + (void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list), + [](const std::pair &pair) { return pair.first; }); + return support_list; +} MS_KERNEL_FACTORY_REG(NativeCpuKernelMod, BoundingBoxEncode, BoundingBoxEncodeCpuKernelMod); } // namespace kernel } // namespace mindspore diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.h b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.h index 5bc26868ab7..ec9f6bc3197 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.h +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/boundingbox_encode_cpu_kernel.h @@ -14,10 +14,11 @@ * limitations under the License. */ -#ifndef MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_BOUNDINGBOX_ENCODE_CPU_KERNEL_H_ -#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_BOUNDINGBOX_ENCODE_CPU_KERNEL_H_ +#ifndef MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_BOUNDINGBOX_ENCODE_CPU_KERNEL_H_ +#define MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_BOUNDINGBOX_ENCODE_CPU_KERNEL_H_ #include +#include #include #include @@ -27,18 +28,22 @@ namespace mindspore { namespace kernel { constexpr size_t INPUT_NUMS = 2; -class BoundingBoxEncodeCpuKernelMod : public DeprecatedNativeCpuKernelMod { +class BoundingBoxEncodeCpuKernelMod : public NativeCpuKernelMod { public: BoundingBoxEncodeCpuKernelMod() = default; ~BoundingBoxEncodeCpuKernelMod() override = default; - void InitKernel(const CNodePtr &kernel_node) override; + bool Init(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs) override; bool Launch(const std::vector &inputs, const std::vector &workspace, const std::vector &outputs) override { return kernel_func_(this, inputs, workspace, outputs); } + int Resize(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs, const std::map &) override; + std::vector GetOpSupport() override; private: @@ -51,11 +56,10 @@ class BoundingBoxEncodeCpuKernelMod : public DeprecatedNativeCpuKernelMod { static std::vector> func_list_; BoundingBoxEncodeFunc kernel_func_; - void InitTaskFunc(const CNodePtr &kernel_node); std::vector means_; std::vector stds_; }; } // namespace kernel } // namespace mindspore -#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_BOUNDINGBOX_ENCODE_CPU_KERNEL_H_ +#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_BOUNDINGBOX_ENCODE_CPU_KERNEL_H_ diff --git a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.cc b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.cc index dda630e9db1..a7ed2e24746 100644 --- a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.cc +++ b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.cc @@ -18,9 +18,121 @@ namespace mindspore { namespace kernel { -MS_REG_GPU_KERNEL_ONE( - BoundingBoxDecode, - KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), - BoundingBoxDecodeGpuKernelMod, float) +bool BoundingBoxDecodeGpuKernelMod::Init(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs) { + MS_EXCEPTION_IF_NULL(base_operator); + kernel_name_ = base_operator->GetPrim()->name(); + constexpr size_t input_num = 2; + CHECK_KERNEL_INPUTS_NUM(inputs.size(), input_num, kernel_name_); + + const size_t coordinate_size = 4; + auto means = base_operator->GetAttr("means"); + if (means->isa()) { + means_ = api::GetValue>(means); + } else if (means->isa()) { + float mean = api::GetValue(means); + for (size_t i = 0; i < coordinate_size; i++) { + (void)means_.emplace_back(mean); + } + } else { + MS_LOG(EXCEPTION) << "For '" << kernel_name_ + << "', the input 'means' must be a tuple or a list, and dtype must be float, but got is not."; + } + + auto stds = base_operator->GetAttr("stds"); + if (stds->isa()) { + stds_ = api::GetValue>(stds); + } else if (stds->isa()) { + float std = api::GetValue(stds); + for (size_t i = 0; i < coordinate_size; i++) { + (void)stds_.emplace_back(std); + } + } else { + MS_LOG(EXCEPTION) << "For '" << kernel_name_ + << "', the input 'stds' must be a tuple or a list, and dtype must be float, but got is not."; + } + + if (means_.size() < coordinate_size || stds_.size() < coordinate_size) { + MS_LOG(EXCEPTION) << "For '" << kernel_name_ + << "', the length of input 'means' and 'stds' must be at least 4, " + "but got the length of 'means': " + << means_.size() << ", and the length of 'stds': " << stds_.size(); + } + + auto max_shape = base_operator->GetAttr("max_shape"); + std::vector max_shape_me = api::GetValue>(max_shape); + (void)std::transform(max_shape_me.begin(), max_shape_me.end(), std::back_inserter(max_shape_), + [](const int64_t &value) { return LongToInt(value); }); + auto wh_ratio_clip = base_operator->GetAttr("wh_ratio_clip"); + wh_ratio_clip_ = api::GetValue(wh_ratio_clip); + + if (max_shape_.size() < kMinMaxShapeSize) { + MS_LOG(EXCEPTION) << "For '" << kernel_name_ + << "', the length of 'max_shape' must be at least 2, but got: " << max_shape_.size(); + } + + auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs); + auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport()); + if (!is_match) { + MS_LOG(ERROR) << "For '" << kernel_name_ << "' does not support this kernel type: " << kernel_attr; + return false; + } + kernel_func_ = func_list_[index].second; + return true; +} + +int BoundingBoxDecodeGpuKernelMod::Resize(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs, + const std::map &inputsOnHost) { + if (auto ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost); ret != KRET_OK) { + return ret; + } + return KRET_OK; +} + +template +bool BoundingBoxDecodeGpuKernelMod::LaunchKernel(const std::vector &inputs, + const std::vector &workspace, + const std::vector &outputs, void *stream_ptr) { + T *rois_addr = GetDeviceAddress(inputs, 0); + T *deltas_addr = GetDeviceAddress(inputs, 1); + T *bboxes_addr = GetDeviceAddress(outputs, 0); + + if (inputs[0]->size != inputs[1]->size) { + MS_LOG(ERROR) << "For '" << kernel_name_ << "', rois box size must equal with deltas box size: " << inputs[1]->size + << ", but got " << inputs[0]->size; + return false; + } + + const size_t coordinate = 4; + const size_t block_size = inputs[0]->size / sizeof(T); + if ((block_size % coordinate) != 0) { + MS_LOG(ERROR) << "For '" << kernel_name_ << ", the size of the box should be a multiple of 4."; + return false; + } + BoundingBoxDecode(block_size / coordinate, rois_addr, deltas_addr, bboxes_addr, means_[0], means_[1], means_[2], + means_[3], stds_[0], stds_[1], stds_[2], stds_[3], max_shape_[0], max_shape_[1], wh_ratio_clip_, + reinterpret_cast(stream_ptr)); + return true; +} + +std::vector> + BoundingBoxDecodeGpuKernelMod::func_list_ = { + {KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), + &BoundingBoxDecodeGpuKernelMod::LaunchKernel}}; + +std::vector BoundingBoxDecodeGpuKernelMod::GetOpSupport() { + std::vector support_list; + (void)std::transform( + func_list_.begin(), func_list_.end(), std::back_inserter(support_list), + [](const std::pair &pair) { + return pair.first; + }); + return support_list; +} + +MS_KERNEL_FACTORY_REG(NativeGpuKernelMod, BoundingBoxDecode, BoundingBoxDecodeGpuKernelMod); } // namespace kernel } // namespace mindspore diff --git a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.h b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.h index 21566fe8fd5..2f0eddebb4a 100644 --- a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.h +++ b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_decode_gpu_kernel.h @@ -14,10 +14,12 @@ * limitations under the License. */ -#ifndef MINDSPORE_CCSRC_KERNEL_GPU_OTHER_BOUNDINGBOX_DECODE_GPU_KERNEL_H -#define MINDSPORE_CCSRC_KERNEL_GPU_OTHER_BOUNDINGBOX_DECODE_GPU_KERNEL_H +#ifndef MINDSPORE_CCSRC_PLUGIN_DEVICE_GPU_KERNEL_OTHER_BOUNDINGBOX_DECODE_GPU_KERNEL_H +#define MINDSPORE_CCSRC_PLUGIN_DEVICE_GPU_KERNEL_OTHER_BOUNDINGBOX_DECODE_GPU_KERNEL_H #include +#include +#include #include #include #include "plugin/device/gpu/kernel/cuda_impl/cuda_ops/boundingbox_decode_impl.cuh" @@ -26,128 +28,37 @@ namespace mindspore { namespace kernel { -template -class BoundingBoxDecodeGpuKernelMod : public DeprecatedNativeGpuKernelMod { +constexpr size_t kMinMaxShapeSize = 2; +class BoundingBoxDecodeGpuKernelMod : public NativeGpuKernelMod { public: - BoundingBoxDecodeGpuKernelMod() - : rois_size_(0), deltas_size_(0), bboxes_size_(0), wh_ratio_clip_(0.016), is_null_input_(false) {} + BoundingBoxDecodeGpuKernelMod() : rois_size_(0), deltas_size_(0), bboxes_size_(0), wh_ratio_clip_(0.016) {} ~BoundingBoxDecodeGpuKernelMod() override = default; bool Launch(const std::vector &inputs, const std::vector &workspace, const std::vector &outputs, void *stream_ptr) override { - if (is_null_input_) { - return true; - } - T *rois_addr = GetDeviceAddress(inputs, 0); - T *deltas_addr = GetDeviceAddress(inputs, 1); - T *bboxes_addr = GetDeviceAddress(outputs, 0); - - if (inputs[0]->size != inputs[1]->size) { - MS_LOG(ERROR) << "For '" << kernel_name_ - << "', rois box size must equal with deltas box size: " << inputs[1]->size << ", but got " - << inputs[0]->size; - return false; - } - - const size_t coordinate = 4; - const size_t block_size = inputs[0]->size / sizeof(T); - if ((block_size % coordinate) != 0) { - MS_LOG(ERROR) << "For '" << kernel_name_ << ", the size of the box should be a multiple of 4."; - return false; - } - - BoundingBoxDecode(block_size / coordinate, rois_addr, deltas_addr, bboxes_addr, means_[0], means_[1], means_[2], - means_[3], stds_[0], stds_[1], stds_[2], stds_[3], max_shape_[0], max_shape_[1], wh_ratio_clip_, - reinterpret_cast(stream_ptr)); - return true; + return kernel_func_(this, inputs, workspace, outputs, stream_ptr); } - bool Init(const CNodePtr &kernel_node) override { - kernel_name_ = common::AnfAlgo::GetCNodeName(kernel_node); - kernel_node_ = kernel_node; - MS_EXCEPTION_IF_NULL(kernel_node); - size_t input_num = common::AnfAlgo::GetInputTensorNum(kernel_node); - if (input_num != 2) { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the number of inputs should be 2, but got " << input_num; - } - rois_size_ = sizeof(T); - deltas_size_ = sizeof(T); - bboxes_size_ = sizeof(T); + bool Init(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs) override; - auto logits_shape = common::AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); - auto labels_shape = common::AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 1); - auto output_shape = common::AnfAlgo::GetOutputInferShape(kernel_node, 0); - is_null_input_ = CHECK_SHAPE_NULL(logits_shape, kernel_name_, "anchor_box") || - CHECK_SHAPE_NULL(labels_shape, kernel_name_, "deltas") || - CHECK_SHAPE_NULL(output_shape, kernel_name_, "output"); - if (is_null_input_) { - InitSizeLists(); - return true; - } - for (size_t i = 0; i < logits_shape.size(); i++) { - rois_size_ *= logits_shape[i]; - } - rois_size_ *= SizeOf(logits_shape); - deltas_size_ *= SizeOf(labels_shape); - bboxes_size_ *= SizeOf(output_shape); - - InitSizeLists(); - - const size_t coordinate_size = 4; - auto prim = common::AnfAlgo::GetCNodePrimitive(kernel_node); - MS_EXCEPTION_IF_NULL(prim); - auto means = prim->GetAttr("means"); - MS_EXCEPTION_IF_NULL(means); - if (means->isa() || means->isa()) { - means_ = GetAttr>(kernel_node, "means"); - } else if (means->isa()) { - float mean = GetAttr(kernel_node, "means"); - for (size_t i = 0; i < coordinate_size; i++) { - means_.emplace_back(mean); - } - } else { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', attribute means type is invalid."; - } - - auto stds = prim->GetAttr("stds"); - MS_EXCEPTION_IF_NULL(stds); - if (stds->isa() || stds->isa()) { - stds_ = GetAttr>(kernel_node, "stds"); - } else if (stds->isa()) { - float std = GetAttr(kernel_node, "stds"); - for (size_t i = 0; i < coordinate_size; i++) { - stds_.emplace_back(std); - } - } else { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', attribute stds type is invalid."; - } - - std::vector max_shape_me = GetAttr>(kernel_node, "max_shape"); - (void)std::transform(max_shape_me.begin(), max_shape_me.end(), std::back_inserter(max_shape_), - [](const int64_t &value) { return static_cast(value); }); - wh_ratio_clip_ = GetAttr(kernel_node, "wh_ratio_clip"); - - if (means_.size() < coordinate_size || stds_.size() < coordinate_size) { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the both size of means or stds cannot be less than 4, but got" - << " the size of means: " << means_.size() << ", the size of stds: " << stds_.size(); - } - - if (max_shape_.size() < 2) { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the size of max_shape cannot be less than 2, but got " - << max_shape_.size(); - } - - return true; - } + int Resize(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs, + const std::map &inputsOnHost) override; protected: - void InitSizeLists() override { - input_size_list_.push_back(rois_size_); - input_size_list_.push_back(deltas_size_); - output_size_list_.push_back(bboxes_size_); - } + std::vector GetOpSupport() override; + template + bool LaunchKernel(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, void *stream_ptr); + using BoundingBoxDecodeLaunchFunc = + std::function &, + const std::vector &, const std::vector &, void *)>; private: + std::string kernel_name_{}; + BoundingBoxDecodeLaunchFunc kernel_func_; + static std::vector> func_list_; size_t rois_size_; size_t deltas_size_; size_t bboxes_size_; @@ -155,9 +66,8 @@ class BoundingBoxDecodeGpuKernelMod : public DeprecatedNativeGpuKernelMod { std::vector stds_; std::vector max_shape_; float wh_ratio_clip_; - bool is_null_input_; }; } // namespace kernel } // namespace mindspore -#endif // MINDSPORE_CCSRC_KERNEL_GPU_OTHER_BOUNDINGBOX_DECODE_GPU_KERNEL_H +#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_GPU_KERNEL_OTHER_BOUNDINGBOX_DECODE_GPU_KERNEL_H diff --git a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.cc b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.cc index 5d096c8995f..86776f26f7a 100644 --- a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.cc +++ b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.cc @@ -18,9 +18,111 @@ namespace mindspore { namespace kernel { -MS_REG_GPU_KERNEL_ONE( - BoundingBoxEncode, - KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), - BoundingBoxEncodeGpuKernelMod, float) +bool BoundingBoxEncodeGpuKernelMod::Init(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs) { + MS_EXCEPTION_IF_NULL(base_operator); + kernel_name_ = base_operator->GetPrim()->name(); + constexpr size_t input_num = 2; + CHECK_KERNEL_INPUTS_NUM(inputs.size(), input_num, kernel_name_); + + const size_t coordinate_size = 4; + auto means = base_operator->GetAttr("means"); + if (means->isa()) { + means_ = api::GetValue>(means); + } else if (means->isa()) { + float mean = api::GetValue(means); + for (size_t i = 0; i < coordinate_size; i++) { + (void)means_.emplace_back(mean); + } + } else { + MS_LOG(EXCEPTION) << "For '" << kernel_name_ + << "', the input 'means' must be a tuple or a list, and dtype must be float, but got is not."; + } + + auto stds = base_operator->GetAttr("stds"); + if (stds->isa()) { + stds_ = api::GetValue>(stds); + } else if (stds->isa()) { + float std = api::GetValue(stds); + for (size_t i = 0; i < coordinate_size; i++) { + (void)stds_.emplace_back(std); + } + } else { + MS_LOG(EXCEPTION) << "For '" << kernel_name_ + << "', the input 'stds' must be a tuple or a list, and dtype must be float, but got is not."; + } + + if (means_.size() < coordinate_size || stds_.size() < coordinate_size) { + MS_LOG(EXCEPTION) << "For '" << kernel_name_ + << "', the length of input 'means' and 'stds' must be at least 4, " + "but got the length of 'means': " + << means_.size() << ", and the length of 'stds': " << stds_.size(); + } + + auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs); + auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport()); + if (!is_match) { + MS_LOG(ERROR) << "For '" << kernel_name_ << "' does not support this kernel type: " << kernel_attr; + return false; + } + kernel_func_ = func_list_[index].second; + return true; +} + +int BoundingBoxEncodeGpuKernelMod::Resize(const BaseOperatorPtr &base_operator, + const std::vector &inputs, + const std::vector &outputs, + const std::map &inputsOnHost) { + if (auto ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost); ret != KRET_OK) { + return ret; + } + return KRET_OK; +} + +template +bool BoundingBoxEncodeGpuKernelMod::LaunchKernel(const std::vector &inputs, + const std::vector &workspace, + const std::vector &outputs, void *stream_ptr) { + T *anchor_addr = GetDeviceAddress(inputs, 0); + T *groundtruth_addr = GetDeviceAddress(inputs, 1); + T *deltas_addr = GetDeviceAddress(outputs, 0); + + if (inputs[0]->size != inputs[1]->size) { + MS_LOG(ERROR) << "For '" << kernel_name_ + << "', anchor box size must equal with groundtruth box size: " << inputs[1]->size << ", but got " + << inputs[0]->size; + return false; + } + + const size_t coordinate = 4; + const size_t block_size = inputs[0]->size / sizeof(T); + if ((block_size % coordinate) != 0) { + MS_LOG(ERROR) << "For '" << kernel_name_ << ", the size of the box should be a multiple of 4."; + return false; + } + + BoundingBoxEncode(block_size / coordinate, anchor_addr, groundtruth_addr, deltas_addr, means_[0], means_[1], + means_[2], means_[3], stds_[0], stds_[1], stds_[2], stds_[3], + reinterpret_cast(stream_ptr)); + return true; +} + +std::vector> + BoundingBoxEncodeGpuKernelMod::func_list_ = { + {KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), + &BoundingBoxEncodeGpuKernelMod::LaunchKernel}}; + +std::vector BoundingBoxEncodeGpuKernelMod::GetOpSupport() { + std::vector support_list; + (void)std::transform( + func_list_.begin(), func_list_.end(), std::back_inserter(support_list), + [](const std::pair &pair) { + return pair.first; + }); + return support_list; +} + +MS_KERNEL_FACTORY_REG(NativeGpuKernelMod, BoundingBoxEncode, BoundingBoxEncodeGpuKernelMod); } // namespace kernel } // namespace mindspore diff --git a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.h b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.h index ae9212ff02b..8bf329b463e 100644 --- a/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.h +++ b/mindspore/ccsrc/plugin/device/gpu/kernel/other/boundingbox_encode_gpu_kernel.h @@ -14,131 +14,55 @@ * limitations under the License. */ -#ifndef MINDSPORE_CCSRC_KERNEL_GPU_OTHER_BOUNDINGBOX_ENCODE_GPU_KERNEL_H -#define MINDSPORE_CCSRC_KERNEL_GPU_OTHER_BOUNDINGBOX_ENCODE_GPU_KERNEL_H +#ifndef MINDSPORE_CCSRC_PLUGIN_DEVICE_GPU_KERNEL_OTHER_BOUNDINGBOX_ENCODE_GPU_KERNEL_H +#define MINDSPORE_CCSRC_PLUGIN_DEVICE_GPU_KERNEL_OTHER_BOUNDINGBOX_ENCODE_GPU_KERNEL_H #include +#include +#include #include +#include #include "plugin/device/gpu/kernel/cuda_impl/cuda_ops/boundingbox_encode_impl.cuh" #include "plugin/device/gpu/kernel/gpu_kernel.h" #include "plugin/device/gpu/kernel/gpu_kernel_factory.h" namespace mindspore { namespace kernel { -template -class BoundingBoxEncodeGpuKernelMod : public DeprecatedNativeGpuKernelMod { +class BoundingBoxEncodeGpuKernelMod : public NativeGpuKernelMod { public: - BoundingBoxEncodeGpuKernelMod() : anchor_size_(0), groundtruth_size_(0), deltas_size_(0), is_null_input_(false) {} + BoundingBoxEncodeGpuKernelMod() : anchor_size_(0), groundtruth_size_(0), deltas_size_(0) {} ~BoundingBoxEncodeGpuKernelMod() override = default; bool Launch(const std::vector &inputs, const std::vector &workspace, const std::vector &outputs, void *stream_ptr) override { - if (is_null_input_) { - return true; - } - T *anchor_addr = GetDeviceAddress(inputs, 0); - T *groundtruth_addr = GetDeviceAddress(inputs, 1); - T *deltas_addr = GetDeviceAddress(outputs, 0); - - if (inputs[0]->size != inputs[1]->size) { - MS_LOG(ERROR) << "For '" << kernel_name_ - << "', anchor box size must equal with groundtruth box size: " << inputs[1]->size << ", but got " - << inputs[0]->size; - return false; - } - - const size_t coordinate = 4; - const size_t block_size = inputs[0]->size / sizeof(T); - if ((block_size % coordinate) != 0) { - MS_LOG(ERROR) << "For '" << kernel_name_ << ", the size of the box should be a multiple of 4."; - return false; - } - - BoundingBoxEncode(block_size / coordinate, anchor_addr, groundtruth_addr, deltas_addr, means_[0], means_[1], - means_[2], means_[3], stds_[0], stds_[1], stds_[2], stds_[3], - reinterpret_cast(stream_ptr)); - return true; + return kernel_func_(this, inputs, workspace, outputs, stream_ptr); } - bool Init(const CNodePtr &kernel_node) override { - kernel_name_ = common::AnfAlgo::GetCNodeName(kernel_node); - kernel_node_ = kernel_node; - MS_EXCEPTION_IF_NULL(kernel_node); - size_t input_num = common::AnfAlgo::GetInputTensorNum(kernel_node); - if (input_num != 2) { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the number of inputs should be 2, but got " << input_num; - } - anchor_size_ = sizeof(T); - groundtruth_size_ = sizeof(T); - deltas_size_ = sizeof(T); + bool Init(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs) override; - auto logits_shape = common::AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0); - auto labels_shape = common::AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 1); - auto output_shape = common::AnfAlgo::GetOutputInferShape(kernel_node, 0); - is_null_input_ = CHECK_SHAPE_NULL(logits_shape, kernel_name_, "anchor_box") || - CHECK_SHAPE_NULL(labels_shape, kernel_name_, "groundtruth_box") || - CHECK_SHAPE_NULL(output_shape, kernel_name_, "output"); - if (is_null_input_) { - InitSizeLists(); - return true; - } - - anchor_size_ *= SizeOf(logits_shape); - groundtruth_size_ *= SizeOf(labels_shape); - deltas_size_ *= SizeOf(output_shape); - - InitSizeLists(); - - const size_t coordinate_size = 4; - auto prim = common::AnfAlgo::GetCNodePrimitive(kernel_node); - MS_EXCEPTION_IF_NULL(prim); - auto means = prim->GetAttr("means"); - MS_EXCEPTION_IF_NULL(means); - if (means->isa() || means->isa()) { - means_ = GetAttr>(kernel_node, "means"); - } else if (means->isa()) { - float mean = GetAttr(kernel_node, "means"); - for (size_t i = 0; i < coordinate_size; i++) { - means_.emplace_back(mean); - } - } else { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', attribute means type is invalid."; - } - auto stds = prim->GetAttr("stds"); - MS_EXCEPTION_IF_NULL(stds); - if (stds->isa() || stds->isa()) { - stds_ = GetAttr>(kernel_node, "stds"); - } else if (stds->isa()) { - float std = GetAttr(kernel_node, "stds"); - for (size_t i = 0; i < coordinate_size; i++) { - stds_.emplace_back(std); - } - } else { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', attribute stds type is invalid."; - } - - if (means_.size() < coordinate_size || stds_.size() < coordinate_size) { - MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the both size of means or stds cannot be less than 4, but got" - << " the size of means: " << means_.size() << ", the size of stds: " << stds_.size(); - } - - return true; - } + int Resize(const BaseOperatorPtr &base_operator, const std::vector &inputs, + const std::vector &outputs, + const std::map &inputsOnHost) override; protected: - void InitSizeLists() override { - input_size_list_.push_back(anchor_size_); - input_size_list_.push_back(groundtruth_size_); - output_size_list_.push_back(deltas_size_); - } + std::vector GetOpSupport() override; + template + bool LaunchKernel(const std::vector &inputs, const std::vector &workspace, + const std::vector &outputs, void *stream_ptr); + using BoundingBoxEncodeLaunchFunc = + std::function &, + const std::vector &, const std::vector &, void *)>; private: + std::string kernel_name_{}; + BoundingBoxEncodeLaunchFunc kernel_func_; + static std::vector> func_list_; size_t anchor_size_; size_t groundtruth_size_; size_t deltas_size_; std::vector means_; std::vector stds_; - bool is_null_input_; }; } // namespace kernel } // namespace mindspore diff --git a/mindspore/core/ops/bounding_box_decode.cc b/mindspore/core/ops/bounding_box_decode.cc index be7d9f3b984..23ef4ef5e25 100644 --- a/mindspore/core/ops/bounding_box_decode.cc +++ b/mindspore/core/ops/bounding_box_decode.cc @@ -31,7 +31,6 @@ abstract::ShapePtr BoundingBoxDecodeInferShape(const PrimitivePtr &primitive, const std::vector &input_args) { MS_EXCEPTION_IF_NULL(primitive); auto prim_name = primitive->name(); - auto anchor_box = input_args[0]->BuildShape(); auto deltas = input_args[1]->BuildShape(); diff --git a/mindspore/core/ops/bounding_box_encode.cc b/mindspore/core/ops/bounding_box_encode.cc new file mode 100644 index 00000000000..307da9a4e26 --- /dev/null +++ b/mindspore/core/ops/bounding_box_encode.cc @@ -0,0 +1,116 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ops/bounding_box_encode.h" + +#include +#include + +#include "abstract/ops/primitive_infer_map.h" +#include "ops/op_utils.h" +#include "utils/check_convert_utils.h" +#include "mindapi/src/helper.h" + +namespace mindspore { +namespace ops { +namespace { +abstract::ShapePtr BoundingBoxEncodeInferShape(const PrimitivePtr &primitive, + const std::vector &input_args) { + MS_EXCEPTION_IF_NULL(primitive); + auto prim_name = primitive->name(); + + auto anchor_box = input_args[0]->BuildShape(); + auto groundtruth_box = input_args[1]->BuildShape(); + + MS_EXCEPTION_IF_NULL(anchor_box); + MS_EXCEPTION_IF_NULL(groundtruth_box); + + const int64_t input_num = 2; + (void)CheckAndConvertUtils::CheckInteger("arg size", SizeToLong(input_args.size()), kEqual, input_num, prim_name); + + auto anchor_box_shape = CheckAndConvertUtils::ConvertShapePtrToShapeMap(input_args[0]->BuildShape())[kShape]; + auto groundtruth_box_shape = CheckAndConvertUtils::ConvertShapePtrToShapeMap(input_args[1]->BuildShape())[kShape]; + + const int64_t kShapeSize = 2; + (void)CheckAndConvertUtils::CheckInteger("anchor box rank", SizeToLong(anchor_box_shape.size()), kEqual, kShapeSize, + prim_name); + (void)CheckAndConvertUtils::CheckInteger("groundtruth box rank", SizeToLong(groundtruth_box_shape.size()), kEqual, + kShapeSize, prim_name); + + if (anchor_box_shape[0] != groundtruth_box_shape[0]) { + MS_EXCEPTION(ValueError) + << "For '" << prim_name + << "', 'anchor_box' and 'groundtruth_box' must have the same first dimension. But got anchor_box_shape[0]: " + << anchor_box_shape[0] << ", groundtruth_box_shape[0]: " << groundtruth_box_shape[0] << "."; + } + + const int64_t last_dimension = 4; + if (anchor_box_shape[1] != last_dimension) { + MS_EXCEPTION(ValueError) << "For '" << prim_name + << "', 'anchor_box' last dimension must be 4, but got: " << anchor_box_shape[1] << "."; + } + if (groundtruth_box_shape[1] != last_dimension) { + MS_EXCEPTION(ValueError) << "For '" << prim_name + << "', 'groundtruth_box' last dimension must be 4, but got: " << groundtruth_box_shape[1] + << "."; + } + + auto x_shape = anchor_box->cast(); + MS_EXCEPTION_IF_NULL(x_shape); + return x_shape; +} + +TypePtr BoundingBoxEncodeInferType(const PrimitivePtr &primitive, const std::vector &input_args) { + MS_EXCEPTION_IF_NULL(primitive); + auto prim_name = primitive->name(); + + for (const auto &item : input_args) { + MS_EXCEPTION_IF_NULL(item); + } + + std::set valid_x_type; + (void)valid_x_type.emplace(kFloat16); + (void)valid_x_type.emplace(kFloat32); + + for (size_t i = 0; i < input_args.size(); i++) { + auto x_type = input_args[i]->BuildType(); + MS_EXCEPTION_IF_NULL(x_type); + (void)CheckAndConvertUtils::CheckTensorTypeValid("x_dtype", x_type, valid_x_type, prim_name); + } + + std::map types; + (void)types.emplace("anchor_box", input_args[0]->BuildType()); + (void)types.emplace("groundtruth_box", input_args[1]->BuildType()); + + return CheckAndConvertUtils::CheckTensorTypeSame(types, common_valid_types, prim_name); +} +} // namespace + +MIND_API_OPERATOR_IMPL(BoundingBoxEncode, BaseOperator); +AbstractBasePtr BoundingBoxEncodeInfer(const abstract::AnalysisEnginePtr &, const PrimitivePtr &primitive, + const std::vector &input_args) { + MS_EXCEPTION_IF_NULL(primitive); + + const int64_t kInputNum = 2; + CheckAndConvertUtils::CheckInputArgs(input_args, kEqual, kInputNum, primitive->name()); + + auto infer_type = BoundingBoxEncodeInferType(primitive, input_args); + auto infer_shape = BoundingBoxEncodeInferShape(primitive, input_args); + return abstract::MakeAbstract(infer_shape, infer_type); +} +REGISTER_PRIMITIVE_EVAL_IMPL(BoundingBoxEncode, prim::kPrimBoundingBoxEncode, BoundingBoxEncodeInfer, nullptr, true); +} // namespace ops +} // namespace mindspore diff --git a/mindspore/core/ops/bounding_box_encode.h b/mindspore/core/ops/bounding_box_encode.h new file mode 100644 index 00000000000..05aaaf98aa8 --- /dev/null +++ b/mindspore/core/ops/bounding_box_encode.h @@ -0,0 +1,44 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CORE_OPS_BOUNDING_BOX_ENCODE_H_ +#define MINDSPORE_CORE_OPS_BOUNDING_BOX_ENCODE_H_ + +#include +#include +#include +#include + +#include "ops/base_operator.h" +#include "mindapi/base/types.h" + +namespace mindspore { +namespace ops { +constexpr auto kNameBoundingBoxEncode = "BoundingBoxEncode"; +class MIND_API BoundingBoxEncode : public BaseOperator { + public: + MIND_API_BASE_MEMBER(BoundingBoxEncode); + BoundingBoxEncode() : BaseOperator(kNameBoundingBoxEncode) { + InitIOName({"anchor_box", "groundtruth_box"}, {"output"}); + } +}; + +abstract::AbstractBasePtr BoundingBoxEncodeInfer(const abstract::AnalysisEnginePtr &, const PrimitivePtr &primitive, + const std::vector &input_args); +} // namespace ops +} // namespace mindspore + +#endif // MINDSPORE_CORE_OPS_BOUNDING_BOX_ENCODE_H_ diff --git a/mindspore/core/ops/core_ops.h b/mindspore/core/ops/core_ops.h index 11a9c3ab002..9245a926fca 100644 --- a/mindspore/core/ops/core_ops.h +++ b/mindspore/core/ops/core_ops.h @@ -914,6 +914,7 @@ GVAR_DEF(PrimitivePtr, kPrimSparseApplyRMSProp, std::make_shared("Spa GVAR_DEF(PrimitivePtr, kPrimApplyKerasMomentum, std::make_shared("ApplyKerasMomentum")); GVAR_DEF(PrimitivePtr, kPrimLARSUpdate, std::make_shared("LARSUpdate")); GVAR_DEF(PrimitivePtr, kPrimBoundingBoxDecode, std::make_shared("BoundingBoxDecode")); +GVAR_DEF(PrimitivePtr, kPrimBoundingBoxEncode, std::make_shared("BoundingBoxEncode")); GVAR_DEF(PrimitivePtr, kPrimROIAlign, std::make_shared("ROIAlign")); GVAR_DEF(PrimitivePtr, kPrimApplyAddSign, std::make_shared("ApplyAddSign")); GVAR_DEF(PrimitivePtr, kPrimApplyAdagrad, std::make_shared("ApplyAdagrad")); diff --git a/mindspore/lite/test/config_level0/cropped_size.cfg b/mindspore/lite/test/config_level0/cropped_size.cfg index 3339ece8461..87b4107f21f 100644 --- a/mindspore/lite/test/config_level0/cropped_size.cfg +++ b/mindspore/lite/test/config_level0/cropped_size.cfg @@ -1,2 +1,2 @@ Note: This is the mindspore Lite inference framework size threshold. Offline review is required before modify this value!!! -1083704 +1085704 diff --git a/mindspore/python/mindspore/ops/operations/other_ops.py b/mindspore/python/mindspore/ops/operations/other_ops.py index e3e1da5e96d..9ac8f003bb6 100644 --- a/mindspore/python/mindspore/ops/operations/other_ops.py +++ b/mindspore/python/mindspore/ops/operations/other_ops.py @@ -153,20 +153,6 @@ class BoundingBoxEncode(PrimitiveWithInfer): validator.check_equal_int(len(means), 4, "means len", self.name) validator.check_equal_int(len(stds), 4, "stds len", self.name) - def infer_shape(self, anchor_box, groundtruth_box): - validator.check('anchor_box shape[0]', anchor_box[0], 'groundtruth_box shape[0]', groundtruth_box[0], Rel.EQ, - self.name) - validator.check("anchor_box rank", len(anchor_box), "", 2, Rel.EQ, self.name) - validator.check("groundtruth_box rank", len(groundtruth_box), "", 2, Rel.EQ, self.name) - validator.check_equal_int(anchor_box[1], 4, 'anchor_box shape[1]', self.name) - validator.check_equal_int(groundtruth_box[1], 4, 'groundtruth_box shape[1]', self.name) - return anchor_box - - def infer_dtype(self, anchor_box, groundtruth_box): - args = {"anchor_box": anchor_box, "groundtruth_box": groundtruth_box} - validator.check_tensors_dtypes_same_and_valid(args, mstype.number_type, self.name) - return anchor_box - class BartlettWindow(Primitive): r""" @@ -662,6 +648,7 @@ class CheckBprop(PrimitiveWithInfer): self.prim_to_check = prim_to_check def infer_shape(self, xshapes, yshapes): + """infer shape""" tips = f"user defined method 'bprop'" validator.check_value_type('grads', xshapes, (tuple,), tips) validator.check_value_type('params', yshapes, (tuple,), tips) @@ -682,6 +669,7 @@ class CheckBprop(PrimitiveWithInfer): return xshapes def infer_dtype(self, xdtypes, ydtypes): + """infer dtype""" tips = f"user defined method 'bprop'" validator.check_value_type('grads', xdtypes, (tuple,), tips) validator.check_value_type('params', ydtypes, (tuple,), tips) diff --git a/tests/st/ops/cpu/test_boundingbox_decode_op.py b/tests/st/ops/cpu/test_boundingbox_decode_op.py index 40aeda5462a..378b3ded9d5 100644 --- a/tests/st/ops/cpu/test_boundingbox_decode_op.py +++ b/tests/st/ops/cpu/test_boundingbox_decode_op.py @@ -92,5 +92,31 @@ def test_bounding_box_decode_functional_modes(): test_bounding_box_decode_functional() -if __name__ == '__main__': - test_bounding_box_decode_functional_modes() +@pytest.mark.level0 +@pytest.mark.platform_x86_cpu +@pytest.mark.env_onecard +def test_dynamic_shape_boundingbox_decode(): + """ + Feature: Test dynamic shape of BoundingBoxDecode operator + Description: dynamic input + Expectation: success. + """ + anchor = np.array([[4, 1, 2, 1], [2, 2, 2, 3]], np.float32) + deltas = np.array([[3, 1, 2, 2], [1, 2, 1, 4]], np.float32) + means = (0.1, 0.1, 0.2, 0.2) + stds = (2.0, 2.0, 3.0, 3.0) + anchor_box = Tensor(anchor, mindspore.float32) + deltas_box = Tensor(deltas, mindspore.float32) + expect_deltas = np.array([[28.6500, 0.0000, 0.0000, 33.8500], + [0.0000, 0.0000, 15.8663, 72.7000]], np.float32) + + error = np.ones(shape=[2, 4]) * 1.0e-4 + + context.set_context(mode=context.GRAPH_MODE, device_target='CPU') + boundingbox_decode = NetBoundingBoxDecode(means, stds) + input_dyn = Tensor(shape=[None, 4], dtype=anchor_box.dtype) + deltas_box_dyn = Tensor(shape=[None, 4], dtype=deltas_box.dtype) + boundingbox_decode.set_inputs(input_dyn, deltas_box_dyn) + output = boundingbox_decode(anchor_box, deltas_box) + diff = output.asnumpy() - expect_deltas + assert np.all(abs(diff) < error) diff --git a/tests/st/ops/cpu/test_boundingbox_encode_op.py b/tests/st/ops/cpu/test_boundingbox_encode_op.py index b9fc256a6b2..fe8231bb837 100644 --- a/tests/st/ops/cpu/test_boundingbox_encode_op.py +++ b/tests/st/ops/cpu/test_boundingbox_encode_op.py @@ -112,5 +112,29 @@ def test_bounding_box_encode_functional_modes(): test_bounding_box_encode_functional() -if __name__ == '__main__': - test_bounding_box_encode_functional_modes() +@pytest.mark.level0 +@pytest.mark.platform_x86_cpu +@pytest.mark.env_onecard +def test_dynamic_shape_boundingbox_encode(): + """ + Feature: Test dynamic shape of BoundingBoxEncode operator + Description: dynamic input + Expectation: success. + """ + anchor = np.array([[4, 1, 6, 9], [2, 5, 5, 9]]).astype(np.float32) + gt = np.array([[3, 2, 7, 7], [1, 5, 5, 8]]).astype(np.float32) + means = (0.1, 0.1, 0.2, 0.2) + stds = (2.0, 2.0, 3.0, 3.0) + anchor_box = Tensor(anchor, mindspore.float32) + groundtruth_box = Tensor(gt, mindspore.float32) + expect_deltas = bbox2delta(anchor, gt, means, stds) + + error = np.ones(shape=[2, 4]) * 1.0e-6 + context.set_context(mode=context.GRAPH_MODE, device_target='CPU') + boundingbox_encode = NetBoundingBoxEncode(means, stds) + input_dyn = Tensor(shape=[None, 4], dtype=anchor_box.dtype) + groundtruth_box_dyn = Tensor(shape=[None, 4], dtype=groundtruth_box.dtype) + boundingbox_encode.set_inputs(input_dyn, groundtruth_box_dyn) + output = boundingbox_encode(anchor_box, groundtruth_box) + diff = output.asnumpy() - expect_deltas + assert np.all(abs(diff) < error) diff --git a/tests/st/ops/gpu/test_boundingbox_decode_op.py b/tests/st/ops/gpu/test_boundingbox_decode_op.py index 9bbcbcb79d8..a878dbb67ac 100644 --- a/tests/st/ops/gpu/test_boundingbox_decode_op.py +++ b/tests/st/ops/gpu/test_boundingbox_decode_op.py @@ -90,3 +90,33 @@ def test_bounding_box_decode_functional_modes(): test_bounding_box_decode_functional() context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU") test_bounding_box_decode_functional() + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_dynamic_shape_boundingbox_decode(): + """ + Feature: Test dynamic shape of BoundingBoxDecode operator + Description: dynamic input + Expectation: success. + """ + anchor = np.array([[4, 1, 2, 1], [2, 2, 2, 3]], np.float32) + deltas = np.array([[3, 1, 2, 2], [1, 2, 1, 4]], np.float32) + means = (0.1, 0.1, 0.2, 0.2) + stds = (2.0, 2.0, 3.0, 3.0) + anchor_box = Tensor(anchor, mindspore.float32) + deltas_box = Tensor(deltas, mindspore.float32) + expect_deltas = np.array([[28.6500, 0.0000, 0.0000, 33.8500], + [0.0000, 0.0000, 15.8663, 72.7000]], np.float32) + + error = np.ones(shape=[2, 4]) * 1.0e-4 + + context.set_context(mode=context.GRAPH_MODE, device_target='GPU') + boundingbox_decode = NetBoundingBoxDecode(means, stds) + input_dyn = Tensor(shape=[None, 4], dtype=anchor_box.dtype) + deltas_box_dyn = Tensor(shape=[None, 4], dtype=deltas_box.dtype) + boundingbox_decode.set_inputs(input_dyn, deltas_box_dyn) + output = boundingbox_decode(anchor_box, deltas_box) + diff = output.asnumpy() - expect_deltas + assert np.all(abs(diff) < error) diff --git a/tests/st/ops/gpu/test_boundingbox_encode_op.py b/tests/st/ops/gpu/test_boundingbox_encode_op.py index 1e93ce9e7e1..54cd1f7650b 100644 --- a/tests/st/ops/gpu/test_boundingbox_encode_op.py +++ b/tests/st/ops/gpu/test_boundingbox_encode_op.py @@ -110,3 +110,31 @@ def test_bounding_box_encode_functional_modes(): test_bounding_box_encode_functional() context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU") test_bounding_box_encode_functional() + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_dynamic_shape_boundingbox_encode(): + """ + Feature: Test dynamic shape of BoundingBoxEncode operator + Description: dynamic input + Expectation: success. + """ + anchor = np.array([[4, 1, 6, 9], [2, 5, 5, 9]]).astype(np.float32) + gt = np.array([[3, 2, 7, 7], [1, 5, 5, 8]]).astype(np.float32) + means = (0.1, 0.1, 0.2, 0.2) + stds = (2.0, 2.0, 3.0, 3.0) + anchor_box = Tensor(anchor, mindspore.float32) + groundtruth_box = Tensor(gt, mindspore.float32) + expect_deltas = bbox2delta(anchor, gt, means, stds) + + error = np.ones(shape=[2, 4]) * 1.0e-6 + context.set_context(mode=context.GRAPH_MODE, device_target='GPU') + boundingbox_encode = NetBoundingBoxEncode(means, stds) + input_dyn = Tensor(shape=[None, 4], dtype=anchor_box.dtype) + groundtruth_box_dyn = Tensor(shape=[None, 4], dtype=groundtruth_box.dtype) + boundingbox_encode.set_inputs(input_dyn, groundtruth_box_dyn) + output = boundingbox_encode(anchor_box, groundtruth_box) + diff = output.asnumpy() - expect_deltas + assert np.all(abs(diff) < error)