forked from mindspore-Ecosystem/mindspore
!33978 [assistant][UpsampleTrilinear3d ][UpsampleTrilinear3dGrad] add new ascend operator UpsampleTrilinear3d & UpsampleTrilinear3dGrad
Merge pull request !33978 from 李文轼/Trilinear3d
This commit is contained in:
commit
b78043c1f6
|
@ -245,6 +245,51 @@ inline size_t NearestIndex(const size_t &output_index, const size_t &input_size,
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T AreaPixelComputeScale(int64_t input_size, int64_t output_size, bool align_corners, double scale) {
|
||||
if (align_corners) {
|
||||
if (output_size > 1) {
|
||||
return static_cast<T>(input_size - 1) / (output_size - 1);
|
||||
} else {
|
||||
return static_cast<T>(0);
|
||||
}
|
||||
} else {
|
||||
return ComputeScales<T>(scale, input_size, output_size);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T AreaPixelComputeSourceIndex(T scale, int64_t dst_index, bool align_corners) {
|
||||
if (align_corners) {
|
||||
return scale * static_cast<T>(dst_index);
|
||||
} else {
|
||||
constexpr T zero = 0.;
|
||||
T src_idx = scale * (dst_index + 0.5) - 0.5;
|
||||
return src_idx < zero ? zero : src_idx;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void ComputeSourceIndexAndLambda(int64_t *const input_index0, int64_t *const input_index1, T *const lambda0,
|
||||
T *const lambda1, T ratio, int64_t output_index, int64_t input_size,
|
||||
int64_t output_size, bool align_corners) {
|
||||
if (output_size == input_size) {
|
||||
// scale_factor = 1
|
||||
*input_index0 = output_index;
|
||||
*input_index1 = output_index;
|
||||
*lambda0 = static_cast<T>(1);
|
||||
*lambda1 = static_cast<T>(0);
|
||||
} else {
|
||||
const T real_input_index = AreaPixelComputeSourceIndex<T>(ratio, output_index, align_corners);
|
||||
*input_index0 = static_cast<int64_t>(real_input_index);
|
||||
int64_t offset = (*input_index0 < input_size - 1) ? 1 : 0;
|
||||
*input_index1 = *input_index0 + offset;
|
||||
*lambda1 = real_input_index - static_cast<T>(*input_index0);
|
||||
constexpr T one = 1.0;
|
||||
*lambda0 = one - *lambda1;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string Vector2Str(const std::vector<T> &inputs) {
|
||||
if (!inputs.empty()) {
|
||||
|
|
|
@ -86,6 +86,8 @@ constexpr auto kTensorScatterElements = "TensorScatterElements";
|
|||
constexpr auto kExtractGlimpse = "ExtractGlimpse";
|
||||
constexpr auto kUpsampleNearest3D = "UpsampleNearest3D";
|
||||
constexpr auto kUpsampleNearest3DGrad = "UpsampleNearest3DGrad";
|
||||
constexpr auto kUpsampleTrilinear3D = "UpsampleTrilinear3D";
|
||||
constexpr auto kUpsampleTrilinear3DGrad = "UpsampleTrilinear3DGrad";
|
||||
constexpr auto kEnvironCreate = "EnvironCreate";
|
||||
constexpr auto kEnvironSet = "EnvironSet";
|
||||
constexpr auto kEnvironGet = "EnvironGet";
|
||||
|
@ -152,6 +154,8 @@ const std::map<std::string, std::string> kOpNameToAicpuOpNameMap{
|
|||
{kUpsampleNearest3DGrad, "UpsampleNearest3dGrad"},
|
||||
{kNameRangeV2, "Range"},
|
||||
{kReLUV3, "Relu"},
|
||||
{kUpsampleTrilinear3D, "UpsampleTrilinear3d"},
|
||||
{kUpsampleTrilinear3DGrad, "UpsampleTrilinear3dGrad"},
|
||||
{kStack, "Pack"},
|
||||
{kUnstack, "Unpack"},
|
||||
{kGather, "GatherV2"},
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* Copyright 2022 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "plugin/device/cpu/kernel/upsample_trilinear_3d_cpu_kernel.h"
|
||||
#include <string>
|
||||
#include "kernel/common_utils.h"
|
||||
#include "plugin/device/cpu/hal/device/cpu_device_address.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace kernel {
|
||||
namespace {
|
||||
constexpr size_t kUpsampleTrilinear3DInputsNum = 1;
|
||||
constexpr size_t kUpsampleTrilinear3DOutputNum = 1;
|
||||
// GRAIN_SIZE for Parallel
|
||||
constexpr size_t kGrainSize = 32768;
|
||||
} // namespace
|
||||
|
||||
void UpsampleTrilinear3DCpuKernelMod::InitKernel(const CNodePtr &kernel_node) {
|
||||
MS_EXCEPTION_IF_NULL(kernel_node);
|
||||
kernel_name_ = common::AnfAlgo::GetCNodeName(kernel_node);
|
||||
in_type_ = AnfAlgo::GetOutputDeviceDataType(kernel_node, kIndex0);
|
||||
x_shape_ = AnfAlgo::GetInputDeviceShape(kernel_node, kIndex0);
|
||||
y_shape_ = AnfAlgo::GetOutputDeviceShape(kernel_node, kIndex0);
|
||||
if (x_shape_.size() != kDim5) {
|
||||
MS_EXCEPTION(ValueError) << "For '" << kernel_name_ << "', the dimension of 'x' should be " << kDim5 << ", but got "
|
||||
<< x_shape_.size();
|
||||
}
|
||||
attr_scales_ = common::AnfAlgo::GetNodeAttr<std::vector<float>>(kernel_node, kAttrScales);
|
||||
if (attr_scales_.empty()) {
|
||||
attr_scales_ = {0, 0, 0};
|
||||
}
|
||||
attr_align_corners_ = common::AnfAlgo::GetNodeAttr<bool>(kernel_node, kAttrAlignCorners);
|
||||
}
|
||||
|
||||
bool UpsampleTrilinear3DCpuKernelMod::Launch(const std::vector<kernel::AddressPtr> &inputs,
|
||||
const std::vector<kernel::AddressPtr> &,
|
||||
const std::vector<kernel::AddressPtr> &outputs) {
|
||||
CHECK_KERNEL_INPUTS_NUM(inputs.size(), kUpsampleTrilinear3DInputsNum, kernel_name_);
|
||||
CHECK_KERNEL_OUTPUTS_NUM(outputs.size(), kUpsampleTrilinear3DOutputNum, kernel_name_);
|
||||
|
||||
bool res = false;
|
||||
switch (in_type_) {
|
||||
case kNumberTypeFloat16:
|
||||
res = LaunchKernel<float16, float>(inputs, outputs);
|
||||
break;
|
||||
case kNumberTypeFloat32:
|
||||
res = LaunchKernel<float, float>(inputs, outputs);
|
||||
break;
|
||||
case kNumberTypeFloat64:
|
||||
res = LaunchKernel<double, double>(inputs, outputs);
|
||||
break;
|
||||
default:
|
||||
MS_EXCEPTION(TypeError) << "For '" << kernel_name_
|
||||
<< "', the dtype of 'x' should be float16, float32 or float64. But got "
|
||||
<< TypeIdLabel(in_type_);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
bool UpsampleTrilinear3DCpuKernelMod::LaunchKernel(const std::vector<kernel::AddressPtr> &inputs,
|
||||
const std::vector<kernel::AddressPtr> &outputs) {
|
||||
// treat batch and channels as one dimension
|
||||
int64_t channels = x_shape_[kIndex0] * x_shape_[kIndex1];
|
||||
int64_t input_depth = x_shape_[kIndex2];
|
||||
int64_t input_height = x_shape_[kIndex3];
|
||||
int64_t input_width = x_shape_[kIndex4];
|
||||
|
||||
int64_t output_depth = y_shape_[kIndex2];
|
||||
int64_t output_height = y_shape_[kIndex3];
|
||||
int64_t output_width = y_shape_[kIndex4];
|
||||
|
||||
MS_EXCEPTION_IF_CHECK_FAIL(channels > 0 && output_depth > 0 && output_height > 0 && output_width > 0,
|
||||
"Invalid output shape.");
|
||||
|
||||
auto x_ptr = reinterpret_cast<T *>(inputs[kIndex0]->addr);
|
||||
auto y_ptr = reinterpret_cast<T *>(outputs[kIndex0]->addr);
|
||||
|
||||
if (input_depth == output_depth && input_height == output_height && input_width == output_width) {
|
||||
auto cpy_ret = memcpy_s(y_ptr, outputs[kIndex0]->size, x_ptr, outputs[kIndex0]->size);
|
||||
if (cpy_ret != EOK) {
|
||||
MS_EXCEPTION(MemoryError) << "For " << kernel_name_ << ", memcpy_s to output failed.";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int64_t input_slice_size = input_depth * input_height * input_width;
|
||||
int64_t output_slice_size = output_depth * output_height * output_width;
|
||||
auto input_indexr_value = [=](int64_t n, int64_t d, int64_t h, int64_t w) {
|
||||
return x_ptr[n * input_slice_size + d * input_height * input_width + h * input_width + w];
|
||||
};
|
||||
auto loop3d = [&](int64_t begin, int64_t end) {
|
||||
const S depth_scale =
|
||||
AreaPixelComputeScale<S>(input_depth, output_depth, attr_align_corners_, attr_scales_[kIndex0]);
|
||||
const S height_scale =
|
||||
AreaPixelComputeScale<S>(input_height, output_height, attr_align_corners_, attr_scales_[kIndex1]);
|
||||
const S width_scale =
|
||||
AreaPixelComputeScale<S>(input_width, output_width, attr_align_corners_, attr_scales_[kIndex2]);
|
||||
int64_t id0(0), id1(0), ih0(0), ih1(0), iw0(0), iw1(0);
|
||||
S d0lambda(0), d1lambda(0), h0lambda(0), h1lambda(0), w0lambda(0), w1lambda(0);
|
||||
for (int64_t n = begin; n < end; ++n) {
|
||||
for (int64_t od = 0; od < output_depth; ++od) {
|
||||
ComputeSourceIndexAndLambda(&id0, &id1, &d0lambda, &d1lambda, depth_scale, od, input_depth, output_depth,
|
||||
attr_align_corners_);
|
||||
for (int64_t oh = 0; oh < output_height; ++oh) {
|
||||
ComputeSourceIndexAndLambda(&ih0, &ih1, &h0lambda, &h1lambda, height_scale, oh, input_height, output_height,
|
||||
attr_align_corners_);
|
||||
for (int64_t ow = 0; ow < output_width; ++ow) {
|
||||
ComputeSourceIndexAndLambda(&iw0, &iw1, &w0lambda, &w1lambda, width_scale, ow, input_width, output_width,
|
||||
attr_align_corners_);
|
||||
auto i000 = static_cast<S>(input_indexr_value(n, id0, ih0, iw0));
|
||||
auto i001 = static_cast<S>(input_indexr_value(n, id0, ih0, iw1));
|
||||
auto i010 = static_cast<S>(input_indexr_value(n, id0, ih1, iw0));
|
||||
auto i011 = static_cast<S>(input_indexr_value(n, id0, ih1, iw1));
|
||||
auto i100 = static_cast<S>(input_indexr_value(n, id1, ih0, iw0));
|
||||
auto i101 = static_cast<S>(input_indexr_value(n, id1, ih0, iw1));
|
||||
auto i110 = static_cast<S>(input_indexr_value(n, id1, ih1, iw0));
|
||||
auto i111 = static_cast<S>(input_indexr_value(n, id1, ih1, iw1));
|
||||
double w000 = static_cast<double>(d0lambda) * h0lambda * w0lambda;
|
||||
double w001 = static_cast<double>(d0lambda) * h0lambda * w1lambda;
|
||||
double w010 = static_cast<double>(d0lambda) * h1lambda * w0lambda;
|
||||
double w011 = static_cast<double>(d0lambda) * h1lambda * w1lambda;
|
||||
double w100 = static_cast<double>(d1lambda) * h0lambda * w0lambda;
|
||||
double w101 = static_cast<double>(d1lambda) * h0lambda * w1lambda;
|
||||
double w110 = static_cast<double>(d1lambda) * h1lambda * w0lambda;
|
||||
double w111 = static_cast<double>(d1lambda) * h1lambda * w1lambda;
|
||||
y_ptr[n * output_slice_size + od * output_height * output_width + oh * output_width + ow] =
|
||||
static_cast<T>(w000 * i000 + w001 * i001 + w010 * i010 + w011 * i011 + w100 * i100 + w101 * i101 +
|
||||
w110 * i110 + w111 * i111);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
float block_size =
|
||||
SizeToLong(kGrainSize) > output_slice_size ? static_cast<float>(kGrainSize / output_slice_size) : 1.0;
|
||||
CPUKernelUtils::ParallelFor(loop3d, channels, block_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<KernelAttr> UpsampleTrilinear3DCpuKernelMod::GetOpSupport() {
|
||||
static std::vector<KernelAttr> support_list = {
|
||||
KernelAttr().AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16),
|
||||
KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32),
|
||||
KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64)};
|
||||
|
||||
return support_list;
|
||||
}
|
||||
MS_KERNEL_FACTORY_REG(NativeCpuKernelMod, UpsampleTrilinear3D, UpsampleTrilinear3DCpuKernelMod);
|
||||
} // namespace kernel
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* 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_BACKEND_KERNEL_COMPILER_CPU_UPSAMLE_TRILINEAR_3D_CPU_KERNEL_H_
|
||||
#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_UPSAMLE_TRILINEAR_3D_CPU_KERNEL_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "plugin/device/cpu/kernel/cpu_kernel.h"
|
||||
#include "kernel/common_utils.h"
|
||||
#include "plugin/factory/ms_factory.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace kernel {
|
||||
class UpsampleTrilinear3DCpuKernelMod : public DeprecatedNativeCpuKernelMod {
|
||||
public:
|
||||
UpsampleTrilinear3DCpuKernelMod() = default;
|
||||
~UpsampleTrilinear3DCpuKernelMod() override = default;
|
||||
|
||||
void InitKernel(const CNodePtr &kernel_node) override;
|
||||
|
||||
bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
|
||||
const std::vector<AddressPtr> &outputs) override;
|
||||
|
||||
protected:
|
||||
std::vector<KernelAttr> GetOpSupport() override;
|
||||
|
||||
private:
|
||||
template <typename T, typename AccT>
|
||||
bool LaunchKernel(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &outputs);
|
||||
|
||||
TypeId in_type_{kTypeUnknown};
|
||||
std::vector<int64_t> x_shape_;
|
||||
std::vector<int64_t> y_shape_;
|
||||
std::vector<float> attr_scales_;
|
||||
bool attr_align_corners_{false};
|
||||
};
|
||||
} // namespace kernel
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_UPSAMLE_TRILINEAR_3D_CPU_KERNEL_H_
|
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
* Copyright 2022 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "plugin/device/cpu/kernel/upsample_trilinear_3d_grad_cpu_kernel.h"
|
||||
#include <string>
|
||||
#include "kernel/common_utils.h"
|
||||
#include "plugin/device/cpu/hal/device/cpu_device_address.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace kernel {
|
||||
namespace {
|
||||
constexpr size_t kUpsampleTrilinear3DGradInputsNum = 1;
|
||||
constexpr size_t kUpsampleTrilinear3DGradOutputNum = 1;
|
||||
// GRAIN_SIZE for Parallel
|
||||
constexpr size_t kGrainSize = 32768;
|
||||
} // namespace
|
||||
|
||||
void UpsampleTrilinear3DGradCpuKernelMod::InitKernel(const CNodePtr &kernel_node) {
|
||||
MS_EXCEPTION_IF_NULL(kernel_node);
|
||||
kernel_name_ = common::AnfAlgo::GetCNodeName(kernel_node);
|
||||
in_type_ = AnfAlgo::GetOutputDeviceDataType(kernel_node, kIndex0);
|
||||
// the input grad of backward process is the output of forward process
|
||||
output_shape_ = AnfAlgo::GetInputDeviceShape(kernel_node, kIndex0);
|
||||
input_shape_ = AnfAlgo::GetOutputDeviceShape(kernel_node, kIndex0);
|
||||
if (output_shape_.size() != kDim5) {
|
||||
MS_EXCEPTION(ValueError) << "For '" << kernel_name_ << "', the dimension of 'grad_out' should be " << kDim5
|
||||
<< ", but got " << output_shape_.size();
|
||||
}
|
||||
attr_scales_ = common::AnfAlgo::GetNodeAttr<std::vector<float>>(kernel_node, kAttrScales);
|
||||
if (attr_scales_.empty()) {
|
||||
attr_scales_ = {0, 0, 0};
|
||||
}
|
||||
attr_align_corners_ = common::AnfAlgo::GetNodeAttr<bool>(kernel_node, kAttrAlignCorners);
|
||||
}
|
||||
|
||||
bool UpsampleTrilinear3DGradCpuKernelMod::Launch(const std::vector<kernel::AddressPtr> &inputs,
|
||||
const std::vector<kernel::AddressPtr> &,
|
||||
const std::vector<kernel::AddressPtr> &outputs) {
|
||||
CHECK_KERNEL_INPUTS_NUM(inputs.size(), kUpsampleTrilinear3DGradInputsNum, kernel_name_);
|
||||
CHECK_KERNEL_OUTPUTS_NUM(outputs.size(), kUpsampleTrilinear3DGradOutputNum, kernel_name_);
|
||||
bool res = false;
|
||||
switch (in_type_) {
|
||||
case kNumberTypeFloat16:
|
||||
res = LaunchKernel<float16, float>(inputs, outputs);
|
||||
break;
|
||||
case kNumberTypeFloat32:
|
||||
res = LaunchKernel<float, float>(inputs, outputs);
|
||||
break;
|
||||
case kNumberTypeFloat64:
|
||||
res = LaunchKernel<double, double>(inputs, outputs);
|
||||
break;
|
||||
default:
|
||||
MS_EXCEPTION(TypeError) << "For '" << kernel_name_
|
||||
<< "', the dtype of 'x' should be float16, float32 or float64. But got "
|
||||
<< TypeIdLabel(in_type_);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
bool UpsampleTrilinear3DGradCpuKernelMod::LaunchKernel(const std::vector<kernel::AddressPtr> &inputs,
|
||||
const std::vector<kernel::AddressPtr> &outputs) {
|
||||
// the input grad of backward process is the output of forward process
|
||||
auto grad_output_ptr = reinterpret_cast<T *>(inputs[kIndex0]->addr);
|
||||
const int64_t total = CPUKernelUtils::CalcElementNum(input_shape_);
|
||||
S *grad_input_ptr = nullptr;
|
||||
bool is_fp16 = std::is_same<T, float16>::value;
|
||||
// define for fp16
|
||||
std::vector<S> grad_input_copy(1);
|
||||
if (is_fp16) {
|
||||
grad_input_copy.resize(total, 0);
|
||||
grad_input_ptr = grad_input_copy.data();
|
||||
} else {
|
||||
grad_input_ptr = reinterpret_cast<S *>(outputs[kIndex0]->addr);
|
||||
std::fill_n(grad_input_ptr, total, S(0));
|
||||
}
|
||||
// treat nbatch and channels as one dimension
|
||||
int64_t channels = input_shape_[kIndex0] * input_shape_[kIndex1];
|
||||
int64_t input_depth = input_shape_[kIndex2];
|
||||
int64_t input_height = input_shape_[kIndex3];
|
||||
int64_t input_width = input_shape_[kIndex4];
|
||||
|
||||
int64_t output_depth = output_shape_[kIndex2];
|
||||
int64_t output_height = output_shape_[kIndex3];
|
||||
int64_t output_width = output_shape_[kIndex4];
|
||||
|
||||
int64_t output_slice_size = output_depth * output_height * output_width;
|
||||
int64_t input_slice_size = input_depth * input_height * input_width;
|
||||
MS_EXCEPTION_IF_CHECK_FAIL(channels != 0 && output_depth != 0 && output_height != 0 && output_width != 0,
|
||||
"Invalid output shape.");
|
||||
|
||||
auto input_index = [=](int64_t c_idx, int64_t d_idx, int64_t h_idx, int64_t w_idx) {
|
||||
return c_idx * input_slice_size + d_idx * input_height * input_width + h_idx * input_width + w_idx;
|
||||
};
|
||||
auto loop3d = [&](int64_t begin, int64_t end) {
|
||||
const S depth_scale =
|
||||
AreaPixelComputeScale<S>(input_depth, output_depth, attr_align_corners_, attr_scales_[kIndex0]);
|
||||
const S height_scale =
|
||||
AreaPixelComputeScale<S>(input_height, output_height, attr_align_corners_, attr_scales_[kIndex1]);
|
||||
const S width_scale =
|
||||
AreaPixelComputeScale<S>(input_width, output_width, attr_align_corners_, attr_scales_[kIndex2]);
|
||||
|
||||
int64_t id0{0}, id1{0}, ih0{0}, ih1{0}, iw0{0}, iw1{0};
|
||||
S d0lambda{0}, d1lambda{0}, h0lambda{0}, h1lambda{0}, w0lambda{0}, w1lambda{0};
|
||||
|
||||
for (int64_t c_idx = begin; c_idx < end; ++c_idx) {
|
||||
for (int64_t od = 0; od < output_depth; ++od) {
|
||||
ComputeSourceIndexAndLambda(&id0, &id1, &d0lambda, &d1lambda, depth_scale, od, input_depth, output_depth,
|
||||
attr_align_corners_);
|
||||
|
||||
for (int64_t oh = 0; oh < output_height; ++oh) {
|
||||
ComputeSourceIndexAndLambda(&ih0, &ih1, &h0lambda, &h1lambda, height_scale, oh, input_height, output_height,
|
||||
attr_align_corners_);
|
||||
|
||||
for (int64_t ow = 0; ow < output_width; ++ow) {
|
||||
ComputeSourceIndexAndLambda(&iw0, &iw1, &w0lambda, &w1lambda, width_scale, ow, input_width, output_width,
|
||||
attr_align_corners_);
|
||||
|
||||
auto grad_output_value = static_cast<S>(
|
||||
grad_output_ptr[c_idx * output_slice_size + od * output_height * output_width + oh * output_width + ow]);
|
||||
double w000 = static_cast<double>(d0lambda) * h0lambda * w0lambda;
|
||||
double w001 = static_cast<double>(d0lambda) * h0lambda * w1lambda;
|
||||
double w010 = static_cast<double>(d0lambda) * h1lambda * w0lambda;
|
||||
double w011 = static_cast<double>(d0lambda) * h1lambda * w1lambda;
|
||||
double w100 = static_cast<double>(d1lambda) * h0lambda * w0lambda;
|
||||
double w101 = static_cast<double>(d1lambda) * h0lambda * w1lambda;
|
||||
double w110 = static_cast<double>(d1lambda) * h1lambda * w0lambda;
|
||||
double w111 = static_cast<double>(d1lambda) * h1lambda * w1lambda;
|
||||
grad_input_ptr[input_index(c_idx, id0, ih0, iw0)] += static_cast<S>(w000 * grad_output_value);
|
||||
grad_input_ptr[input_index(c_idx, id0, ih0, iw1)] += static_cast<S>(w001 * grad_output_value);
|
||||
grad_input_ptr[input_index(c_idx, id0, ih1, iw0)] += static_cast<S>(w010 * grad_output_value);
|
||||
grad_input_ptr[input_index(c_idx, id0, ih1, iw1)] += static_cast<S>(w011 * grad_output_value);
|
||||
grad_input_ptr[input_index(c_idx, id1, ih0, iw0)] += static_cast<S>(w100 * grad_output_value);
|
||||
grad_input_ptr[input_index(c_idx, id1, ih0, iw1)] += static_cast<S>(w101 * grad_output_value);
|
||||
grad_input_ptr[input_index(c_idx, id1, ih1, iw0)] += static_cast<S>(w110 * grad_output_value);
|
||||
grad_input_ptr[input_index(c_idx, id1, ih1, iw1)] += static_cast<S>(w111 * grad_output_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
float block_size =
|
||||
SizeToLong(kGrainSize) > output_slice_size ? static_cast<float>(kGrainSize / output_slice_size) : 1.0;
|
||||
CPUKernelUtils::ParallelFor(loop3d, channels, block_size);
|
||||
// memcopy and cast for fp16
|
||||
if (is_fp16) {
|
||||
T *real_input_ptr = reinterpret_cast<T *>(outputs[kIndex0]->addr);
|
||||
for (int64_t idx = 0; idx < total; ++idx) {
|
||||
real_input_ptr[idx] = static_cast<T>(grad_input_ptr[idx]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<KernelAttr> UpsampleTrilinear3DGradCpuKernelMod::GetOpSupport() {
|
||||
static std::vector<KernelAttr> support_list = {
|
||||
KernelAttr().AddInputAttr(kNumberTypeFloat16).AddOutputAttr(kNumberTypeFloat16),
|
||||
KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32),
|
||||
KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64)};
|
||||
|
||||
return support_list;
|
||||
}
|
||||
MS_KERNEL_FACTORY_REG(NativeCpuKernelMod, UpsampleTrilinear3DGrad, UpsampleTrilinear3DGradCpuKernelMod);
|
||||
} // namespace kernel
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* 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_BACKEND_KERNEL_COMPILER_CPU_UPSAMLE_TRILINEAR_3D_GRAD_CPU_KERNEL_H_
|
||||
#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_UPSAMLE_TRILINEAR_3D_GRAD_CPU_KERNEL_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "kernel/common_utils.h"
|
||||
#include "plugin/device/cpu/kernel/cpu_kernel.h"
|
||||
#include "plugin/factory/ms_factory.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace kernel {
|
||||
class UpsampleTrilinear3DGradCpuKernelMod : public DeprecatedNativeCpuKernelMod {
|
||||
public:
|
||||
UpsampleTrilinear3DGradCpuKernelMod() = default;
|
||||
~UpsampleTrilinear3DGradCpuKernelMod() override = default;
|
||||
|
||||
void InitKernel(const CNodePtr &kernel_node) override;
|
||||
|
||||
bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
|
||||
const std::vector<AddressPtr> &outputs) override;
|
||||
|
||||
protected:
|
||||
std::vector<KernelAttr> GetOpSupport() override;
|
||||
|
||||
private:
|
||||
template <typename T, typename S>
|
||||
bool LaunchKernel(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &outputs);
|
||||
|
||||
TypeId in_type_{kTypeUnknown};
|
||||
std::vector<int64_t> input_shape_;
|
||||
std::vector<int64_t> output_shape_;
|
||||
std::vector<float> attr_scales_;
|
||||
bool attr_align_corners_{false};
|
||||
};
|
||||
} // namespace kernel
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_UPSAMLE_TRILINEAR_3D_GRAD_CPU_KERNEL_H_
|
|
@ -115,9 +115,8 @@ abstract::ShapePtr UpsampleTrilinear3DGradInferShape(const PrimitivePtr &primiti
|
|||
|
||||
TypePtr UpsampleTrilinear3DGradInferType(const PrimitivePtr &primitive,
|
||||
const std::vector<AbstractBasePtr> &input_args) {
|
||||
std::set<TypePtr> valid_types = {kFloat16, kFloat32};
|
||||
TypePtr grad_type = input_args[kInputIndex0]->BuildType();
|
||||
return CheckAndConvertUtils::CheckTensorTypeValid("grad", grad_type, valid_types, primitive->name());
|
||||
return CheckAndConvertUtils::CheckTensorTypeValid("grad", grad_type, common_float_types, primitive->name());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
/**
|
||||
* 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_GRAD_UPSAMPLE_TRILINEAR_3D_GRAD_H
|
||||
#define MINDSPORE_CORE_OPS_GRAD_UPSAMPLE_TRILINEAR_3D_GRAD_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ops/base_operator.h"
|
||||
#include "mindapi/base/types.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace ops {
|
||||
constexpr auto kNameUpsampleTrilinear3DGrad = "UpsampleTrilinear3DGrad";
|
||||
class MIND_API UpsampleTrilinear3DGrad : public BaseOperator {
|
||||
public:
|
||||
MIND_API_BASE_MEMBER(UpsampleTrilinear3DGrad);
|
||||
UpsampleTrilinear3DGrad() : BaseOperator(kNameUpsampleTrilinear3DGrad) { InitIOName({"grad"}, {"dx"}); }
|
||||
bool get_align_corners() const;
|
||||
std::vector<int64_t> get_out_spatial_size() const;
|
||||
std::vector<int64_t> get_grad_spatial_size() const;
|
||||
std::vector<float> get_scale_factors() const;
|
||||
};
|
||||
|
||||
abstract::AbstractBasePtr UpsampleTrilinear3DGradInfer(const abstract::AnalysisEnginePtr &,
|
||||
const PrimitivePtr &primitive,
|
||||
const std::vector<abstract::AbstractBasePtr> &input_args);
|
||||
using PrimUpsampleTrilinear3DGrad = std::shared_ptr<UpsampleTrilinear3DGrad>;
|
||||
} // namespace ops
|
||||
} // namespace mindspore
|
||||
#endif // MINDSPORE_CORE_OPS_GRAD_UPSAMPLE_TRILINEAR_3D_GRAD_H
|
||||
/**
|
||||
* 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_GRAD_UPSAMPLE_TRILINEAR_3D_GRAD_H
|
||||
#define MINDSPORE_CORE_OPS_GRAD_UPSAMPLE_TRILINEAR_3D_GRAD_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ops/base_operator.h"
|
||||
#include "mindapi/base/types.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace ops {
|
||||
constexpr auto kNameUpsampleTrilinear3DGrad = "UpsampleTrilinear3DGrad";
|
||||
class MIND_API UpsampleTrilinear3DGrad : public BaseOperator {
|
||||
public:
|
||||
MIND_API_BASE_MEMBER(UpsampleTrilinear3DGrad);
|
||||
UpsampleTrilinear3DGrad() : BaseOperator(kNameUpsampleTrilinear3DGrad) { InitIOName({"grad"}, {"dx"}); }
|
||||
bool get_align_corners() const;
|
||||
std::vector<int64_t> get_out_spatial_size() const;
|
||||
std::vector<int64_t> get_grad_spatial_size() const;
|
||||
std::vector<float> get_scale_factors() const;
|
||||
};
|
||||
|
||||
abstract::AbstractBasePtr UpsampleTrilinear3DGradInfer(const abstract::AnalysisEnginePtr &,
|
||||
const PrimitivePtr &primitive,
|
||||
const std::vector<abstract::AbstractBasePtr> &input_args);
|
||||
using PrimUpsampleTrilinear3DGrad = std::shared_ptr<UpsampleTrilinear3DGrad>;
|
||||
} // namespace ops
|
||||
} // namespace mindspore
|
||||
#endif // MINDSPORE_CORE_OPS_GRAD_UPSAMPLE_TRILINEAR_3D_GRAD_H
|
||||
|
|
|
@ -41,6 +41,7 @@ const std::set<TypePtr> common_valid_types_with_complex_and_bool = {
|
|||
kInt8, kInt16, kInt32, kInt64, kUInt8, kUInt16, kUInt32,
|
||||
kUInt64, kFloat16, kFloat32, kFloat64, kComplex64, kComplex128, kBool};
|
||||
|
||||
const std::set<TypePtr> common_float_types = {kFloat16, kFloat32, kFloat64};
|
||||
const std::set<TypePtr> all_types = {
|
||||
kBool, kInt, kInt8, kInt16, kInt32, kInt64, kUInt, kUInt8,
|
||||
kUInt16, kUInt32, kUInt64, kFloat, kFloat16, kFloat32, kFloat64, kComplex64,
|
||||
|
|
|
@ -15,11 +15,15 @@
|
|||
*/
|
||||
|
||||
#include "ops/upsample_trilinear_3d.h"
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "abstract/ops/primitive_infer_map.h"
|
||||
#include "ops/op_utils.h"
|
||||
#include "mindapi/src/helper.h"
|
||||
#include "utils/check_convert_utils.h"
|
||||
#include "mindapi/src/helper.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace ops {
|
||||
|
@ -36,81 +40,70 @@ void CheckDims(string check_dim_name, string op_name, std::vector<T> check_vecto
|
|||
|
||||
abstract::ShapePtr UpsampleTrilinear3DInferShape(const PrimitivePtr &primitive,
|
||||
const std::vector<AbstractBasePtr> &input_args) {
|
||||
string op_name = primitive->name();
|
||||
MS_EXCEPTION_IF_NULL(input_args[kInputIndex0]);
|
||||
auto input_shape = CheckAndConvertUtils::ConvertShapePtrToShapeMap(input_args[kInputIndex0]->BuildShape())[kShape];
|
||||
auto input_shape_ptr = input_args[kInputIndex0]->BuildShape();
|
||||
const size_t kDimSize5 = 5;
|
||||
if (input_shape.size() != kDimSize5) {
|
||||
MS_EXCEPTION(TypeError) << "input_shape of UpsampleTrilinear3D must be 5, but got" << input_shape.size();
|
||||
}
|
||||
auto prim_name = primitive->name();
|
||||
auto x_shape = CheckAndConvertUtils::ConvertShapePtrToShapeMap(input_args[kInputIndex0]->BuildShape())[kShape];
|
||||
|
||||
const size_t kOutputSizeDims = 3;
|
||||
const size_t kScalesDims = 3;
|
||||
auto output_size = GetValue<std::vector<int64_t>>(primitive->GetAttr("output_size"));
|
||||
auto scales = GetValue<std::vector<float>>(primitive->GetAttr("scales"));
|
||||
if (output_size.empty() && scales.empty()) {
|
||||
MS_EXCEPTION(ValueError) << "For '" << op_name << "', either output_size or scales should be defined.";
|
||||
(void)CheckAndConvertUtils::CheckInteger("dimension of x", SizeToLong(x_shape.size()), kEqual, SizeToLong(kDim5),
|
||||
prim_name);
|
||||
|
||||
auto output_size_ptr = primitive->GetAttr(kOutputSize);
|
||||
MS_EXCEPTION_IF_NULL(output_size_ptr);
|
||||
auto output_size = GetValue<std::vector<int64_t>>(output_size_ptr);
|
||||
|
||||
auto scales_ptr = primitive->GetAttr(kScales);
|
||||
MS_EXCEPTION_IF_NULL(scales_ptr);
|
||||
auto scales = GetValue<std::vector<float>>(scales_ptr);
|
||||
|
||||
ShapeVector output_shape;
|
||||
output_shape.emplace_back(x_shape[kInputIndex0]);
|
||||
output_shape.emplace_back(x_shape[kInputIndex1]);
|
||||
|
||||
if (!output_size.empty() && scales.empty()) {
|
||||
(void)CheckAndConvertUtils::CheckPositiveVector(kOutputSize, output_size, prim_name);
|
||||
(void)CheckAndConvertUtils::CheckInteger("the elements number of output_size", SizeToLong(output_size.size()),
|
||||
kEqual, SizeToLong(kDim3), prim_name);
|
||||
output_shape.insert(output_shape.end(), output_size.begin(), output_size.end());
|
||||
} else if (output_size.empty() && !scales.empty()) {
|
||||
(void)CheckAndConvertUtils::CheckPositiveVector(kScales, scales, prim_name);
|
||||
(void)CheckAndConvertUtils::CheckInteger("the elements number of scales", SizeToLong(scales.size()), kEqual,
|
||||
SizeToLong(kDim3), prim_name);
|
||||
for (size_t idx = 0; idx < kDim3; ++idx) {
|
||||
output_shape.emplace_back(int64_t(floor(x_shape[idx + kDim2] * scales[idx])));
|
||||
}
|
||||
} else if (output_size.empty() && scales.empty()) {
|
||||
MS_EXCEPTION(ValueError) << "For " << prim_name << ", only one of 'scales' and 'output_size' can be specified."
|
||||
<< " But get both empty or None.";
|
||||
} else if (!output_size.empty() && !scales.empty()) {
|
||||
MS_EXCEPTION(ValueError) << "For '" << op_name << "', only one of output_size or scales should be defined.";
|
||||
MS_EXCEPTION(ValueError) << "For " << prim_name << ", only one of 'scales' and 'output_size' can be specified."
|
||||
<< " But get both.";
|
||||
}
|
||||
if (!output_size.empty() && output_size.size() != kOutputSizeDims) {
|
||||
MS_EXCEPTION(ValueError) << "For '" << op_name << "', output_size must be size of 3, but got "
|
||||
<< std::to_string(output_size.size()) << ".";
|
||||
}
|
||||
if (!scales.empty() && scales.size() != kScalesDims) {
|
||||
MS_EXCEPTION(ValueError) << "For '" << op_name << "', scales must be size of 3, but got "
|
||||
<< std::to_string(scales.size()) << ".";
|
||||
}
|
||||
string name_ = "scales";
|
||||
std::vector<int64_t> output_shape(input_shape.size());
|
||||
output_shape[0] = input_shape[0];
|
||||
output_shape[1] = input_shape[1];
|
||||
if (output_size.empty()) {
|
||||
CheckDims(name_, op_name, scales);
|
||||
output_shape[kInputIndex2] = static_cast<int64_t>(std::floor(input_shape[kInputIndex2] * scales[kInputIndex0]));
|
||||
output_shape[kInputIndex3] = static_cast<int64_t>(std::floor(input_shape[kInputIndex3] * scales[kInputIndex1]));
|
||||
output_shape[kInputIndex4] = static_cast<int64_t>(std::floor(input_shape[kInputIndex4] * scales[kInputIndex2]));
|
||||
} else {
|
||||
name_ = "output_size";
|
||||
CheckDims(name_, op_name, output_size);
|
||||
output_shape[kInputIndex2] = output_size[kInputIndex0];
|
||||
output_shape[kInputIndex3] = output_size[kInputIndex1];
|
||||
output_shape[kInputIndex4] = output_size[kInputIndex2];
|
||||
}
|
||||
if (input_shape_ptr->IsDynamic()) {
|
||||
return std::make_shared<abstract::Shape>(output_shape);
|
||||
}
|
||||
|
||||
name_ = "output_shape";
|
||||
CheckDims(name_, op_name, output_shape);
|
||||
constexpr auto name_ = "output_shape";
|
||||
CheckDims(name_, prim_name, output_shape);
|
||||
return std::make_shared<abstract::Shape>(output_shape);
|
||||
}
|
||||
|
||||
TypePtr UpsampleTrilinear3DInferType(const PrimitivePtr &primitive, const std::vector<AbstractBasePtr> &input_args) {
|
||||
const std::set<TypePtr> valid_types = {kFloat16, kFloat32};
|
||||
TypePtr input_type = input_args[kInputIndex0]->BuildType();
|
||||
return CheckAndConvertUtils::CheckTypeValid("x", input_type, valid_types, primitive->name());
|
||||
return CheckAndConvertUtils::CheckTensorTypeValid("x", input_args[kInputIndex0]->BuildType(), common_float_types,
|
||||
primitive->name());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
MIND_API_OPERATOR_IMPL(UpsampleTrilinear3D, BaseOperator);
|
||||
AbstractBasePtr UpsampleTrilinear3DInfer(const abstract::AnalysisEnginePtr &, const PrimitivePtr &primitive,
|
||||
const std::vector<AbstractBasePtr> &input_args) {
|
||||
MS_EXCEPTION_IF_NULL(primitive);
|
||||
const int64_t kInputsNum = 1;
|
||||
CheckAndConvertUtils::CheckInputArgs(input_args, kEqual, kInputsNum, primitive->name());
|
||||
auto prim_name = primitive->name();
|
||||
constexpr int64_t input_num = 1;
|
||||
CheckAndConvertUtils::CheckInputArgs(input_args, kEqual, input_num, prim_name);
|
||||
auto infer_type = UpsampleTrilinear3DInferType(primitive, input_args);
|
||||
auto infer_shape = UpsampleTrilinear3DInferShape(primitive, input_args);
|
||||
return abstract::MakeAbstract(infer_shape, infer_type);
|
||||
}
|
||||
|
||||
std::vector<int64_t> UpsampleTrilinear3D::get_out_spatial_size() const {
|
||||
auto value_ptr = this->GetAttr("output_size");
|
||||
auto value_ptr = this->GetAttr(kOutputSize);
|
||||
return GetValue<std::vector<int64_t>>(value_ptr);
|
||||
}
|
||||
std::vector<float> UpsampleTrilinear3D::get_scale_factors() const {
|
||||
auto value_ptr = this->GetAttr("scales");
|
||||
auto value_ptr = this->GetAttr(kScales);
|
||||
return GetValue<std::vector<float>>(value_ptr);
|
||||
}
|
||||
bool UpsampleTrilinear3D::get_align_corners() const {
|
||||
|
@ -118,6 +111,7 @@ bool UpsampleTrilinear3D::get_align_corners() const {
|
|||
return GetValue<bool>(value_ptr);
|
||||
}
|
||||
|
||||
MIND_API_OPERATOR_IMPL(UpsampleTrilinear3D, BaseOperator);
|
||||
REGISTER_PRIMITIVE_EVAL_IMPL(UpsampleTrilinear3D, prim::kPrimUpsampleTrilinear3D, UpsampleTrilinear3DInfer, nullptr,
|
||||
true);
|
||||
} // namespace ops
|
||||
|
|
|
@ -274,7 +274,7 @@ class Validator:
|
|||
@staticmethod
|
||||
def check_positive_int_sequence(sequence, arg_name=None, prim_name=None):
|
||||
"""
|
||||
Check argument is positive sequence, which mean all element > 0 in sequence.
|
||||
Check argument is positive int sequence, which mean all element > 0 in sequence.
|
||||
|
||||
Usage:
|
||||
- sequence = check_positive_int_sequence(sequence)
|
||||
|
|
|
@ -36,6 +36,8 @@ from ..operations._grad_ops import FractionalAvgPoolGrad
|
|||
from ..operations.nn_ops import MultiMarginLoss
|
||||
from ..operations.nn_ops import MultilabelMarginLoss
|
||||
from ..operations.nn_ops import NthElement
|
||||
from ..operations.nn_ops import UpsampleTrilinear3D
|
||||
from ..operations._grad_ops import UpsampleTrilinear3DGrad
|
||||
from ..operations.nn_ops import PSROIPooling
|
||||
from ..operations._grad_ops import PSROIPoolingGrad
|
||||
from ..operations.nn_ops import AvgPoolV1
|
||||
|
@ -172,6 +174,21 @@ def get_bprop_upsample_nearest_3d(self):
|
|||
return bprop
|
||||
|
||||
|
||||
@bprop_getters.register(UpsampleTrilinear3D)
|
||||
def get_bprop_upsample_trilinear_3d(self):
|
||||
"""Grad definition for `UpsampleTrilinear3D` operation."""
|
||||
output_size = self.output_size
|
||||
scales = self.scales
|
||||
align_corners = self.align_corners
|
||||
def bprop(x, out, dout):
|
||||
input_size = P.Shape()(x)
|
||||
grad_op = UpsampleTrilinear3DGrad(input_size, output_size, scales, align_corners)
|
||||
dx = grad_op(dout)
|
||||
return (dx,)
|
||||
|
||||
return bprop
|
||||
|
||||
|
||||
@bprop_getters.register(GridSampler3D)
|
||||
def get_bprop_grid_sampler_3d(self):
|
||||
"""Grad definition for `GridSampler3D` operation."""
|
||||
|
|
|
@ -156,6 +156,8 @@ from .poisson import _poisson_aicpu
|
|||
from .update_cache import _update_cache_aicpu
|
||||
from .upsample_nearest_3d import _upsample_nearest_3d_aicpu
|
||||
from .upsample_nearest_3d_grad import _upsample_nearest_3d_grad_aicpu
|
||||
from .upsample_trilinear_3d import _upsample_trilinear_3d_aicpu
|
||||
from .upsample_trilinear_3d_grad import _upsample_trilinear_3d_grad_aicpu
|
||||
from .cache_swap_table import _cache_swap_table_aicpu
|
||||
from .uniform_int import _uniform_int_aicpu
|
||||
from .uniform_real import _uniform_real_aicpu
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# 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.
|
||||
# ============================================================================
|
||||
|
||||
"""UpsampleTrilinear3D op"""
|
||||
from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType
|
||||
|
||||
upsample_trilinear_3d_op_info = AiCPURegOp("UpsampleTrilinear3D") \
|
||||
.fusion_type("OPAQUE") \
|
||||
.attr("output_size", "listInt") \
|
||||
.attr("scales", "listFloat") \
|
||||
.attr("align_corners", "bool") \
|
||||
.input(0, "x", "required") \
|
||||
.output(0, "y", "required") \
|
||||
.dtype_format(DataType.F16_Default, DataType.F16_Default) \
|
||||
.dtype_format(DataType.F32_Default, DataType.F32_Default) \
|
||||
.dtype_format(DataType.F64_Default, DataType.F64_Default) \
|
||||
.get_op_info()
|
||||
|
||||
|
||||
@op_info_register(upsample_trilinear_3d_op_info)
|
||||
def _upsample_trilinear_3d_aicpu():
|
||||
"""UpsampleTrilinear3D AiCPU register"""
|
||||
return
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
|
||||
|
||||
# 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.
|
||||
# ============================================================================
|
||||
|
||||
"""UpsampleTrilinear3DGrad op"""
|
||||
from mindspore.ops.op_info_register import op_info_register, AiCPURegOp, DataType
|
||||
|
||||
upsample_trilinear_3d_grad_op_info = AiCPURegOp("UpsampleTrilinear3DGrad") \
|
||||
.fusion_type("OPAQUE") \
|
||||
.attr("input_size", "listInt") \
|
||||
.attr("output_size", "listInt") \
|
||||
.attr("scales", "listFloat") \
|
||||
.attr("align_corners", "bool") \
|
||||
.input(0, "grad_output", "required") \
|
||||
.output(0, "y", "required") \
|
||||
.dtype_format(DataType.F16_Default, DataType.F16_Default) \
|
||||
.dtype_format(DataType.F32_Default, DataType.F32_Default) \
|
||||
.dtype_format(DataType.F64_Default, DataType.F64_Default) \
|
||||
.get_op_info()
|
||||
|
||||
|
||||
@op_info_register(upsample_trilinear_3d_grad_op_info)
|
||||
def _upsample_trilinear_3d_grad_aicpu():
|
||||
"""UpsampleTrilinear3DGrad AiCPU register"""
|
||||
return
|
|
@ -3011,6 +3011,84 @@ class MultiMarginLossGrad(Primitive):
|
|||
self.init_prim_io_names(inputs=['y_grad', 'x', 'target', 'weight'], outputs=['x_grad'])
|
||||
|
||||
|
||||
class UpsampleTrilinear3DGrad(Primitive):
|
||||
r"""
|
||||
Upsample the 3-D gradient data with trilinear interpolation algorithm.
|
||||
|
||||
Args:
|
||||
input_size (Union[tuple[int], list[int]]): An required listInt.
|
||||
contain 5 elements: [batch, channels, depth, height, width]. Must:
|
||||
input_size[0] == grad_output_tensor_size[0]
|
||||
input_size[1] == grad_output_tensor_size[1].
|
||||
output_size (Union[tuple[int], list[int]]): An optional listInt. Defaults to none.
|
||||
contain 3 elements: depth, height, width. The number of elements of 'output_size' should
|
||||
be the same as the rank of input 'grad_output'.
|
||||
Only one of 'scales' and 'output_size' can be specified. Must:
|
||||
grad_output_tensor_size[2] == floor(input_size[2] * scales[0]) == output_size[0]
|
||||
grad_output_tensor_size[3] == floor(input_size[3] * scales[1]) == output_size[1]
|
||||
grad_output_tensor_size[4] == floor(input_size[4] * scales[2]) == output_size[2].
|
||||
scales (Union[tuple[float], list[float]]): An optional listFloat. Defaults to none.
|
||||
The scale array along each dimension, contain 3 elements: scale_depth, scale_height, scale_width.
|
||||
The number of elements of 'scales' should be the same as the rank of input 'grad_output'.
|
||||
One of 'scales' and 'output_size' MUST be specified and it is an error if both are specified.
|
||||
align_corners (bool): An optional bool. Defaults to false.
|
||||
|
||||
Inputs:
|
||||
- **grad_output** (Tensor) - A 5-D input tensor [N, C, D, H, W].
|
||||
Must be one of the following types: [float16, float32, float64].
|
||||
|
||||
Outputs:
|
||||
backprops Tensor - A Tensor with shape depends on intput_size and output_size/scales.
|
||||
Must be one of the following types: [float16, float32, float64].
|
||||
|
||||
Raises:
|
||||
TypeError: If dtype of `x` is not int [float16, float32, float64].
|
||||
TypeError: If `input_size` is not list[int] or tuple[int].
|
||||
TypeError: When `output_size` is not none and `output_size` is not list[int] or tuple[int].
|
||||
TypeError: When `scales` is not none and `scales` is not list[float] or tuple[float].
|
||||
TypeError: If type of `align_corners` is not bool.
|
||||
ValueError: If any value of `output_size` is negative or zero when `output_size` is not empty.
|
||||
ValueError: If any value of `scales` is negative or zero when `scales` is not empty.
|
||||
ValueError: If shape of `x` is not 5D.
|
||||
ValueError: If none of `scales` and `output_size` is specified or both specified.
|
||||
ValueError: If size of `scales` is not equal 3 when `scales` is specified.
|
||||
ValueError: If size of `output_size` is not equal 3 when `output_size` is specified.
|
||||
TypeError: If `input_size` is not Union[tuple[int], list[int]].
|
||||
ValueError: If any value of `input_size` is negative.
|
||||
ValueError: If elements number of `input_size` is not 5.
|
||||
|
||||
Supported Platforms:
|
||||
``Ascend`` ``CPU`` ``GPU``
|
||||
"""
|
||||
@prim_attr_register
|
||||
def __init__(self, input_size, output_size=None, scales=None, align_corners=False):
|
||||
"""Initialize UpsampleTrilinear3DGrad."""
|
||||
self.init_prim_io_names(inputs=['grad_output'], outputs=['y'])
|
||||
self.input_size = input_size
|
||||
self.output_size = [] if output_size is None else output_size
|
||||
self.scales = [] if scales is None else scales
|
||||
self.align_corners = align_corners
|
||||
|
||||
validator.check_value_type("input_size", self.input_size, [list, tuple], self.name)
|
||||
validator.check_equal_int(len(self.input_size), 5, "the dimension of input_size", self.name)
|
||||
validator.check_value_type("output_size", self.output_size, [list, tuple], self.name)
|
||||
validator.check_value_type("scales", self.scales, [list, tuple], self.name)
|
||||
validator.check_bool(self.align_corners, self.name)
|
||||
if len(self.output_size) == 3:
|
||||
validator.check_positive_int_sequence(self.output_size, "output_size", self.name)
|
||||
if len(self.scales) == 3:
|
||||
validator.check_positive_float_sequence(self.scales, "scales", self.name)
|
||||
if self.output_size == []:
|
||||
validator.check_equal_int(len(self.scales), 3, 'size of scales', self.name)
|
||||
if self.scales == []:
|
||||
validator.check_equal_int(len(self.output_size), 3, 'size of output_size', self.name)
|
||||
|
||||
self.add_prim_attr('input_size', self.input_size)
|
||||
self.add_prim_attr('output_size', self.output_size)
|
||||
self.add_prim_attr('scales', self.scales)
|
||||
self.add_prim_attr('align_corners', self.align_corners)
|
||||
|
||||
|
||||
class GridSampler3DGrad(Primitive):
|
||||
"""
|
||||
Computes gradients for GridSampler3D operation.
|
||||
|
@ -3433,67 +3511,6 @@ class GridSampler2DGrad(Primitive):
|
|||
self.add_prim_attr('align_corners', align_corners)
|
||||
|
||||
|
||||
class UpsampleTrilinear3DGrad(Primitive):
|
||||
"""
|
||||
Computes gradients for UpsampleTrilinear3DGrad operation.
|
||||
|
||||
Args:
|
||||
input_size (Union[tuple[int], list[int]]): A list or tuple of int specifying the forward pass
|
||||
input Tensor size, identical to the gradient tensor returned by this op.
|
||||
output_size (Union[tuple[int], list[int]]): A list or tuple of int specifying the output
|
||||
volumetric size, identical to the backprop gradient entering this op. Defaults to None.
|
||||
scales (Union[tuple[float], list[float]]): A list or tuple of float specifying the upsampling factors.
|
||||
Defaults to None.
|
||||
align_corners (bool): An optional bool. If "true", the centers of the corner pixels of the input and output
|
||||
tensors are aligned. Defaults to "false".
|
||||
|
||||
Inputs:
|
||||
- **grad** (Tensor) - 5D tensor of shape :math:`(N, C, D_{grad}, H_{grad}, W_{grad})`. With float16 or
|
||||
float32 data type.
|
||||
|
||||
Outputs:
|
||||
- **dx** (Tensor) - 5D tensor of shape :math:`(N, C, D_{dx}, H_{dx}, W_{dx})`. With float16 or
|
||||
float32 data type.
|
||||
|
||||
Raises:
|
||||
TypeError: If data type of `grad` is not float16, float32.
|
||||
TypeError: If `input_size` is not provided.
|
||||
ValueError: If size of `grad` is not a 5D tensor.
|
||||
ValueError: If `output_size` is a list or tuple and if `output_size` length is not 3.
|
||||
ValueError: If `scales` is a list or tuple and if `scales` length is not 3.
|
||||
ValueError: If both `output_size` and `scales` are None.
|
||||
ValueError: If both `output_size` and `scales` are non-empty lists.
|
||||
|
||||
|
||||
Supported Platforms:
|
||||
``GPU``
|
||||
"""
|
||||
|
||||
@prim_attr_register
|
||||
def __init__(self, input_size, output_size=None, scales=None, align_corners=None):
|
||||
self.init_prim_io_names(inputs=['grad'], outputs=['dx'])
|
||||
if output_size is None:
|
||||
output_size = []
|
||||
if scales is None:
|
||||
scales = []
|
||||
if align_corners is None:
|
||||
align_corners = False
|
||||
validator.check_value_type('input_size', input_size, [list, tuple], self.name)
|
||||
for item in input_size:
|
||||
validator.check_value_type('input_size_item', item, int, self.name)
|
||||
validator.check_value_type("output_size", output_size, [list, tuple], self.name)
|
||||
for item in output_size:
|
||||
validator.check_value_type('output_size_item', item, int, self.name)
|
||||
validator.check_value_type("scales", scales, [list, tuple], self.name)
|
||||
for item in scales:
|
||||
validator.check_value_type('scales_item', item, float, self.name)
|
||||
validator.check_value_type('align_corners', align_corners, bool, self.name)
|
||||
self.add_prim_attr('input_size', input_size)
|
||||
self.add_prim_attr('output_size', output_size)
|
||||
self.add_prim_attr('scales', scales)
|
||||
self.add_prim_attr('align_corners', align_corners)
|
||||
|
||||
|
||||
class ResizeBicubicGrad(Primitive):
|
||||
"""
|
||||
Computes gradients for ResizeBicubicGrad operation.
|
||||
|
|
|
@ -3744,6 +3744,92 @@ class ResizeBilinear(PrimitiveWithInfer):
|
|||
return input_dtype
|
||||
|
||||
|
||||
class UpsampleTrilinear3D(Primitive):
|
||||
r"""
|
||||
Performs upsampling with trilinear interpolation across 3dims for 5dim inputs.
|
||||
|
||||
This operator scale up the volumetric input with specified `output_size` or `scales` factors,
|
||||
using trilinear upscaling algorithm.
|
||||
|
||||
Note:
|
||||
One of `scales` and `output_size` MUST be specified and it is an error if both are specified.
|
||||
|
||||
Args:
|
||||
output_size (Union[tuple[int], list[int]]): A tuple or list of 3 int
|
||||
elements :math:`(output\_depth, output\_height, output\_width)`.
|
||||
Defaults to None. Only one of `scales` and `output_size` can be specified.
|
||||
scales (Union[tuple[float], list[float]]): A tuple or list of 3 float
|
||||
elements :math:`(scale\_depth, scale\_height, scale\_width)`. Defaults to None.
|
||||
align_corners (bool): An optional bool. Defaults to false.
|
||||
If true, the input and output tensors are aligned by the center points of their corner pixels,
|
||||
preserving the values at the corner pixels.
|
||||
If false, the input and output tensors are aligned by the corner points of their corner pixels,
|
||||
and the interpolation use edge value padding for out of boundary values.
|
||||
|
||||
Inputs:
|
||||
- **x** (Tensor) - A 5-D input tensor of shape :math:`(N, C, D_{in}, H_{in}, W_{in})`.
|
||||
Must be one of the following types: float16, float32, float64.
|
||||
|
||||
Outputs:
|
||||
- **y** (Tensor) - Upsampled output with the same data type as `x`.
|
||||
Tensor of shape :math:`(N, C, D_{out}, H_{out}, W_{out})`.
|
||||
|
||||
Raises:
|
||||
TypeError: When `output_size` is not none and `output_size` is not list[int] or tuple[int].
|
||||
TypeError: When `scales` is not none and `scales` is not list[float] or tuple[float].
|
||||
TypeError: If dtype of `x` is not in [float16, float32, float64].
|
||||
TypeError: If type of `align_corners` is not bool.
|
||||
ValueError: If any value of `output_size` is negative or zero when `output_size` is not empty.
|
||||
ValueError: If any value of `scales` is negative or zero when `scales` is not empty.
|
||||
ValueError: If shape of `x` is not 5D.
|
||||
ValueError: If none of `scales` and `output_size` is specified or both specified.
|
||||
ValueError: If size of `scales` is not equal 3 when `scales` is specified.
|
||||
ValueError: If size of `output_size` is not equal 3 when `output_size` is specified.
|
||||
|
||||
Supported Platforms:
|
||||
``Ascend`` ``CPU`` ``GPU``
|
||||
|
||||
Examples:
|
||||
>>> ops = P.UpsampleTrilinear3D(output_size=[4, 64, 48])
|
||||
>>> out = ops(Tensor(input_data=np.random.randn(2, 3, 4, 512, 256)))
|
||||
>>> print(out.shape)
|
||||
(2, 3, 4, 64, 48)
|
||||
|
||||
>>> ops = P.UpsampleTrilinear3D(output_size=[2, 4, 4])
|
||||
>>> in_x = Tensor(np.arange(1, 5, dtype=np.float32).reshape((1, 1, 1, 2, 2)))
|
||||
>>> out = ops(in_x)
|
||||
>>> print(out)
|
||||
[[[[[1. 1.25 1.75 2. ]
|
||||
[1.5 1.75 2.25 2.5 ]
|
||||
[2.5 2.75 3.25 3.5 ]
|
||||
[3. 3.25 3.75 4. ]]
|
||||
[[1. 1.25 1.75 2. ]
|
||||
[1.5 1.75 2.25 2.5 ]
|
||||
[2.5 2.75 3.25 3.5 ]
|
||||
[3. 3.25 3.75 4. ]]]]]
|
||||
"""
|
||||
@prim_attr_register
|
||||
def __init__(self, output_size=None, scales=None, align_corners=False):
|
||||
"""Initialize UpsampleTrilinear3D."""
|
||||
self.init_prim_io_names(inputs=['x'], outputs=['y'])
|
||||
self.output_size = [] if output_size is None else output_size
|
||||
self.scales = [] if scales is None else scales
|
||||
self.align_corners = align_corners
|
||||
|
||||
validator.check_value_type("output_size", self.output_size, [list, tuple], self.name)
|
||||
validator.check_value_type("scales", self.scales, [list, tuple], self.name)
|
||||
validator.check_bool(self.align_corners, "align_corners", self.name)
|
||||
if len(self.output_size) == 3:
|
||||
validator.check_positive_int_sequence(self.output_size, "output_size", self.name)
|
||||
if len(self.scales) == 3:
|
||||
validator.check_positive_float_sequence(self.scales, "scales", self.name)
|
||||
|
||||
self.add_prim_attr('output_size', self.output_size)
|
||||
self.add_prim_attr('scales', self.scales)
|
||||
self.add_prim_attr('align_corners', self.align_corners)
|
||||
|
||||
|
||||
|
||||
class OneHot(Primitive):
|
||||
r"""
|
||||
Computes a one-hot tensor.
|
||||
|
@ -10148,84 +10234,6 @@ class Pdist(Primitive):
|
|||
self.init_prim_io_names(inputs=['x'], outputs=['y'])
|
||||
|
||||
|
||||
class UpsampleTrilinear3D(Primitive):
|
||||
r"""
|
||||
Performs upsampling with trilinear interpolation across 3dims for 5dim inputs.
|
||||
|
||||
This operator scale up the volumetric input with specified `output_size` or `scales` factors,
|
||||
using trilinear upscaling algorithm.
|
||||
|
||||
One of `output_size` or `scales` must be given, and cannot specify both.
|
||||
|
||||
Args:
|
||||
output_size (Union[tuple[int], list[int]]): A list of int specifying the output volumetric size. Default: None.
|
||||
scales (Union[tuple[float], list[float]]): A list of float specifying the upsampling factors. Default: None.
|
||||
align_corners (bool): If true, rescale input by :math:`(new\_height - 1) / (height - 1)`,
|
||||
which exactly aligns the 4 corners of images and resized images. If false,
|
||||
rescale by :math:`new\_height / height`. Default: False.
|
||||
|
||||
Inputs:
|
||||
- **x** (Tensor) - 5D tensor of shape :math:`(N, C, D_{in}, H_{in}, W_{in})`.
|
||||
|
||||
Outputs:
|
||||
- **y** (Tensor) - Upsampled output with the same data type as `x`.
|
||||
Tensor of shape :math:`(N, C, D_{out}, H_{out}, W_{out})`.
|
||||
|
||||
Raises:
|
||||
TypeError: If `x` is not a 5D tensor.
|
||||
TypeError: If data type of `x` is not float16, float32.
|
||||
TypeError: If data type of `output_size` is not list(int).
|
||||
TypeError: If data type of `scales` is not list(float).
|
||||
TypeError: If `align_corners` is not a bool.
|
||||
ValueError: If `output_size` is a list and if `output_size` length is not 3.
|
||||
ValueError: If `scales` is a list and if `scales` length is not 3.
|
||||
ValueError: If both `output_size` and `scales` are None.
|
||||
ValueError: If both `output_size` and `scales` are non-empty lists.
|
||||
|
||||
|
||||
Supported Platforms:
|
||||
``GPU``
|
||||
|
||||
Examples:
|
||||
>>> x = Tensor(np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
|
||||
... .reshape([1, 1, 2, 2, 4]), mstype.float32)
|
||||
>>> output_size = [3, 4, 5]
|
||||
>>> net = ops.UpsampleTrilinear3D(output_size = output_size)
|
||||
>>> output = net(x)
|
||||
>>> print(output)
|
||||
[[[[[ 1. 1.7 2.5 3.3 4.]
|
||||
[ 2. 2.7 3.5 4.3 5.]
|
||||
[ 4. 4.7 5.5 6.3 7.]
|
||||
[ 5. 5.7 6.5 7.3 8.]]
|
||||
[[ 5. 5.7 6.5 7.3 8.]
|
||||
[ 6. 6.7 7.5 8.3 9.]
|
||||
[ 8. 8.700001 9.5 10.3 11.]
|
||||
[ 9. 9.700001 10.5 11.3 12.]]
|
||||
[[ 9. 9.7 10.5 11.3 12.]
|
||||
[10. 10.7 11.5 12.3 13.]
|
||||
[12. 12.700001 13.5 14.3 15.]
|
||||
[13. 13.700001 14.5 15.3 16.]]]]]
|
||||
"""
|
||||
|
||||
@prim_attr_register
|
||||
def __init__(self, output_size=None, scales=None, align_corners=False):
|
||||
self.init_prim_io_names(inputs=['x'], outputs=['y'])
|
||||
if output_size is None:
|
||||
output_size = []
|
||||
if scales is None:
|
||||
scales = []
|
||||
validator.check_value_type('output_size', output_size, [tuple, list], self.name)
|
||||
for item in output_size:
|
||||
validator.check_value_type('output_size_item', item, int, self.name)
|
||||
validator.check_value_type('scales', scales, [tuple, list], self.name)
|
||||
for item in scales:
|
||||
validator.check_value_type('scales_item', item, float, self.name)
|
||||
validator.check_value_type('align_corners', align_corners, bool, self.name)
|
||||
self.add_prim_attr('output_size', output_size)
|
||||
self.add_prim_attr('scales', scales)
|
||||
self.add_prim_attr('align_corners', align_corners)
|
||||
|
||||
|
||||
class UpsampleNearest3D(Primitive):
|
||||
r"""
|
||||
Performs nearest neighbor upsampling operation.
|
||||
|
|
|
@ -246,7 +246,7 @@ def test_upsample_nearest_3d_error():
|
|||
"""
|
||||
context.set_context(mode=context.GRAPH_MODE, device_target='GPU')
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
with pytest.raises(ValueError):
|
||||
input_tensor = Tensor(np.ones((2, 2, 2, 2), dtype=np.float32))
|
||||
net = UpsampleTrilinear3DNet(output_size=[3, 4, 5])
|
||||
net(input_tensor)
|
||||
|
|
|
@ -116,6 +116,8 @@ from mindspore.ops.operations.nn_ops import UpsampleNearest3D
|
|||
from mindspore.ops.operations._grad_ops import UpsampleNearest3DGrad
|
||||
from mindspore.ops.operations.nn_ops import AvgPoolV1
|
||||
from mindspore.ops.operations._grad_ops import AvgPoolGradV1
|
||||
from mindspore.ops.operations.nn_ops import UpsampleTrilinear3D
|
||||
from mindspore.ops.operations._grad_ops import UpsampleTrilinear3DGrad
|
||||
from mindspore.ops.operations.nn_ops import MaxPoolV1
|
||||
from mindspore.ops.operations.array_ops import NonZero
|
||||
from mindspore.ops.operations._grad_ops import MaxPoolGradV1
|
||||
|
@ -2730,6 +2732,14 @@ test_case_nn_ops = [
|
|||
'desc_const': [Tensor(np.array([1, 2, 3, 4]).astype(np.int32))],
|
||||
'desc_inputs': [],
|
||||
'skip': ['backward']}),
|
||||
('UpsampleTrilinear3D', {
|
||||
'block': UpsampleTrilinear3D(output_size=[4, 64, 48]),
|
||||
'desc_inputs': [([2, 3, 4, 512, 256], {'dtype': np.float32})],
|
||||
'desc_bprop': [([2, 3, 4, 64, 48], {'dtype': np.float32})]}),
|
||||
('UpsampleNearest3DGrad', {
|
||||
'block': UpsampleTrilinear3DGrad(input_size=[2, 3, 4, 512, 256], output_size=[4, 64, 48], scales=None),
|
||||
'desc_inputs': [([2, 3, 4, 64, 48], {'dtype': np.float32})],
|
||||
'skip': ['backward']}),
|
||||
('DropoutGenMask', {
|
||||
'block': P.DropoutGenMask(),
|
||||
'desc_const': [(2, 2), Tensor(0.5, mstype.float32)],
|
||||
|
|
Loading…
Reference in New Issue