add GeLU fp32 ops

pull/9978/head
liuwenhao4 4 years ago
parent 28696b9d4d
commit 9b328f28b4

@ -0,0 +1,39 @@
/**
* Copyright 2019 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/fp32/gelu_fp32.h"
#include "nnacl/gelu_parameter.h"
#include <string.h>
#include <math.h>
#include "nnacl/errorcode.h"
int DoGeLU(float *src, float *out, int64_t real_dst_count, const GeLUParameter *param) {
if (src == NULL || out == NULL) {
return NNACL_ERR;
}
if (param->approximate_) {
for (int i = 0; i < real_dst_count; i++) {
out[i] = 0.5 * src[i] * (1.0 + tanh(0.7978845608028654 * (src[i] + 0.044715 * pow(src[i], 3))));
}
} else {
for (int i = 0; i < real_dst_count; i++) {
out[i] = 0.5 * src[i] * (1.0 + erf(src[i] / 1.4142135623730951));
}
}
return NNACL_OK;
}

@ -0,0 +1,31 @@
/**
* 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_FP32_GELU_H_
#define MINDSPORE_LITE_NNACL_FP32_GELU_H_
#include "nnacl/op_base.h"
#include "nnacl/gelu_parameter.h"
#ifdef __cplusplus
extern "C" {
#endif
int DoGeLU(float *src, float *out, int64_t real_dst_count, const GeLUParameter *param);
#ifdef __cplusplus
}
#endif
#endif // MINDSPORE_LITE_NNACL_FP32_GELU_H_

@ -0,0 +1,28 @@
/**
* 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_GELU_PARAMETER_H_
#define MINDSPORE_LITE_NNACL_GELU_PARAMETER_H_
#include "nnacl/op_base.h"
typedef struct GeLUParameter {
// Primitive parameter
OpParameter op_parameter_;
bool approximate_;
} GeLUParameter;
#endif // MINDSPORE_LITE_NNACL_GELU_PARAMETER_H_

@ -1226,3 +1226,7 @@ table Reciprocal {
table Merge {
}
table GeLU {
approximate : bool = false;
}

@ -0,0 +1,42 @@
/**
* Copyright 2019-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/ops/gelu.h"
#include <memory>
#include "include/errorcode.h"
#include "src/common/log_adapter.h"
#include "src/tensor.h"
#ifndef PRIMITIVE_WRITEABLE
#include "src/ops/ops_register.h"
#endif
namespace mindspore {
namespace lite {
#ifdef PRIMITIVE_WRITEABLE
// int GeLU::GetApproximate() const { return this->primitive_->value.AsGeLU()->approximate; }
// void GeLU::SetApproximate(bool approximate) { this->primitive_->value.AsGeLU()->approximate = approximate; }
#else
// int GeLU::GetApproximate() const { return this->primitive_->value_as_GeLU()->approximate(); }
// PrimitiveC *GeLUCreator(const schema::Primitive *primitive) { return PrimitiveC::NewPrimitiveC<GeLU>(primitive); }
// Registry GeLURegistry(schema::PrimitiveType_GeLU, GeLUCreator);
#endif
} // namespace lite
} // namespace mindspore

@ -0,0 +1,45 @@
/**
* Copyright 2019-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 LITE_MINDSPORE_LITE_C_OPS_GELU_H_
#define LITE_MINDSPORE_LITE_C_OPS_GELU_H_
#include <vector>
#include <set>
#include <cmath>
#include "src/ops/primitive_c.h"
namespace mindspore {
namespace lite {
class GeLU : public PrimitiveC {
public:
GeLU() = default;
~GeLU() = default;
#ifdef PRIMITIVE_WRITEABLE
MS_DECLARE_PARENT(GeLU, PrimitiveC);
explicit GeLU(schema::PrimitiveT *primitive) : PrimitiveC(primitive) {}
// int UnPackAttr(const Primitive &prim, const std::vector<AnfNodePtr> &inputs) override;
// void SetApproximate(bool approximate);
#else
// int UnPackToFlatBuilder(const schema::Primitive *primitive, flatbuffers::FlatBufferBuilder *fbb) override;
#endif
int InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Tensor *> outputs_) override;
// bool GetApproximate() const;
};
} // namespace lite
} // namespace mindspore
#endif // LITE_MINDSPORE_LITE_C_OPS_GELU_H_

@ -0,0 +1,40 @@
/**
* 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/ops/primitive_c.h"
#include "src/ops/populate/populate_register.h"
#include "src/ops/gelu.h"
#include "nnacl/gelu_parameter.h"
namespace mindspore {
namespace lite {
OpParameter *PopulateGeLUParameter(const mindspore::lite::PrimitiveC *primitive) {
// const auto param = reinterpret_cast<mindspore::lite::GeLU *>(const_cast<mindspore::lite::PrimitiveC
// *>(primitive));
GeLUParameter *gelu_param = reinterpret_cast<GeLUParameter *>(malloc(sizeof(GeLUParameter)));
if (gelu_param == nullptr) {
MS_LOG(ERROR) << "malloc GeLUParameter failed.";
return nullptr;
}
memset(gelu_param, 0, sizeof(GeLUParameter));
gelu_param->op_parameter_.type_ = primitive->Type();
// gelu_param->approximate_ = param->GetApproximate();
return reinterpret_cast<OpParameter *>(gelu_param);
}
// Registry GeLUParameterRegistry(schema::PrimitiveType_GeLU, PopulateGeLUParameter);
} // namespace lite
} // namespace mindspore

@ -0,0 +1,59 @@
/**
* 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/base/gelu_base.h"
#include <vector>
#include "src/runtime/kernel/arm/fp32/gelu_fp32.h"
#include "nnacl/fp32/gelu_fp32.h"
#include "schema/model_generated.h"
#include "src/kernel_registry.h"
#include "include/errorcode.h"
#include "include/context.h"
using mindspore::lite::KernelRegistrar;
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_OK;
// using mindspore::schema::PrimitiveType_GeLU;
namespace mindspore::kernel {
int GeLUBaseCPUKernel::Init() { return RET_OK; }
kernel::LiteKernel *CpuGeLUFp32KernelCreator(const std::vector<lite::Tensor *> &inputs,
const std::vector<lite::Tensor *> &outputs, OpParameter *opParameter,
const InnerContext *ctx, const kernel::KernelKey &desc,
const mindspore::lite::PrimitiveC *primitive) {
if (opParameter == nullptr) {
MS_LOG(ERROR) << "Input opParameter is nullptr!";
return nullptr;
}
// MS_ASSERT(desc.type == schema::PrimitiveType_GeLU);
auto *kernel = new (std::nothrow) GeLUCPUKernel(opParameter, inputs, outputs, ctx, primitive);
if (kernel == nullptr) {
MS_LOG(ERROR) << "new GeLUCPUKernel fail!";
free(opParameter);
return nullptr;
}
auto ret = kernel->Init();
if (ret != RET_OK) {
MS_LOG(ERROR) << "Init kernel failed, name: " << opParameter->name_ << ", type: "
<< schema::EnumNamePrimitiveType(static_cast<schema::PrimitiveType>(opParameter->type_));
delete kernel;
return nullptr;
}
return kernel;
}
// REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_GeLU, CpuGeLUFp32KernelCreator)
} // namespace mindspore::kernel

@ -0,0 +1,50 @@
/**
* 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_BASE_GELU_BASE_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_BASE_GELU_BASE_H_
#include <vector>
#include "src/lite_kernel.h"
#include "nnacl/gelu_parameter.h"
#include "src/runtime/kernel/arm/base/layout_transform.h"
using mindspore::lite::InnerContext;
namespace mindspore::kernel {
class GeLUBaseCPUKernel : public LiteKernel {
public:
GeLUBaseCPUKernel(OpParameter *parameter, const std::vector<lite::Tensor *> &inputs,
const std::vector<lite::Tensor *> &outputs, const InnerContext *ctx,
const mindspore::lite::PrimitiveC *primitive)
: LiteKernel(parameter, inputs, outputs, ctx, primitive), ctx_(ctx), thread_count_(ctx->thread_num_) {
gelu_param_ = reinterpret_cast<GeLUParameter *>(op_parameter_);
}
virtual ~GeLUBaseCPUKernel() = default;
int Init() override;
int Run() override { return 0; }
protected:
const InnerContext *ctx_ = nullptr;
int thread_count_ = 1;
GeLUParameter *gelu_param_ = nullptr;
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_BASE_GELU_BASE_H_

@ -0,0 +1,88 @@
/**
* 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/fp32/gelu_fp32.h"
#include "src/runtime/kernel/arm/base/gelu_base.h"
#include "nnacl/fp32/gelu_fp32.h"
#include "nnacl/gelu_parameter.h"
#include "src/kernel_registry.h"
#include "include/errorcode.h"
#include "src/runtime/runtime_api.h"
using mindspore::kernel::KERNEL_ARCH::kCPU;
using mindspore::lite::KernelRegistrar;
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_OK;
// using mindspore::schema::PrimitiveType_GeLU;
namespace mindspore::kernel {
int GeLUCPUKernel::Init() {
auto ret = GeLUBaseCPUKernel::Init();
if (ret != RET_OK) {
return ret;
}
if (!InferShapeDone()) {
return RET_OK;
}
return ReSize();
}
int GeLUCPUKernel::ReSize() { return RET_OK; }
int GeLUCPUKernel::GeLU(int task_id) {
int64_t real_dst_count = MSMIN(elements_num_ - task_id * count_unit_, count_unit_);
if (real_dst_count <= 0) {
return lite::RET_OK;
}
float *cur_input_data = input_ptr_ + task_id * count_unit_;
float *cur_output_data = output_ptr_ + task_id * count_unit_;
auto ret = DoGeLU(cur_input_data, cur_output_data, real_dst_count, gelu_param_);
if (ret != RET_OK) {
MS_LOG(ERROR) << "GeLU error task_id[" << task_id << "] error_code[" << ret << "]";
return RET_ERROR;
}
return RET_OK;
}
int GeLURun(void *cdata, int task_id) {
auto g_kernel = reinterpret_cast<GeLUCPUKernel *>(cdata);
auto ret = g_kernel->GeLU(task_id);
if (ret != RET_OK) {
MS_LOG(ERROR) << "GeLURun error task_id[" << task_id << "] error_code[" << ret << "]";
return RET_ERROR;
}
return RET_OK;
}
int GeLUCPUKernel::Run() {
auto in_tensor = in_tensors_.front();
auto out_tensor = out_tensors_.front();
input_ptr_ = reinterpret_cast<float *>(in_tensor->MutableData());
output_ptr_ = reinterpret_cast<float *>(out_tensor->MutableData());
elements_num_ = out_tensor->ElementsNum();
count_unit_ = thread_count_ > 1 ? UP_DIV(elements_num_, thread_count_) : elements_num_;
auto ret = ParallelLaunch(this->context_->thread_pool_, GeLURun, this, thread_count_);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Scale error error_code[" << ret << "]";
return RET_ERROR;
}
return RET_OK;
}
} // namespace mindspore::kernel

@ -0,0 +1,46 @@
/**
* 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_FP32_GELU_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_GELU_H_
#include <vector>
#include "src/runtime/kernel/arm/base/gelu_base.h"
#include "src/lite_kernel.h"
namespace mindspore::kernel {
class GeLUCPUKernel : public GeLUBaseCPUKernel {
public:
GeLUCPUKernel(OpParameter *parameter, const std::vector<lite::Tensor *> &inputs,
const std::vector<lite::Tensor *> &outputs, const lite::InnerContext *ctx,
const mindspore::lite::PrimitiveC *primitive)
: GeLUBaseCPUKernel(parameter, inputs, outputs, ctx, primitive) {}
~GeLUCPUKernel() override = default;
int Init() override;
int ReSize() override;
int Run() override;
int GeLU(int task_id);
private:
float *input_ptr_ = nullptr;
float *output_ptr_ = nullptr;
int64_t elements_num_ = 0;
int64_t count_unit_ = 0;
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_GELU_H_
Loading…
Cancel
Save