add dynamic shape of BoundingBoxEncode and BoundingBoxDecode.

This commit is contained in:
ZhidanLiu 2022-09-19 00:21:17 +08:00
parent 9b4db1b646
commit bb4dfa4b69
18 changed files with 728 additions and 324 deletions

View File

@ -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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &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<ValueTuple>() ||
common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa<ValueList>()) {
means_ = common::AnfAlgo::GetNodeAttr<std::vector<float>>(kernel_node, "means");
} else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa<FloatImm>()) {
float mean = common::AnfAlgo::GetNodeAttr<float>(kernel_node, "means");
auto means = base_operator->GetAttr("means");
if (means->isa<api::ValueSequence>()) {
means_ = api::GetValue<std::vector<float>>(means);
} else if (means->isa<api::FloatImm>()) {
float mean = api::GetValue<float>(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<ValueTuple>() ||
common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa<ValueList>()) {
stds_ = common::AnfAlgo::GetNodeAttr<std::vector<float>>(kernel_node, "stds");
} else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa<FloatImm>()) {
float std = common::AnfAlgo::GetNodeAttr<float>(kernel_node, "stds");
auto stds = base_operator->GetAttr("stds");
if (stds->isa<api::ValueSequence>()) {
stds_ = api::GetValue<std::vector<float>>(stds);
} else if (stds->isa<api::FloatImm>()) {
float std = api::GetValue<float>(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<int64_t> max_shape_me = common::AnfAlgo::GetNodeAttr<std::vector<int64_t>>(kernel_node, "max_shape");
auto max_shape = base_operator->GetAttr("max_shape");
std::vector<int64_t> max_shape_me = api::GetValue<std::vector<int64_t>>(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<float>(kernel_node, "wh_ratio_clip");
auto wh_ratio_clip = base_operator->GetAttr("wh_ratio_clip");
wh_ratio_clip_ = api::GetValue<float>(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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &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 <typename T>
@ -165,15 +221,6 @@ std::vector<std::pair<KernelAttr, BoundingBoxDecodeCpuKernelMod::BoundingBoxDeco
{KernelAttr().AddInputAttr(kNumberTypeFloat16).AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16),
&BoundingBoxDecodeCpuKernelMod::LaunchKernel<float16>}};
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<KernelAttr> BoundingBoxDecodeCpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
(void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list),

View File

@ -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 <vector>
#include <algorithm>
#include <utility>
#include <map>
#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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) override;
bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs) override {
return kernel_func_(this, inputs, workspace, outputs);
}
int Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs, const std::map<uint32_t, tensor::TensorPtr> &) override;
std::vector<KernelAttr> GetOpSupport() override;
private:
void InitTaskFunc(const CNodePtr &kernel_node);
template <typename T>
bool LaunchKernel(const std::vector<kernel::AddressPtr> &inputs, const std::vector<kernel::AddressPtr> &workspace,
const std::vector<kernel::AddressPtr> &outputs);
@ -55,10 +58,10 @@ class BoundingBoxDecodeCpuKernelMod : public DeprecatedNativeCpuKernelMod {
std::vector<float> means_;
std::vector<float> stds_;
std::vector<int> max_shape_;
std::vector<size_t> 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_

View File

@ -20,43 +20,25 @@
namespace mindspore {
namespace kernel {
std::vector<std::pair<KernelAttr, BoundingBoxEncodeCpuKernelMod::BoundingBoxEncodeFunc>>
BoundingBoxEncodeCpuKernelMod::func_list_ = {
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32),
&BoundingBoxEncodeCpuKernelMod::LaunchKernel<float>},
{KernelAttr().AddInputAttr(kNumberTypeFloat16).AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16),
&BoundingBoxEncodeCpuKernelMod::LaunchKernel<float16>}};
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<KernelAttr> BoundingBoxEncodeCpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
(void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, BoundingBoxEncodeFunc> &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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &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<ValueTuple>() ||
common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa<ValueList>()) {
means_ = common::AnfAlgo::GetNodeAttr<std::vector<float>>(kernel_node, "means");
} else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("means")->isa<FloatImm>()) {
float mean = common::AnfAlgo::GetNodeAttr<float>(kernel_node, "means");
auto means = base_operator->GetAttr("means");
if (means->isa<api::ValueSequence>()) {
means_ = api::GetValue<std::vector<float>>(means);
} else if (means->isa<api::FloatImm>()) {
float mean = api::GetValue<float>(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<ValueTuple>() ||
common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa<ValueList>()) {
stds_ = common::AnfAlgo::GetNodeAttr<std::vector<float>>(kernel_node, "stds");
} else if (common::AnfAlgo::GetCNodePrimitive(kernel_node)->GetAttr("stds")->isa<FloatImm>()) {
float std = common::AnfAlgo::GetNodeAttr<float>(kernel_node, "stds");
auto stds = base_operator->GetAttr("stds");
if (stds->isa<api::ValueSequence>()) {
stds_ = api::GetValue<std::vector<float>>(stds);
} else if (stds->isa<api::FloatImm>()) {
float std = api::GetValue<float>(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 <typename T>
@ -152,6 +142,62 @@ bool BoundingBoxEncodeCpuKernelMod::LaunchKernel(const std::vector<AddressPtr> &
return true;
}
int BoundingBoxEncodeCpuKernelMod::Resize(const BaseOperatorPtr &base_operator,
const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &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<std::pair<KernelAttr, BoundingBoxEncodeCpuKernelMod::BoundingBoxEncodeFunc>>
BoundingBoxEncodeCpuKernelMod::func_list_ = {
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32),
&BoundingBoxEncodeCpuKernelMod::LaunchKernel<float>},
{KernelAttr().AddInputAttr(kNumberTypeFloat16).AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16),
&BoundingBoxEncodeCpuKernelMod::LaunchKernel<float16>}};
std::vector<KernelAttr> BoundingBoxEncodeCpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
(void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, BoundingBoxEncodeFunc> &pair) { return pair.first; });
return support_list;
}
MS_KERNEL_FACTORY_REG(NativeCpuKernelMod, BoundingBoxEncode, BoundingBoxEncodeCpuKernelMod);
} // namespace kernel
} // namespace mindspore

