xxToTensor\TensorToxx cpu kernel & scalar ops

This commit is contained in:
huoxinyou 2023-02-01 17:42:11 +08:00
parent 58a5017a1b
commit 17751243c7
30 changed files with 1772 additions and 58 deletions

View File

@ -35,7 +35,7 @@ PrimToFunction::PrimToFunction()
{kScalarLt, kPrimTypeNumTwoArgs}, {"scalar_ne", kPrimTypeNumTwoArgs},
{kScalarMod, kPrimTypeNumTwoArgs}, {kScalarMul, kPrimTypeNumTwoArgs},
{kScalarPow, kPrimTypeNumTwoArgs}, {kScalarSub, kPrimTypeNumTwoArgs},
{kScalarFloordiv, kPrimTypeNumTwoArgs}, {kScalarBitwiseAnd, kPrimTypeNumTwoArgs},
{kScalarFloorDiv, kPrimTypeNumTwoArgs}, {kScalarBitwiseAnd, kPrimTypeNumTwoArgs},
{kScalarBitwiseOr, kPrimTypeNumTwoArgs}, {"bit_xor", kPrimTypeNumTwoArgs},
{"bit_left_shift", kPrimTypeNumTwoArgs}, {"bit_right_shift", kPrimTypeNumTwoArgs},
{kStringNot, kPrimTypeStrOneArg}, {kStringConcat, kPrimTypeStrTwoArgs},

View File

@ -3063,7 +3063,6 @@ PrimitiveToImplMap &GetUniformPrimitiveToImplMap() {
using R = PrimitiveToImplMap::mapped_type;
static PrimitiveToImplMap uniform_prim_implement_map{
{prim::kPrimScalarPow, R{prim::ScalarPow, true, nullptr, true}},
{prim::kPrimScalarFloordiv, R{prim::ScalarFloordiv, true, nullptr, true}},
{prim::kPrimScalarUadd, R{prim::ScalarUAdd, true, nullptr, true}},
{prim::kPrimScalarUsub, R{prim::ScalarUSub, true, nullptr, true}},
{prim::kPrimScalarLog, R{prim::ScalarLog, true, nullptr, true}},

View File

@ -0,0 +1,365 @@
/**
* Copyright 2020-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 "plugin/device/cpu/kernel/sequence/scalar_arithmetic_cpu_kernel.h"
#include <algorithm>
#include <utility>
#include <limits>
#include <set>
#include <string>
#include <unordered_map>
#include <complex>
#include "plugin/device/cpu/hal/device/cpu_device_address.h"
#include "utils/ms_utils.h"
#include "include/common/thread_pool.h"
#include "mindspore/core/ops/op_utils.h"
namespace mindspore {
namespace kernel {
namespace {
constexpr auto kScalarAdd = "ScalarAdd";
constexpr auto kScalarSub = "ScalarSub";
constexpr auto kScalarMul = "ScalarMul";
constexpr auto kScalarDiv = "ScalarDiv";
constexpr auto kScalarFloorDiv = "ScalarFloorDiv";
constexpr auto kScalarMod = "ScalarMod";
constexpr auto kScalarGt = "ScalarGreater";
constexpr auto kScalarGe = "ScalarGreaterEqual";
constexpr auto kScalarLt = "ScalarLess";
constexpr auto kScalarLe = "ScalarLessEqual";
constexpr auto kScalarEq = "ScalarEqual";
constexpr size_t kInputNum = 2;
constexpr size_t kInputx = 0;
constexpr size_t kInputy = 1;
constexpr size_t kOutputNum = 1;
} // namespace
template <typename T, typename S, typename N>
void AddImpl(const T *in_x, const S *in_y, N *out) {
N x = static_cast<N>(*in_x);
N y = static_cast<N>(*in_y);
#ifndef _MSC_VER
if constexpr (std::is_integral<N>::value && std::is_signed<N>::value) {
if (__builtin_add_overflow(x, y, out)) {
MS_EXCEPTION(ValueError) << "For prim ScalarAdd Overflow of the sum of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
return;
}
#endif
*out = x + y;
}
template <typename T, typename S, typename N>
void SubImpl(const T *in_x, const S *in_y, N *out) {
N x = static_cast<N>(*in_x);
N y = static_cast<N>(*in_y);
#ifndef _MSC_VER
if constexpr (std::is_integral<N>::value && std::is_signed<N>::value) {
if (__builtin_sub_overflow(x, y, out)) {
MS_EXCEPTION(ValueError) << "For prim ScalarSub Overflow of the sub of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
return;
}
#endif
*out = x - y;
}
template <typename T, typename S, typename N>
void MulImpl(const T *in_x, const S *in_y, N *out) {
N x = static_cast<N>(*in_x);
N y = static_cast<N>(*in_y);
#ifndef _MSC_VER
if constexpr (std::is_integral<N>::value && std::is_signed<N>::value) {
if (__builtin_mul_overflow(x, y, out)) {
MS_EXCEPTION(ValueError) << "For prim ScalarMul Overflow of the mul of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
return;
}
#endif
auto res = static_cast<double>(x) * static_cast<double>(y);
*out = static_cast<N>(res);
}
template <typename T, typename S, typename N>
void DivImpl(const T *in_x, const S *in_y, N *out) {
N x = static_cast<N>(*in_x);
N y = static_cast<N>(*in_y);
N zero = 0;
if (y == zero) {
MS_EXCEPTION(ValueError) << "The divisor could not be zero. But the divisor is zero now.";
}
if constexpr (std::is_integral<N>::value && std::is_signed<N>::value) {
if (x == std::numeric_limits<N>::min() && static_cast<int64_t>(y) == -1) {
MS_EXCEPTION(ValueError) << "For prim ScalarDiv Overflow of the div of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
}
*out = x / y;
}
template <typename T, typename S, typename N>
void FloorDivImpl(const T *in_x, const S *in_y, N *out) {
N x = static_cast<N>(*in_x);
N y = static_cast<N>(*in_y);
N zero = 0;
if (y == zero) {
MS_EXCEPTION(ValueError) << "The divisor could not be zero. But the divisor is zero now.";
}
if constexpr (std::is_integral<N>::value && std::is_signed<N>::value) {
if (x == std::numeric_limits<N>::min() && static_cast<int64_t>(y) == -1) {
MS_EXCEPTION(ValueError) << "For prim ScalarDiv Overflow of the div of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
}
*out = std::floor(x / y);
}
template <typename T, typename S, typename N>
void ModImpl(const T *in_x, const S *in_y, N *out) {
N x = static_cast<N>(*in_x);
N y = static_cast<N>(*in_y);
N zero = 0;
if (y == zero) {
MS_EXCEPTION(ValueError) << "Cannot perform modulo operation on zero.";
}
if constexpr (std::is_integral<N>::value && std::is_signed<N>::value) {
if (x == std::numeric_limits<N>::min() && static_cast<int64_t>(y) == -1) {
MS_EXCEPTION(ValueError) << "For prim ScalarDiv Overflow of the div of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
}
T n = std::floor(static_cast<float>(x) / static_cast<float>(y));
*out = x - n * y;
}
template <typename T, typename S, typename N>
void EqImpl(const T *in_x, const S *in_y, N *out) {
double x = static_cast<double>(*in_x);
double y = static_cast<double>(*in_y);
if (std::isinf(static_cast<double>(x)) && std::isinf(static_cast<double>(y))) {
*out = static_cast<N>((x > 0 && y > 0) || (x < 0 && y < 0));
return;
}
double error_abs = fabs(x - y);
*out = static_cast<N>(error_abs < DBL_EPSILON);
}
template <typename T, typename S, typename N>
void LtImpl(const T *in_x, const S *in_y, N *out) {
double x = static_cast<double>(*in_x);
double y = static_cast<double>(*in_y);
*out = static_cast<N>(x < y);
}
template <typename T, typename S, typename N>
void LeImpl(const T *in_x, const S *in_y, N *out) {
double x = static_cast<double>(*in_x);
double y = static_cast<double>(*in_y);
*out = static_cast<N>(x <= y);
}
template <typename T, typename S, typename N>
void GtImpl(const T *in_x, const S *in_y, N *out) {
double x = static_cast<double>(*in_x);
double y = static_cast<double>(*in_y);
*out = static_cast<N>(x > y);
}
template <typename T, typename S, typename N>
void GeImpl(const T *in_x, const S *in_y, N *out) {
double x = static_cast<double>(*in_x);
double y = static_cast<double>(*in_y);
*out = static_cast<N>(x >= y);
}
bool ScalarArithmeticCpuKernelMod::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();
if (kernel_name_ != kernel_type_) {
MS_LOG(EXCEPTION) << "Suppose to be " << kernel_type_ << " but got " << kernel_name_;
}
if (inputs.size() != kInputNum) {
MS_LOG(EXCEPTION) << "For kernel '" << kernel_type_ << "' input_num must be 2, but got " << inputs.size();
}
auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs);
auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport());
if (!is_match) {
MS_LOG(ERROR) << "For '" << kernel_name_ << "', it does not support this kernel data type: " << kernel_attr;
return false;
}
if (kernel_type_ == kScalarDiv) {
kernel_func_ = div_func_list_[index].second;
} else if (is_logic_ops_) {
kernel_func_ = logic_func_list_[index].second;
} else {
kernel_func_ = math_func_list_[index].second;
}
return true;
}
int ScalarArithmeticCpuKernelMod::Resize(const BaseOperatorPtr &base_operator,
const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
int ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost);
if (ret != 0) {
return ret;
}
return KRET_OK;
}
template <typename T, typename S, typename N>
bool ScalarArithmeticCpuKernelMod::LaunchKernel(const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &) {
CHECK_KERNEL_INPUTS_NUM(inputs.size(), kInputNum, kernel_name_);
CHECK_KERNEL_OUTPUTS_NUM(outputs.size(), kOutputNum, kernel_name_);
using MathImplFunc = std::function<void(const T *x, const S *y, N *out)>;
std::unordered_map<std::string, MathImplFunc> func_map = {{kScalarAdd, AddImpl<T, S, N>},
{kScalarSub, SubImpl<T, S, N>},
{kScalarMul, MulImpl<T, S, N>},
{kScalarDiv, DivImpl<T, S, N>},
{kScalarMod, ModImpl<T, S, N>},
{kScalarEq, EqImpl<T, S, N>},
{kScalarGt, GtImpl<T, S, N>},
{kScalarLt, LtImpl<T, S, N>},
{kScalarGe, GeImpl<T, S, N>},
{kScalarLe, LeImpl<T, S, N>},
{kScalarFloorDiv, FloorDivImpl<T, S, N>}};
auto iter = func_map.find(kernel_name_);
if (iter == func_map.end()) {
MS_EXCEPTION(TypeError) << "For '" << kernel_name_
<< "' don't support. Only support [Add, Sub, Mul, Div, Mod, Eq, Le, Ge, Lt, Gt]";
}
MathImplFunc compute_func = iter->second;
auto input_x = reinterpret_cast<T *>(inputs[kInputx]->GetData()->addr);
auto input_y = reinterpret_cast<S *>(inputs[kInputy]->GetData()->addr);
auto output = reinterpret_cast<N *>(outputs[0]->GetData()->addr);
compute_func(input_x, input_y, output);
return true;
}
#define ADD_KERNEL(x_dtype, y_dtype, out_dtype, x_type, y_type, out_type) \
{ \
KernelAttr() \
.AddInputAttr(kObjectTypeNumber, kNumberType##x_dtype) \
.AddInputAttr(kObjectTypeNumber, kNumberType##y_dtype) \
.AddOutputAttr(kObjectTypeNumber, kNumberType##out_dtype), \
&ScalarArithmeticCpuKernelMod::LaunchKernel<x_type, y_type, out_type> \
}
std::vector<std::pair<KernelAttr, ScalarArithmeticCpuKernelMod::ScalarArithmeticFunc>>
ScalarArithmeticCpuKernelMod::math_func_list_ = {
ADD_KERNEL(Float32, Float32, Float32, float, float, float),
ADD_KERNEL(Float32, Float64, Float64, float, double, double),
ADD_KERNEL(Float32, Int32, Float32, float, int32_t, float),
ADD_KERNEL(Float32, Int64, Float32, float, int64_t, float),
ADD_KERNEL(Float64, Float64, Float64, double, double, double),
ADD_KERNEL(Float64, Float32, Float64, double, float, double),
ADD_KERNEL(Float64, Int64, Float64, double, int64_t, double),
ADD_KERNEL(Float64, Int32, Float64, double, int32_t, double),
ADD_KERNEL(Int32, Float32, Float32, int32_t, float, float),
ADD_KERNEL(Int32, Float64, Float64, int32_t, double, double),
ADD_KERNEL(Int32, Int32, Int32, int32_t, int32_t, int32_t),
ADD_KERNEL(Int32, Int64, Int64, int32_t, int64_t, int64_t),
ADD_KERNEL(Int64, Float64, Float64, int64_t, double, double),
ADD_KERNEL(Int64, Float32, Float32, int64_t, float, float),
ADD_KERNEL(Int64, Int64, Int64, int64_t, int64_t, int64_t),
ADD_KERNEL(Int64, Int32, Int64, int64_t, int32_t, int64_t),
};
std::vector<std::pair<KernelAttr, ScalarArithmeticCpuKernelMod::ScalarArithmeticFunc>>
ScalarArithmeticCpuKernelMod::div_func_list_ = {
ADD_KERNEL(Float32, Float32, Float32, float, float, float),
ADD_KERNEL(Float32, Float64, Float32, float, double, float),
ADD_KERNEL(Float32, Int32, Float32, float, int32_t, float),
ADD_KERNEL(Float32, Int64, Float32, float, int64_t, float),
ADD_KERNEL(Float64, Float64, Float32, double, double, float),
ADD_KERNEL(Float64, Float32, Float32, double, float, float),
ADD_KERNEL(Float64, Int64, Float32, double, int64_t, float),
ADD_KERNEL(Float64, Int32, Float32, double, int32_t, float),
ADD_KERNEL(Int32, Float32, Float32, int32_t, float, float),
ADD_KERNEL(Int32, Float64, Float32, int32_t, double, float),
ADD_KERNEL(Int32, Int32, Float32, int32_t, int32_t, float),
ADD_KERNEL(Int32, Int64, Float32, int32_t, int64_t, float),
ADD_KERNEL(Int64, Float64, Float32, int64_t, double, float),
ADD_KERNEL(Int64, Float32, Float32, int64_t, float, float),
ADD_KERNEL(Int64, Int64, Float32, int64_t, int64_t, float),
ADD_KERNEL(Int64, Int32, Float32, int64_t, int32_t, float),
};
std::vector<std::pair<KernelAttr, ScalarArithmeticCpuKernelMod::ScalarArithmeticFunc>>
ScalarArithmeticCpuKernelMod::logic_func_list_ = {
ADD_KERNEL(Float32, Float32, Bool, float, float, bool), ADD_KERNEL(Float32, Float64, Bool, float, double, bool),
ADD_KERNEL(Float32, Int32, Bool, float, int32_t, bool), ADD_KERNEL(Float32, Int64, Bool, float, int64_t, bool),
ADD_KERNEL(Float64, Float64, Bool, double, double, bool), ADD_KERNEL(Float64, Float32, Bool, double, float, bool),
ADD_KERNEL(Float64, Int64, Bool, double, int64_t, bool), ADD_KERNEL(Float64, Int32, Bool, double, int32_t, bool),
ADD_KERNEL(Int32, Float32, Bool, int32_t, float, bool), ADD_KERNEL(Int32, Float64, Bool, int32_t, double, bool),
ADD_KERNEL(Int32, Int32, Bool, int32_t, int32_t, bool), ADD_KERNEL(Int32, Int64, Bool, int32_t, int64_t, bool),
ADD_KERNEL(Int64, Float64, Bool, int64_t, double, bool), ADD_KERNEL(Int64, Float32, Bool, int64_t, float, bool),
ADD_KERNEL(Int64, Int64, Bool, int64_t, int64_t, bool), ADD_KERNEL(Int64, Int32, Bool, int64_t, int32_t, bool),
};
std::vector<KernelAttr> ScalarArithmeticCpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
std::set<std::string> logic_ops = {kScalarEq, kScalarGe, kScalarGt, kScalarLt, kScalarLe};
auto iter = logic_ops.find(kernel_type_);
if (kernel_type_ == kScalarDiv) {
(void)std::transform(div_func_list_.begin(), div_func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, ScalarArithmeticFunc> &item) { return item.first; });
} else if (iter != logic_ops.end()) {
is_logic_ops_ = true;
(void)std::transform(logic_func_list_.begin(), logic_func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, ScalarArithmeticFunc> &item) { return item.first; });
} else {
(void)std::transform(math_func_list_.begin(), math_func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, ScalarArithmeticFunc> &item) { return item.first; });
}
return support_list;
}
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarAdd,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarAdd); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarSub,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarSub); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarMul,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarMul); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarDiv,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarDiv); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarFloorDiv,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarFloorDiv); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarMod,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarMod); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarEqual,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarEq); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarGreater,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarGt); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarGreaterEqual,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarGe); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarLess,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarLt); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarLessEqual,
[]() { return std::make_shared<ScalarArithmeticCpuKernelMod>(kScalarLe); });
} // namespace kernel
} // namespace mindspore

View File

@ -0,0 +1,68 @@
/**
* 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_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_ARITHMETIC_CPU_KERNEL_H_
#define MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_ARITHMETIC_CPU_KERNEL_H_
#include <vector>
#include <string>
#include <memory>
#include <utility>
#include <map>
#include "plugin/device/cpu/kernel/cpu_kernel.h"
#include "plugin/factory/ms_factory.h"
namespace mindspore {
namespace kernel {
class ScalarArithmeticCpuKernelMod : public NativeCpuKernelMod {
public:
ScalarArithmeticCpuKernelMod() = default;
explicit ScalarArithmeticCpuKernelMod(const std::string &kernel_type) : kernel_type_(kernel_type) {}
~ScalarArithmeticCpuKernelMod() override = default;
bool Init(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) override;
int Resize(
const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost = std::map<uint32_t, tensor::TensorPtr>()) override;
bool Launch(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &workspace) override {
return kernel_func_(this, inputs, outputs, workspace);
}
std::vector<KernelAttr> GetOpSupport() override;
private:
template <typename T, typename S, typename N>
bool LaunchKernel(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &);
using ScalarArithmeticFunc =
std::function<bool(ScalarArithmeticCpuKernelMod *, const std::vector<kernel::KernelTensorPtr> &,
const std::vector<kernel::KernelTensorPtr> &, const std::vector<kernel::AddressPtr> &)>;
static std::vector<std::pair<KernelAttr, ScalarArithmeticFunc>> math_func_list_;
static std::vector<std::pair<KernelAttr, ScalarArithmeticFunc>> div_func_list_;
static std::vector<std::pair<KernelAttr, ScalarArithmeticFunc>> logic_func_list_;
ScalarArithmeticFunc kernel_func_;
std::string kernel_type_;
bool is_logic_ops_{false};
};
} // namespace kernel
} // namespace mindspore
#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_ARITHMETIC_CPU_KERNEL_H_

View File

@ -0,0 +1,135 @@
/**
* Copyright 2020-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 "plugin/device/cpu/kernel/sequence/scalar_bitwise_cpu_kernel.h"
#include <algorithm>
#include <utility>
#include <complex>
#include "plugin/device/cpu/hal/device/cpu_device_address.h"
#include "utils/ms_utils.h"
#include "include/common/thread_pool.h"
#include "mindspore/core/ops/op_utils.h"
namespace mindspore {
namespace kernel {
namespace {
constexpr auto kScalarBitwiseAnd = "ScalarBitwiseAnd";
constexpr auto kScalarBitwiseOr = "ScalarBitwiseOr";
constexpr size_t kInputNum = 2;
constexpr size_t kInputx = 0;
constexpr size_t kInputy = 1;
constexpr size_t kOutputNum = 1;
} // namespace
template <typename T, typename S, typename N>
void AddImpl(const T *in_x, const S *in_y, N *out) {
N x = static_cast<N>(*in_x);
N y = static_cast<N>(*in_y);
#ifndef _MSC_VER
if constexpr (std::is_integral<N>::value && std::is_signed<N>::value) {
if (__builtin_add_overflow(x, y, out)) {
MS_EXCEPTION(ValueError) << "For prim ScalarAdd Overflow of the sum of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
return;
}
#endif
*out = x + y;
}
bool ScalarBitwiseCpuKernelMod::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();
if (kernel_name_ != kernel_type_) {
MS_LOG(EXCEPTION) << "Suppose to be " << kernel_type_ << " but got " << kernel_name_;
}
if (inputs.size() != kInputNum) {
MS_LOG(EXCEPTION) << "For kernel '" << kernel_type_ << "' input_num must be 2, but got " << inputs.size();
}
auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs);
auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport());
if (!is_match) {
MS_LOG(ERROR) << "For '" << kernel_name_ << "', it does not support this kernel data type: " << kernel_attr;
return false;
}
kernel_func_ = func_list_[index].second;
return true;
}
int ScalarBitwiseCpuKernelMod::Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
int ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost);
if (ret != 0) {
return ret;
}
return KRET_OK;
}
template <typename T, typename S, typename N>
bool ScalarBitwiseCpuKernelMod::LaunchKernel(const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &) {
CHECK_KERNEL_INPUTS_NUM(inputs.size(), kInputNum, kernel_name_);
CHECK_KERNEL_OUTPUTS_NUM(outputs.size(), kOutputNum, kernel_name_);
auto input_x = reinterpret_cast<T *>(inputs[kInputx]->GetData()->addr);
auto input_y = reinterpret_cast<S *>(inputs[kInputy]->GetData()->addr);
auto output = reinterpret_cast<N *>(outputs[0]->GetData()->addr);
auto x = static_cast<N>(*input_x);
auto y = static_cast<N>(*input_y);
if (kernel_type_ == kScalarBitwiseAnd) {
*output = x & y;
} else {
*output = x | y;
}
return true;
}
#define ADD_KERNEL(x_dtype, y_dtype, out_dtype, x_type, y_type, out_type) \
{ \
KernelAttr() \
.AddInputAttr(kObjectTypeNumber, kNumberType##x_dtype) \
.AddInputAttr(kObjectTypeNumber, kNumberType##y_dtype) \
.AddOutputAttr(kObjectTypeNumber, kNumberType##out_dtype), \
&ScalarBitwiseCpuKernelMod::LaunchKernel<x_type, y_type, out_type> \
}
std::vector<std::pair<KernelAttr, ScalarBitwiseCpuKernelMod::ScalarBitwiseFunc>> ScalarBitwiseCpuKernelMod::func_list_ =
{ADD_KERNEL(Int32, Int32, Int32, int32_t, int32_t, int32_t),
ADD_KERNEL(Int32, Int64, Int64, int32_t, int64_t, int64_t),
ADD_KERNEL(Int32, Bool, Int32, int32_t, bool, int32_t),
ADD_KERNEL(Int64, Int64, Int64, int64_t, int64_t, int64_t),
ADD_KERNEL(Int64, Int32, Int64, int64_t, int32_t, int64_t),
ADD_KERNEL(Int64, Bool, Int64, int64_t, bool, int64_t),
ADD_KERNEL(Bool, Int64, Int64, bool, int64_t, int64_t),
ADD_KERNEL(Bool, Int32, Int32, bool, int32_t, int32_t),
ADD_KERNEL(Bool, Bool, Bool, bool, bool, bool)};
std::vector<KernelAttr> ScalarBitwiseCpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
(void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, ScalarBitwiseFunc> &item) { return item.first; });
return support_list;
}
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarBitwiseAnd,
[]() { return std::make_shared<ScalarBitwiseCpuKernelMod>(kScalarBitwiseAnd); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarBitwiseOr,
[]() { return std::make_shared<ScalarBitwiseCpuKernelMod>(kScalarBitwiseOr); });
} // namespace kernel
} // namespace mindspore

View File

@ -0,0 +1,65 @@
/**
* 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_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_BITWISE_CPU_KERNEL_H_
#define MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_BITWISE_CPU_KERNEL_H_
#include <vector>
#include <memory>
#include <utility>
#include <map>
#include <string>
#include "plugin/device/cpu/kernel/cpu_kernel.h"
#include "plugin/factory/ms_factory.h"
namespace mindspore {
namespace kernel {
class ScalarBitwiseCpuKernelMod : public NativeCpuKernelMod {
public:
ScalarBitwiseCpuKernelMod() = default;
explicit ScalarBitwiseCpuKernelMod(const std::string &kernel_type) : kernel_type_(kernel_type) {}
~ScalarBitwiseCpuKernelMod() override = default;
bool Init(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) override;
int Resize(
const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost = std::map<uint32_t, tensor::TensorPtr>()) override;
bool Launch(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &workspace) override {
return kernel_func_(this, inputs, outputs, workspace);
}
std::vector<KernelAttr> GetOpSupport() override;
private:
template <typename T, typename S, typename N>
bool LaunchKernel(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &);
using ScalarBitwiseFunc =
std::function<bool(ScalarBitwiseCpuKernelMod *, const std::vector<kernel::KernelTensorPtr> &,
const std::vector<kernel::KernelTensorPtr> &, const std::vector<kernel::AddressPtr> &)>;
static std::vector<std::pair<KernelAttr, ScalarBitwiseFunc>> func_list_;
ScalarBitwiseFunc kernel_func_;
std::string kernel_type_;
};
} // namespace kernel
} // namespace mindspore
#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_BITWISE_CPU_KERNEL_H_

View File

@ -0,0 +1,92 @@
/**
* Copyright 2020-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 "plugin/device/cpu/kernel/sequence/scalar_bool_cpu_kernel.h"
#include <algorithm>
#include <utility>
#include <complex>
#include "plugin/device/cpu/hal/device/cpu_device_address.h"
#include "utils/ms_utils.h"
#include "include/common/thread_pool.h"
#include "mindspore/core/ops/op_utils.h"
namespace mindspore {
namespace kernel {
namespace {
constexpr size_t kInputNum = 1;
constexpr size_t kOutputNum = 1;
} // namespace
bool ScalarBoolCpuKernelMod::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();
if (inputs.size() != kInputNum) {
MS_LOG(EXCEPTION) << "For kernel '" << kernel_name_ << "' input_num must be 1, but got " << inputs.size();
}
auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs);
auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport());
if (!is_match) {
MS_LOG(ERROR) << "For '" << kernel_name_ << "', it does not support this kernel data type: " << kernel_attr;
return false;
}
kernel_func_ = func_list_[index].second;
return true;
}
int ScalarBoolCpuKernelMod::Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
int ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost);
if (ret != 0) {
return ret;
}
return KRET_OK;
}
template <typename T>
bool ScalarBoolCpuKernelMod::LaunchKernel(const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &) {
CHECK_KERNEL_INPUTS_NUM(inputs.size(), kInputNum, kernel_name_);
CHECK_KERNEL_OUTPUTS_NUM(outputs.size(), kOutputNum, kernel_name_);
auto input_x = reinterpret_cast<T *>(inputs[0]->GetData()->addr);
auto output = reinterpret_cast<bool *>(outputs[0]->GetData()->addr);
*output = static_cast<bool>(*input_x);
return true;
}
#define ADD_KERNEL(in_dtype, out_dtype, in_type) \
{ \
KernelAttr() \
.AddInputAttr(kObjectTypeNumber, kNumberType##in_dtype) \
.AddOutputAttr(kObjectTypeNumber, kNumberType##out_dtype), \
&ScalarBoolCpuKernelMod::LaunchKernel<in_type> \
}
std::vector<std::pair<KernelAttr, ScalarBoolCpuKernelMod::ScalarBoolFunc>> ScalarBoolCpuKernelMod::func_list_ = {
ADD_KERNEL(Float32, Bool, float), ADD_KERNEL(Float64, Bool, double), ADD_KERNEL(Int32, Bool, int32_t),
ADD_KERNEL(Int64, Bool, int64_t), ADD_KERNEL(Bool, Bool, bool)};
std::vector<KernelAttr> ScalarBoolCpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
(void)std::transform(func_list_.begin(), func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, ScalarBoolFunc> &item) { return item.first; });
return support_list;
}
MS_KERNEL_FACTORY_REG(NativeCpuKernelMod, ScalarBool, ScalarBoolCpuKernelMod);
} // namespace kernel
} // namespace mindspore

View File

@ -0,0 +1,62 @@
/**
* 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_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_BOOL_CPU_KERNEL_H_
#define MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_BOOL_CPU_KERNEL_H_
#include <vector>
#include <memory>
#include <utility>
#include <map>
#include "plugin/device/cpu/kernel/cpu_kernel.h"
#include "plugin/factory/ms_factory.h"
namespace mindspore {
namespace kernel {
class ScalarBoolCpuKernelMod : public NativeCpuKernelMod {
public:
ScalarBoolCpuKernelMod() = default;
~ScalarBoolCpuKernelMod() override = default;
bool Init(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) override;
int Resize(
const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost = std::map<uint32_t, tensor::TensorPtr>()) override;
bool Launch(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &workspace) override {
return kernel_func_(this, inputs, outputs, workspace);
}
std::vector<KernelAttr> GetOpSupport() override;
private:
template <typename T>
bool LaunchKernel(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &);
using ScalarBoolFunc =
std::function<bool(ScalarBoolCpuKernelMod *, const std::vector<kernel::KernelTensorPtr> &,
const std::vector<kernel::KernelTensorPtr> &, const std::vector<kernel::AddressPtr> &)>;
static std::vector<std::pair<KernelAttr, ScalarBoolFunc>> func_list_;
ScalarBoolFunc kernel_func_;
};
} // namespace kernel
} // namespace mindspore
#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SCALAR_BOOL_CPU_KERNEL_H_

View File

@ -0,0 +1,140 @@
/**
* Copyright 2020-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 "plugin/device/cpu/kernel/sequence/sequence_to_tensor_cpu_kernel.h"
#include <algorithm>
#include <utility>
#include <complex>
#include "plugin/device/cpu/hal/device/cpu_device_address.h"
#include "utils/ms_utils.h"
#include "include/common/thread_pool.h"
namespace mindspore {
namespace kernel {
namespace {
constexpr auto kTupleToTensor = "TupleToTensor";
constexpr auto kScalarToTensor = "ScalarToTensor";
constexpr size_t kInputNum = 1;
constexpr size_t kOutputNum = 1;
} // namespace
template <typename T, typename S>
void Cast(const T *in, S *out, size_t length) {
for (size_t i = 0; i < length; i++) {
out[i] = static_cast<S>(in[i]);
}
}
bool SeqToTensorCpuKernelMod::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();
if (kernel_name_ != kernel_type_) {
MS_LOG(EXCEPTION) << "Suppose to be " << kernel_type_ << " but got " << kernel_name_;
}
CHECK_KERNEL_INPUTS_NUM(inputs.size(), kInputNum, kernel_name_);
CHECK_KERNEL_OUTPUTS_NUM(outputs.size(), kOutputNum, kernel_name_);
auto kernel_attr = GetKernelAttrFromTensors(inputs, outputs);
auto [is_match, index] = MatchKernelAttr(kernel_attr, GetOpSupport());
if (!is_match) {
MS_LOG(ERROR) << "For '" << kernel_name_ << "', it does not support this kernel data type: " << kernel_attr;
return false;
}
if (kernel_type_ == kScalarToTensor) {
kernel_func_ = scalar_func_list_[index].second;
} else {
kernel_func_ = seq_func_list_[index].second;
}
return true;
}
int SeqToTensorCpuKernelMod::Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
int ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost);
if (ret != 0) {
return ret;
}
return KRET_OK;
}
template <typename T, typename S>
bool SeqToTensorCpuKernelMod::LaunchKernel(const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &) {
const auto input_addr = reinterpret_cast<T *>(inputs[0]->GetData()->addr);
auto output_addr = reinterpret_cast<S *>(outputs[0]->GetData()->addr);
auto input_size = inputs[0]->GetData()->size / sizeof(T);
auto output_size = outputs[0]->GetData()->size / sizeof(S);
if (input_size != output_size) {
MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the size of 'input_x': {" << input_size
<< "} is not equal to the size of output: {" << output_size << "}";
}
Cast<T, S>(input_addr, output_addr, input_size);
return true;
}
#define ADD_TUPLE_KERNEL(x_dtype, out_dtype, in_type, out_type) \
{ \
KernelAttr().AddInputAttr(kObjectTypeTuple, kNumberType##x_dtype).AddOutputAttr(kNumberType##out_dtype), \
&SeqToTensorCpuKernelMod::LaunchKernel<in_type, out_type> \
}
#define ADD_SCALAR_KERNEL(x_dtype, out_dtype, in_type, out_type) \
{ \
KernelAttr().AddInputAttr(kObjectTypeNumber, kNumberType##x_dtype).AddOutputAttr(kNumberType##out_dtype), \
&SeqToTensorCpuKernelMod::LaunchKernel<in_type, out_type> \
}
std::vector<std::pair<KernelAttr, SeqToTensorCpuKernelMod::SeqToTensorFunc>> SeqToTensorCpuKernelMod::seq_func_list_ = {
ADD_TUPLE_KERNEL(Float32, Float32, float, float), ADD_TUPLE_KERNEL(Float32, Float64, float, double),
ADD_TUPLE_KERNEL(Float32, Int32, float, int32_t), ADD_TUPLE_KERNEL(Float32, Int64, float, int64_t),
ADD_TUPLE_KERNEL(Float64, Float32, double, float), ADD_TUPLE_KERNEL(Float64, Float64, double, double),
ADD_TUPLE_KERNEL(Float64, Int32, double, int32_t), ADD_TUPLE_KERNEL(Float64, Int64, double, int64_t),
ADD_TUPLE_KERNEL(Int32, Float32, int32_t, float), ADD_TUPLE_KERNEL(Int32, Float64, int32_t, double),
ADD_TUPLE_KERNEL(Int32, Int32, int32_t, int32_t), ADD_TUPLE_KERNEL(Int32, Int64, int32_t, int64_t),
ADD_TUPLE_KERNEL(Int64, Float32, int64_t, float), ADD_TUPLE_KERNEL(Int64, Float64, int64_t, double),
ADD_TUPLE_KERNEL(Int64, Int32, int64_t, int32_t), ADD_TUPLE_KERNEL(Int64, Int64, int64_t, int64_t)};
std::vector<std::pair<KernelAttr, SeqToTensorCpuKernelMod::SeqToTensorFunc>>
SeqToTensorCpuKernelMod::scalar_func_list_ = {
ADD_SCALAR_KERNEL(Float32, Float32, float, float), ADD_SCALAR_KERNEL(Float32, Float64, float, double),
ADD_SCALAR_KERNEL(Float32, Int32, float, int32_t), ADD_SCALAR_KERNEL(Float32, Int64, float, int64_t),
ADD_SCALAR_KERNEL(Float64, Float32, double, float), ADD_SCALAR_KERNEL(Float64, Float64, double, double),
ADD_SCALAR_KERNEL(Float64, Int32, double, int32_t), ADD_SCALAR_KERNEL(Float64, Int64, double, int64_t),
ADD_SCALAR_KERNEL(Int32, Float32, int32_t, float), ADD_SCALAR_KERNEL(Int32, Float64, int32_t, double),
ADD_SCALAR_KERNEL(Int32, Int32, int32_t, int32_t), ADD_SCALAR_KERNEL(Int32, Int64, int32_t, int64_t),
ADD_SCALAR_KERNEL(Int64, Float32, int64_t, float), ADD_SCALAR_KERNEL(Int64, Float64, int64_t, double),
ADD_SCALAR_KERNEL(Int64, Int32, int64_t, int32_t), ADD_SCALAR_KERNEL(Int64, Int64, int64_t, int64_t)};
std::vector<KernelAttr> SeqToTensorCpuKernelMod::GetOpSupport() {
std::vector<KernelAttr> support_list;
if (kernel_type_ == kScalarToTensor) {
(void)std::transform(scalar_func_list_.begin(), scalar_func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, SeqToTensorFunc> &item) { return item.first; });
} else {
(void)std::transform(seq_func_list_.begin(), seq_func_list_.end(), std::back_inserter(support_list),
[](const std::pair<KernelAttr, SeqToTensorFunc> &item) { return item.first; });
}
return support_list;
}
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, TupleToTensor,
[]() { return std::make_shared<SeqToTensorCpuKernelMod>(kTupleToTensor); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, ScalarToTensor,
[]() { return std::make_shared<SeqToTensorCpuKernelMod>(kScalarToTensor); });
} // namespace kernel
} // namespace mindspore

View File

@ -0,0 +1,66 @@
/**
* Copyright 2020-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_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SEQUENCE_TO_TENSOR_CPU_KERNEL_H_
#define MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SEQUENCE_TO_TENSOR_CPU_KERNEL_H_
#include <vector>
#include <memory>
#include <utility>
#include <string>
#include <map>
#include "plugin/device/cpu/kernel/cpu_kernel.h"
#include "plugin/factory/ms_factory.h"
namespace mindspore {
namespace kernel {
class SeqToTensorCpuKernelMod : public NativeCpuKernelMod {
public:
SeqToTensorCpuKernelMod() = default;
explicit SeqToTensorCpuKernelMod(const std::string &kernel_type) : kernel_type_(kernel_type) {}
~SeqToTensorCpuKernelMod() override = default;
bool Init(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) override;
int Resize(
const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost = std::map<uint32_t, tensor::TensorPtr>()) override;
bool Launch(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &workspace) override {
return kernel_func_(this, inputs, outputs, workspace);
}
std::vector<KernelAttr> GetOpSupport() override;
private:
template <typename T, typename S>
bool LaunchKernel(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &);
using SeqToTensorFunc =
std::function<bool(SeqToTensorCpuKernelMod *, const std::vector<kernel::KernelTensorPtr> &,
const std::vector<kernel::KernelTensorPtr> &, const std::vector<kernel::AddressPtr> &)>;
static std::vector<std::pair<KernelAttr, SeqToTensorFunc>> seq_func_list_;
static std::vector<std::pair<KernelAttr, SeqToTensorFunc>> scalar_func_list_;
SeqToTensorFunc kernel_func_;
std::string kernel_type_;
};
} // namespace kernel
} // namespace mindspore
#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_SEQUENCE_TO_TENSOR_CPU_KERNEL_H_

View File

@ -0,0 +1,105 @@
/**
* Copyright 2020-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 "plugin/device/cpu/kernel/sequence/tensor_to_sequence_cpu_kernel.h"
#include <algorithm>
#include <utility>
#include <complex>
#include "plugin/device/cpu/hal/device/cpu_device_address.h"
#include "utils/ms_utils.h"
#include "include/common/thread_pool.h"
namespace mindspore {
namespace kernel {
namespace {
constexpr auto kTensorToTuple = "TensorToTuple";
constexpr auto kTensorToScalar = "TensorToScalar";
constexpr size_t kInputNum = 1;
constexpr size_t kOutputNum = 1;
} // namespace
bool TensorToSeqCpuKernelMod::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();
if (kernel_name_ != kernel_type_) {
MS_LOG(EXCEPTION) << "Suppose to be " << kernel_type_ << " but got " << kernel_name_;
}
return true;
}
int TensorToSeqCpuKernelMod::Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
int ret = KernelMod::Resize(base_operator, inputs, outputs, inputsOnHost);
if (ret != 0) {
return ret;
}
return KRET_OK;
}
bool TensorToSeqCpuKernelMod::Launch(const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &workspace) {
CHECK_KERNEL_INPUTS_NUM(inputs.size(), kInputNum, kernel_name_);
CHECK_KERNEL_OUTPUTS_NUM(outputs.size(), kOutputNum, kernel_name_);
const auto input_addr = inputs[0]->GetData()->addr;
auto output_addr = outputs[0]->GetData()->addr;
auto input_size = inputs[0]->GetData()->size;
auto output_size = outputs[0]->GetData()->size;
if (input_size != output_size) {
MS_LOG(EXCEPTION) << "For '" << kernel_name_ << "', the size of 'input_x': {" << inputs[0]->GetData()->size
<< "} is not equal to the size of output: {" << outputs[0]->GetData()->size << "}";
}
auto cp_ret = memcpy_s(output_addr, output_size, input_addr, input_size);
if (cp_ret != EOK) {
MS_LOG(EXCEPTION) << "For " << kernel_name_ << ", memcpy error, errorno: " << cp_ret;
}
return true;
}
std::vector<KernelAttr> TensorToSeqCpuKernelMod::sequence_list_ = {
KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kObjectTypeTuple, kNumberTypeFloat32),
KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kObjectTypeTuple, kNumberTypeFloat64),
KernelAttr().AddInputAttr(kNumberTypeInt32).AddOutputAttr(kObjectTypeTuple, kNumberTypeInt32),
KernelAttr().AddInputAttr(kNumberTypeInt64).AddOutputAttr(kObjectTypeTuple, kNumberTypeInt64),
};
std::vector<KernelAttr> TensorToSeqCpuKernelMod::scalar_list_ = {
KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kObjectTypeNumber, kNumberTypeFloat32),
KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kObjectTypeNumber, kNumberTypeFloat64),
KernelAttr().AddInputAttr(kNumberTypeInt32).AddOutputAttr(kObjectTypeNumber, kNumberTypeInt32),
KernelAttr().AddInputAttr(kNumberTypeInt64).AddOutputAttr(kObjectTypeNumber, kNumberTypeInt64),
};
std::map<std::string, std::vector<KernelAttr>> TensorToSeqCpuKernelMod::kernel_attr_lists_ = {
{kTensorToTuple, sequence_list_}, {kTensorToScalar, scalar_list_}};
std::vector<KernelAttr> TensorToSeqCpuKernelMod::GetOpSupport() {
auto iter = kernel_attr_lists_.find(kernel_type_);
if (iter == kernel_attr_lists_.end()) {
MS_LOG(ERROR) << "For prim[" << kernel_type_ << "], it don't support.";
return std::vector<KernelAttr>{};
}
return iter->second;
}
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, TensorToTuple,
[]() { return std::make_shared<TensorToSeqCpuKernelMod>(kTensorToTuple); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, TensorToScalar,
[]() { return std::make_shared<TensorToSeqCpuKernelMod>(kTensorToScalar); });
} // namespace kernel
} // namespace mindspore

View File

@ -0,0 +1,59 @@
/**
* Copyright 2020-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_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_TENSOR_TO_SEQUENCE_CPU_KERNEL_H_
#define MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_TENSOR_TO_SEQUENCE_CPU_KERNEL_H_
#include <vector>
#include <string>
#include <memory>
#include <utility>
#include <map>
#include "plugin/device/cpu/kernel/cpu_kernel.h"
#include "plugin/factory/ms_factory.h"
namespace mindspore {
namespace kernel {
class TensorToSeqCpuKernelMod : public NativeCpuKernelMod {
public:
TensorToSeqCpuKernelMod() = default;
explicit TensorToSeqCpuKernelMod(const std::string &kernel_type) : kernel_type_(kernel_type) {}
~TensorToSeqCpuKernelMod() override = default;
bool Init(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) override;
int Resize(
const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost = std::map<uint32_t, tensor::TensorPtr>()) override;
bool Launch(const std::vector<KernelTensorPtr> &inputs, const std::vector<KernelTensorPtr> &outputs,
const std::vector<AddressPtr> &workspace) override;
std::vector<KernelAttr> GetOpSupport() override;
protected:
static std::map<std::string, std::vector<KernelAttr>> kernel_attr_lists_;
static std::vector<KernelAttr> sequence_list_;
static std::vector<KernelAttr> scalar_list_;
private:
std::string kernel_type_;
};
} // namespace kernel
} // namespace mindspore
#endif // MINDSPORE_CCSRC_PLUGIN_DEVICE_CPU_KERNEL_TENSOR_TO_SEQUENCE_CPU_KERNEL_H_

View File

@ -69,7 +69,7 @@ constexpr auto kScalarAdd = "ScalarAdd";
constexpr auto kScalarSub = "ScalarSub";
constexpr auto kScalarMul = "ScalarMul";
constexpr auto kScalarDiv = "ScalarDiv";
constexpr auto kScalarFloordiv = "ScalarFloordiv";
constexpr auto kScalarFloorDiv = "ScalarFloorDiv";
constexpr auto kScalarMod = "ScalarMod";
constexpr auto kScalarPow = "ScalarPow";
constexpr auto kScalarTrunc = "ScalarTrunc";
@ -181,7 +181,7 @@ constexpr auto kLogNormalReverse = "LogNormalReverse";
constexpr auto kUnstack = "Unstack";
constexpr auto kUnpack = "Unpack";
constexpr auto kTupleGetItem = "TupleGetItem";
constexpr auto kListGetItem = "list_getitem";
constexpr auto kListGetItem = "ListGetItem";
constexpr auto kSliceGetItem = "SliceGetItem";
constexpr auto kGeLU = "GeLU";
constexpr auto kUnravelIndex = "UnravelIndex";
@ -486,7 +486,7 @@ GVAR_DEF(PrimitivePtr, kPrimScalarAdd, std::make_shared<Primitive>(kScalarAdd));
GVAR_DEF(PrimitivePtr, kPrimScalarSub, std::make_shared<Primitive>(kScalarSub));
GVAR_DEF(PrimitivePtr, kPrimScalarMul, std::make_shared<Primitive>(kScalarMul));
GVAR_DEF(PrimitivePtr, kPrimScalarDiv, std::make_shared<Primitive>(kScalarDiv));
GVAR_DEF(PrimitivePtr, kPrimScalarFloordiv, std::make_shared<Primitive>(kScalarFloordiv));
GVAR_DEF(PrimitivePtr, kPrimScalarFloorDiv, std::make_shared<Primitive>(kScalarFloorDiv));
GVAR_DEF(PrimitivePtr, kPrimScalarMod, std::make_shared<Primitive>(kScalarMod));
GVAR_DEF(PrimitivePtr, kPrimScalarPow, std::make_shared<Primitive>(kScalarPow));
GVAR_DEF(PrimitivePtr, kPrimScalarTrunc, std::make_shared<Primitive>(kScalarTrunc));

View File

@ -27,6 +27,7 @@
#include "ops/scalar_sub.h"
#include "ops/scalar_mul.h"
#include "ops/scalar_div.h"
#include "ops/scalar_floordiv.h"
#include "ops/scalar_mod.h"
#include "ops/scalar_eq.h"
#include "ops/scalar_lt.h"
@ -116,6 +117,27 @@ ValuePtr DivImpl(const ValuePtr &x_value, const ValuePtr &y_value, const std::st
return MakeValue(static_cast<float>(x) / static_cast<float>(y));
}
template <typename T>
ValuePtr FloorDivImpl(const ValuePtr &x_value, const ValuePtr &y_value, const std::string &op_name) {
MS_EXCEPTION_IF_NULL(x_value);
MS_EXCEPTION_IF_NULL(y_value);
auto x = GetScalarValue<T>(op_name, x_value);
auto y = GetScalarValue<T>(op_name, y_value);
T zero = 0;
if (y == zero) {
MS_EXCEPTION(ValueError) << "The divisor could not be zero. But the divisor is zero now.";
}
if constexpr (std::is_signed<T>::value) {
if (x == std::numeric_limits<T>::min() && static_cast<int64_t>(y) == -1) {
MS_EXCEPTION(ValueError) << "For prim '" << op_name
<< "' Overflow of the mod of two signed number x: " << std::to_string(x)
<< ", y: " << std::to_string(y) << ".";
}
}
T res = std::floor(x / y);
return MakeValue(res);
}
template <typename T>
ValuePtr ModImpl(const ValuePtr &x_value, const ValuePtr &y_value, const std::string &op_name) {
MS_EXCEPTION_IF_NULL(x_value);
@ -192,11 +214,17 @@ using MathImplFunc = std::function<ValuePtr(const ValuePtr &, const ValuePtr &,
template <typename T>
MathImplFunc ChooseFunc(const std::string &prim_name) {
std::map<std::string, MathImplFunc> infer_value_func_map = {
{prim::kScalarAdd, AddImpl<T>}, {prim::kScalarSub, SubImpl<T>}, {prim::kScalarMul, MulImpl<T>},
{prim::kScalarDiv, DivImpl<T>}, {prim::kScalarMod, ModImpl<T>}, {prim::kScalarEq, EqImpl<T>},
{prim::kScalarGt, GtImpl<T>}, {prim::kScalarLt, LtImpl<T>}, {prim::kScalarGe, GeImpl<T>},
{prim::kScalarLe, LeImpl<T>}};
std::map<std::string, MathImplFunc> infer_value_func_map = {{prim::kScalarAdd, AddImpl<T>},
{prim::kScalarSub, SubImpl<T>},
{prim::kScalarMul, MulImpl<T>},
{prim::kScalarDiv, DivImpl<T>},
{prim::kScalarMod, ModImpl<T>},
{prim::kScalarEq, EqImpl<T>},
{prim::kScalarGt, GtImpl<T>},
{prim::kScalarLt, LtImpl<T>},
{prim::kScalarGe, GeImpl<T>},
{prim::kScalarLe, LeImpl<T>},
{prim::kScalarFloorDiv, FloorDivImpl<T>}};
auto iter = infer_value_func_map.find(prim_name);
if (iter == infer_value_func_map.end()) {
MS_EXCEPTION(TypeError) << "For '" << prim_name
@ -305,6 +333,7 @@ MIND_API_OPERATOR_IMPL(ScalarAdd, BaseOperator);
MIND_API_OPERATOR_IMPL(ScalarSub, BaseOperator);
MIND_API_OPERATOR_IMPL(ScalarMul, BaseOperator);
MIND_API_OPERATOR_IMPL(ScalarDiv, BaseOperator);
MIND_API_OPERATOR_IMPL(ScalarFloorDiv, BaseOperator);
MIND_API_OPERATOR_IMPL(ScalarMod, BaseOperator);
MIND_API_OPERATOR_IMPL(ScalarEqual, BaseOperator);
MIND_API_OPERATOR_IMPL(ScalarGreater, BaseOperator);
@ -315,6 +344,7 @@ REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarAdd, prim::kPrimScalarAdd, ScalarArithmet
REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarSub, prim::kPrimScalarSub, ScalarArithmeticInfer, true);
REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarMul, prim::kPrimScalarMul, ScalarArithmeticInfer, true);
REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarDiv, prim::kPrimScalarDiv, ScalarArithmeticInfer, true);
REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarFloorDiv, prim::kPrimScalarFloorDiv, ScalarArithmeticInfer, true);
REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarMod, prim::kPrimScalarMod, ScalarArithmeticInfer, true);
REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarEqual, prim::kPrimScalarEq, ScalarArithmeticInfer, true);
REGISTER_PRIMITIVE_OP_INFER_IMPL(ScalarGreater, prim::kPrimScalarGt, ScalarArithmeticInfer, true);

View File

@ -0,0 +1,36 @@
/**
* 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_SCALAR_FLOORDIV_H_
#define MINDSPORE_CORE_OPS_SCALAR_FLOORDIV_H_
#include "ops/base_operator.h"
#include "mindspore/core/ops/core_ops.h"
namespace mindspore {
namespace ops {
/// \brief ScalarFloorDiv op is used to div between variable scalar.
class MIND_API ScalarFloorDiv : public BaseOperator {
public:
MIND_API_BASE_MEMBER(ScalarFloorDiv);
/// \brief Constructor.
ScalarFloorDiv() : BaseOperator(prim::kScalarFloorDiv) {}
/// \brief Init.
void Init() const {}
};
} // namespace ops
} // namespace mindspore
#endif // MINDSPORE_CORE_OPS_SCALAR_FLOORDIV_H_

View File

@ -23,7 +23,7 @@
namespace mindspore {
// clang-format off
#ifndef ENABLE_SECURITY
static const std::set<std::string> PARALLEL_BLACK_LIST_ = {prim::kTupleGetItem, "J", "list_getitem",
static const std::set<std::string> PARALLEL_BLACK_LIST_ = {prim::kTupleGetItem, "J", "ListGetItem",
"array_getitem", "tuple_setitem", "Depend", "list_setitem", "array_setitem", "dict_getitem",
"list_append", "list_map", "list_reduce", "tuple_reversed", "tile_shape", "tuple_div", "tuple_to_array",
"make_dict", "make_slice", "string_eq", "VirtualLoss", "Return", "env_getitem",
@ -33,7 +33,7 @@ static const std::set<std::string> PARALLEL_BLACK_LIST_ = {prim::kTupleGetItem,
"InvertPermutation", "DropoutGenMask", "StatelessDropOutGenMask", "embed", "create_instance", "RefToEmbed",
"StopGradient", "UpdateState", "Load", "Switch", "Print", "call_instance"};
#else
static const std::set<std::string> PARALLEL_BLACK_LIST_ = {prim::kTupleGetItem, "J", "list_getitem",
static const std::set<std::string> PARALLEL_BLACK_LIST_ = {prim::kTupleGetItem, "J", "ListGetItem",
"array_getitem", "tuple_setitem", "Depend", "list_setitem", "array_setitem", "dict_getitem",
"list_append", "list_map", "list_reduce", "tuple_reversed", "tile_shape", "tuple_div", "tuple_to_array",
"make_dict", "make_slice", "string_eq", "VirtualLoss", "Return", "env_getitem",

View File

@ -117,7 +117,7 @@ def Switch(c, x, y):
return x if c else y
def list_getitem(data, item):
def ListGetItem(data, item):
"""Implement `list_getitem`."""
return data[item]

View File

@ -18,7 +18,6 @@
""" Define constants"""
# Arithmetic
kScalarFloordiv = "ScalarFloordiv"
kScalarPow = "ScalarPow"
kScalarTrunc = "ScalarTrunc"
kScalarFloor = "ScalarFloor"

View File

@ -20,7 +20,6 @@ from mindspore.ops import operations as P
from mindspore.ops.composite import multitype_ops as C
from mindspore.ops._grad.grad_base import bprops
from mindspore.common import dtype as mstype
from mindspore.ops.operations import _scalar_ops
get_dtype = P.DType()
# Unused parameters are placeholders.
@ -36,30 +35,6 @@ def bprop_max_and_minimum_grad_grad(x, y, z, out, dout):
return F.zeros_like(x), F.zeros_like(y), dz
@bprops.register(_scalar_ops.ScalarAdd)
def bprop_scalar_add(x, y, out, dout):
"""Backpropagator for primitive `scalar_add`."""
return dout, dout
@bprops.register(_scalar_ops.ScalarMul)
def bprop_scalar_mul(x, y, out, dout):
"""Backpropagator for primitive `scalar_mul`."""
return dout * y, dout * x
@bprops.register(_scalar_ops.ScalarSub)
def bprop_scalar_sub(x, y, out, dout):
"""Backpropagator for primitive `scalar_sub`."""
return dout, -dout
@bprops.register(_scalar_ops.ScalarDiv)
def bprop_scalar_div(x, y, out, dout):
"""Backpropagator for primitive `scalar_div`."""
return dout / y, (-dout) * (out / y)
@bprops.register(_constants.kScalarPow)
def bprop_scalar_pow(x, y, out, dout):
"""Backpropagator for primitive `scalar_pow`."""
@ -96,7 +71,7 @@ def bprop_tuple_getitem(data, idx, out, dout):
return F.tuple_setitem(C.zeros_like(data), idx, dout), C.zeros_like(idx)
@bprops.register("list_getitem")
@bprops.register("ListGetItem")
def bprop_list_getitem(data, idx, out, dout):
"""Backpropagator for primitive `list_getitem`."""
return F.list_setitem(C.zeros_like(data), idx, dout), C.zeros_like(idx)
@ -188,16 +163,9 @@ def bprop_mutable(x, out, dout):
return (dout,)
@bprops.register(_scalar_ops.ScalarGreater)
@bprops.register(_scalar_ops.ScalarLess)
@bprops.register(_scalar_ops.ScalarGreaterEqual)
@bprops.register(_scalar_ops.ScalarLessEqual)
@bprops.register(_scalar_ops.ScalarEqual)
@bprops.register("scalar_ne")
@bprops.register("bool_and")
@bprops.register("bool_or")
@bprops.register(_scalar_ops.ScalarBitwiseAnd)
@bprops.register(_scalar_ops.ScalarBitwiseOr)
@bprops.register("bit_xor")
@bprops.register("bit_left_shift")
@bprops.register("bit_right_shift")

View File

@ -24,5 +24,6 @@ from mindspore.ops._grad_experimental import grad_math_ops
from mindspore.ops._grad_experimental import grad_linalg_ops
from mindspore.ops._grad_experimental import grad_sparse
from mindspore.ops._grad_experimental import grad_sparse_ops
from mindspore.ops._grad_experimental import grad_scalar_ops
__all__ = ['get_bprop_fn']

View File

@ -0,0 +1,112 @@
# Copyright 2023 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.
# ============================================================================
"""Generate bprop for quantization aware ops"""
from mindspore.ops.operations import _scalar_ops
from mindspore.ops._grad.grad_base import bprop_getters
from mindspore.ops.composite.multitype_ops.zeros_like_impl import zeros_like
@bprop_getters.register(_scalar_ops.ScalarAdd)
def get_bprop_scalar_add(self):
"""Grad definition for `ScalarAdd` operation."""
def bprop(x, y, out, dout):
return dout, dout
return bprop
@bprop_getters.register(_scalar_ops.ScalarSub)
def get_bprop_scalar_sub(self):
"""Grad definition for `ScalarSub` operation."""
def bprop(x, y, out, dout):
return dout, 0 - dout
return bprop
@bprop_getters.register(_scalar_ops.ScalarMul)
def get_bprop_scalar_mul(self):
"""Grad definition for `ScalarMul` operation."""
def bprop(x, y, out, dout):
bc_dx = y * dout
bc_dy = x * dout
return bc_dx, bc_dy
return bprop
@bprop_getters.register(_scalar_ops.ScalarDiv)
def get_bprop_scalar_div(self):
"""Grad definition for `ScalarDiv` operation."""
def bprop(x, y, out, dout):
bc_dx = dout / y
bc_dy = 0 - bc_dx * out
return bc_dx, bc_dy
return bprop
@bprop_getters.register(_scalar_ops.ScalarFloorDiv)
def get_bprop_scalar_floordiv(self):
"""Grad definition for `ScalarFloorDiv` operation."""
def bprop(x, y, out, dout):
return zeros_like(x), zeros_like(y)
return bprop
@bprop_getters.register(_scalar_ops.ScalarMod)
def get_bprop_scalar_mod(self):
"""Grad definition for `ScalarMod` operation."""
def bprop(x, y, out, dout):
bc_dx = dout
bc_dy = -dout * (x // y)
return bc_dx, bc_dy
return bprop
@bprop_getters.register(_scalar_ops.ScalarEqual)
@bprop_getters.register(_scalar_ops.ScalarLessEqual)
@bprop_getters.register(_scalar_ops.ScalarLess)
@bprop_getters.register(_scalar_ops.ScalarGreaterEqual)
@bprop_getters.register(_scalar_ops.ScalarGreater)
@bprop_getters.register(_scalar_ops.ScalarBitwiseAnd)
@bprop_getters.register(_scalar_ops.ScalarBitwiseOr)
def get_bprop_scalar_logic(self):
"""Grad definition for `ScalarLogicOps` operation."""
def bprop(x, y, out, dout):
return zeros_like(x), zeros_like(y)
return bprop
@bprop_getters.register(_scalar_ops.ScalarBool)
def get_bprop_scalar_bool(self):
"""Grad definition for `ScalarBool` operation."""
def bprop(x, out, dout):
return zeros_like(x)
return bprop

View File

@ -50,7 +50,7 @@ def get_identity_vmap_rule(prim, axis_size):
return vmap_rule
@vmap_rules_getters.register("list_getitem")
@vmap_rules_getters.register("ListGetItem")
@vmap_rules_getters.register("TupleGetItem")
def get_seq_get_item_vmap_rule(prim, axis_size):
"""VmapRule for `list_getitem` or `TupleGetItem` operation."""

View File

@ -73,7 +73,7 @@ class _ListSlice(base.SequenceSliceGetItem_):
def __init__(self, name):
"""Initialize _TupleSlice."""
base.SequenceSliceGetItem_.__init__(self, name, "make_list", "list_getitem")
base.SequenceSliceGetItem_.__init__(self, name, "make_list", "ListGetItem")
def __call__(self, *args):
pass

View File

@ -66,10 +66,11 @@ scalar_ge = _scalar_ops.ScalarGreaterEqual()
scalar_le = _scalar_ops.ScalarLessEqual()
scalar_lt = _scalar_ops.ScalarLess()
scalar_eq = _scalar_ops.ScalarEqual()
scalar_floordiv = _scalar_ops.ScalarFloorDiv()
tuple_setitem = Primitive('tuple_setitem')
tuple_getitem = Primitive(_constants.kTupleGetItem)
list_getitem = Primitive('list_getitem')
list_getitem = Primitive('ListGetItem')
list_setitem = Primitive('list_setitem')
dict_getitem = Primitive('dict_getitem')
dict_setitem = Primitive('dict_setitem')
@ -84,7 +85,6 @@ make_list = Primitive('make_list')
make_slice = Primitive('make_slice')
tuple_equal = Primitive("tuple_equal")
list_equal = Primitive("list_equal")
scalar_floordiv = Primitive(_constants.kScalarFloordiv)
scalar_log = Primitive('scalar_log')
scalar_pow = Primitive(_constants.kScalarPow)
scalar_ne = Primitive('scalar_ne')

View File

@ -48,6 +48,38 @@ class ScalarDiv(Primitive):
"""Initialize ScalarDiv"""
class ScalarFloorDiv(Primitive):
r"""
Computes the quotient of dividing the first input scalar by the second input scalar element-wise.
.. math::
out_{i} = \frac{x_i}{y_i}
.. note::
The inputs can be constant/variable value. Usage is the same as '//' in Python.
This primitive only have 'CPU' implementation, for other platform, it runs using heterogeneous.
Inputs:
- **x** (Scalar) - A constant or variable scalar.
- **y** (Scalar) - A constant or variable scalar.
Outputs:
Scalar, the type of scalar is float.
Raises:
TypeError: If `x` and `y` are not scalar.
ValueError: If `y` is 0.
Supported Platforms:
``Ascend`` ``GPU`` ``CPU``
"""
@prim_attr_register
def __init__(self):
"""Initialize ScalarFloorDiv"""
self.init_prim_io_names(inputs=['x', 'y'], outputs=['output'])
class ScalarAdd(Primitive):
r"""
Adds two input scalar.

View File

@ -0,0 +1,296 @@
# 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.
# ============================================================================
import pytest
from mindspore import context
from mindspore.nn import Cell
from tuple_help import TupleFactory
context.set_context(mode=context.GRAPH_MODE)
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_add():
"""
Feature: test ScalarAdd.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x + y
def func(x, y):
return x + y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_sub():
"""
Feature: test ScalarSub.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x - y
def func(x, y):
return x - y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_mul():
"""
Feature: test ScalarMul.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x * y
def func(x, y):
return x * y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_div():
"""
Feature: test ScalarDiv.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x / y
def func(x, y):
return x / y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_mod():
"""
Feature: test ScalarMod.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x % y
def func(x, y):
return x % y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_floordiv():
"""
Feature: test ScalarFloorDiv.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x // y
def func(x, y):
return x // y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_eq():
"""
Feature: test ScalarEqual.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x == y
def func(x, y):
return x == y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_ge():
"""
Feature: test ScalarGreaterEqual.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x >= y
def func(x, y):
return x >= y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_gt():
"""
Feature: test ScalarGreater.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x > y
def func(x, y):
return x > y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_le():
"""
Feature: test ScalarLessEqual.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x <= y
def func(x, y):
return x <= y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_scalar_lt():
"""
Feature: test ScalarLess.
Description: inputs is dynamic scalar.
Expectation: the result match with numpy result
"""
class Net(Cell):
def construct(self, x, y):
return x < y
def func(x, y):
return x < y
net_ms = Net()
input_x = 3
input_y = 4
context.set_context(mode=context.GRAPH_MODE)
fact = TupleFactory(net_ms, func, (input_x, input_y))
fact.forward_cmp()
fact.grad_impl()

View File

@ -0,0 +1,84 @@
# 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.
# ============================================================================
from mindspore.common import mutable
from mindspore.nn import Cell
from mindspore.ops.composite import GradOperation
from mindspore.common import ParameterTuple
class _Grad(Cell):
def __init__(self, grad, network, wrt_params=False, real_inputs_count=None):
super().__init__()
self.network = network
self.grad = grad
self.sens_param = self.grad.sens_param
self.wrt_params = wrt_params
self.real_inputs_count = real_inputs_count
if self.wrt_params:
self.params = ParameterTuple(self.network.trainable_params())
def construct(self, *inputs):
return self.grad(self.network)(*inputs)
class GradOfFirstInput(_Grad):
"""
get grad of first input
"""
def __init__(self, network, sens_param=True, real_inputs_count=None):
super().__init__(grad=GradOperation(sens_param=sens_param),
network=network, real_inputs_count=real_inputs_count)
class GradOfAllInputs(_Grad):
"""
get grads of all inputs
"""
def __init__(self, network, sens_param=True, real_inputs_count=None):
super().__init__(grad=GradOperation(get_all=True, sens_param=sens_param),
network=network, real_inputs_count=real_inputs_count)
class TupleFactory():
def __init__(self, net_x, func_x, input_x, const_value_idx=None):
self.input_num = len(input_x)
self.input = []
if const_value_idx is None:
const_value_idx = []
for i, item in enumerate(input_x):
if i not in const_value_idx:
if isinstance(item, int):
self.input.append(mutable(item))
else:
self.input.append(mutable(item, True))
else:
self.input.append(item)
self.input_func = input_x
self.net = net_x
self.func = func_x
self.grad_input = None
def forward_cmp(self):
out_func = self.func(*self.input_func)
self.grad_input = out_func
out_mindspore = self.net(*self.input)
assert out_func == out_mindspore
def grad_impl(self):
grad_net = GradOfFirstInput(self.net) if self.input_num == 1 else GradOfAllInputs(self.net)
grad_net.set_train()
input_grad = grad_net(*self.input, self.grad_input)
return input_grad

View File

@ -263,7 +263,7 @@ TEST_F(TestComposite, test_TupleSlice_arg_slice_step_positive) {
/// Description: The second input is a scalar
/// Expectation: Throw type error
TEST_F(TestComposite, test_ListSlice_arg_one_number) {
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "list_getitem");
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "ListGetItem");
FuncGraphPtr list_graph = UTCompositeUtils::MakeFuncGraph(list_slice, 3);
AbstractBasePtrList eles;
@ -298,7 +298,7 @@ TEST_F(TestComposite, test_ListSlice_arg_one_number) {
/// Expectation: No Expectation
TEST_F(TestComposite, test_ListSlice_arg_slice) {
std::shared_ptr<py::scoped_interpreter> env = python_adapter::set_python_scoped();
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "list_getitem");
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "ListGetItem");
FuncGraphPtr list_slice_graph = UTCompositeUtils::MakeFuncGraph(list_slice, 2);
AbstractBasePtrList eles;
@ -327,7 +327,7 @@ TEST_F(TestComposite, test_ListSlice_arg_slice) {
/// Description: Test List slice the step is none
/// Expectation: No Expectation
TEST_F(TestComposite, test_ListSlice_arg_slice_step_none) {
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "list_getitem");
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "ListGetItem");
FuncGraphPtr list_slice_graph = UTCompositeUtils::MakeFuncGraph(list_slice, 2);
AbstractBasePtrList eles;
@ -356,7 +356,7 @@ TEST_F(TestComposite, test_ListSlice_arg_slice_step_none) {
/// Description: Test List slice the step is negative
/// Expectation: No Expectation
TEST_F(TestComposite, test_ListSlice_arg_slice_step_negative) {
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "list_getitem");
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "ListGetItem");
FuncGraphPtr list_slice_graph = UTCompositeUtils::MakeFuncGraph(list_slice, 2);
AbstractBasePtrList eles;
@ -385,7 +385,7 @@ TEST_F(TestComposite, test_ListSlice_arg_slice_step_negative) {
/// Description: Test List slice the step is positive
/// Expectation: No Expectation
TEST_F(TestComposite, test_ListSlice_arg_slice_step_positive) {
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "list_getitem");
MetaFuncGraphPtr list_slice = std::make_shared<prim::SequenceSliceGetItem>("list_slice", "make_list", "ListGetItem");
FuncGraphPtr list_slice_graph = UTCompositeUtils::MakeFuncGraph(list_slice, 2);
AbstractBasePtrList eles;

View File

@ -189,7 +189,7 @@ TEST_F(TestOps, TupleGetItemTest) {
}
TEST_F(TestOps, ListGetItemTest) {
auto prim = std::make_shared<Primitive>("list_getitem");
auto prim = std::make_shared<Primitive>("ListGetItem");
ASSERT_EQ(prim->name(), kPrimListGetItem->name());
}

View File

@ -682,7 +682,7 @@ TEST_F(TestPrim, test_list_getitem) {
args_spec_list.push_back(abstract_v1);
args_spec_list.push_back(abstract_v2);
auto prim = std::make_shared<Primitive>("list_getitem");
auto prim = std::make_shared<Primitive>("ListGetItem");
FuncGraphPtr func_graph = MakeFuncGraph(prim, 2);
AbstractBasePtr res = engine_->Run(func_graph, args_spec_list).eval_result->abstract();