forked from mindspore-Ecosystem/mindspore
xxToTensor\TensorToxx cpu kernel & scalar ops
This commit is contained in:
parent
58a5017a1b
commit
17751243c7
|
@ -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},
|
||||
|
|
|
@ -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}},
|
||||
|
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_
|
|
@ -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",
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
""" Define constants"""
|
||||
|
||||
# Arithmetic
|
||||
kScalarFloordiv = "ScalarFloordiv"
|
||||
kScalarPow = "ScalarPow"
|
||||
kScalarTrunc = "ScalarTrunc"
|
||||
kScalarFloor = "ScalarFloor"
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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
|
|
@ -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."""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue