File: testqa.cc

package info (click to toggle)
volk 3.2.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,916 kB
  • sloc: ansic: 40,447; cpp: 2,005; asm: 918; python: 897; xml: 375; sh: 157; makefile: 14
file content (145 lines) | stat: -rw-r--r-- 5,640 bytes parent folder | download | duplicates (2)
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* -*- c++ -*- */
/*
 * Copyright 2012-2014 Free Software Foundation, Inc.
 *
 * This file is part of VOLK
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#include <stdbool.h> // for bool, false, true
#include <fstream>   // IWYU pragma: keep
#include <iostream>  // for operator<<, basic_ostream, endl, char...
#include <map>       // for map, map<>::iterator, _Rb_tree_iterator
#include <string>    // for string, operator<<
#include <utility>   // for pair
#include <vector>    // for vector

#include "kernel_tests.h"      // for init_test_list
#include "qa_utils.h"          // for volk_test_case_t, volk_test_results_t
#include "volk/volk_complex.h" // for lv_32fc_t
#include <volk/volk.h>

void print_qa_xml(std::vector<volk_test_results_t> results, unsigned int nfails);

int main(int argc, char* argv[])
{
    bool qa_ret_val = 0;

    float def_tol = 1e-6;
    lv_32fc_t def_scalar = 327.0;
    int def_iter = 1;
    int def_vlen = 131071;
    bool def_benchmark_mode = true;
    std::string def_kernel_regex = "";

    volk_test_params_t test_params(
        def_tol, def_scalar, def_vlen, def_iter, def_benchmark_mode, def_kernel_regex);
    std::vector<volk_test_case_t> test_cases = init_test_list(test_params);
    std::vector<volk_test_results_t> results;

    if (argc > 1) {
        for (unsigned int ii = 0; ii < test_cases.size(); ++ii) {
            if (std::string(argv[1]) == test_cases[ii].name()) {
                volk_test_case_t test_case = test_cases[ii];
                if (run_volk_tests(test_case.desc(),
                                   test_case.kernel_ptr(),
                                   test_case.name(),
                                   test_case.test_parameters(),
                                   &results,
                                   test_case.puppet_master_name())) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }
        std::cerr << "Did not run a test for kernel: " << std::string(argv[1]) << " !"
                  << std::endl;
        return 0;

    } else {
        std::vector<std::string> qa_failures;
        // Test every kernel reporting failures when they occur
        for (unsigned int ii = 0; ii < test_cases.size(); ++ii) {
            bool qa_result = false;
            volk_test_case_t test_case = test_cases[ii];
            try {
                qa_result = run_volk_tests(test_case.desc(),
                                           test_case.kernel_ptr(),
                                           test_case.name(),
                                           test_case.test_parameters(),
                                           &results,
                                           test_case.puppet_master_name());
            } catch (...) {
                // TODO: what exceptions might we need to catch and how do we handle them?
                std::cerr << "Exception found on kernel: " << test_case.name()
                          << std::endl;
                qa_result = false;
            }

            if (qa_result) {
                std::cerr << "Failure on " << test_case.name() << std::endl;
                qa_failures.push_back(test_case.name());
            }
        }

        // Generate XML results
        print_qa_xml(results, qa_failures.size());

        // Summarize QA results
        std::cerr << "Kernel QA finished: " << qa_failures.size() << " failures out of "
                  << test_cases.size() << " tests." << std::endl;
        if (qa_failures.size() > 0) {
            std::cerr << "The following kernels failed QA:" << std::endl;
            for (unsigned int ii = 0; ii < qa_failures.size(); ++ii) {
                std::cerr << "    " << qa_failures[ii] << std::endl;
            }
            qa_ret_val = 1;
        }
    }

    return qa_ret_val;
}

/*
 * This function prints qa results as XML output similar to output
 * from Junit. For reference output see https://llg.cubic.org/docs/junit/
 */
void print_qa_xml(std::vector<volk_test_results_t> results, unsigned int nfails)
{
    std::ofstream qa_file;
    qa_file.open(".unittest/kernels.xml");

    qa_file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
    qa_file << "<testsuites name=\"kernels\" "
            << "tests=\"" << results.size() << "\" "
            << "failures=\"" << nfails << "\" id=\"1\">" << std::endl;

    // Results are in a vector by kernel. Each element has a result
    // map containing time and arch name with test result
    for (unsigned int ii = 0; ii < results.size(); ++ii) {
        volk_test_results_t result = results[ii];
        qa_file << "  <testsuite name=\"" << result.name << "\">" << std::endl;

        std::map<std::string, volk_test_time_t>::iterator kernel_time_pair;
        for (kernel_time_pair = result.results.begin();
             kernel_time_pair != result.results.end();
             ++kernel_time_pair) {
            volk_test_time_t test_time = kernel_time_pair->second;
            qa_file << "    <testcase name=\"" << test_time.name << "\" "
                    << "classname=\"" << result.name << "\" "
                    << "time=\"" << test_time.time << "\">" << std::endl;
            if (!test_time.pass)
                qa_file << "      <failure "
                        << "message=\"fail on arch " << test_time.name << "\">"
                        << "</failure>" << std::endl;
            qa_file << "    </testcase>" << std::endl;
        }
        qa_file << "  </testsuite>" << std::endl;
    }


    qa_file << "</testsuites>" << std::endl;
    qa_file.close();
}