Updated Python bindings to reflect API changes
authorAjay Jayaraj <ajayj@ti.com>
Wed, 31 Oct 2018 14:56:26 +0000 (09:56 -0500)
committerAjay Jayaraj <ajayj@ti.com>
Wed, 31 Oct 2018 17:37:56 +0000 (12:37 -0500)
(MCT-1080)

13 files changed:
examples/pybind/layer_output.py
examples/pybind/one_eo_per_frame.py
examples/pybind/tidl_app_utils.py [changed mode: 0755->0644]
examples/pybind/two_eo_per_frame.py
examples/pybind/two_eo_per_frame_opt.py [new file with mode: 0755]
tidl_api/inc/configuration.h
tidl_api/src/execution_object.cpp
tidl_api/src/imgutil.cpp
tidl_api/src/pybind_eo.cpp
tidl_api/src/pybind_eop.cpp
tidl_api/src/pybind_executor.cpp
tidl_api/src/util.cpp
tidl_api/src/util.h

index 56f1d4a9b98ce348b2b393915caaf7ca4054c599..255fa790095504702ee64f38cf776d903360bed2 100755 (executable)
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 # THE POSSIBILITY OF SUCH DAMAGE.
 
+""" Layer output
+
+Illustrates writing the outputs of intermediate layers in the network to file.
+"""
+
+import argparse
 
 from tidl import DeviceId, DeviceType, Configuration, Executor, TidlError
 from tidl import allocate_memory, free_memory
 
-from tidl_app_utils import read_frame, write_output, report_time
+from tidl_app_utils import read_frame
 
-import argparse
 
-def main(config_file, num_frames):
-    c = Configuration()
-    c.read_from_file(config_file)
-    c.enable_layer_dump = True
-    c.num_frames = num_frames
+def main():
+    """ Parse arguments, read configuration and run network"""
+
+    parser = argparse.ArgumentParser(description=
+                                     'Dump output of each network layer to file.')
+    parser.add_argument(
+        '-c', '--config_file',
+        default='../test/testvecs/config/infer/tidl_config_j11_v2.txt',
+        help='Path to TIDL config file')
+
+    args = parser.parse_args()
+
+    # Run network for 1 frame since we interested in intermediate layer outputs
+    num_frames = 1
+
+    # Read configuration from file
+    configuration = Configuration()
+    configuration.read_from_file(args.config_file)
+    configuration.enable_layer_dump = True
+    configuration.num_frames = num_frames
 
     num_dsp = Executor.get_num_devices(DeviceType.DSP)
     num_eve = Executor.get_num_devices(DeviceType.EVE)
 
-    if (num_dsp == 0 and num_eve == 0):
+    if num_dsp == 0 and num_eve == 0:
         print('No TIDL API capable devices available')
         return
 
-    if (num_eve > 0):
+    if num_eve > 0:
         device_type = DeviceType.EVE
     else:
         device_type = DeviceType.DSP
 
     # Since we are dumping layer outputs, just run on one device
-    run(device_type, 1, c)
+    run(device_type, 1, configuration)
 
-    return
 
-def run(device_type, num_devices, c):
+def run(device_type, num_devices, configuration):
     """ Run the network on a single device and dump output of each layer"""
 
     print('Running network on {} {}'.format(num_devices, device_type))
@@ -67,7 +86,7 @@ def run(device_type, num_devices, c):
     try:
         print('TIDL API: performing one time initialization ...')
 
-        executor = Executor(device_type, device_ids, c, 1)
+        executor = Executor(device_type, device_ids, configuration, 1)
 
         # Collect all EOs from EVE and DSP executors
         eos = []
@@ -77,37 +96,27 @@ def run(device_type, num_devices, c):
         allocate_memory(eos)
 
         # Open input, output files
-        f_in  = open(c.in_data, 'rb')
+        f_in = open(configuration.in_data, 'rb')
 
 
         print('TIDL API: processing input frames ...')
 
         num_eos = len(eos)
-        for frame_index in range(c.num_frames+num_eos):
-            eo = eos [frame_index % num_eos]
-
-            if (eo.process_frame_wait()):
-                eo.write_layer_outputs_to_file()
+        for frame_index in range(configuration.num_frames+num_eos):
+            execution_object = eos[frame_index % num_eos]
 
-            if (read_frame(eo, frame_index, c, f_in)):
-                eo.process_frame_start_async()
+            if execution_object.process_frame_wait():
+                execution_object.write_layer_outputs_to_file()
 
+            if read_frame(execution_object, frame_index, configuration, f_in):
+                execution_object.process_frame_start_async()
 
         f_in.close()
 
         free_memory(eos)
     except TidlError as err:
-        print (err)
+        print(err)
 
-    return
 
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description=
-                       'Dump output of each network layer to file. ')
-    parser.add_argument('-c', '--config_file',
-               default='../test/testvecs/config/infer/tidl_config_j11_v2.txt',
-               help='Path to TIDL config file')
-    args = parser.parse_args()
-
-    # Run network for 1 frame since we interested in intermediate layer outputs
-    main(args.config_file, 1)
+    main()
index 96eb420542064a84c03c05f04c55b6647decff5d..0b44c7b0cd90707696b20c0b981ea414c395926c 100755 (executable)
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 # THE POSSIBILITY OF SUCH DAMAGE.
 
+""" Process each frame using a single ExecutionObject.
+    Increase throughput by using multiple ExecutionObjects.
+"""
+
+import argparse
 
 from tidl import DeviceId, DeviceType, Configuration, Executor, TidlError
-from tidl import allocate_memory, free_memory
+from tidl import allocate_memory, free_memory, enable_time_stamps
 
 from tidl_app_utils import read_frame, write_output, report_time
 
-import argparse
 
-def main(config_file, num_frames):
-    c = Configuration()
-    c.read_from_file(config_file)
-    c.enable_api_trace = False
-    c.num_frames = num_frames
+def main():
+    """Read the configuration and run the network"""
+
+    args = parse_args()
+
+    # Heaps are sized for the j11_v2 network. Changing the network will
+    # require updating network_heap_size and param_heap_size
+    config_file = '../test/testvecs/config/infer/tidl_config_j11_v2.txt'
+
+    configuration = Configuration()
+    configuration.read_from_file(config_file)
+    configuration.enable_api_trace = False
+    configuration.num_frames = args.num_frames
 
     num_dsp = Executor.get_num_devices(DeviceType.DSP)
     num_eve = Executor.get_num_devices(DeviceType.EVE)
 
-    if (num_dsp == 0 and num_eve == 0):
+    if num_dsp == 0 and num_eve == 0:
         print('No TIDL API capable devices available')
         return
 
-    run(num_eve, num_dsp, c)
+    enable_time_stamps("1eo_timestamp.log", 16)
+    run(num_eve, num_dsp, configuration)
 
     return
 
-def run(num_eve, num_dsp, c):
+
+DESCRIPTION = 'Process frames using all available Execution Objects. '\
+              'Each ExecutionObject processes a single frame'
+
+def parse_args():
+    """Parse input arguments"""
+
+    parser = argparse.ArgumentParser(description=DESCRIPTION)
+    parser.add_argument('-n', '--num_frames',
+                        type=int,
+                        default=16,
+                        help='Number of frames to process')
+    args = parser.parse_args()
+
+    return args
+
+
+def run(num_eve, num_dsp, configuration):
     """ Run the network on the specified device type and number of devices"""
 
     print('Running network across {} EVEs, {} DSPs'.format(num_eve, num_dsp))
@@ -62,15 +92,15 @@ def run(num_eve, num_dsp, c):
                           DeviceId.ID2, DeviceId.ID3][0:num_eve])
 
     # Heap sizes for this network determined using Configuration.showHeapStats
-    c.param_heap_size   = (3 << 20)
-    c.network_heap_size = (20 << 20)
+    configuration.param_heap_size = (3 << 20)
+    configuration.network_heap_size = (20 << 20)
 
 
     try:
         print('TIDL API: performing one time initialization ...')
 
-        eve = Executor(DeviceType.EVE, eve_device_ids, c, 1)
-        dsp = Executor(DeviceType.DSP, dsp_device_ids, c, 1)
+        eve = Executor(DeviceType.EVE, eve_device_ids, configuration, 1)
+        dsp = Executor(DeviceType.DSP, dsp_device_ids, configuration, 1)
 
         # Collect all EOs from EVE and DSP executors
         eos = []
@@ -83,22 +113,22 @@ def run(num_eve, num_dsp, c):
         allocate_memory(eos)
 
         # Open input, output files
-        f_in  = open(c.in_data, 'rb')
-        f_out = open(c.out_data, 'wb')
+        f_in = open(configuration.in_data, 'rb')
+        f_out = open(configuration.out_data, 'wb')
 
 
         print('TIDL API: processing input frames ...')
 
         num_eos = len(eos)
-        for frame_index in range(c.num_frames+num_eos):
-            eo = eos [frame_index % num_eos]
+        for frame_index in range(configuration.num_frames+num_eos):
+            execution_object = eos[frame_index % num_eos]
 
-            if (eo.process_frame_wait()):
-                report_time(eo)
-                write_output(eo, f_out)
+            if execution_object.process_frame_wait():
+                report_time(execution_object)
+                write_output(execution_object, f_out)
 
-            if (read_frame(eo, frame_index, c, f_in)):
-                eo.process_frame_start_async()
+            if read_frame(execution_object, frame_index, configuration, f_in):
+                execution_object.process_frame_start_async()
 
 
         f_in.close()
@@ -106,21 +136,8 @@ def run(num_eve, num_dsp, c):
 
         free_memory(eos)
     except TidlError as err:
-        print (err)
+        print(err)
 
-    return
 
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description=
-                       'Process frames using all available Execution Objects. '
-                       'Each ExecutionObject processes a single frame')
-    parser.add_argument('-n', '--num_frames',
-                        type=int,
-                        default=1,
-                        help='Number of frames to process')
-    args = parser.parse_args()
-
-    # Heaps are sized for the j11_v2 network. Changing the network will
-    # require updating network_heap_size and param_heap_size
-    main('../test/testvecs/config/infer/tidl_config_j11_v2.txt', 
-         args.num_frames)
+    main()
old mode 100755 (executable)
new mode 100644 (file)
index e8be16c..2cd2d60
@@ -63,16 +63,11 @@ def write_output(eo, f):
     f.write(arg_info)
 
 def report_time(eo):
-    """Report execution time on host and device"""
+    """Report execution time on device"""
 
-    elapsed_host   = eo.get_host_process_time_in_ms()
     elapsed_device = eo.get_process_time_in_ms()
-    overhead = elapsed_host - elapsed_device
 
     # https://pyformat.info/
-    print('frame{:3d}: Time on {}: {:4.2f} ms, host: {:4.2f} ms '
-          'API overhead: {:2.2f} ms'.format(eo.get_frame_index(),
-                                           eo.get_device_name(),
-                                           elapsed_device,
-                                           elapsed_host,
-                                           overhead))
+    print('frame{:3d}: Time on {}: {:4.2f} ms '.format(eo.get_frame_index(),
+                                                       eo.get_device_name(),
+                                                       elapsed_device))
index c6b16c6dd42abb508eb9d1be97732a30aef4faef..a1cd58c0dc9d547b94a6980f31c8b14ae0162499 100755 (executable)
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 # THE POSSIBILITY OF SUCH DAMAGE.
 
+""" Process frames using ExecutionObjectPipeline.
+    Each ExecutionObjectPipeline processes a single frame.
+"""
+
+import argparse
 
 from tidl import DeviceId, DeviceType, Configuration, TidlError
 from tidl import Executor, ExecutionObjectPipeline
-from tidl import allocate_memory, free_memory
+from tidl import allocate_memory, free_memory, enable_time_stamps
 
-from tidl_app_utils import read_frame, write_output, report_time
+from tidl_app_utils import read_frame, write_output
 
-import argparse
 
-def main(config_file, num_frames):
-    c = Configuration()
-    c.read_from_file(config_file)
-    c.enable_api_trace = False
-    c.num_frames = num_frames
+def main():
+    """Read the configuration and run the network"""
+
+    args = parse_args()
+
+    # Heaps are sized for the j11_v2 network. Changing the network will
+    # require updating network_heap_size and param_heap_size
+    config_file = '../test/testvecs/config/infer/tidl_config_j11_v2.txt'
+
+    configuration = Configuration()
+    configuration.read_from_file(config_file)
+    configuration.enable_api_trace = False
+    configuration.num_frames = args.num_frames
+
+    # Heap sizes for this network determined using Configuration.showHeapStats
+    configuration.param_heap_size = (3 << 20)
+    configuration.network_heap_size = (20 << 20)
 
     num_dsp = Executor.get_num_devices(DeviceType.DSP)
     num_eve = Executor.get_num_devices(DeviceType.EVE)
 
-    if (num_dsp == 0 or num_eve == 0):
+    if num_dsp == 0 or num_eve == 0:
         print('This example required EVEs and DSPs.')
         return
 
-    run(num_eve, num_dsp, c)
+    enable_time_stamps("2eo_timestamp.log", 16)
+    run(num_eve, num_dsp, configuration)
 
-    return
+# Run layer group 1 on EVE, 2 on DSP
+EVE_LAYER_GROUP_ID = 1
+DSP_LAYER_GROUP_ID = 2
 
 def run(num_eve, num_dsp, c):
     """ Run the network on the specified device type and number of devices"""
@@ -62,16 +81,9 @@ def run(num_eve, num_dsp, c):
     eve_device_ids = set([DeviceId.ID0, DeviceId.ID1,
                           DeviceId.ID2, DeviceId.ID3][0:num_eve])
 
-    EVE_LAYER_GROUP_ID = 1
-    DSP_LAYER_GROUP_ID = 2
-    c.layer_index_to_layer_group_id = {12:DSP_LAYER_GROUP_ID, 
-                                       13:DSP_LAYER_GROUP_ID, 
-                                       14:DSP_LAYER_GROUP_ID};
-    
-    # Heap sizes for this network determined using Configuration.showHeapStats
-    c.param_heap_size   = (3 << 20)
-    c.network_heap_size = (20 << 20)
-
+    c.layer_index_to_layer_group_id = {12:DSP_LAYER_GROUP_ID,
+                                       13:DSP_LAYER_GROUP_ID,
+                                       14:DSP_LAYER_GROUP_ID}
 
     try:
         print('TIDL API: performing one time initialization ...')
@@ -85,13 +97,13 @@ def run(num_eve, num_dsp, c):
         eops = []
         num_pipe = max(num_eve_eos, num_dsp_eos)
         for i in range(num_pipe):
-            eops.append(ExecutionObjectPipeline( [ eve.at(i % num_eve_eos),
-                                                   dsp.at(i % num_dsp_eos)]))
+            eops.append(ExecutionObjectPipeline([eve.at(i % num_eve_eos),
+                                                 dsp.at(i % num_dsp_eos)]))
 
         allocate_memory(eops)
 
         # Open input, output files
-        f_in  = open(c.in_data, 'rb')
+        f_in = open(c.in_data, 'rb')
         f_out = open(c.out_data, 'wb')
 
 
@@ -99,36 +111,37 @@ def run(num_eve, num_dsp, c):
 
         num_eops = len(eops)
         for frame_index in range(c.num_frames+num_eops):
-            eop = eops [frame_index % num_eops]
+            eop = eops[frame_index % num_eops]
 
-            if (eop.process_frame_wait()):
-                report_time(eop)
+            if eop.process_frame_wait():
                 write_output(eop, f_out)
 
-            if (read_frame(eop, frame_index, c, f_in)):
+            if read_frame(eop, frame_index, c, f_in):
                 eop.process_frame_start_async()
 
-
         f_in.close()
         f_out.close()
 
         free_memory(eops)
     except TidlError as err:
-        print (err)
+        print(err)
 
-    return
 
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description=
-                       'Process frames using ExecutionObjectPipeline. '
-                       'Each ExecutionObjectPipeline processes a single frame')
+DESCRIPTION = 'Process frames using ExecutionObjectPipeline. '\
+              'Each ExecutionObjectPipeline processes a single frame'
+
+def parse_args():
+    """Parse input arguments"""
+
+    parser = argparse.ArgumentParser(description=DESCRIPTION)
     parser.add_argument('-n', '--num_frames',
                         type=int,
-                        default=1,
+                        default=16,
                         help='Number of frames to process')
     args = parser.parse_args()
 
-    # Heaps are sized for the j11_v2 network. Changing the network will
-    # require updating network_heap_size and param_heap_size
-    main('../test/testvecs/config/infer/tidl_config_j11_v2.txt', 
-         args.num_frames)
+    return args
+
+
+if __name__ == '__main__':
+    main()
diff --git a/examples/pybind/two_eo_per_frame_opt.py b/examples/pybind/two_eo_per_frame_opt.py
new file mode 100755 (executable)
index 0000000..4fe235c
--- /dev/null
@@ -0,0 +1,155 @@
+#!/usr/bin/python3
+
+# 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.
+
+
+import argparse
+from tidl import DeviceId, DeviceType, Configuration, TidlError
+from tidl import Executor, ExecutionObjectPipeline
+from tidl import allocate_memory, free_memory, enable_time_stamps
+
+from tidl_app_utils import read_frame, write_output
+
+
+def main():
+    """Read the configuration and run the network"""
+
+    args = parse_args()
+
+    # Heaps are sized for the j11_v2 network. Changing the network will
+    # require updating network_heap_size and param_heap_size
+    config_file = '../test/testvecs/config/infer/tidl_config_j11_v2.txt'
+
+    configuration = Configuration()
+    configuration.read_from_file(config_file)
+    configuration.enable_api_trace = False
+    configuration.num_frames = args.num_frames
+
+    # Heap sizes for this network determined using Configuration.showHeapStats
+    configuration.param_heap_size = (3 << 20)
+    configuration.network_heap_size = (20 << 20)
+
+    num_dsp = Executor.get_num_devices(DeviceType.DSP)
+    num_eve = Executor.get_num_devices(DeviceType.EVE)
+
+    if num_dsp == 0 or num_eve == 0:
+        print('This example required EVEs and DSPs.')
+        return
+
+    enable_time_stamps("2eo_opt_timestamp.log", 16)
+    run(num_eve, num_dsp, configuration)
+
+# Run layer group 1 on EVE, 2 on DSP
+EVE_LAYER_GROUP_ID = 1
+DSP_LAYER_GROUP_ID = 2
+
+
+def run(num_eve, num_dsp, c):
+    """ Run the network on the specified device type and number of devices"""
+
+    print('Running on {} EVEs, {} DSPs'.format(num_eve, num_dsp))
+
+    dsp_device_ids = set([DeviceId.ID0, DeviceId.ID1,
+                          DeviceId.ID2, DeviceId.ID3][0:num_dsp])
+    eve_device_ids = set([DeviceId.ID0, DeviceId.ID1,
+                          DeviceId.ID2, DeviceId.ID3][0:num_eve])
+
+    c.layer_index_to_layer_group_id = {12:DSP_LAYER_GROUP_ID,
+                                       13:DSP_LAYER_GROUP_ID,
+                                       14:DSP_LAYER_GROUP_ID}
+
+    try:
+        print('TIDL API: performing one time initialization ...')
+
+        eve = Executor(DeviceType.EVE, eve_device_ids, c, EVE_LAYER_GROUP_ID)
+        dsp = Executor(DeviceType.DSP, dsp_device_ids, c, DSP_LAYER_GROUP_ID)
+
+        num_eve_eos = eve.get_num_execution_objects()
+        num_dsp_eos = dsp.get_num_execution_objects()
+
+        # On AM5749, create a total of 4 pipelines (EOPs):
+        # EOPs[0] : { EVE1, DSP1 }
+        # EOPs[1] : { EVE1, DSP1 } for double buffering
+        # EOPs[2] : { EVE2, DSP2 }
+        # EOPs[3] : { EVE2, DSP2 } for double buffering
+        PIPELINE_DEPTH = 2
+
+        eops = []
+        num_pipe = max(num_eve_eos, num_dsp_eos)
+        for i in range(num_pipe):
+            for i in range(PIPELINE_DEPTH):
+                eops.append(ExecutionObjectPipeline([eve.at(i % num_eve_eos),
+                                                     dsp.at(i % num_dsp_eos)]))
+
+        allocate_memory(eops)
+
+        # Open input, output files
+        f_in = open(c.in_data, 'rb')
+        f_out = open(c.out_data, 'wb')
+
+
+        print('TIDL API: processing input frames ...')
+
+        num_eops = len(eops)
+        for frame_index in range(c.num_frames+num_eops):
+            eop = eops[frame_index % num_eops]
+
+            if eop.process_frame_wait():
+                write_output(eop, f_out)
+
+            if read_frame(eop, frame_index, c, f_in):
+                eop.process_frame_start_async()
+
+
+        f_in.close()
+        f_out.close()
+
+        free_memory(eops)
+    except TidlError as err:
+        print(err)
+
+
+DESCRIPTION = 'Process frames using ExecutionObjectPipeline. '\
+              'Each ExecutionObjectPipeline processes a single frame. '\
+              'The example also uses double buffering on the EOPs to '\
+              'hide frame read overhead.'
+
+def parse_args():
+    """Parse input arguments"""
+
+    parser = argparse.ArgumentParser(description=DESCRIPTION)
+    parser.add_argument('-n', '--num_frames',
+                        type=int,
+                        default=16,
+                        help='Number of frames to process')
+    args = parser.parse_args()
+
+    return args
+
+
+if __name__ == '__main__':
+    main()
index 913272a7f2bc1954e156507f448befdfb0eb01d8..6e2128e59967e94c27c3789437ca969f575fd63f 100644 (file)
@@ -67,6 +67,11 @@ class Configuration
 
     //! Pre-processing type applied to the input frame
     //! Specific to each network, can take values from 0 to 4, default is 0