View File

@ -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 <vector>
#include <map>
#include <algorithm>
#include <utility>
@ -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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) override;
bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs) override {
return kernel_func_(this, inputs, workspace, outputs);
}
int Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs, const std::map<uint32_t, tensor::TensorPtr> &) override;
std::vector<KernelAttr> GetOpSupport() override;
private:
@ -51,11 +56,10 @@ class BoundingBoxEncodeCpuKernelMod : public DeprecatedNativeCpuKernelMod {
static std::vector<std::pair<KernelAttr, BoundingBoxEncodeFunc>> func_list_;
BoundingBoxEncodeFunc kernel_func_;
void InitTaskFunc(const CNodePtr &kernel_node);
std::vector<float> means_;
std::vector<float> 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_

View File

@ -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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &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<api::ValueSequence>()) {
means_ = api::GetValue<std::vector<float>>(means);
} else if (means->isa<api::FloatImm>()) {
float mean = api::GetValue<float>(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<api::ValueSequence>()) {
stds_ = api::GetValue<std::vector<float>>(stds);
} else if (stds->isa<api::FloatImm>()) {
float std = api::GetValue<float>(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<int64_t> max_shape_me = api::GetValue<std::vector<int64_t>>(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<float>(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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
if (auto ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost); ret != KRET_OK) {
return ret;
}
return KRET_OK;
}
template <typename T>
bool BoundingBoxDecodeGpuKernelMod::LaunchKernel(const std::vector<AddressPtr> &inputs,
const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr) {
T *rois_addr = GetDeviceAddress<T>(inputs, 0);
T *deltas_addr = GetDeviceAddress<T>(inputs, 1);
T *bboxes_addr = GetDeviceAddress<T>(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<cudaStream_t>(stream_ptr));
return true;
}
std::vector<std::pair<KernelAttr, BoundingBoxDecodeGpuKernelMod::BoundingBoxDecodeLaunchFunc>>
BoundingBoxDecodeGpuKernelMod::func_list_ = {
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32),
&BoundingBoxDecodeGpuKernelMod::LaunchKernel<float>}};
std::vector<KernelAttr> BoundingBoxDecodeGpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
(void)std::transform(
func_list_.begin(), func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, BoundingBoxDecodeGpuKernelMod::BoundingBoxDecodeLaunchFunc> &pair) {
return pair.first;
});
return support_list;
}
MS_KERNEL_FACTORY_REG(NativeGpuKernelMod, BoundingBoxDecode, BoundingBoxDecodeGpuKernelMod);
} // namespace kernel
} // namespace mindspore

