1be168c0dSopenharmony_ci/*
2be168c0dSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3be168c0dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4be168c0dSopenharmony_ci * you may not use this file except in compliance with the License.
5be168c0dSopenharmony_ci * You may obtain a copy of the License at
6be168c0dSopenharmony_ci *
7be168c0dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8be168c0dSopenharmony_ci *
9be168c0dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10be168c0dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11be168c0dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12be168c0dSopenharmony_ci * See the License for the specific language governing permissions and
13be168c0dSopenharmony_ci * limitations under the License.
14be168c0dSopenharmony_ci */
15be168c0dSopenharmony_ci
16be168c0dSopenharmony_ci#include "common.h"
17be168c0dSopenharmony_ci#include <numeric>
18be168c0dSopenharmony_ci#include <inttypes.h>
19be168c0dSopenharmony_ci#include <securec.h>
20be168c0dSopenharmony_ci
21be168c0dSopenharmony_ci/*
22be168c0dSopenharmony_ci * getDimInfo: get dim info from data file(int64_t)
23be168c0dSopenharmony_ci * param:
24be168c0dSopenharmony_ci * fp: the testing datafile object
25be168c0dSopenharmony_ci *
26be168c0dSopenharmony_ci * return :
27be168c0dSopenharmony_ci * dim_info: array to store the info of the dim in datafile, like
28be168c0dSopenharmony_ci * [4,3,3,6,3,162(3*3*6*3)],4 is dim size,3,3,6,3 is the dim shape data_size:
29be168c0dSopenharmony_ci * the size of the testing data including the data file
30be168c0dSopenharmony_ci * */
31be168c0dSopenharmony_civoid getDimInfo(FILE *fp, std::vector<int64_t>* dim_info) {
32be168c0dSopenharmony_ci    const int MAX_HEAD_SIZE = 50;
33be168c0dSopenharmony_ci    uint32_t *dim_buffer = reinterpret_cast<uint32_t *>(malloc(MAX_HEAD_SIZE * sizeof(uint32_t)));
34be168c0dSopenharmony_ci    size_t ret = fread(dim_buffer, sizeof(uint32_t), MAX_HEAD_SIZE, fp);
35be168c0dSopenharmony_ci    if (ret == 0) {
36be168c0dSopenharmony_ci        free(dim_buffer);
37be168c0dSopenharmony_ci        return;
38be168c0dSopenharmony_ci    }
39be168c0dSopenharmony_ci    dim_info->push_back(*dim_buffer);  // get dim size
40be168c0dSopenharmony_ci
41be168c0dSopenharmony_ci    // get data shape to compute the datasize
42be168c0dSopenharmony_ci    uint64_t data_size = 1;
43be168c0dSopenharmony_ci    uint32_t i = 1;
44be168c0dSopenharmony_ci    for (; i <= dim_info->at(0); i++) {
45be168c0dSopenharmony_ci        dim_info->push_back(*(dim_buffer + i));
46be168c0dSopenharmony_ci        data_size *= *(dim_buffer + i);
47be168c0dSopenharmony_ci    }
48be168c0dSopenharmony_ci    dim_info->push_back(data_size);
49be168c0dSopenharmony_ci
50be168c0dSopenharmony_ci    free(dim_buffer);
51be168c0dSopenharmony_ci}
52be168c0dSopenharmony_ci
53be168c0dSopenharmony_ci/*
54be168c0dSopenharmony_ci * readTestDataFile: read test date from hisi .t datafile(int64_t)
55be168c0dSopenharmony_ci * param:
56be168c0dSopenharmony_ci * infile: the path of hisi .t datafile
57be168c0dSopenharmony_ci * return:
58be168c0dSopenharmony_ci * dim_info: array to store the info of the dim in datafile, like [4,3,3,6,3],4
59be168c0dSopenharmony_ci * is dim size,3,3,6,3 is the dim shape
60be168c0dSopenharmony_ci * */
61be168c0dSopenharmony_civoid *readTestDataFile(std::string infile, std::vector<int64_t>* dim_info1) {
62be168c0dSopenharmony_ci    printf("\n [common.cpp] Loading data from: %s\n", infile.c_str());
63be168c0dSopenharmony_ci
64be168c0dSopenharmony_ci    FILE *fp;
65be168c0dSopenharmony_ci    fp = fopen(infile.c_str(), "r");
66be168c0dSopenharmony_ci    if (fp == nullptr) {
67be168c0dSopenharmony_ci        printf("ERROR: cant't open file %s\n", infile.c_str());
68be168c0dSopenharmony_ci        return nullptr;
69be168c0dSopenharmony_ci    } else {
70be168c0dSopenharmony_ci        std::vector<int64_t> dim_info;
71be168c0dSopenharmony_ci        std::vector<int64_t>* ptr_dim_info = &dim_info;
72be168c0dSopenharmony_ci        getDimInfo(fp, ptr_dim_info);
73be168c0dSopenharmony_ci        uint64_t data_size = ptr_dim_info->at(ptr_dim_info->size() - 1);
74be168c0dSopenharmony_ci        fclose(fp);
75be168c0dSopenharmony_ci
76be168c0dSopenharmony_ci        fp = fopen(infile.c_str(), "r");
77be168c0dSopenharmony_ci        if (fp == nullptr) {
78be168c0dSopenharmony_ci            printf("ERROR: cant't open file %s\n", infile.c_str());
79be168c0dSopenharmony_ci            return nullptr;
80be168c0dSopenharmony_ci        }
81be168c0dSopenharmony_ci        uint32_t *memory = reinterpret_cast<uint32_t *>(malloc((dim_info[0] + 1) * sizeof(uint32_t)));
82be168c0dSopenharmony_ci
83be168c0dSopenharmony_ci        size_t ret = fread(memory, sizeof(uint32_t), (dim_info[0] + 1), fp);
84be168c0dSopenharmony_ci        if (ret == 0) {
85be168c0dSopenharmony_ci            free(memory);
86be168c0dSopenharmony_ci            fclose(fp);
87be168c0dSopenharmony_ci            return nullptr;
88be168c0dSopenharmony_ci        }
89be168c0dSopenharmony_ci        uint32_t *data = reinterpret_cast<uint32_t *>(malloc((data_size) * sizeof(uint32_t)));
90be168c0dSopenharmony_ci        size_t ret2 = fread(data, sizeof(uint32_t), data_size, fp);
91be168c0dSopenharmony_ci        if (ret2 == 0) {
92be168c0dSopenharmony_ci            free(data);
93be168c0dSopenharmony_ci            fclose(fp);
94be168c0dSopenharmony_ci            return nullptr;
95be168c0dSopenharmony_ci        }
96be168c0dSopenharmony_ci        free(memory);
97be168c0dSopenharmony_ci        fclose(fp);
98be168c0dSopenharmony_ci
99be168c0dSopenharmony_ci        for (int i = 0; i < dim_info[0]; i++) {
100be168c0dSopenharmony_ci            dim_info1->push_back(dim_info[i + 1]);
101be168c0dSopenharmony_ci        }
102be168c0dSopenharmony_ci
103be168c0dSopenharmony_ci        printf("\n [common.cpp] Read test data file Over, get dimInfo as: (");
104be168c0dSopenharmony_ci        int count = dim_info1->size();
105be168c0dSopenharmony_ci        for (int i = 0; i < count; i++) {
106be168c0dSopenharmony_ci            printf("%" PRId64, dim_info1->at(i));
107be168c0dSopenharmony_ci        }
108be168c0dSopenharmony_ci        printf(")\n");
109be168c0dSopenharmony_ci        return data;
110be168c0dSopenharmony_ci    }
111be168c0dSopenharmony_ci}
112be168c0dSopenharmony_ci
113be168c0dSopenharmony_ci/*
114be168c0dSopenharmony_ci * allclose
115be168c0dSopenharmony_ci * param:
116be168c0dSopenharmony_ci *  a:compared file a
117be168c0dSopenharmony_ci *  b:compared file b
118be168c0dSopenharmony_ci *  count: the count size which will compare
119be168c0dSopenharmony_ci *  rtol:
120be168c0dSopenharmony_ci *  atol:
121be168c0dSopenharmony_ci * return:
122be168c0dSopenharmony_ci *  true or false
123be168c0dSopenharmony_ci * */
124be168c0dSopenharmony_cibool allclose(float *a, float *b, uint64_t count, float rtol = 1e-05,
125be168c0dSopenharmony_ci              float atol = 1e-08, bool isquant = false) {
126be168c0dSopenharmony_ci    uint32_t i = 0;
127be168c0dSopenharmony_ci
128be168c0dSopenharmony_ci    // add fail loop print
129be168c0dSopenharmony_ci    uint32_t fail_count = 0;
130be168c0dSopenharmony_ci    float tol = 0;
131be168c0dSopenharmony_ci    float tol1 = 0;
132be168c0dSopenharmony_ci    float tol2 = 0;
133be168c0dSopenharmony_ci    bool nan_occur_in_accuray = false;
134be168c0dSopenharmony_ci
135be168c0dSopenharmony_ci    float sum = 0.0f;
136be168c0dSopenharmony_ci    static float sum_all;
137be168c0dSopenharmony_ci    static float maximum = 0;
138be168c0dSopenharmony_ci    static float minimum = 0;
139be168c0dSopenharmony_ci    static uint64_t c = 0;
140be168c0dSopenharmony_ci
141be168c0dSopenharmony_ci    if (a == nullptr || b == nullptr) {
142be168c0dSopenharmony_ci        return false;
143be168c0dSopenharmony_ci    }
144be168c0dSopenharmony_ci
145be168c0dSopenharmony_ci    for (; i < count; ++i) {
146be168c0dSopenharmony_ci        sum = sum + fabs(a[i] - b[i]) / (atol + rtol * fabs(b[i]));
147be168c0dSopenharmony_ci        sum_all = sum_all + fabs(a[i] - b[i]) / (atol + rtol * fabs(b[i]));
148be168c0dSopenharmony_ci        maximum = std::max(maximum, fabs(a[i] - b[i]) / (atol + rtol * fabs(b[i])));
149be168c0dSopenharmony_ci        minimum = std::min(minimum, fabs(a[i] - b[i]) / (atol + rtol * fabs(b[i])));
150be168c0dSopenharmony_ci        if (isnan(a[i]) || isinf(a[i])) {
151be168c0dSopenharmony_ci            fail_count = fail_count + 1;
152be168c0dSopenharmony_ci            nan_occur_in_accuray = true;
153be168c0dSopenharmony_ci            if (fail_count < 100) {
154be168c0dSopenharmony_ci                printf("     i = %2u:   %+f  |  %+f\n", i, a[i], b[i]);
155be168c0dSopenharmony_ci            }
156be168c0dSopenharmony_ci        } else if (fabs(a[i] - b[i]) > (atol + rtol * fabs(b[i]))) {
157be168c0dSopenharmony_ci            tol = tol + fabs(a[i] - b[i]) / (fabs(b[i]) + 1);
158be168c0dSopenharmony_ci            tol1 = tol1 + fabs(a[i] - b[i]);
159be168c0dSopenharmony_ci            tol2 = tol2 + fabs(a[i] - b[i]) / fabs(b[i]);
160be168c0dSopenharmony_ci            fail_count = fail_count + 1;
161be168c0dSopenharmony_ci            if (fail_count < 100) {
162be168c0dSopenharmony_ci                printf("     i = %2u:   %+f  |  %+f\n", i, a[i], b[i]);
163be168c0dSopenharmony_ci            }
164be168c0dSopenharmony_ci        }
165be168c0dSopenharmony_ci
166be168c0dSopenharmony_ci        if (i == count - 1) {
167be168c0dSopenharmony_ci            printf("     ......\n");
168be168c0dSopenharmony_ci            printf("\n *** Total fail_count: %u\n", fail_count);
169be168c0dSopenharmony_ci            if (fail_count != 0) {
170be168c0dSopenharmony_ci                printf("\n     fabs(a[i] - b[i])/(fabs(b[i])+1) : %f\n",
171be168c0dSopenharmony_ci                       tol / fail_count);
172be168c0dSopenharmony_ci                printf("\n     fabs(a[i] - b[i]) : %f\n", tol1 / fail_count);
173be168c0dSopenharmony_ci                printf("\n     fabs(a[i] - b[i])/fabs(b[i]) : %f\n", tol2 / fail_count);
174be168c0dSopenharmony_ci            }
175be168c0dSopenharmony_ci            c = c + count;
176be168c0dSopenharmony_ci            printf("\n     avg : %f\n", sum / count);
177be168c0dSopenharmony_ci            printf("\n     min : %f\n", minimum);
178be168c0dSopenharmony_ci            printf("\n     max :  %f\n", maximum);
179be168c0dSopenharmony_ci            printf("\n     avg_all :  %f\n", sum_all / c);
180be168c0dSopenharmony_ci            printf("\n");
181be168c0dSopenharmony_ci            std::fstream file;
182be168c0dSopenharmony_ci            file.open("cout.csv", std::ios::app);
183be168c0dSopenharmony_ci
184be168c0dSopenharmony_ci            file << ","
185be168c0dSopenharmony_ci                 << "1,"
186be168c0dSopenharmony_ci                 << "0," << maximum;
187be168c0dSopenharmony_ci            if (fail_count == 0) {
188be168c0dSopenharmony_ci                file << "," << sum_all / c;
189be168c0dSopenharmony_ci            } else {
190be168c0dSopenharmony_ci                file << "," << tol / fail_count;
191be168c0dSopenharmony_ci            }
192be168c0dSopenharmony_ci            file.close();
193be168c0dSopenharmony_ci        }
194be168c0dSopenharmony_ci    }
195be168c0dSopenharmony_ci    if (nan_occur_in_accuray) {
196be168c0dSopenharmony_ci        printf("\n[common.cpp] eval output include some NAN/INF\n");
197be168c0dSopenharmony_ci        return false;
198be168c0dSopenharmony_ci    }
199be168c0dSopenharmony_ci
200be168c0dSopenharmony_ci    if (fail_count > 0) {
201be168c0dSopenharmony_ci        printf("\n *** These data compare failed: atol = %f, rtol = %f\n", atol,
202be168c0dSopenharmony_ci               rtol);
203be168c0dSopenharmony_ci        printf("\n");
204be168c0dSopenharmony_ci        if (isquant) {
205be168c0dSopenharmony_ci            if (tol / fail_count < 0.04) {
206be168c0dSopenharmony_ci                return true;
207be168c0dSopenharmony_ci            }
208be168c0dSopenharmony_ci        }
209be168c0dSopenharmony_ci        return false;
210be168c0dSopenharmony_ci    }
211be168c0dSopenharmony_ci    return true;
212be168c0dSopenharmony_ci}
213be168c0dSopenharmony_ci
214be168c0dSopenharmony_cibool allclose_int8(uint8_t *a, uint8_t *b, uint64_t count, float rtol = 1e-05,
215be168c0dSopenharmony_ci                   float atol = 1e-08, bool isquant = false) {
216be168c0dSopenharmony_ci    uint32_t i = 0;
217be168c0dSopenharmony_ci    // add fail loop print
218be168c0dSopenharmony_ci    uint32_t fail_count = 0;
219be168c0dSopenharmony_ci    float tol = 0;
220be168c0dSopenharmony_ci    float tol1 = 0;
221be168c0dSopenharmony_ci    float tol2 = 0;
222be168c0dSopenharmony_ci    bool nan_occur_in_accuray = false;
223be168c0dSopenharmony_ci
224be168c0dSopenharmony_ci    float sum = 0.0f;
225be168c0dSopenharmony_ci    static float sum_all;
226be168c0dSopenharmony_ci    static float maximum = 0;
227be168c0dSopenharmony_ci    static float minimum = 0;
228be168c0dSopenharmony_ci    static uint64_t c = 0;
229be168c0dSopenharmony_ci    // add fail loop print
230be168c0dSopenharmony_ci
231be168c0dSopenharmony_ci    if (a == nullptr || b == nullptr) {
232be168c0dSopenharmony_ci        return false;
233be168c0dSopenharmony_ci    }
234be168c0dSopenharmony_ci
235be168c0dSopenharmony_ci    for (; i < count; ++i) {
236be168c0dSopenharmony_ci        sum = sum + fabs(a[i] - b[i]) / (atol + rtol * fabs(b[i]));
237be168c0dSopenharmony_ci        sum_all = sum_all + fabs(a[i] - b[i]) / (atol + rtol * fabs(b[i]));
238be168c0dSopenharmony_ci        maximum = std::max(static_cast<double>(maximum),
239be168c0dSopenharmony_ci                      static_cast<double>(fabs(a[i] - b[i])) / (atol + rtol * fabs(b[i])));
240be168c0dSopenharmony_ci        minimum = std::min(static_cast<double>(minimum),
241be168c0dSopenharmony_ci                      static_cast<double>(fabs(a[i] - b[i])) / (atol + rtol * fabs(b[i])));
242be168c0dSopenharmony_ci        if (isnan(a[i]) || isinf(a[i])) {
243be168c0dSopenharmony_ci            fail_count = fail_count + 1;
244be168c0dSopenharmony_ci            nan_occur_in_accuray = true;
245be168c0dSopenharmony_ci            if (fail_count < 100) {
246be168c0dSopenharmony_ci                printf("     i = %2u:   %+f  |  %+f\n", i, static_cast<float>(a[i]), static_cast<float>(b[i]));
247be168c0dSopenharmony_ci            }
248be168c0dSopenharmony_ci        } else if (fabs(a[i] - b[i]) > 0) {
249be168c0dSopenharmony_ci            tol = tol + fabs(a[i] - b[i]) / (fabs(b[i]) + 1);
250be168c0dSopenharmony_ci            tol1 = tol1 + fabs(a[i] - b[i]);
251be168c0dSopenharmony_ci            tol2 = tol2 + fabs(a[i] - b[i]) / fabs(b[i]);
252be168c0dSopenharmony_ci            fail_count = fail_count + 1;
253be168c0dSopenharmony_ci            printf("%2d", static_cast<int>(fabs(a[i] - b[i])));
254be168c0dSopenharmony_ci            printf("     i = %2u:   %2d  |  %2d\n", i, a[i], b[i]);
255be168c0dSopenharmony_ci        }
256be168c0dSopenharmony_ci        if (i == count - 1) {
257be168c0dSopenharmony_ci            printf("     ……\n");
258be168c0dSopenharmony_ci            printf("\n *** Total fail_count: %u\n", fail_count);
259be168c0dSopenharmony_ci            if (fail_count != 0) {
260be168c0dSopenharmony_ci                printf("\n     fabs(a[i] - b[i])/(fabs(b[i])+1) : %f\n",
261be168c0dSopenharmony_ci                       tol / fail_count);
262be168c0dSopenharmony_ci                printf("\n     fabs(a[i] - b[i]) : %f\n", tol1 / fail_count);
263be168c0dSopenharmony_ci                printf("\n     fabs(a[i] - b[i])/fabs(b[i]) : %f\n", tol2 / fail_count);
264be168c0dSopenharmony_ci            }
265be168c0dSopenharmony_ci
266be168c0dSopenharmony_ci            c = c + count;
267be168c0dSopenharmony_ci            printf("\n     avg : %f\n", sum / count);
268be168c0dSopenharmony_ci            printf("\n     min : %f\n", minimum);
269be168c0dSopenharmony_ci
270be168c0dSopenharmony_ci            printf("\n     max :  %f\n", maximum);
271be168c0dSopenharmony_ci            printf("\n     avg_all :  %f\n", sum_all / c);
272be168c0dSopenharmony_ci            printf("\n");
273be168c0dSopenharmony_ci            std::fstream file;
274be168c0dSopenharmony_ci            file.open("cout.csv", std::ios::app);
275be168c0dSopenharmony_ci
276be168c0dSopenharmony_ci            file << ","
277be168c0dSopenharmony_ci                 << "1,"
278be168c0dSopenharmony_ci                 << "0," << maximum;
279be168c0dSopenharmony_ci            if (fail_count == 0) {
280be168c0dSopenharmony_ci                file << "," << sum_all / c;
281be168c0dSopenharmony_ci            } else {
282be168c0dSopenharmony_ci                file << "," << tol / fail_count;
283be168c0dSopenharmony_ci            }
284be168c0dSopenharmony_ci            file.close();
285be168c0dSopenharmony_ci        }
286be168c0dSopenharmony_ci    }
287be168c0dSopenharmony_ci    if (nan_occur_in_accuray) {
288be168c0dSopenharmony_ci        printf("\n[common.cpp] eval output include some NAN/INF\n");
289be168c0dSopenharmony_ci        return false;
290be168c0dSopenharmony_ci    }
291be168c0dSopenharmony_ci    if (fail_count > 0) {
292be168c0dSopenharmony_ci        printf("\n *** These data compare failed: atol = %f, rtol = %f\n", atol,
293be168c0dSopenharmony_ci               rtol);
294be168c0dSopenharmony_ci        printf("\n");
295be168c0dSopenharmony_ci        if (isquant) {
296be168c0dSopenharmony_ci            if (tol / fail_count < 0.04) {
297be168c0dSopenharmony_ci                return true;
298be168c0dSopenharmony_ci            }
299be168c0dSopenharmony_ci        }
300be168c0dSopenharmony_ci        return false;
301be168c0dSopenharmony_ci    }
302be168c0dSopenharmony_ci    return true;
303be168c0dSopenharmony_ci}
304be168c0dSopenharmony_ci
305be168c0dSopenharmony_ci/*
306be168c0dSopenharmony_ci * compFp32WithTData: compare the data with the data in hisi .t file
307be168c0dSopenharmony_ci * param:
308be168c0dSopenharmony_ci *  actualOutputData: the result of ge
309be168c0dSopenharmony_ci *  expectedDataFile: the path of hisi .t result file
310be168c0dSopenharmony_ci *  rtol:
311be168c0dSopenharmony_ci *  atol:
312be168c0dSopenharmony_ci * return:
313be168c0dSopenharmony_ci *  true of false
314be168c0dSopenharmony_ci * */
315be168c0dSopenharmony_cibool compFp32WithTData(float *actualOutputData, const std::string& expectedDataFile,
316be168c0dSopenharmony_ci                       float rtol = 1e-05, float atol = 1e-08,
317be168c0dSopenharmony_ci                       bool isquant = false) {
318be168c0dSopenharmony_ci    std::vector<int64_t> dim_info;
319be168c0dSopenharmony_ci    std::vector<int64_t>* ptr_dim_info = &dim_info;
320be168c0dSopenharmony_ci    float *expectedOutputData =
321be168c0dSopenharmony_ci            reinterpret_cast<float *>(readTestDataFile(expectedDataFile, ptr_dim_info));
322be168c0dSopenharmony_ci    uint32_t i = 0;
323be168c0dSopenharmony_ci    uint64_t data_size = 1;
324be168c0dSopenharmony_ci    data_size = accumulate(dim_info.begin(), dim_info.end(), 1, std::multiplies<uint64_t>());
325be168c0dSopenharmony_ci
326be168c0dSopenharmony_ci    // print caffe/tf output:
327be168c0dSopenharmony_ci    printf("[common.cpp] expected output data:");
328be168c0dSopenharmony_ci    for (; i < data_size && i < 10; i++) {
329be168c0dSopenharmony_ci        printf("%4f ", expectedOutputData[i]);
330be168c0dSopenharmony_ci    }
331be168c0dSopenharmony_ci    printf("\n");
332be168c0dSopenharmony_ci    if (isquant) {
333be168c0dSopenharmony_ci        bool ret = allclose(actualOutputData, expectedOutputData, data_size, rtol, atol,
334be168c0dSopenharmony_ci                            true);
335be168c0dSopenharmony_ci        free(expectedOutputData);
336be168c0dSopenharmony_ci        return ret;
337be168c0dSopenharmony_ci    }
338be168c0dSopenharmony_ci    bool ret =  allclose(actualOutputData, expectedOutputData, data_size, rtol, atol);
339be168c0dSopenharmony_ci    free(expectedOutputData);
340be168c0dSopenharmony_ci    return ret;
341be168c0dSopenharmony_ci}
342be168c0dSopenharmony_ci
343be168c0dSopenharmony_cibool compUint8WithTData(uint8_t *actualOutputData, const std::string& expectedDataFile,
344be168c0dSopenharmony_ci                        float rtol = 1e-05, float atol = 1e-08,
345be168c0dSopenharmony_ci                        bool isquant = false) {
346be168c0dSopenharmony_ci    std::vector<int64_t> dim_info;
347be168c0dSopenharmony_ci    std::vector<int64_t>* ptr_dim_info = &dim_info;
348be168c0dSopenharmony_ci    auto dataFile = readTestDataFile(expectedDataFile, ptr_dim_info);
349be168c0dSopenharmony_ci    if(dataFile == nullptr){
350be168c0dSopenharmony_ci        return false;
351be168c0dSopenharmony_ci    }
352be168c0dSopenharmony_ci    uint8_t *expectedOutputData =
353be168c0dSopenharmony_ci            reinterpret_cast<uint8_t *>(dataFile);
354be168c0dSopenharmony_ci    uint32_t i = 0;
355be168c0dSopenharmony_ci    uint64_t data_size = 1;
356be168c0dSopenharmony_ci    data_size = accumulate(dim_info.begin(), dim_info.end(), 1, std::multiplies<uint64_t>());
357be168c0dSopenharmony_ci
358be168c0dSopenharmony_ci    // print caffe/tf output:
359be168c0dSopenharmony_ci    printf("\n [common.cpp] expected output data:\n");
360be168c0dSopenharmony_ci    for (; i < data_size && i < 10; i++) {
361be168c0dSopenharmony_ci        printf("%4hhu ", static_cast<unsigned char>(expectedOutputData[i]));
362be168c0dSopenharmony_ci    }
363be168c0dSopenharmony_ci    printf("\n");
364be168c0dSopenharmony_ci    if (isquant) {
365be168c0dSopenharmony_ci        bool ret =  allclose_int8(actualOutputData, expectedOutputData, data_size, rtol,
366be168c0dSopenharmony_ci                                  atol, true);
367be168c0dSopenharmony_ci        free(expectedOutputData);
368be168c0dSopenharmony_ci        return ret;
369be168c0dSopenharmony_ci    }
370be168c0dSopenharmony_ci    bool ret =  allclose_int8(actualOutputData, expectedOutputData, data_size, rtol,
371be168c0dSopenharmony_ci                              atol);
372be168c0dSopenharmony_ci    free(expectedOutputData);
373be168c0dSopenharmony_ci    return ret;
374be168c0dSopenharmony_ci}
375be168c0dSopenharmony_ci
376be168c0dSopenharmony_ci/*
377be168c0dSopenharmony_ci * ReadFile: read file of model
378be168c0dSopenharmony_ci * param:
379be168c0dSopenharmony_ci *  file: file location
380be168c0dSopenharmony_ci *  size: file size
381be168c0dSopenharmony_ci * return:
382be168c0dSopenharmony_ci *  buf of file
383be168c0dSopenharmony_ci * */
384be168c0dSopenharmony_cichar *ReadFile(const char *file, size_t* size) {
385be168c0dSopenharmony_ci    printf("[common.cpp] Loading data from: %s\n", file);
386be168c0dSopenharmony_ci
387be168c0dSopenharmony_ci    std::ifstream ifs(file);
388be168c0dSopenharmony_ci    if (!ifs.good()) {
389be168c0dSopenharmony_ci        return nullptr;
390be168c0dSopenharmony_ci    }
391be168c0dSopenharmony_ci
392be168c0dSopenharmony_ci    if (!ifs.is_open()) {
393be168c0dSopenharmony_ci        ifs.close();
394be168c0dSopenharmony_ci        return nullptr;
395be168c0dSopenharmony_ci    }
396be168c0dSopenharmony_ci
397be168c0dSopenharmony_ci    ifs.seekg(0, std::ios::end);
398be168c0dSopenharmony_ci    *size = ifs.tellg();
399be168c0dSopenharmony_ci
400be168c0dSopenharmony_ci    char *buf = new char[*size];
401be168c0dSopenharmony_ci    if (buf == nullptr) {
402be168c0dSopenharmony_ci        ifs.close();
403be168c0dSopenharmony_ci        return nullptr;
404be168c0dSopenharmony_ci    }
405be168c0dSopenharmony_ci
406be168c0dSopenharmony_ci    ifs.seekg(0, std::ios::beg);
407be168c0dSopenharmony_ci    ifs.read(buf, *size);
408be168c0dSopenharmony_ci    ifs.close();
409be168c0dSopenharmony_ci    printf("[common.cpp]Read Binary Data Over, get tensorSize as: %" PRId64 ".\n", static_cast<int64_t>(*size));
410be168c0dSopenharmony_ci
411be168c0dSopenharmony_ci    return buf;
412be168c0dSopenharmony_ci}
413be168c0dSopenharmony_ci
414be168c0dSopenharmony_civoid PackNCHWToNHWCFp32(const char *src, char *dst, int batch, int plane, int channel) {
415be168c0dSopenharmony_ci    for (int n = 0; n < batch; n++) {
416be168c0dSopenharmony_ci        for (int c = 0; c < channel; c++) {
417be168c0dSopenharmony_ci            for (int hw = 0; hw < plane; hw++) {
418be168c0dSopenharmony_ci                int nhwc_index = n * channel * plane + hw * channel + c;
419be168c0dSopenharmony_ci                int nchw_index = n * channel * plane + c * plane + hw;
420be168c0dSopenharmony_ci                dst[nhwc_index * 4] = src[nchw_index * 4];
421be168c0dSopenharmony_ci                dst[nhwc_index * 4 + 1] = src[nchw_index * 4 + 1];
422be168c0dSopenharmony_ci                dst[nhwc_index * 4 + 2] = src[nchw_index * 4 + 2];
423be168c0dSopenharmony_ci                dst[nhwc_index * 4 + 3] = src[nchw_index * 4 + 3];
424be168c0dSopenharmony_ci            }
425be168c0dSopenharmony_ci        }
426be168c0dSopenharmony_ci    }
427be168c0dSopenharmony_ci    return;
428be168c0dSopenharmony_ci}
429be168c0dSopenharmony_ci
430be168c0dSopenharmony_cichar **TransStrVectorToCharArrays(const std::vector<std::string> &s) {
431be168c0dSopenharmony_ci    char **charArr = static_cast<char **>(malloc(s.size() * sizeof(char *)));
432be168c0dSopenharmony_ci    for (size_t i = 0; i < s.size(); i++) {
433be168c0dSopenharmony_ci        charArr[i] = static_cast<char *>(malloc((s[i].size() + 1)));
434be168c0dSopenharmony_ci        errno_t ret = memcpy_s(charArr[i], s[i].size(), s[i].c_str(), s[i].size());
435be168c0dSopenharmony_ci        if (ret != EOK) {
436be168c0dSopenharmony_ci            printf("memcpy_s failed, ret: %d\n", ret);
437be168c0dSopenharmony_ci        }
438be168c0dSopenharmony_ci        *(charArr[i] + s[i].size()) = '\0';
439be168c0dSopenharmony_ci    }
440be168c0dSopenharmony_ci    return charArr;
441be168c0dSopenharmony_ci}
442be168c0dSopenharmony_ci
443be168c0dSopenharmony_cistd::vector<std::string> TransCharArraysToStrVector(char **c, const size_t &num) {
444be168c0dSopenharmony_ci    std::vector<std::string> str;
445be168c0dSopenharmony_ci    for (size_t i = 0; i < num; i++) {
446be168c0dSopenharmony_ci        str.push_back(std::string(c[i]));
447be168c0dSopenharmony_ci    }
448be168c0dSopenharmony_ci    return str;
449be168c0dSopenharmony_ci}
450