+    //! 0 -> Caffe-Jacinto models
+    //! 1 -> Caffe models (SqueezeNet)
+    //! 2 -> TensorFlow (Inception, MobileNet)
+    //! 3 -> CIFAR 10
+    //! 4 -> JdetNet
     int     preProcType;
 
     //! Force to run all layers, regardless of layersGroupId partitioning
index 08b5796fd368f52e47dcc0c7679e2c71ef8fc491..20c423cceadc8adda668c621cf9ab0b879b42c75 100644 (file)
@@ -631,11 +631,18 @@ bool ExecutionObject::Impl::Wait(CallType ct, uint32_t context_idx)
                                     __FILE__, __FUNCTION__, __LINE__);
 
                 HostReadNetOutput(context_idx);
-            }
 
-            RecordEvent(current_frame_idx_m[context_idx],
-                        (layers_group_id_m == 1) ? TimeStamp::EO1_PFW_END:
-                                                   TimeStamp::EO2_PFW_END);
+                RecordEvent(current_frame_idx_m[context_idx],
+                            (layers_group_id_m == 1) ? TimeStamp::EO1_PFW_END:
+                                                       TimeStamp::EO2_PFW_END);
+            }
+            else
+            {
+                // If there is no work, reset start event time
+                ResetEvent(current_frame_idx_m[context_idx],
+                           (layers_group_id_m == 1) ? TimeStamp::EO1_PFW_START:
+                                                      TimeStamp::EO2_PFW_START);
+            }
 
             return has_work;
         }
index 18896f28820237be595dc35803c2c7758a78fe4f..1bee1e493e4d465009d7599b4c3eeca37390f74a 100644 (file)
@@ -81,10 +81,11 @@ bool tidl::imgutil::PreprocessImage(Mat& image, char *ptr,
         meanValues[2] = 123;
 
     }