View File

@ -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 <vector>
#include <utility>
#include <map>
#include <string>
#include <algorithm>
#include "plugin/device/gpu/kernel/cuda_impl/cuda_ops/boundingbox_decode_impl.cuh"
@ -26,128 +28,37 @@
namespace mindspore {
namespace kernel {
template <typename T>
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<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr) override {
if (is_null_input_) {
return true;
}
T *rois_addr = GetDeviceAddress<T>(inputs, 0);
T *deltas_addr = GetDeviceAddress<T>(inputs, 1);
T *bboxes_addr = GetDeviceAddress<T>(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<cudaStream_t>(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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &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<ValueTuple>() || means->isa<ValueList>()) {
means_ = GetAttr<std::vector<float>>(kernel_node, "means");
} else if (means->isa<FloatImm>()) {
float mean = GetAttr<float>(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<ValueTuple>() || stds->isa<ValueList>()) {
stds_ = GetAttr<std::vector<float>>(kernel_node, "stds");
} else if (stds->isa<FloatImm>()) {
float std = GetAttr<float>(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<int64_t> max_shape_me = GetAttr<std::vector<int64_t>>(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<int>(value); });
wh_ratio_clip_ = GetAttr<float>(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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &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<KernelAttr> GetOpSupport() override;
template <typename T>
bool LaunchKernel(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr);
using BoundingBoxDecodeLaunchFunc =
std::function<bool(BoundingBoxDecodeGpuKernelMod *, const std::vector<kernel::AddressPtr> &,
const std::vector<kernel::AddressPtr> &, const std::vector<kernel::AddressPtr> &, void *)>;
private:
std::string kernel_name_{};
BoundingBoxDecodeLaunchFunc kernel_func_;
static std::vector<std::pair<KernelAttr, BoundingBoxDecodeLaunchFunc>> func_list_;
size_t rois_size_;
size_t deltas_size_;
size_t bboxes_size_;
@ -155,9 +66,8 @@ class BoundingBoxDecodeGpuKernelMod : public DeprecatedNativeGpuKernelMod {
std::vector<float> stds_;
std::vector<int> 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

View File

@ -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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &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<api::ValueSequence>()) {
means_ = api::GetValue<std::vector<float>>(means);
} else if (means->isa<api::FloatImm>()) {
float mean = api::GetValue<float>(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<api::ValueSequence>()) {
stds_ = api::GetValue<std::vector<float>>(stds);
} else if (stds->isa<api::FloatImm>()) {
float std = api::GetValue<float>(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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
if (auto ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost); ret != KRET_OK) {
return ret;
}
return KRET_OK;
}
template <typename T>
bool BoundingBoxEncodeGpuKernelMod::LaunchKernel(const std::vector<AddressPtr> &inputs,
const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr) {
T *anchor_addr = GetDeviceAddress<T>(inputs, 0);
T *groundtruth_addr = GetDeviceAddress<T>(inputs, 1);
T *deltas_addr = GetDeviceAddress<T>(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<cudaStream_t>(stream_ptr));
return true;
}
std::vector<std::pair<KernelAttr, BoundingBoxEncodeGpuKernelMod::BoundingBoxEncodeLaunchFunc>>
BoundingBoxEncodeGpuKernelMod::func_list_ = {
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32),
&BoundingBoxEncodeGpuKernelMod::LaunchKernel<float>}};
std::vector<KernelAttr> BoundingBoxEncodeGpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
(void)std::transform(
func_list_.begin(), func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, BoundingBoxEncodeGpuKernelMod::BoundingBoxEncodeLaunchFunc> &pair) {
return pair.first;
});
return support_list;
}
MS_KERNEL_FACTORY_REG(NativeGpuKernelMod, BoundingBoxEncode, BoundingBoxEncodeGpuKernelMod);
} // namespace kernel
} // namespace mindspore

View File

@ -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 <vector>
#include <map>
#include <utility>
#include <string>
#include <algorithm>
#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 <typename T>
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<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr) override {
if (is_null_input_) {
return true;
}
T *anchor_addr = GetDeviceAddress<T>(inputs, 0);
T *groundtruth_addr = GetDeviceAddress<T>(inputs, 1);
T *deltas_addr = GetDeviceAddress<T>(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<cudaStream_t>(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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &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<ValueTuple>() || means->isa<ValueList>()) {
means_ = GetAttr<std::vector<float>>(kernel_node, "means");
} else if (means->isa<FloatImm>()) {
float mean = GetAttr<float>(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<ValueTuple>() || stds->isa<ValueList>()) {
stds_ = GetAttr<std::vector<float>>(kernel_node, "stds");
} else if (stds->isa<FloatImm>()) {
float std = GetAttr<float>(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<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &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<KernelAttr> GetOpSupport() override;
template <typename T>
bool LaunchKernel(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr);
using BoundingBoxEncodeLaunchFunc =
std::function<bool(BoundingBoxEncodeGpuKernelMod *, const std::vector<kernel::AddressPtr> &,
const std::vector<kernel::AddressPtr> &, const std::vector<kernel::AddressPtr> &, void *)>;
private:
std::string kernel_name_{};
BoundingBoxEncodeLaunchFunc kernel_func_;
static std::vector<std::pair<KernelAttr, BoundingBoxEncodeLaunchFunc>> func_list_;
size_t anchor_size_;
size_t groundtruth_size_;
size_t deltas_size_;
std::vector<float> means_;
std::vector<float> stds_;
bool is_null_input_;
};
} // namespace kernel
} // namespace mindspore

View File

@ -31,7 +31,6 @@ abstract::ShapePtr BoundingBoxDecodeInferShape(const PrimitivePtr &primitive,
const std::vector<AbstractBasePtr> &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();

View File

@ -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 <algorithm>
#include <set>
#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<AbstractBasePtr> &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<abstract::ShapePtr>();
MS_EXCEPTION_IF_NULL(x_shape);
return x_shape;
}
TypePtr BoundingBoxEncodeInferType(const PrimitivePtr &primitive, const std::vector<AbstractBasePtr> &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<TypePtr> 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<std::string, TypePtr> 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<AbstractBasePtr> &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

View File

@ -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 <map>
#include <vector>
#include <string>
#include <memory>
#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<abstract::AbstractBasePtr> &input_args);
} // namespace ops
} // namespace mindspore
#endif // MINDSPORE_CORE_OPS_BOUNDING_BOX_ENCODE_H_

View File

@ -914,6 +914,7 @@ GVAR_DEF(PrimitivePtr, kPrimSparseApplyRMSProp, std::make_shared<Primitive>("Spa
GVAR_DEF(PrimitivePtr, kPrimApplyKerasMomentum, std::make_shared<Primitive>("ApplyKerasMomentum"));
GVAR_DEF(PrimitivePtr, kPrimLARSUpdate, std::make_shared<Primitive>("LARSUpdate"));
GVAR_DEF(PrimitivePtr, kPrimBoundingBoxDecode, std::make_shared<Primitive>("BoundingBoxDecode"));
GVAR_DEF(PrimitivePtr, kPrimBoundingBoxEncode, std::make_shared<Primitive>("BoundingBoxEncode"));
GVAR_DEF(PrimitivePtr, kPrimROIAlign, std::make_shared<Primitive>("ROIAlign"));
GVAR_DEF(PrimitivePtr, kPrimApplyAddSign, std::make_shared<Primitive>("ApplyAddSign"));
GVAR_DEF(PrimitivePtr, kPrimApplyAdagrad, std::make_shared<Primitive>("ApplyAdagrad"));

View File

@ -1,2 +1,2 @@
Note: This is the mindspore Lite inference framework size threshold. Offline review is required before modify this value!!!
1083704
1085704

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)