Refactor examples - test, one_eo_per_frame
authorAjay Jayaraj <ajayj@ti.com>
Mon, 27 Aug 2018 21:41:25 +0000 (16:41 -0500)
committerAjay Jayaraj <ajayj@ti.com>
Wed, 29 Aug 2018 14:23:38 +0000 (09:23 -0500)
- Remove code duplication across test/main.cpp,
  test/multiple_executors.cpp and one_eo_per_frame/main.cpp
- Moved common code into common/utils.h, common/utils.cpp

(MCT-1047)

docs/source/example.rst
docs/source/index.rst
examples/common/utils.cpp [new file with mode: 0644]
examples/common/utils.h [new file with mode: 0644]
examples/one_eo_per_frame/Makefile
examples/one_eo_per_frame/main.cpp
examples/test/Makefile
examples/test/main.cpp
examples/test/multiple_executors.cpp
tidl_api/src/ocl_device.cpp

index 7ba9bc7d3761368f0d9b5fae8b5b7a2eeb9472d6..1b16d014643fc45fa24070070598c97ccfee0bd1 100644 (file)
@@ -2,12 +2,31 @@
 Examples
 ********
 
-We ship three end-to-end examples within the tidl-api package
-to demonstrate three categories of deep learning networks.  The first
-two examples can run on AM57x SoCs with either EVE or DSP devices.  The last
-example requires AM57x SoCs with both EVE and DSP.  The performance
++---------------------+-----------------------------------------------------+
+| Example             | Description                                         |
++---------------------+-----------------------------------------------------+
+| one_eo_per_frame    | Simple example to illustrate processing a single    |
+|                     | frame with one :term:`EO` using the j11_v2 network. |
+|                     | The per-frame processing time for this network is   |
+|                     | fairly similar across EVE and C66x DSP. The example |
+|                     | parallelizes frame processing across all available  |
+|                     | EVE and C66x cores.                                 |
++---------------------+-----------------------------------------------------+
+| imagenet            | Classification                                      |
++---------------------+-----------------------------------------------------+
+| segmentation        | Pixel level segmentation                            |
++---------------------+-----------------------------------------------------+
+| ssd_multibox        | Object detection                                    |
++---------------------+-----------------------------------------------------+
+| tidl_classification | Classification                                      |
++---------------------+-----------------------------------------------------+
+| test                | Unit test. Tests supported networks on C66x and EVE |
++---------------------+-----------------------------------------------------+
+
+The examples included in the tidl-api package demonstrate three categories of
+deep learning networks: classification, segmentation and object detection. ``imagenet`` and ``segmentation`` can run on AM57x processors with either EVE or C66x cores. ``ssd_multibox`` requires AM57x processors with both EVE and C66x.  The performance
 numbers that we present here were obtained on an AM5729 EVM, which
-includes 2 ARM A15 cores running at 1.5GHz, 4 EVE cores at 535MHz, and
+includes 2 Arm Cortex-A15 cores running at 1.5GHz, 4 EVE cores at 535MHz, and
 2 DSP cores at 750MHz.
 
 For each example, we report device processing time, host processing time,
index ee2fda39f8df4007020804ec3497e2626968bf74..a32f4c15fba8650c47e55f1974915a45d523bfcf 100644 (file)
@@ -10,9 +10,9 @@ TI Deep Learning API User's Guide
    intro
    overview
    using_api
-   viewer
    example
    api
+   viewer
    faq/index
    readme/index
    notice
