Add option to specify object classes list file
[tidl/tidl-api.git] / examples / one_eo_per_frame / main.cpp
1 /******************************************************************************
2  * Copyright (c) 2017-2018  Texas Instruments Incorporated - http://www.ti.com/
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *      * Redistributions of source code must retain the above copyright
8  *        notice, this list of conditions and the following disclaimer.
9  *      * Redistributions in binary form must reproduce the above copyright
10  *        notice, this list of conditions and the following disclaimer in the
11  *        documentation and/or other materials provided with the distribution.
12  *      * Neither the name of Texas Instruments Incorporated nor the
13  *        names of its contributors may be used to endorse or promote products
14  *        derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  *  THE POSSIBILITY OF SUCH DAMAGE.
27  *****************************************************************************/
29 //
30 // This example illustrates using a single EO to process a frame. To increase
31 // throughput, multiple EOs are used.
32 // For details, refer http://downloads.ti.com/mctools/esd/docs/tidl-api/
33 //
34 #include <signal.h>
35 #include <iostream>
36 #include <fstream>
37 #include <cassert>
38 #include <string>
40 #include "executor.h"
41 #include "execution_object.h"
42 #include "configuration.h"
43 #include "utils.h"
45 using namespace tidl;
46 using std::string;
47 using std::unique_ptr;
48 using std::vector;
50 bool Run(const string& config_file, int num_eve,int num_dsp,
51          const char* ref_output);
53 Executor* CreateExecutor(DeviceType dt, int num, const Configuration& c);
54 void      CollectEOs(const Executor *e, vector<ExecutionObject *>& EOs);
57 int main(int argc, char *argv[])
58 {
59     // Catch ctrl-c to ensure a clean exit
60     signal(SIGABRT, exit);
61     signal(SIGTERM, exit);
63     // If there are no devices capable of offloading TIDL on the SoC, exit
64     uint32_t num_eve = Executor::GetNumDevices(DeviceType::EVE);
65     uint32_t num_dsp = Executor::GetNumDevices(DeviceType::DSP);
66     if (num_eve == 0 && num_dsp == 0)
67     {
68         std::cout << "TI DL not supported on this SoC." << std::endl;
69         return EXIT_SUCCESS;
70     }
72     string config_file ="../test/testvecs/config/infer/tidl_config_j11_v2.txt";
73     string ref_file    ="../test/testvecs/reference/j11_v2_ref.bin";
75     unique_ptr<const char> reference_output(ReadReferenceOutput(ref_file));
77     // Enable time stamp generation. The timestamp file is post processed
78     // by execution_graph.py to generate graphical view of frame execution.
79     // Refer to the User's Guide for details.
80     EnableTimeStamps("1eo.log");
82     bool status = Run(config_file, num_eve, num_dsp, reference_output.get());
84     if (!status)
85     {
86         std::cout << "FAILED" << std::endl;
87         return EXIT_FAILURE;
88     }
90     std::cout << "PASSED" << std::endl;
91     return EXIT_SUCCESS;
92 }
94 bool Run(const string& config_file, int num_eve, int num_dsp,
95          const char* ref_output)
96 {
97     Configuration c;
98     if (!c.ReadFromFile(config_file))
99         return false;
101     // Heap sizes for this network determined using Configuration::showHeapStats
102     c.PARAM_HEAP_SIZE   = (3 << 20); // 3MB
103     c.NETWORK_HEAP_SIZE = (20 << 20); // 20MB
105     c.numFrames = 16;
107     // Open input file for reading
108     std::ifstream input_data_file(c.inData, std::ios::binary);
110     bool status = true;
111     try
112     {
113         // Create Executors - use all the DSP and EVE cores available
114         unique_ptr<Executor> e_dsp(CreateExecutor(DeviceType::DSP, num_dsp, c));
115         unique_ptr<Executor> e_eve(CreateExecutor(DeviceType::EVE, num_eve, c));
117         // Accumulate all the EOs from across the Executors
118         vector<ExecutionObject *> EOs;
119         CollectEOs(e_eve.get(), EOs);
120         CollectEOs(e_dsp.get(), EOs);
122         AllocateMemory(EOs);
124         // Process frames with EOs in a pipelined manner
125         // additional num_eos iterations to flush the pipeline (epilogue)
126         int num_eos = EOs.size();
127         for (int frame_idx = 0; frame_idx < c.numFrames + num_eos; frame_idx++)
128         {
129             ExecutionObject* eo = EOs[frame_idx % num_eos];
131             // Wait for previous frame on the same eo to finish processing
132             if (eo->ProcessFrameWait())
133             {
134                 ReportTime(eo);
135                 if (frame_idx < num_eos && !CheckFrame(eo, ref_output))
136                     status = false;
137             }
139             // Read a frame and start processing it with current eo
140             if (ReadFrame(eo, frame_idx, c, input_data_file))
141                 eo->ProcessFrameStartAsync();
142         }
144         FreeMemory(EOs);
146     }
147     catch (tidl::Exception &e)
148     {
149         std::cerr << e.what() << std::endl;
150         status = false;
151     }
153     input_data_file.close();
155     return status;
158 // Create an Executor with the specified type and number of EOs
159 Executor* CreateExecutor(DeviceType dt, int num, const Configuration& c)
161     if (num == 0) return nullptr;
163     DeviceIds ids;
164     for (int i = 0; i < num; i++)
165         ids.insert(static_cast<DeviceId>(i));
167     return new Executor(dt, ids, c);
170 // Accumulate EOs from an Executor into a vector of EOs
171 void CollectEOs(const Executor *e, vector<ExecutionObject *>& EOs)
173     if (!e) return;
175     for (unsigned int i = 0; i < e->GetNumExecutionObjects(); i++)
176         EOs.push_back((*e)[i]);