+    // See https://github.com/tensorflow/models/blob/82e783e3172f254b62dc4af08987754ebb7c348c/research/slim/preprocessing/inception_preprocessing.py#L244
     else if (preProcType == 2) // mobileNet, inceptionNet
     {
         cv::cvtColor(image, image, CV_BGR2RGB);
-        float factor  = 0.875;
+        float factor  = 0.875; // From TF preprocess_for_eval
         int32_t orgWidth  = image.size[1];
         int32_t orgHeight = image.size[0];
 
@@ -107,7 +108,7 @@ bool tidl::imgutil::PreprocessImage(Mat& image, char *ptr,
         meanValues[1] = 128;
         meanValues[2] = 128;
     }
-    else if (preProcType == 3)
+    else if (preProcType == 3) // CIFAR 10
     {
         cv::cvtColor(image, image, CV_BGR2RGB);
         int32_t half_the_width  =  32/ 2;
@@ -122,7 +123,7 @@ bool tidl::imgutil::PreprocessImage(Mat& image, char *ptr,
         image = tempImage(myROI);
         enableMeanSub = false;
     }
-    else if (preProcType == 4)
+    else if (preProcType == 4) // JdetNet
     {
         cv::resize(image, tempImage, Size(output_width,output_height),
                    0, 0, cv::INTER_AREA);
index edd58c8314323785821270c536bc447e3cf2955b..6e57c5897395648b0295d23b648052a6c4c216bd 100644 (file)
@@ -74,10 +74,6 @@ void init_eo(module &m)
 
         .def("get_device_name", &EO::GetDeviceName)
 
-        .def("get_host_process_time_in_ms",
-             &EO::GetHostProcessTimeInMilliSeconds,
-             "Milliseconds taken on the host to process a frame")
-
         .def("get_process_time_in_ms",
              &EO::GetProcessTimeInMilliSeconds,
              "Milliseconds taken on the device to process a frame")
index e387794d6ea1561cb5356294b7d0ac5ef9db694e..415eb7dcf4dea81e10248e2e057e1aefefd55dcd 100644 (file)
@@ -73,25 +73,6 @@ void init_eop(module &m)
              "returns false if process_frame_wait() was called without a\n"
              " corresponding call to process_frame_start_async")
 
-        .def("get_device_name", &EOP::GetDeviceName)
-
-        .def("get_host_process_time_in_ms",
-             (float (EOP::*)() const) &EOP::GetHostProcessTimeInMilliSeconds,
-             "Milliseconds taken on the host to process a frame")
-
-        .def("get_process_time_in_ms",
-             (float (EOP::*)() const) &EOP::GetProcessTimeInMilliSeconds,
-             "Milliseconds taken on the device to process a frame")
-
-        .def("get_host_process_time_in_ms",
-             (float (EOP::*)(uint32_t) const)
-             &EOP::GetHostProcessTimeInMilliSeconds,
-             "Milliseconds taken on the host to process\n"
-             "a frame by the specified EO")
-
-        .def("get_process_time_in_ms",
-             (float (EOP::*)(uint32_t) const)
-             &EOP::GetProcessTimeInMilliSeconds,
-             "Milliseconds taken on the device to process\n"
-             "a frame by the specified EO");
+        .def("get_device_name", &EOP::GetDeviceName,
+             "Returns the combined device names used by the pipeline");
 }
index 1eb3559c33961c1820f372120487f8fc5038ca41..8f813212eea9ae29522ae4946d8a02247d6afb4d 100644 (file)
@@ -124,5 +124,9 @@ PYBIND11_MODULE(tidl, m)
     m.def("free_memory",
            (void (*)(const vector<EOP *>&)) &FreeMemory,
           "Free input and output buffers of all ExecutionObjectPipelines");
+
+    m.def("enable_time_stamps",
+           &EnableTimeStamps,
+          "Enable timestamp generation for API events");
 }
 
index 2c0b3727b33fbad09058836f2733c54e28a1e0a3..b09533e66596dff9cf30707e76124fef42c747e1 100644 (file)
@@ -67,6 +67,7 @@ TimeStamp::TimeStamp(const std::string& file, int num_entries):
 void TimeStamp::Update(int frame_idx, EventKind k, int type, int id)
 {
     int idx = frame_idx % num_entries_m;
+
     entries_m[idx].frame_idx = frame_idx;
     entries_m[idx].timestamp[k] = duration_cast<microseconds>
                  (high_resolution_clock::now().time_since_epoch()).count();
@@ -84,6 +85,15 @@ void TimeStamp::Update(int frame_idx, EventKind k, int type, int id)
 
 }
 
+void TimeStamp::Zero(int frame_idx, EventKind k)
+{
+    int idx = frame_idx % num_entries_m;
+
+    entries_m[idx].frame_idx    = frame_idx;
+    entries_m[idx].timestamp[k] = 0;
+}
+
+
 TimeStamp::~TimeStamp()
 {
     std::ofstream ofs;
@@ -146,6 +156,12 @@ void tidl::RecordEvent(int frame_idx, TimeStamp::EventKind k,
         t->Update(frame_idx, k, eo_type, eo_id);
 }
 
+void tidl::ResetEvent(int frame_idx, TimeStamp::EventKind k)
+{
+    TimeStamp* t = tidl_api_timestamps.get();
+    if (t)
+        t->Zero(frame_idx, k);
+}
 
 std::size_t tidl::GetBinaryFileSize(const std::string &F)
 {
index 368c2c552f5984c408b44f0e4d7747e6393a8a71..554f30836a067af85d517d2281cad3bdcc2b68a1 100644 (file)
@@ -65,6 +65,7 @@ class TimeStamp
         TimeStamp(const std::string& file, int num_entries);
         ~TimeStamp();
         void Update(int frame_idx, EventKind k, int type=0, int id=0);
+        void Zero  (int frame_idx, EventKind k);
 
     private:
         Entry*            entries_m;
@@ -76,4 +77,5 @@ class TimeStamp
 void RecordEvent(int frame_idx, TimeStamp::EventKind k,
                  int eo_type=0, int eo_id=0);
 
+void ResetEvent(int frame_idx, TimeStamp::EventKind k);
 } // namespace tidl