diff --git a/examples/common/utils.cpp b/examples/common/utils.cpp
new file mode 100644 (file)
index 0000000..a4c978b
--- /dev/null
@@ -0,0 +1,130 @@
+/******************************************************************************
+ * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Texas Instruments Incorporated nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#include <boost/format.hpp>
+#include <cstring>
+
+#include "utils.h"
+
+using namespace tidl;
+
+using boost::format;
+using std::string;
+
+bool ReadFrame(ExecutionObject* eo, int frame_idx,
+               const Configuration& configuration,
+               std::istream& input_file)
+{
+    if (frame_idx >= configuration.numFrames)
+        return false;
+
+    assert (eo->GetInputBufferPtr() != nullptr);
+    assert (input_file.good());
+
+    input_file.read(eo->GetInputBufferPtr(),
+                    eo->GetInputBufferSizeInBytes());
+    assert (input_file.good());
+
+    if (input_file.eof())
+        return false;
+
+    // Note: Frame index is used by the EO for debug messages only
+    eo->SetFrameIndex(frame_idx);
+
+    // Wrap-around : if EOF is reached, start reading from the beginning.
+    if (input_file.peek() == EOF)
+        input_file.seekg(0, input_file.beg);
+
+    if (input_file.good())
+        return true;
+
+    return false;
+}
+
+bool WriteFrame(const ExecutionObject* eo, std::ostream& output_file)
+{
+    output_file.write(eo->GetOutputBufferPtr(),
+                      eo->GetOutputBufferSizeInBytes());
+    assert(output_file.good() == true);
+
+    if (output_file.good())
+        return true;
+
+    return false;
+}
+
+void ReportTime(const ExecutionObject* eo)
+{
+    double elapsed_host   = eo->GetHostProcessTimeInMilliSeconds();
+    double elapsed_device = eo->GetProcessTimeInMilliSeconds();
+    double overhead = 100 - (elapsed_device/elapsed_host*100);
+
+    std::cout << format("frame[%3d]: Time on %s: %4.2f ms, host: %4.2f ms"
+                        " API overhead: %2.2f %%\n")
+                        % eo->GetFrameIndex() % eo->GetDeviceName()
+                        % elapsed_device % elapsed_host % overhead;
+}
+
+// Compare output against reference output
+bool CheckFrame(const ExecutionObject *eo, const char *ref_output)
+{
+    if (std::memcmp(static_cast<const void*>(ref_output),
+               static_cast<const void*>(eo->GetOutputBufferPtr()),
+               eo->GetOutputBufferSizeInBytes()) == 0)
+        return true;
+
+    return false;
+}
+
+
+namespace tidl {
+std::size_t GetBinaryFileSize (const std::string &F);
+bool        ReadBinary        (const std::string &F, char* buffer, int size);
+}
+
+// Read file into a buffer.
+const char* ReadReferenceOutput(const string& name)
+{
+    size_t size = GetBinaryFileSize(name);
+
+    if (size == 0)
+        return nullptr;
+
+    char* buffer = new char[size];
+
+    if (!buffer)
+        return nullptr;
+
+    if (!ReadBinary(name, buffer, size))
+    {
+        delete [] buffer;
+        return nullptr;
+    }
+
+    return buffer;
+}
diff --git a/examples/common/utils.h b/examples/common/utils.h
new file mode 100644 (file)
index 0000000..9da1916
--- /dev/null
@@ -0,0 +1,48 @@
+/******************************************************************************
+ * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Texas Instruments Incorporated nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+#pragma once
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include "executor.h"
+#include "execution_object.h"
+#include "configuration.h"
+
+bool ReadFrame(tidl::ExecutionObject*     eo,
+               int                        frame_idx,
+               const tidl::Configuration& configuration,
+               std::istream&              input_file);
+
+bool WriteFrame(const tidl::ExecutionObject* eo, std::ostream& output_file);
+
+void ReportTime(const tidl::ExecutionObject* eo);
+
+bool CheckFrame(const tidl::ExecutionObject* eo, const char *ref_output);
+
+const char* ReadReferenceOutput(const std::string& name);
index 10f5f0f2fed3d45b3c038daf8c9e60e54fa75f1c..8420254ad2f5652a853e6f4f7ac8afecc7a11f82 100644 (file)
@@ -28,7 +28,9 @@ EXE = one_eo_per_frame
 
 include ../make.common
 
-SOURCES = main.cpp
+CXXFLAGS += -I../common
+
+SOURCES = main.cpp ../common/utils.cpp
 
 $(EXE): $(TIDL_API_LIB) $(HEADERS) $(SOURCES)
        $(CXX) $(CXXFLAGS) $(SOURCES) $(TIDL_API_LIB) $(LDFLAGS) $(LIBS) -o $@
index f79500ad8417054a4aa3dac9818ac2b1fd6b0087..a7f10a8b106bddc79b58ed8efc199d4c78bad980 100644 (file)
 //
 #include <signal.h>
 #include <iostream>
-#include <iomanip>
 #include <fstream>
 #include <cassert>
 #include <string>
-#include <cstring>
 
 #include "executor.h"
 #include "execution_object.h"
 #include "configuration.h"
-#include <boost/format.hpp>
+#include "utils.h"
 
 using namespace tidl;
 using std::string;
 using std::unique_ptr;
 using std::vector;
-using boost::format;
 
 bool Run(const string& config_file, int num_eve,int num_dsp,
          const char* ref_output);
 
-bool ReadFrame(ExecutionObject*     eo,
-               int                  frame_idx,
-               const Configuration& configuration,
-               std::istream&        input_file);
-bool CheckFrame(const ExecutionObject *eo, const char *ref_output);
-
-const char* ReadReferenceOutput(const string& name);
-void        ReportTime(const ExecutionObject* eo);
-
 Executor* CreateExecutor(DeviceType dt, int num, const Configuration& c);
 void      CollectEOs(const Executor *e, vector<ExecutionObject *>& EOs);
 
@@ -116,7 +104,6 @@ bool Run(const string& config_file, int num_eve, int num_dsp,
 
     // Open input file for reading
     std::ifstream input_data_file(c.inData, std::ios::binary);
-    assert (input_data_file.good());
 
     bool status = true;
     try
@@ -211,82 +198,3 @@ void FreeMemory(const vector<ExecutionObject *>& EOs)
     }
 
 }
-
-// Read a frame. Since the sample input has a single frame, read the same
-// frame over and over.
-bool ReadFrame(ExecutionObject *eo, int frame_idx,
-               const Configuration& configuration,
-               std::istream& input_file)
-{
-    char*  frame_buffer = eo->GetInputBufferPtr();
-    assert (frame_buffer != nullptr);
-
-    input_file.seekg(0, input_file.beg);
-
-    input_file.read(eo->GetInputBufferPtr(),
-                    eo->GetInputBufferSizeInBytes());
-
-    if (input_file.eof())
-        return false;
-
-    assert (input_file.good());
-
-    // Note: Frame index is used by the EO for debug messages only
-    eo->SetFrameIndex(frame_idx);
-
-    if (input_file.good())
-        return true;
-
-    return false;
-}
-
-// Compare output against reference output
-bool CheckFrame(const ExecutionObject *eo, const char *ref_output)
-{
-    if (std::memcmp(static_cast<const void*>(ref_output),
-               static_cast<const void*>(eo->GetOutputBufferPtr()),
-               eo->GetOutputBufferSizeInBytes()) == 0)
-        return true;
-
-    return false;
-}
-
-
-void ReportTime(const ExecutionObject* eo)
-{
-    double elapsed_host   = eo->GetHostProcessTimeInMilliSeconds();
-    double elapsed_device = eo->GetProcessTimeInMilliSeconds();
-    double overhead = 100 - (elapsed_device/elapsed_host*100);
-
-    std::cout << format("frame[%3d]: Time on %s: %4.2f ms, host: %4.2f ms"
-                        " API overhead: %2.2f %%\n")
-                        % eo->GetFrameIndex() % eo->GetDeviceName()
-                        % elapsed_device % elapsed_host % overhead;
-}
-
-namespace tidl {
-std::size_t GetBinaryFileSize (const std::string &F);
-bool        ReadBinary        (const std::string &F, char* buffer, int size);
-}
-
-// Read a file into a buffer.
-const char* ReadReferenceOutput(const string& name)
-{
-    size_t size = GetBinaryFileSize(name);
-
-    if (size == 0)
-        return nullptr;
-
-    char* buffer = new char[size];
-
-    if (!buffer)
-        return nullptr;
-
-    if (!ReadBinary(name, buffer, size))
-    {
-        delete [] buffer;
-        return nullptr;
-    }
-
-    return buffer;
-}
index 646fced80a602beb39e4750f23abfe98089fb846..df609aa35d23cb3cb1d94854fadf6a600a85f120 100644 (file)
@@ -28,7 +28,9 @@ EXE = test_tidl
 
 include ../make.common
 
-$(EXE): SOURCES = main.cpp multiple_executors.cpp
+CXXFLAGS += -I../common
+
+SOURCES = main.cpp multiple_executors.cpp ../common/utils.cpp
 
 $(EXE): $(TIDL_API_LIB) $(HEADERS) $(SOURCES)
        $(CXX) $(CXXFLAGS) $(SOURCES) $(TIDL_API_LIB) $(LDFLAGS) $(LIBS) -o $@
index 5fdfd641ab47daf4e46c5cb7ba43cf6cea6dd768..3fdb9065438f8bd3ebe47e70af0c1183b3357985 100644 (file)
 #include <signal.h>
 #include <getopt.h>
 #include <iostream>
-#include <iomanip>
 #include <fstream>
 #include <cassert>
 #include <string>
-#include <functional>
-#include <algorithm>
-#include <time.h>
+#include <vector>
 
 #include "executor.h"
 #include "execution_object.h"
 #include "configuration.h"
-
-bool __TI_show_debug_ = false;
+#include "utils.h"
 
 using namespace tidl;
+using std::string;
 
-bool RunMultipleExecutors(const std::string& config_file_1,
-                          const std::string& config_file_2,
-                          uint32_t num_devices_available);
+bool RunMultipleExecutors(const string& config_file_1,
+                          const string& config_file_2,
+                          uint32_t      num_devices_available);
 
-bool RunConfiguration(const std::string& config_file, int num_devices,
-                      DeviceType device_type);
-bool RunAllConfigurations(int32_t num_devices, DeviceType device_type);
+bool RunConfiguration(const string& config_file,
+                      int           num_devices,
+                      DeviceType    device_type);
 
-bool ReadFrame(ExecutionObject&     eo,
-               int                  frame_idx,
-               const Configuration& configuration,
-               std::istream&        input_file);
+bool RunAllConfigurations(int32_t    num_devices,
+                          DeviceType device_type);
 
-bool WriteFrame(const ExecutionObject &eo,
-                std::ostream& output_file);
+bool RunNetwork(DeviceType           device_type,
+                const DeviceIds&     ids,
+                const Configuration& c,
+                std::istream&        input,
+                std::ostream&        output);
 
 static void ProcessArgs(int argc, char *argv[],
-                        std::string& config_file,
-                        int& num_devices,
+                        string&     config_file,
+                        int&        num_devices,
                         DeviceType& device_type);
 
 static void DisplayHelp();
 
-static double ms_diff(struct timespec &t0, struct timespec &t1)
-{ return (t1.tv_sec - t0.tv_sec) * 1e3 + (t1.tv_nsec - t0.tv_nsec) / 1e6; }
-
+bool verbose = false;
 
 int main(int argc, char *argv[])
 {
@@ -82,13 +78,12 @@ int main(int argc, char *argv[])
     uint32_t num_dsp = Executor::GetNumDevices(DeviceType::DSP);
     if (num_eve == 0 && num_dsp == 0)
     {
-        std::cout << "TI DL not supported on this SoC." << std::endl;
+        std::cout << "TI DL not supported on this processor." << std::endl;
         return EXIT_SUCCESS;
     }
-    std::cout << "API Version: " << Executor::GetAPIVersion() << std::endl;
 
     // Process arguments
-    std::string config_file;
+    string      config_file;
     int         num_devices = 1;
     DeviceType  device_type = DeviceType::EVE;
     ProcessArgs(argc, argv, config_file, num_devices, device_type);
@@ -144,92 +139,78 @@ bool RunConfiguration(const std::string& config_file, int num_devices,
         ids.insert(static_cast<DeviceId>(i));
 
     // Read the TI DL configuration file
-    Configuration configuration;
-    bool status = configuration.ReadFromFile(config_file);
-    if (!status)
-    {
-        std::cerr << "Error in configuration file: " << config_file
-                  << std::endl;
-        return false;
-    }
+    Configuration c;
+    if (!c.ReadFromFile(config_file)) return false;
+    if (verbose)                      c.enableApiTrace = true;
 
     // Open input and output files
-    std::ifstream input_data_file(configuration.inData, std::ios::binary);
-    std::ofstream output_data_file(configuration.outData, std::ios::binary);
+    std::ifstream input_data_file(c.inData, std::ios::binary);
+    std::ofstream output_data_file(c.outData, std::ios::binary);
     assert (input_data_file.good());
     assert (output_data_file.good());
 
+    bool status = RunNetwork(device_type, ids, c,
+                             input_data_file, output_data_file);
+
+    input_data_file.close();
+    output_data_file.close();
+
+    return status;
+}
+
+bool RunNetwork(DeviceType           device_type,
+                const DeviceIds&     ids,
+                const Configuration& c,
+                std::istream&        input,
+                std::ostream&        output)
+{
+    bool status = true;
+
     try
     {
-        // Create a executor with the approriate core type, number of cores
-        // and configuration specified
-        Executor executor(device_type, ids, configuration);
+        // Create a executor with the specified core type, number of cores
+        // and configuration
+        Executor E(device_type, ids, c);
+
+        std::vector<ExecutionObject *> EOs;
+        for (unsigned int i = 0; i < E.GetNumExecutionObjects(); i++)
+            EOs.push_back(E[i]);
 
-        // Query Executor for set of ExecutionObjects created
-        const ExecutionObjects& execution_objects =
-                                                executor.GetExecutionObjects();
-        int num_eos = execution_objects.size();
+        int num_eos = EOs.size();
 
         // Allocate input and output buffers for each execution object
-        std::vector<void *> buffers;
-        for (auto &eo : execution_objects)
+        for (auto eo : EOs)
         {
             size_t in_size  = eo->GetInputBufferSizeInBytes();
             size_t out_size = eo->GetOutputBufferSizeInBytes();
             ArgInfo in  = { ArgInfo(malloc(in_size),  in_size)};
             ArgInfo out = { ArgInfo(malloc(out_size), out_size)};
             eo->SetInputOutputBuffer(in, out);
-
-            buffers.push_back(in.ptr());
-            buffers.push_back(out.ptr());
         }
 
-        #define MAX_NUM_EOS  4
-        struct timespec t0[MAX_NUM_EOS], t1;
-
         // Process frames with available execution objects in a pipelined manner
         // additional num_eos iterations to flush the pipeline (epilogue)
-        for (int frame_idx = 0;
-             frame_idx < configuration.numFrames + num_eos; frame_idx++)
+        for (int frame_idx = 0; frame_idx < c.numFrames + num_eos; frame_idx++)
         {
-            ExecutionObject* eo = execution_objects[frame_idx % num_eos].get();
+            ExecutionObject* eo = EOs[frame_idx % num_eos];
 
             // Wait for previous frame on the same eo to finish processing
             if (eo->ProcessFrameWait())
             {
-                clock_gettime(CLOCK_MONOTONIC, &t1);
-                double elapsed_host =
-                                ms_diff(t0[eo->GetFrameIndex() % num_eos], t1);
-                double elapsed_device = eo->GetProcessTimeInMilliSeconds();
-                double overhead = 100 - (elapsed_device/elapsed_host*100);
-
-                std::cout << "frame[" << eo->GetFrameIndex() << "]: "
-                          << "Time on device: "
-                          << std::setw(6) << std::setprecision(4)
-                          << elapsed_device << "ms, "
-                          << "host: "
-                          << std::setw(6) << std::setprecision(4)
-                          << elapsed_host << "ms ";
-                std::cout << "API overhead: "
-                          << std::setw(6) << std::setprecision(3)
-                          << overhead << " %" << std::endl;
-
-                WriteFrame(*eo, output_data_file);
-                if (configuration.enableOutputTrace)
-                    eo->WriteLayerOutputsToFile();
+                ReportTime(eo);
+                WriteFrame(eo, output);
             }
 
             // Read a frame and start processing it with current eo
-            if (ReadFrame(*eo, frame_idx, configuration, input_data_file))
-            {
-                clock_gettime(CLOCK_MONOTONIC, &t0[frame_idx % num_eos]);
+            if (ReadFrame(eo, frame_idx, c, input))
                 eo->ProcessFrameStartAsync();
-            }
         }
 
-        for (auto b : buffers)
-            free(b);
-
+        for (auto eo : EOs)
+        {
+            free(eo->GetInputBufferPtr());
+            free(eo->GetOutputBufferPtr());
+        }
     }
     catch (tidl::Exception &e)
     {
@@ -237,13 +218,10 @@ bool RunConfiguration(const std::string& config_file, int num_devices,
         status = false;
     }
 
-
-    input_data_file.close();
-    output_data_file.close();
-
     return status;
 }
 
+
 namespace tidl {
 extern bool CompareFiles (const std::string &F1, const std::string &F2);
 extern bool CompareFrames(const std::string &F1, const std::string &F2,
@@ -303,49 +281,6 @@ bool RunAllConfigurations(int32_t num_devices, DeviceType device_type)
     return true;
 }
 
-
-
-bool ReadFrame(ExecutionObject &eo, int frame_idx,
-               const Configuration& configuration,
-               std::istream& input_file)
-{
-    if (frame_idx >= configuration.numFrames)
-        return false;
-
-    char*  frame_buffer = eo.GetInputBufferPtr();
-    assert (frame_buffer != nullptr);
-
-    input_file.read(eo.GetInputBufferPtr(),
-                    eo.GetInputBufferSizeInBytes());
-
-    if (input_file.eof())
-        return false;
-
-    assert (input_file.good());
-
-    // Set the frame index  being processed by the EO. This is used to
-    // sort the frames before they are output
-    eo.SetFrameIndex(frame_idx);
-
-    if (input_file.good())
-        return true;
-
-    return false;
-}
-
-bool WriteFrame(const ExecutionObject &eo, std::ostream& output_file)
-{
-    output_file.write(
-            eo.GetOutputBufferPtr(), eo.GetOutputBufferSizeInBytes());
-    assert(output_file.good() == true);
-
-    if (output_file.good())
-        return true;
-
-    return false;
-}
-
-
 void ProcessArgs(int argc, char *argv[], std::string& config_file,
                  int& num_devices, DeviceType& device_type)
 {
@@ -389,7 +324,7 @@ void ProcessArgs(int argc, char *argv[], std::string& config_file,
                       }
                       break;
 
-            case 'v': __TI_show_debug_ = true;
+            case 'v': verbose = true;
                       break;
 
             case 'h': DisplayHelp();
index 41821b55a11e6c62e222c1b39fce8d9a91e96971..8bf839f7fc79a4df54a709efe69bd9e9d9fd647b 100644 (file)
@@ -1,29 +1,29 @@
 /******************************************************************************
  * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
- *   All rights reserved.
+ * All rights reserved.
  *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions are met:
- *       * Redistributions of source code must retain the above copyright
- *         notice, this list of conditions and the following disclaimer.
- *       * Redistributions in binary form must reproduce the above copyright
- *         notice, this list of conditions and the following disclaimer in the
- *         documentation and/or other materials provided with the distribution.
- *       * Neither the name of Texas Instruments Incorporated nor the
- *         names of its contributors may be used to endorse or promote products
- *         derived from this software without specific prior written permission.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Texas Instruments Incorporated nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
  *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- *   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- *   THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
 //! @file multiple_executors.cpp
 #include "executor.h"
 #include "execution_object.h"
 #include "configuration.h"
+#include "utils.h"
 
 using namespace tidl;
 
-extern bool ReadFrame(ExecutionObject&     eo,
-               int                  frame_idx,
-               const Configuration& configuration,
-               std::istream&        input_file);
-
-extern bool WriteFrame(const ExecutionObject &eo,
-                std::ostream& output_file);
+extern
+bool RunNetwork(DeviceType           device_type,
+                const DeviceIds&     ids,
+                const Configuration& c,
+                std::istream&        input,
+                std::ostream&        output);
 
 void* run_network(void *data);
 
@@ -153,57 +153,8 @@ void* run_network(void *data)
     assert (input_data_file.good());
     assert (output_data_file.good());
 
-    // Determine input frame size from configuration
-    size_t frame_sz = configuration.inWidth * configuration.inHeight *
-                      configuration.inNumChannels;
-
-    try
-    {
-        // Create a executor with the approriate core type, number of cores
-        // and configuration specified
-        Executor executor(DeviceType::EVE, ids, configuration);
-
-        const ExecutionObjects& execution_objects =
-                                                executor.GetExecutionObjects();
-        int num_eos = execution_objects.size();
-
-        // Allocate input and output buffers for each execution object
-        std::vector<void *> buffers;
-        for (auto &eo : execution_objects)
-        {
-            ArgInfo in  = { ArgInfo(malloc_ddr<char>(frame_sz), frame_sz)};
-            ArgInfo out = { ArgInfo(malloc_ddr<char>(frame_sz), frame_sz)};
-            eo->SetInputOutputBuffer(in, out);
-
-            buffers.push_back(in.ptr());
-            buffers.push_back(out.ptr());
-        }
-
-        // Process frames with available execution objects in a pipelined manner
-        // additional num_eos iterations to flush the pipeline (epilogue)
-        for (int frame_idx = 0;
-             frame_idx < configuration.numFrames + num_eos; frame_idx++)
-        {
-            ExecutionObject* eo = execution_objects[frame_idx % num_eos].get();
-
-            // Wait for previous frame on the same eo to finish processing
-            if (eo->ProcessFrameWait())
-                WriteFrame(*eo, output_data_file);
-
-            // Read a frame and start processing it with current eo
-            if (ReadFrame(*eo, frame_idx, configuration, input_data_file))
-                eo->ProcessFrameStartAsync();
-        }
-
-
-        for (auto b : buffers)
-            __free_ddr(b);
-    }
-    catch (tidl::Exception &e)
-    {
-        std::cerr << e.what() << std::endl;
-        status = false;
-    }
+    RunNetwork(DeviceType::EVE, ids, configuration,
+               input_data_file, output_data_file);
 
     input_data_file.close();
     output_data_file.close();
index 1e4d27779e657cca6c687da6fbc46fb489a8f945..5768627521a8f33ed46e508b13eb4cba6d9363ab 100644 (file)
@@ -500,6 +500,31 @@ Device::Ptr Device::Create(DeviceType core_type, const DeviceIds& ids,
     return p;
 }
 
+// Minimum version of OpenCL required for this version of TIDL API
+#define MIN_OCL_VERSION "01.01.16.00"
+static bool CheckOpenCLVersion(cl_platform_id id)
+{
+    cl_int err;
+    size_t length;
+    err = clGetPlatformInfo(id, CL_PLATFORM_VERSION, 0, nullptr, &length);
+    if (err != CL_SUCCESS) return false;
+
+    std::unique_ptr<char> version(new char[length]);
+    err = clGetPlatformInfo(id, CL_PLATFORM_VERSION, length, version.get(),
+                            nullptr);
+    if (err != CL_SUCCESS) return false;
+
+    std::string v(version.get());
+
+    if (v.substr(v.find("01."), sizeof(MIN_OCL_VERSION)) >= MIN_OCL_VERSION)
+        return true;
+
+    std::cerr << "TIDL API Error: OpenCL " << MIN_OCL_VERSION
+              << " or higher required." << std::endl;
+
+    return false;
+}
+
 static bool PlatformIsAM57()
 {
     cl_platform_id id;
@@ -508,6 +533,9 @@ static bool PlatformIsAM57()
     err = clGetPlatformIDs(1, &id, nullptr);
     if (err != CL_SUCCESS) return false;
 
+    if (!CheckOpenCLVersion(id))
+       return false;
+
     // Check if the device name is AM57
     size_t length;
     err = clGetPlatformInfo(id, CL_PLATFORM_NAME, 0, nullptr, &length);