1/* 2 * Copyright (c) 2020 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include <stdio.h> 22#include <string.h> 23#include <math.h> 24#include "libavfilter/dnn/dnn_backend_native_layer_mathunary.h" 25#include "libavutil/avassert.h" 26 27#define EPS 0.00001 28 29static float get_expected(float f, DNNMathUnaryOperation op) 30{ 31 switch (op) 32 { 33 case DMUO_ABS: 34 return (f >= 0) ? f : -f; 35 case DMUO_SIN: 36 return sin(f); 37 case DMUO_COS: 38 return cos(f); 39 case DMUO_TAN: 40 return tan(f); 41 case DMUO_ASIN: 42 return asin(f); 43 case DMUO_ACOS: 44 return acos(f); 45 case DMUO_ATAN: 46 return atan(f); 47 case DMUO_SINH: 48 return sinh(f); 49 case DMUO_COSH: 50 return cosh(f); 51 case DMUO_TANH: 52 return tanh(f); 53 case DMUO_ASINH: 54 return asinh(f); 55 case DMUO_ACOSH: 56 return acosh(f); 57 case DMUO_ATANH: 58 return atanh(f); 59 case DMUO_CEIL: 60 return ceil(f); 61 case DMUO_FLOOR: 62 return floor(f); 63 case DMUO_ROUND: 64 return round(f); 65 default: 66 av_assert0(!"not supported yet"); 67 return 0.f; 68 } 69} 70 71static int test(DNNMathUnaryOperation op) 72{ 73 DnnLayerMathUnaryParams params; 74 DnnOperand operands[2]; 75 int32_t input_indexes[1]; 76 float input[1*1*3*3] = { 77 0.1, 0.5, 0.75, -3, 2.5, 2, -2.1, 7.8, 100}; 78 float *output; 79 80 params.un_op = op; 81 82 operands[0].data = input; 83 operands[0].dims[0] = 1; 84 operands[0].dims[1] = 1; 85 operands[0].dims[2] = 3; 86 operands[0].dims[3] = 3; 87 operands[1].data = NULL; 88 89 input_indexes[0] = 0; 90 ff_dnn_execute_layer_math_unary(operands, input_indexes, 1, ¶ms, NULL); 91 92 output = operands[1].data; 93 for (int i = 0; i < sizeof(input) / sizeof(float); ++i) { 94 float expected_output = get_expected(input[i], op); 95 int output_nan = isnan(output[i]); 96 int expected_nan = isnan(expected_output); 97 if ((!output_nan && !expected_nan && fabs(output[i] - expected_output) > EPS) || 98 (output_nan && !expected_nan) || (!output_nan && expected_nan)) { 99 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output); 100 av_freep(&output); 101 return 1; 102 } 103 } 104 105 av_freep(&output); 106 return 0; 107} 108 109int main(int agrc, char **argv) 110{ 111 if (test(DMUO_ABS)) 112 return 1; 113 if (test(DMUO_SIN)) 114 return 1; 115 if (test(DMUO_COS)) 116 return 1; 117 if (test(DMUO_TAN)) 118 return 1; 119 if (test(DMUO_ASIN)) 120 return 1; 121 if (test(DMUO_ACOS)) 122 return 1; 123 if (test(DMUO_ATAN)) 124 return 1; 125 if (test(DMUO_SINH)) 126 return 1; 127 if (test(DMUO_COSH)) 128 return 1; 129 if (test(DMUO_TANH)) 130 return 1; 131 if (test(DMUO_ASINH)) 132 return 1; 133 if (test(DMUO_ACOSH)) 134 return 1; 135 if (test(DMUO_ATANH)) 136 return 1; 137 if (test(DMUO_CEIL)) 138 return 1; 139 if (test(DMUO_FLOOR)) 140 return 1; 141 if (test(DMUO_ROUND)) 142 return 1; 143 return 0; 144} 145