mirror of https://github.com/alibaba/MNN.git
288 lines
10 KiB
C++
288 lines
10 KiB
C++
//
|
|
// UnaryGradTest.cpp
|
|
// MNNTests
|
|
//
|
|
// Created by MNN on 2022/07/12.
|
|
// Copyright © 2018, Alibaba Group Holding Limited
|
|
//
|
|
|
|
#include <MNN/expr/Expr.hpp>
|
|
#include <MNN/expr/ExprCreator.hpp>
|
|
#include "MNNTestSuite.h"
|
|
#include "TestUtils.h"
|
|
#include "../tools/train/source/grad/OpGrad.hpp"
|
|
|
|
using namespace MNN;
|
|
using namespace MNN::Express;
|
|
|
|
class UnaryGradTest : public MNNTestCase {
|
|
public:
|
|
char name[20] = "Unary";
|
|
virtual ~UnaryGradTest() = default;
|
|
|
|
bool checkResult(VARP output, std::vector<float> outputDiff, std::vector<float> expectedOutput, const char* subname) {
|
|
const int len = outputDiff.size();
|
|
auto opExpr = output->expr().first;
|
|
auto grad = OpGrad::get(opExpr->get()->type());
|
|
if (grad == nullptr) {
|
|
MNN_ERROR("no grad defined for: %s %s\n", name, subname);
|
|
}
|
|
auto inputGrad = grad->onGrad(opExpr, {_Const(outputDiff.data(), {len})});
|
|
auto gotOutput = inputGrad[0]->readMap<float>();
|
|
|
|
for (int i = 0; i < len; ++i) {
|
|
auto diff = ::fabsf(gotOutput[i] - expectedOutput[i]);
|
|
if (diff > 0.001) {
|
|
MNN_ERROR("%s %s grad test failed, expected: %f, but got: %f!\n", name, subname, expectedOutput[i], gotOutput[i]);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
virtual bool run(int precision) {
|
|
const int len = 5;
|
|
auto input = _Input({len}, NCHW);
|
|
const float inpudata[] = {-1.0, -2.0, 0.0, 4.0, -5.0};
|
|
auto inputPtr = input->writeMap<float>();
|
|
memcpy(inputPtr, inpudata, len * sizeof(float));
|
|
std::vector<float> outputDiff = {0.1, -0.2, -0.3, 0.4, 0.5};
|
|
|
|
{
|
|
auto output = _Log1p(input);
|
|
const std::vector<float> expectedOutput = {INFINITY, 0.2000, -0.3000, 0.0800, -0.1250};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Log1p")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Exp(input);
|
|
const std::vector<float> expectedOutput = {3.6787946e-02, -2.7067056e-02, -3.0000e-01, 2.1839260e+01, 3.3689735e-03};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Exp")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Log(input);
|
|
const std::vector<float> expectedOutput = {-0.1000, 0.1000, -INFINITY, 0.1000, -0.1000};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Log")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Cos(input);
|
|
const std::vector<float> expectedOutput = {0.0841, -0.1819, 0.0000, 0.3027, -0.4795};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Cos")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Sin(input);
|
|
const std::vector<float> expectedOutput = {0.0540, 0.0832, -0.3000, -0.2615, 0.1418};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Sin")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Abs(input);
|
|
const std::vector<float> expectedOutput = {-0.1000, 0.2000, 0.0000, 0.4000, -0.5000};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Abs")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Negative(input);
|
|
const std::vector<float> expectedOutput = {-0.1, 0.2, 0.3, -0.4, -0.5};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Negative")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Sqrt(input);
|
|
const std::vector<float> expectedOutput = {NAN, NAN, 0.0f, 0.1000, NAN};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Sqrt")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Square(input);
|
|
const std::vector<float> expectedOutput = {-0.2000, 0.8000, 0.0000, 3.2000, -5.0000};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Square")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Sigmoid(input);
|
|
const std::vector<float> expectedOutput = {0.0197, -0.0210, -0.0750, 0.0071, 0.0033};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Sigmoid")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Tanh(input);
|
|
const std::vector<float> expectedOutput = {4.1997e-02, -1.4130e-02, -3.0000e-01, 5.3636e-04, 9.0774e-05};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Tanh")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Rsqrt(input);
|
|
const std::vector<float> expectedOutput = {NAN, NAN, INFINITY, -0.0250, NAN};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Rsqrt")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Tan(input);
|
|
const std::vector<float> expectedOutput = {0.3426, -1.1549, -0.3000, 0.9362, 6.2139};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Tan")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
const float inpudata[] = {-0.1, -0.2, 0.0, 4.0, -5.0};
|
|
memcpy(inputPtr, inpudata, len * sizeof(float));
|
|
auto output = _Asin(input);
|
|
const std::vector<float> expectedOutput = {0.1005, -0.2041, -0.3000, NAN, NAN};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Asin")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
const float inpudata[] = {-0.1, -0.2, 0.0, 4.0, -5.0};
|
|
memcpy(inputPtr, inpudata, len * sizeof(float));
|
|
auto output = _Acos(input);
|
|
const std::vector<float> expectedOutput = {-0.1005, 0.2041, 0.3000, NAN, NAN};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Acos")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
memcpy(inputPtr, inpudata, len * sizeof(float));
|
|
auto output = _Atan(input);
|
|
const std::vector<float> expectedOutput = {0.0500, -0.0400, -0.3000, 0.0235, 0.0192};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Atan")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Reciprocal(input);
|
|
const std::vector<float> expectedOutput = {-0.1000, 0.0500, INFINITY, -0.0250, -0.0200};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Reciprocal")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Acosh(input);
|
|
const std::vector<float> expectedOutput = {INFINITY, -0.1155, NAN, 0.1033, 0.1021};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Acosh")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Sinh(input);
|
|
const std::vector<float> expectedOutput = {0.1543, -0.7524, -0.3000, 10.9233, 37.1050};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Sinh")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Cosh(input);
|
|
const std::vector<float> expectedOutput = {-0.1175, 0.7254, 0.0000, 10.9160, -37.1016};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Cosh")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Asinh(input);
|
|
const std::vector<float> expectedOutput = {0.0707, -0.0894, -0.3000, 0.0970, 0.0981};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Asinh")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Atanh(input);
|
|
const std::vector<float> expectedOutput = {INFINITY, 0.0667, -0.3000, -0.0267, -0.0208};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Atanh")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Erf(input);
|
|
const std::vector<float> expectedOutput = {4.1511e-02, -4.1334e-03, -3.3851e-01, 5.0793e-08, 7.8354e-12};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Erf")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Erfc(input);
|
|
const std::vector<float> expectedOutput = {-4.1511e-02, 4.1334e-03, 3.3851e-01, -5.0793e-08, -7.8354e-12};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Erfc")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
const float inpudata[] = {-0.1, -0.2, 0.0, 4.0, -5.0};
|
|
memcpy(inputPtr, inpudata, len * sizeof(float));
|
|
auto output = _Erfinv(input);
|
|
const std::vector<float> expectedOutput = {0.0893, -0.1830, -0.2659, NAN, NAN};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Erfinv")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
memcpy(inputPtr, inpudata, len * sizeof(float));
|
|
auto output = _Expm1(input);
|
|
const std::vector<float> expectedOutput = {3.6788e-02, -2.7067e-02, -3.0000e-01, 2.1839e+01, 3.3690e-03};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Expm1")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Hardswish(input);
|
|
const std::vector<float> expectedOutput = {0.0167, 0.0333, -0.1500, 0.4000, 0.0000};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Hardswish")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto output = _Gelu(input);
|
|
const std::vector<float> expectedOutput = {-8.3315e-03, 1.7046e-02, -1.5000e-01, 4.0020e-01, -3.5614e-06};
|
|
if (!checkResult(output, outputDiff, expectedOutput, "Gelu")) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
MNNTestSuiteRegister(UnaryGradTest, "grad/unary");
|