1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2019 Guo Yejun 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include <stdio.h> 22cabdff1aSopenharmony_ci#include <string.h> 23cabdff1aSopenharmony_ci#include <math.h> 24cabdff1aSopenharmony_ci#include "libavfilter/dnn/dnn_backend_native_layer_pad.h" 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#define EPSON 0.00001 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_cistatic int test_with_mode_symmetric(void) 29cabdff1aSopenharmony_ci{ 30cabdff1aSopenharmony_ci // the input data and expected data are generated with below python code. 31cabdff1aSopenharmony_ci /* 32cabdff1aSopenharmony_ci x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) 33cabdff1aSopenharmony_ci y = tf.pad(x, [[0, 0], [2, 3], [3, 2], [0, 0]], 'SYMMETRIC') 34cabdff1aSopenharmony_ci data = np.arange(48).reshape(1, 4, 4, 3); 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci sess=tf.Session() 37cabdff1aSopenharmony_ci sess.run(tf.global_variables_initializer()) 38cabdff1aSopenharmony_ci output = sess.run(y, feed_dict={x: data}) 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_ci print(list(data.flatten())) 41cabdff1aSopenharmony_ci print(list(output.flatten())) 42cabdff1aSopenharmony_ci print(data.shape) 43cabdff1aSopenharmony_ci print(output.shape) 44cabdff1aSopenharmony_ci */ 45cabdff1aSopenharmony_ci 46cabdff1aSopenharmony_ci LayerPadParams params; 47cabdff1aSopenharmony_ci DnnOperand operands[2]; 48cabdff1aSopenharmony_ci int32_t input_indexes[1]; 49cabdff1aSopenharmony_ci float input[1*4*4*3] = { 50cabdff1aSopenharmony_ci 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 51cabdff1aSopenharmony_ci }; 52cabdff1aSopenharmony_ci float expected_output[1*9*9*3] = { 53cabdff1aSopenharmony_ci 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0, 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0, 6.0, 7.0, 8.0, 3.0, 54cabdff1aSopenharmony_ci 4.0, 5.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 9.0, 10.0, 11.0, 6.0, 7.0, 8.0, 6.0, 7.0, 8.0, 3.0, 4.0, 5.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 3.0, 55cabdff1aSopenharmony_ci 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 9.0, 10.0, 11.0, 6.0, 7.0, 8.0, 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0, 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 56cabdff1aSopenharmony_ci 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0, 30.0, 31.0, 32.0, 27.0, 28.0, 29.0, 24.0, 25.0, 26.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 33.0, 57cabdff1aSopenharmony_ci 34.0, 35.0, 30.0, 31.0, 32.0, 42.0, 43.0, 44.0, 39.0, 40.0, 41.0, 36.0, 37.0, 38.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 45.0, 46.0, 47.0, 42.0, 43.0, 58cabdff1aSopenharmony_ci 44.0, 42.0, 43.0, 44.0, 39.0, 40.0, 41.0, 36.0, 37.0, 38.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 45.0, 46.0, 47.0, 42.0, 43.0, 44.0, 30.0, 31.0, 32.0, 59cabdff1aSopenharmony_ci 27.0, 28.0, 29.0, 24.0, 25.0, 26.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 33.0, 34.0, 35.0, 30.0, 31.0, 32.0, 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0, 60cabdff1aSopenharmony_ci 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0 61cabdff1aSopenharmony_ci }; 62cabdff1aSopenharmony_ci float *output; 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci params.mode = LPMP_SYMMETRIC; 65cabdff1aSopenharmony_ci params.paddings[0][0] = 0; 66cabdff1aSopenharmony_ci params.paddings[0][1] = 0; 67cabdff1aSopenharmony_ci params.paddings[1][0] = 2; 68cabdff1aSopenharmony_ci params.paddings[1][1] = 3; 69cabdff1aSopenharmony_ci params.paddings[2][0] = 3; 70cabdff1aSopenharmony_ci params.paddings[2][1] = 2; 71cabdff1aSopenharmony_ci params.paddings[3][0] = 0; 72cabdff1aSopenharmony_ci params.paddings[3][1] = 0; 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci operands[0].data = input; 75cabdff1aSopenharmony_ci operands[0].dims[0] = 1; 76cabdff1aSopenharmony_ci operands[0].dims[1] = 4; 77cabdff1aSopenharmony_ci operands[0].dims[2] = 4; 78cabdff1aSopenharmony_ci operands[0].dims[3] = 3; 79cabdff1aSopenharmony_ci operands[1].data = NULL; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci input_indexes[0] = 0; 82cabdff1aSopenharmony_ci ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL); 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_ci output = operands[1].data; 85cabdff1aSopenharmony_ci for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { 86cabdff1aSopenharmony_ci if (fabs(output[i] - expected_output[i]) > EPSON) { 87cabdff1aSopenharmony_ci printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]); 88cabdff1aSopenharmony_ci av_freep(&output); 89cabdff1aSopenharmony_ci return 1; 90cabdff1aSopenharmony_ci } 91cabdff1aSopenharmony_ci } 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ci av_freep(&output); 94cabdff1aSopenharmony_ci return 0; 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci} 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_cistatic int test_with_mode_reflect(void) 99cabdff1aSopenharmony_ci{ 100cabdff1aSopenharmony_ci // the input data and expected data are generated with below python code. 101cabdff1aSopenharmony_ci /* 102cabdff1aSopenharmony_ci x = tf.placeholder(tf.float32, shape=[3, None, None, 3]) 103cabdff1aSopenharmony_ci y = tf.pad(x, [[1, 2], [0, 0], [0, 0], [0, 0]], 'REFLECT') 104cabdff1aSopenharmony_ci data = np.arange(36).reshape(3, 2, 2, 3); 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci sess=tf.Session() 107cabdff1aSopenharmony_ci sess.run(tf.global_variables_initializer()) 108cabdff1aSopenharmony_ci output = sess.run(y, feed_dict={x: data}) 109cabdff1aSopenharmony_ci 110cabdff1aSopenharmony_ci print(list(data.flatten())) 111cabdff1aSopenharmony_ci print(list(output.flatten())) 112cabdff1aSopenharmony_ci print(data.shape) 113cabdff1aSopenharmony_ci print(output.shape) 114cabdff1aSopenharmony_ci */ 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci LayerPadParams params; 117cabdff1aSopenharmony_ci DnnOperand operands[2]; 118cabdff1aSopenharmony_ci int32_t input_indexes[1]; 119cabdff1aSopenharmony_ci float input[3*2*2*3] = { 120cabdff1aSopenharmony_ci 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 121cabdff1aSopenharmony_ci }; 122cabdff1aSopenharmony_ci float expected_output[6*2*2*3] = { 123cabdff1aSopenharmony_ci 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 124cabdff1aSopenharmony_ci 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 125cabdff1aSopenharmony_ci 35.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 126cabdff1aSopenharmony_ci }; 127cabdff1aSopenharmony_ci float *output; 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_ci params.mode = LPMP_REFLECT; 130cabdff1aSopenharmony_ci params.paddings[0][0] = 1; 131cabdff1aSopenharmony_ci params.paddings[0][1] = 2; 132cabdff1aSopenharmony_ci params.paddings[1][0] = 0; 133cabdff1aSopenharmony_ci params.paddings[1][1] = 0; 134cabdff1aSopenharmony_ci params.paddings[2][0] = 0; 135cabdff1aSopenharmony_ci params.paddings[2][1] = 0; 136cabdff1aSopenharmony_ci params.paddings[3][0] = 0; 137cabdff1aSopenharmony_ci params.paddings[3][1] = 0; 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci operands[0].data = input; 140cabdff1aSopenharmony_ci operands[0].dims[0] = 3; 141cabdff1aSopenharmony_ci operands[0].dims[1] = 2; 142cabdff1aSopenharmony_ci operands[0].dims[2] = 2; 143cabdff1aSopenharmony_ci operands[0].dims[3] = 3; 144cabdff1aSopenharmony_ci operands[1].data = NULL; 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_ci input_indexes[0] = 0; 147cabdff1aSopenharmony_ci ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL); 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci output = operands[1].data; 150cabdff1aSopenharmony_ci for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { 151cabdff1aSopenharmony_ci if (fabs(output[i] - expected_output[i]) > EPSON) { 152cabdff1aSopenharmony_ci printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]); 153cabdff1aSopenharmony_ci av_freep(&output); 154cabdff1aSopenharmony_ci return 1; 155cabdff1aSopenharmony_ci } 156cabdff1aSopenharmony_ci } 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci av_freep(&output); 159cabdff1aSopenharmony_ci return 0; 160cabdff1aSopenharmony_ci 161cabdff1aSopenharmony_ci} 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_cistatic int test_with_mode_constant(void) 164cabdff1aSopenharmony_ci{ 165cabdff1aSopenharmony_ci // the input data and expected data are generated with below python code. 166cabdff1aSopenharmony_ci /* 167cabdff1aSopenharmony_ci x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) 168cabdff1aSopenharmony_ci y = tf.pad(x, [[0, 0], [1, 0], [0, 0], [1, 2]], 'CONSTANT', constant_values=728) 169cabdff1aSopenharmony_ci data = np.arange(12).reshape(1, 2, 2, 3); 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci sess=tf.Session() 172cabdff1aSopenharmony_ci sess.run(tf.global_variables_initializer()) 173cabdff1aSopenharmony_ci output = sess.run(y, feed_dict={x: data}) 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci print(list(data.flatten())) 176cabdff1aSopenharmony_ci print(list(output.flatten())) 177cabdff1aSopenharmony_ci print(data.shape) 178cabdff1aSopenharmony_ci print(output.shape) 179cabdff1aSopenharmony_ci */ 180cabdff1aSopenharmony_ci 181cabdff1aSopenharmony_ci LayerPadParams params; 182cabdff1aSopenharmony_ci DnnOperand operands[2]; 183cabdff1aSopenharmony_ci int32_t input_indexes[1]; 184cabdff1aSopenharmony_ci float input[1*2*2*3] = { 185cabdff1aSopenharmony_ci 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 186cabdff1aSopenharmony_ci }; 187cabdff1aSopenharmony_ci float expected_output[1*3*2*6] = { 188cabdff1aSopenharmony_ci 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 189cabdff1aSopenharmony_ci 728.0, 728.0, 0.0, 1.0, 2.0, 728.0, 728.0, 728.0, 3.0, 4.0, 5.0, 728.0, 728.0, 190cabdff1aSopenharmony_ci 728.0, 6.0, 7.0, 8.0, 728.0, 728.0, 728.0, 9.0, 10.0, 11.0, 728.0, 728.0 191cabdff1aSopenharmony_ci }; 192cabdff1aSopenharmony_ci float *output; 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci params.mode = LPMP_CONSTANT; 195cabdff1aSopenharmony_ci params.constant_values = 728; 196cabdff1aSopenharmony_ci params.paddings[0][0] = 0; 197cabdff1aSopenharmony_ci params.paddings[0][1] = 0; 198cabdff1aSopenharmony_ci params.paddings[1][0] = 1; 199cabdff1aSopenharmony_ci params.paddings[1][1] = 0; 200cabdff1aSopenharmony_ci params.paddings[2][0] = 0; 201cabdff1aSopenharmony_ci params.paddings[2][1] = 0; 202cabdff1aSopenharmony_ci params.paddings[3][0] = 1; 203cabdff1aSopenharmony_ci params.paddings[3][1] = 2; 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci operands[0].data = input; 206cabdff1aSopenharmony_ci operands[0].dims[0] = 1; 207cabdff1aSopenharmony_ci operands[0].dims[1] = 2; 208cabdff1aSopenharmony_ci operands[0].dims[2] = 2; 209cabdff1aSopenharmony_ci operands[0].dims[3] = 3; 210cabdff1aSopenharmony_ci operands[1].data = NULL; 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci input_indexes[0] = 0; 213cabdff1aSopenharmony_ci ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL); 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci output = operands[1].data; 216cabdff1aSopenharmony_ci for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) { 217cabdff1aSopenharmony_ci if (fabs(output[i] - expected_output[i]) > EPSON) { 218cabdff1aSopenharmony_ci printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]); 219cabdff1aSopenharmony_ci av_freep(&output); 220cabdff1aSopenharmony_ci return 1; 221cabdff1aSopenharmony_ci } 222cabdff1aSopenharmony_ci } 223cabdff1aSopenharmony_ci 224cabdff1aSopenharmony_ci av_freep(&output); 225cabdff1aSopenharmony_ci return 0; 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci} 228cabdff1aSopenharmony_ci 229cabdff1aSopenharmony_ciint main(int argc, char **argv) 230cabdff1aSopenharmony_ci{ 231cabdff1aSopenharmony_ci if (test_with_mode_symmetric()) 232cabdff1aSopenharmony_ci return 1; 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci if (test_with_mode_reflect()) 235cabdff1aSopenharmony_ci return 1; 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci if (test_with_mode_constant()) 238cabdff1aSopenharmony_ci return 1; 239cabdff1aSopenharmony_ci} 240