parent
7913f8361c
commit
e2c4e74ecd
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright 2020 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 "nnacl/int8/space_to_batch_int8.h"
|
||||
#include "nnacl/arithmetic_common.h"
|
||||
|
||||
void DoSpaceToBatchNHWCInt8(const int8_t *input, int8_t *output, int *block_sizes, int *in_shape,
|
||||
int *out_shape) {
|
||||
int out_dim0 = out_shape[0];
|
||||
int out_dim1 = out_shape[1];
|
||||
int out_dim2 = out_shape[2];
|
||||
int copy_num = out_shape[3];
|
||||
int block_w = block_sizes[1];
|
||||
int block_h = block_sizes[0];
|
||||
int in_strides[4];
|
||||
ComputeStrides(in_shape, in_strides, 4);
|
||||
int out_strides[4];
|
||||
ComputeStrides(out_shape, out_strides, 4);
|
||||
size_t copy_size = copy_num * sizeof(int8_t);
|
||||
size_t out_offset = 0;
|
||||
for (int n = 0; n < out_dim0; ++n) {
|
||||
int in_n = n % in_shape[0];
|
||||
int32_t stride_w = (n / in_shape[0]) % block_w;
|
||||
int32_t stride_h = (n / in_shape[0]) / block_w;
|
||||
size_t in_offset0 = in_n * in_strides[0];
|
||||
for (int h = 0; h < out_dim1; ++h) {
|
||||
size_t in_offset1 = in_offset0 + (h * block_h + stride_h) * in_strides[1];
|
||||
for (int w = 0; w < out_dim2; ++w) {
|
||||
size_t in_offset2 = in_offset1 + (w * block_w + stride_w) * in_strides[2];
|
||||
memcpy(output + out_offset, input + in_offset2, copy_size);
|
||||
out_offset += copy_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoSpaceToBatchPaddingNHWCInt8(const int8_t *input, int8_t *output, int *in_shape, int *padding, int *out_shape) {
|
||||
int in_h = in_shape[1];
|
||||
int in_w = in_shape[2];
|
||||
int in_c = in_shape[3];
|
||||
int out_w = out_shape[2];
|
||||
int out_c = out_shape[3];
|
||||
size_t ped_h_num = out_w * out_c;
|
||||
size_t ped_h_size = ped_h_num * sizeof(int8_t);
|
||||
size_t ped_w_size = out_c * sizeof(int8_t);
|
||||
size_t out_offset = 0;
|
||||
int in_strides[4];
|
||||
ComputeStrides(in_shape, in_strides, 4);
|
||||
int out_strides[4];
|
||||
ComputeStrides(out_shape, out_strides, 4);
|
||||
size_t copy_size = in_c * sizeof(int8_t);
|
||||
for (int i = 0; i < in_shape[0]; ++i) {
|
||||
size_t in_offset0 = i * in_strides[0];
|
||||
for (int pad_h_top = 0; pad_h_top < padding[0]; ++pad_h_top) {
|
||||
memset(output + out_offset, 0, ped_h_size);
|
||||
out_offset += ped_h_num;
|
||||
}
|
||||
for (int j = 0; j < in_h; ++j) {
|
||||
size_t in_offset1 = in_offset0 + j * in_strides[1];
|
||||
for (int pad_w_left = 0; pad_w_left < padding[2]; ++pad_w_left) {
|
||||
memset(output + out_offset, 0, ped_w_size);
|
||||
out_offset += out_c;
|
||||
}
|
||||
for (int k = 0; k < in_w; ++k) {
|
||||
size_t in_offset2 = in_offset1 + k * in_strides[2];
|
||||
memcpy(output + out_offset, input + in_offset2, copy_size);
|
||||
out_offset += in_c;
|
||||
}
|
||||
for (int pad_w_right = 0; pad_w_right < padding[3]; ++pad_w_right) {
|
||||
memset(output + out_offset, 0, ped_w_size);
|
||||
out_offset += out_c;
|
||||
}
|
||||
}
|
||||
for (int pad_h_bottom = 0; pad_h_bottom < padding[1]; ++pad_h_bottom) {
|
||||
memset(output + out_offset, 0, ped_h_size);
|
||||
out_offset += ped_h_num;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright 2020 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_LITE_NNACL_INT8_SPACE_TO_BATCH_INT8_H_
|
||||
#define MINDSPORE_LITE_NNACL_INT8_SPACE_TO_BATCH_INT8_H_
|
||||
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void DoSpaceToBatchNHWCInt8(const int8_t *input, int8_t *output, int *block_sizes, int *in_shape, int *out_shape);
|
||||
void DoSpaceToBatchPaddingNHWCInt8(const int8_t *input, int8_t *output, int *in_shape, int *padding, int *out_shape);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MINDSPORE_LITE_NNACL_INT8_SPACE_TO_BATCH_INT8_H_
|
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright 2020 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 "src/runtime/kernel/arm/int8/space_to_batch_int8.h"
|
||||
#include "src/kernel_registry.h"
|
||||
#include "nnacl/fp32/space_to_batch.h"
|
||||
#include "nnacl/int8/space_to_batch_int8.h"
|
||||
|
||||
using mindspore::lite::KernelRegistrar;
|
||||
using mindspore::lite::RET_ERROR;
|
||||
using mindspore::lite::RET_OK;
|
||||
using mindspore::schema::PrimitiveType_SpaceToBatch;
|
||||
using mindspore::schema::PrimitiveType_SpaceToBatchND;
|
||||
|
||||
namespace mindspore::kernel {
|
||||
int SpaceToBatchInt8CPUKernel::Run() {
|
||||
auto ret = Prepare();
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "Prepare fail!ret: " << ret;
|
||||
return ret;
|
||||
}
|
||||
auto input_tensor = in_tensors_.at(0);
|
||||
auto output_tensor = out_tensors_.at(0);
|
||||
auto input_ptr = reinterpret_cast<const int8_t *>(input_tensor->MutableData());
|
||||
auto output_ptr = reinterpret_cast<int8_t *>(output_tensor->MutableData());
|
||||
SpaceToBatchParameter *param = reinterpret_cast<SpaceToBatchParameter *>(this->op_parameter_);
|
||||
|
||||
if (param->need_paddings_) {
|
||||
padded_input_ = context_->allocator->Malloc(param->padded_input_element_num * sizeof(int8_t));
|
||||
if (padded_input_ == nullptr) {
|
||||
MS_LOG(ERROR) << "Memory allocation failed";
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto padded_input = reinterpret_cast<int8_t *>(padded_input_);
|
||||
DoSpaceToBatchPaddingNHWCInt8(input_ptr, padded_input, param->input_shape_, param->paddings_,
|
||||
param->padded_in_shape_);
|
||||
DoSpaceToBatchNHWCInt8(padded_input, output_ptr, param->block_sizes_, param->padded_in_shape_,
|
||||
param->output_shape_);
|
||||
FreeTmpBuffer();
|
||||
} else {
|
||||
DoSpaceToBatchNHWCInt8(input_ptr, output_ptr, param->block_sizes_, param->input_shape_, param->output_shape_);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
kernel::LiteKernel *CpuSpaceToBatchInt8KernelCreator(const std::vector<lite::Tensor *> &inputs,
|
||||
const std::vector<lite::Tensor *> &outputs,
|
||||
OpParameter *param, const lite::Context *ctx,
|
||||
const kernel::KernelKey &desc,
|
||||
const mindspore::lite::PrimitiveC *primitive) {
|
||||
if (param == nullptr) {
|
||||
MS_LOG(ERROR) << "Input param is nullptr!";
|
||||
return nullptr;
|
||||
}
|
||||
auto *kernel = new (std::nothrow) SpaceToBatchInt8CPUKernel(param, inputs, outputs, ctx, primitive);
|
||||
if (kernel == nullptr) {
|
||||
MS_LOG(ERROR) << "new SpaceToBatchInt8CPUKernel fail!";
|
||||
return nullptr;
|
||||
}
|
||||
auto ret = kernel->Init();
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "Init kernel failed, name: " << param->name_
|
||||
<< ", type: " << schema::EnumNamePrimitiveType(static_cast<schema::PrimitiveType>(param->type_));
|
||||
delete kernel;
|
||||
return nullptr;
|
||||
}
|
||||
return kernel;
|
||||
}
|
||||
|
||||
REG_KERNEL(kCPU, kNumberTypeInt8, PrimitiveType_SpaceToBatch, CpuSpaceToBatchInt8KernelCreator)
|
||||
REG_KERNEL(kCPU, kNumberTypeInt8, PrimitiveType_SpaceToBatchND, CpuSpaceToBatchInt8KernelCreator)
|
||||
} // namespace mindspore::kernel
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright 2020 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_LITE_SRC_RUNTIME_KERNEL_ARM_INT8_SPACE_TO_BATCH_INT8_H_
|
||||
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_INT8_SPACE_TO_BATCH_INT8_H_
|
||||
|
||||
#include <vector>
|
||||
#include "src/runtime/kernel/arm/fp32/space_to_batch.h"
|
||||
|
||||
namespace mindspore::kernel {
|
||||
class SpaceToBatchInt8CPUKernel : public SpaceToBatchCPUKernel {
|
||||
public:
|
||||
SpaceToBatchInt8CPUKernel(OpParameter *parameter, const std::vector<lite::Tensor *> &inputs,
|
||||
const std::vector<lite::Tensor *> &outputs, const lite::Context *ctx,
|
||||
const mindspore::lite::PrimitiveC *primitive)
|
||||
: SpaceToBatchCPUKernel(parameter, inputs, outputs, ctx, primitive) {}
|
||||
|
||||
~SpaceToBatchInt8CPUKernel() {}
|
||||
|
||||
int Run() override;
|
||||
};
|
||||
} // namespace mindspore::kernel
|
||||
|
||||
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_INT8_SPACE_TO_BATCH_INT8_H_
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright 2020 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 <iostream>
|
||||
#include "common/common_test.h"
|
||||
#include "nnacl/fp32/space_to_batch.h"
|
||||
#include "mindspore/lite/src/kernel_registry.h"
|
||||
|
||||
namespace mindspore {
|
||||
class SpaceToBatchTestInt8 : public mindspore::CommonTest {
|
||||
public:
|
||||
SpaceToBatchTestInt8() {}
|
||||
};
|
||||
|
||||
TEST_F(SpaceToBatchTestInt8, test1) {
|
||||
lite::Tensor in_tensor(kNumberTypeInt8, {1, 2, 2, 1});
|
||||
lite::Tensor out_tensor(kNumberTypeInt8, {4, 2, 2, 1});
|
||||
int8_t input_data[] = {1, 2, 3, 4};
|
||||
int8_t output_data[16] = {0};
|
||||
in_tensor.SetData(input_data);
|
||||
out_tensor.SetData(output_data);
|
||||
std::vector<lite::Tensor *> inputs = {&in_tensor};
|
||||
std::vector<lite::Tensor *> outputs = {&out_tensor};
|
||||
|
||||
SpaceToBatchParameter parameter = {{}, false, {2, 2}, {1, 1, 1, 1}};
|
||||
kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeInt8, schema::PrimitiveType_SpaceToBatchND};
|
||||
|
||||
auto creator = lite::KernelRegistry::GetInstance()->GetCreator(desc);
|
||||
ASSERT_NE(creator, nullptr);
|
||||
|
||||
auto ctx = std::make_shared<lite::Context>();
|
||||
auto kernel = creator(inputs, outputs, reinterpret_cast<OpParameter *>(¶meter), ctx.get(), desc, nullptr);
|
||||
ASSERT_NE(kernel, nullptr);
|
||||
|
||||
auto ret = kernel->Run();
|
||||
EXPECT_EQ(0, ret);
|
||||
|
||||
int8_t expect[] = {0, 0, 0, 4, 0, 0, 3, 0, 0, 2, 0, 0, 1, 0, 0, 0};
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
EXPECT_EQ(output_data[i], expect[i]);
|
||||
}
|
||||
in_tensor.SetData(nullptr);
|
||||
out_tensor.SetData(nullptr);
|
||||
}
|
||||
} // namespace mindspore
|
Loading…
Reference in new issue