From 61d8cb0f6b2a51d84724da952b8a36137a54e6cf Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Thu, 14 Feb 2019 15:49:44 +0800 Subject: [PATCH 01/12] [tflite] export SetNumThreads to TFLite Python API export SetNumThreadS() and add an option to set the number of threads in the `label_image.py` for TFLite. --- tensorflow/lite/examples/python/label_image.py | 8 +++++++- tensorflow/lite/python/interpreter.py | 3 +++ .../python/interpreter_wrapper/interpreter_wrapper.cc | 5 +++++ .../lite/python/interpreter_wrapper/interpreter_wrapper.h | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tensorflow/lite/examples/python/label_image.py b/tensorflow/lite/examples/python/label_image.py index 0bc15d36a8a..a1cc41a4505 100644 --- a/tensorflow/lite/examples/python/label_image.py +++ b/tensorflow/lite/examples/python/label_image.py @@ -20,6 +20,7 @@ from __future__ import print_function import argparse import numpy as np +import time from PIL import Image @@ -46,6 +47,7 @@ if __name__ == "__main__": parser.add_argument("--input_mean", default=127.5, help="input_mean") parser.add_argument("--input_std", default=127.5, \ help="input standard deviation") + parser.add_argument("--num_threads", default=1, help="number of threads") args = parser.parse_args() interpreter = interpreter_wrapper.Interpreter(model_path=args.model_file) @@ -70,9 +72,11 @@ if __name__ == "__main__": if floating_model: input_data = (np.float32(input_data) - args.input_mean) / args.input_std + interpreter.set_num_threads(int(args.num_threads)) interpreter.set_tensor(input_details[0]['index'], input_data) - + start_time = time.time() interpreter.invoke() + stop_time = time.time() output_data = interpreter.get_tensor(output_details[0]['index']) results = np.squeeze(output_data) @@ -84,3 +88,5 @@ if __name__ == "__main__": print('{0:08.6f}'.format(float(results[i]))+":", labels[i]) else: print('{0:08.6f}'.format(float(results[i]/255.0))+":", labels[i]) + + print("time: ", stop_time - start_time) diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index 9b9516f6d0b..6ef88b5418b 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -292,3 +292,6 @@ class Interpreter(object): def reset_all_variables(self): return self._interpreter.ResetVariableTensors() + + def set_num_threads(self, i): + return self._interpreter.SetNumThreads(i) diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc index 6023587d3b1..3bbae751f4a 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc @@ -436,5 +436,10 @@ PyObject* InterpreterWrapper::ResetVariableTensors() { Py_RETURN_NONE; } +PyObject* InterpreterWrapper::SetNumThreads(int i) { + interpreter_->SetNumThreads(i); + Py_RETURN_NONE; +} + } // namespace interpreter_wrapper } // namespace tflite diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h index ffb02780255..28774dc05ef 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h @@ -72,6 +72,8 @@ class InterpreterWrapper { // should be the interpreter object providing the memory. PyObject* tensor(PyObject* base_object, int i); + PyObject* SetNumThreads(int i); + private: // Helper function to construct an `InterpreterWrapper` object. // It only returns InterpreterWrapper if it can construct an `Interpreter`. From 7dba4b1abc6315d9b3cdfddafe6a351c48c573b1 Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Thu, 21 Mar 2019 14:47:57 +0800 Subject: [PATCH 02/12] add simple description of set_num_threads() --- tensorflow/lite/python/interpreter.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index 6ef88b5418b..6e4c49d20e5 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -294,4 +294,12 @@ class Interpreter(object): return self._interpreter.ResetVariableTensors() def set_num_threads(self, i): + """Set number of threads used by TFLite kernels. + + If not set, kernels are running single-threaded. Note that currently, + only some kernels, such as conv, are multithreaded. + + Args: + i: number of threads. + """ return self._interpreter.SetNumThreads(i) From 225b06d1d0d95f2cf63b203af9fd633ffcd094fd Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Thu, 13 Feb 2020 14:35:05 +0800 Subject: [PATCH 03/12] cleanup --- tensorflow/lite/examples/python/label_image.py | 14 ++++++-------- tensorflow/lite/python/interpreter.py | 2 +- .../interpreter_wrapper/interpreter_wrapper.cc | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/tensorflow/lite/examples/python/label_image.py b/tensorflow/lite/examples/python/label_image.py index 9fa1f74b7c1..45bec783bc1 100644 --- a/tensorflow/lite/examples/python/label_image.py +++ b/tensorflow/lite/examples/python/label_image.py @@ -19,14 +19,11 @@ from __future__ import division from __future__ import print_function import argparse - -import numpy as np import time -from PIL import Image - +import numpy as np import tensorflow as tf # TF2 - +from PIL import Image def load_labels(filename): with open(filename, 'r') as f: @@ -59,8 +56,8 @@ if __name__ == '__main__': default=127.5, type=float, help='input standard deviation') parser.add_argument( - '--num_threads', - default=1, + '--num_threads', + default=1, help='number of threads') args = parser.parse_args() @@ -86,6 +83,7 @@ if __name__ == '__main__': interpreter.set_num_threads(int(args.num_threads)) interpreter.set_tensor(input_details[0]['index'], input_data) + start_time = time.time() interpreter.invoke() stop_time = time.time() @@ -101,4 +99,4 @@ if __name__ == '__main__': else: print('{:08.6f}: {}'.format(float(results[i] / 255.0), labels[i])) - print("time: ", stop_time - start_time) \ No newline at end of file + print("time: ", stop_time - start_time) diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index 3b98fe58dd2..659b47daf53 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -555,4 +555,4 @@ class InterpreterWithCustomOps(Interpreter): super(InterpreterWithCustomOps, self).__init__( model_path=model_path, model_content=model_content, - experimental_delegates=experimental_delegates) \ No newline at end of file + experimental_delegates=experimental_delegates) diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc index 439c996f31b..9c41c8abf53 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc @@ -630,10 +630,10 @@ PyObject* InterpreterWrapper::ResetVariableTensors() { PyObject* InterpreterWrapper::SetNumThreads(int i) { TFLITE_PY_ENSURE_VALID_INTERPRETER(); - TFLITE_PY_CHECK(interpreter_->SetNumThreads(i)); + interpreter_->SetNumThreads(i); Py_RETURN_NONE; } - + PyObject* InterpreterWrapper::ModifyGraphWithDelegate( TfLiteDelegate* delegate) { TFLITE_PY_ENSURE_VALID_INTERPRETER(); From 14592a9c24d925c97da033186e9a6285aac187fd Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Thu, 13 Feb 2020 15:37:24 +0800 Subject: [PATCH 04/12] set number of threads in constructor --- .../lite/examples/python/label_image.py | 5 +++-- tensorflow/lite/python/interpreter.py | 19 +++++++------------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/tensorflow/lite/examples/python/label_image.py b/tensorflow/lite/examples/python/label_image.py index 45bec783bc1..c6e0fbdb2bd 100644 --- a/tensorflow/lite/examples/python/label_image.py +++ b/tensorflow/lite/examples/python/label_image.py @@ -61,7 +61,9 @@ if __name__ == '__main__': help='number of threads') args = parser.parse_args() - interpreter = tf.lite.Interpreter(model_path=args.model_file) + interpreter = tf.lite.Interpreter( + model_path=args.model_file, + num_threads=int(args.num_threads)) interpreter.allocate_tensors() input_details = interpreter.get_input_details() @@ -81,7 +83,6 @@ if __name__ == '__main__': if floating_model: input_data = (np.float32(input_data) - args.input_mean) / args.input_std - interpreter.set_num_threads(int(args.num_threads)) interpreter.set_tensor(input_details[0]['index'], input_data) start_time = time.time() diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index 659b47daf53..4c8e788faaa 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -183,7 +183,8 @@ class Interpreter(object): def __init__(self, model_path=None, model_content=None, - experimental_delegates=None): + experimental_delegates=None, + num_threads=1): """Constructor. Args: @@ -192,6 +193,9 @@ class Interpreter(object): experimental_delegates: Experimental. Subject to change. List of [TfLiteDelegate](https://www.tensorflow.org/lite/performance/delegates) objects returned by lite.load_delegate(). + num_threads: Set the number of threads used by TFLite kernels. + If not set, kernels are running single-threaded. Note that currently, + only some kernels, such as conv, are multithreaded. Raises: ValueError: If the interpreter was unable to create. @@ -228,6 +232,8 @@ class Interpreter(object): self._interpreter.ModifyGraphWithDelegate( delegate._get_native_delegate_pointer()) # pylint: disable=protected-access + self._interpreter.SetNumThreads(num_threads) + def __del__(self): # Must make sure the interpreter is destroyed before things that # are used by it like the delegates. NOTE this only works on CPython @@ -510,17 +516,6 @@ class Interpreter(object): def reset_all_variables(self): return self._interpreter.ResetVariableTensors() - def set_num_threads(self, i): - """Set number of threads used by TFLite kernels. - - If not set, kernels are running single-threaded. Note that currently, - only some kernels, such as conv, are multithreaded. - - Args: - i: number of threads. - """ - return self._interpreter.SetNumThreads(i) - class InterpreterWithCustomOps(Interpreter): """Interpreter interface for TensorFlow Lite Models that accepts custom ops. From d79c4d435fc6e7be6cc69a3ca446716ebf6190b9 Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Sat, 15 Feb 2020 10:24:03 +0800 Subject: [PATCH 05/12] address review concerns 1. change default value of num_threads to Non 2. set num_threads before delegate 3. check the type of num_threads before setting it --- tensorflow/lite/python/interpreter.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index 4c8e788faaa..b5a2109926e 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -184,7 +184,7 @@ class Interpreter(object): model_path=None, model_content=None, experimental_delegates=None, - num_threads=1): + num_threads=None): """Constructor. Args: @@ -221,6 +221,11 @@ class Interpreter(object): else: raise ValueError('Can\'t both provide `model_path` and `model_content`') + if num_threads: + if not isinstance(num_threads, int): + raise ValueError('type of num_threads should be int') + self._interpreter.SetNumThreads(num_threads) + # Each delegate is a wrapper that owns the delegates that have been loaded # as plugins. The interpreter wrapper will be using them, but we need to # hold them in a list so that the lifetime is preserved at least as long as @@ -232,8 +237,6 @@ class Interpreter(object): self._interpreter.ModifyGraphWithDelegate( delegate._get_native_delegate_pointer()) # pylint: disable=protected-access - self._interpreter.SetNumThreads(num_threads) - def __del__(self): # Must make sure the interpreter is destroyed before things that # are used by it like the delegates. NOTE this only works on CPython From 81f322d8dd8fce0d43b56298ae5b6c738d60e9a9 Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Fri, 13 Mar 2020 11:10:31 +0800 Subject: [PATCH 06/12] update goldens for CI we changed Python API, so we have to update goldens accordingly --- .../tools/api/golden/v1/tensorflow.lite.-interpreter.pbtxt | 2 +- .../tools/api/golden/v2/tensorflow.lite.-interpreter.pbtxt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tensorflow/tools/api/golden/v1/tensorflow.lite.-interpreter.pbtxt b/tensorflow/tools/api/golden/v1/tensorflow.lite.-interpreter.pbtxt index 5af7412e646..7e73d3a8079 100644 --- a/tensorflow/tools/api/golden/v1/tensorflow.lite.-interpreter.pbtxt +++ b/tensorflow/tools/api/golden/v1/tensorflow.lite.-interpreter.pbtxt @@ -4,7 +4,7 @@ tf_class { is_instance: "" member_method { name: "__init__" - argspec: "args=[\'self\', \'model_path\', \'model_content\', \'experimental_delegates\'], varargs=None, keywords=None, defaults=[\'None\', \'None\', \'None\'], " + argspec: "args=[\'self\', \'model_path\', \'model_content\', \'experimental_delegates\', \'num_threads\'], varargs=None, keywords=None, defaults=[\'None\', \'None\', \'None\', \'None\'], " } member_method { name: "allocate_tensors" diff --git a/tensorflow/tools/api/golden/v2/tensorflow.lite.-interpreter.pbtxt b/tensorflow/tools/api/golden/v2/tensorflow.lite.-interpreter.pbtxt index 5af7412e646..7e73d3a8079 100644 --- a/tensorflow/tools/api/golden/v2/tensorflow.lite.-interpreter.pbtxt +++ b/tensorflow/tools/api/golden/v2/tensorflow.lite.-interpreter.pbtxt @@ -4,7 +4,7 @@ tf_class { is_instance: "" member_method { name: "__init__" - argspec: "args=[\'self\', \'model_path\', \'model_content\', \'experimental_delegates\'], varargs=None, keywords=None, defaults=[\'None\', \'None\', \'None\'], " + argspec: "args=[\'self\', \'model_path\', \'model_content\', \'experimental_delegates\', \'num_threads\'], varargs=None, keywords=None, defaults=[\'None\', \'None\', \'None\', \'None\'], " } member_method { name: "allocate_tensors" From d0041222fdd18fb4aebfd56c5fab8da653cf984e Mon Sep 17 00:00:00 2001 From: Eugene Mikhantiev Date: Tue, 14 Apr 2020 04:29:58 +0000 Subject: [PATCH 07/12] Add SetNumThreads definition for pybind11 --- .../interpreter_wrapper/interpreter_wrapper_pybind11.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc index 27159365f69..79d032771ea 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc @@ -145,5 +145,9 @@ PYBIND11_MODULE(_pywrap_tensorflow_interpreter_wrapper, m) { }, R"pbdoc( Adds a delegate to the interpreter. - )pbdoc"); + )pbdoc") + .def("SetNumThreads", + [](InterpreterWrapper& self, int i) { + return tensorflow::pyo_or_throw(self.SetNumThreads(i)); + }); } From e1695e465003d395298d222cfca42fdb10895797 Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Tue, 14 Apr 2020 16:20:33 +0800 Subject: [PATCH 08/12] clang-format and add doc --- .../interpreter_wrapper_pybind11.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc index 79d032771ea..d1f71d40dac 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc @@ -146,8 +146,12 @@ PYBIND11_MODULE(_pywrap_tensorflow_interpreter_wrapper, m) { R"pbdoc( Adds a delegate to the interpreter. )pbdoc") - .def("SetNumThreads", - [](InterpreterWrapper& self, int i) { - return tensorflow::pyo_or_throw(self.SetNumThreads(i)); - }); + .def( + "SetNumThreads", + [](InterpreterWrapper& self, int i) { + return tensorflow::pyo_or_throw(self.SetNumThreads(i)); + }, + R"pbdoc( + ask the interpreter to set the number of threads to use. + )pbdoc"); } From 30e5e29d484ac8cfa196ae037546d01748a8b56f Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Wed, 20 May 2020 16:26:15 +0800 Subject: [PATCH 09/12] address review commments --- tensorflow/lite/examples/python/label_image.py | 7 ++++--- tensorflow/lite/python/interpreter.py | 1 + .../lite/python/interpreter_wrapper/interpreter_wrapper.cc | 4 ++-- .../lite/python/interpreter_wrapper/interpreter_wrapper.h | 2 +- .../interpreter_wrapper/interpreter_wrapper_pybind11.cc | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tensorflow/lite/examples/python/label_image.py b/tensorflow/lite/examples/python/label_image.py index c6e0fbdb2bd..9d3c47fc4c2 100644 --- a/tensorflow/lite/examples/python/label_image.py +++ b/tensorflow/lite/examples/python/label_image.py @@ -57,13 +57,13 @@ if __name__ == '__main__': help='input standard deviation') parser.add_argument( '--num_threads', - default=1, + default=1, type=int, help='number of threads') args = parser.parse_args() interpreter = tf.lite.Interpreter( model_path=args.model_file, - num_threads=int(args.num_threads)) + num_threads=args.num_threads) interpreter.allocate_tensors() input_details = interpreter.get_input_details() @@ -100,4 +100,5 @@ if __name__ == '__main__': else: print('{:08.6f}: {}'.format(float(results[i] / 255.0), labels[i])) - print("time: ", stop_time - start_time) + #print("time: ", stop_time - start_time) + print('time: {:.3f}ms'.format((stop_time - start_time) * 1000)) diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index 4c2528000da..36ea2e26943 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -523,6 +523,7 @@ class Interpreter(object): def reset_all_variables(self): return self._interpreter.ResetVariableTensors() + class InterpreterWithCustomOps(Interpreter): """Interpreter interface for TensorFlow Lite Models that accepts custom ops. diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc index c457e68c91b..2a8c1ffdcd6 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc @@ -706,9 +706,9 @@ PyObject* InterpreterWrapper::ResetVariableTensors() { Py_RETURN_NONE; } -PyObject* InterpreterWrapper::SetNumThreads(int i) { +PyObject* InterpreterWrapper::SetNumThreads(int num_threads) { TFLITE_PY_ENSURE_VALID_INTERPRETER(); - interpreter_->SetNumThreads(i); + interpreter_->SetNumThreads(num_threads); Py_RETURN_NONE; } diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h index d7141189319..b799a3067f6 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h @@ -87,7 +87,7 @@ class InterpreterWrapper { // should be the interpreter object providing the memory. PyObject* tensor(PyObject* base_object, int i); - PyObject* SetNumThreads(int i); + PyObject* SetNumThreads(int num_threads); // Adds a delegate to the interpreter. PyObject* ModifyGraphWithDelegate(TfLiteDelegate* delegate); diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc index 55c377c2bf1..74bbf6fdedd 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc @@ -149,7 +149,7 @@ PYBIND11_MODULE(_pywrap_tensorflow_interpreter_wrapper, m) { .def( "SetNumThreads", [](InterpreterWrapper& self, int i) { - return tensorflow::pyo_or_throw(self.SetNumThreads(i)); + return tensorflow::PyoOrThrow(self.SetNumThreads(i)); }, R"pbdoc( ask the interpreter to set the number of threads to use. From a7c3bc9ebdee8a519e8e3de5441f76eaaf71575f Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Wed, 20 May 2020 16:33:30 +0800 Subject: [PATCH 10/12] more modifications --- tensorflow/lite/python/interpreter.py | 2 ++ .../interpreter_wrapper/interpreter_wrapper_pybind11.cc | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index 36ea2e26943..a34f4f66b6f 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -213,6 +213,8 @@ class Interpreter(object): if num_threads: if not isinstance(num_threads, int): raise ValueError('type of num_threads should be int') + if num_threads < 1: + raise ValueError('num_threads should >= 1') self._interpreter.SetNumThreads(num_threads) # Each delegate is a wrapper that owns the delegates that have been loaded diff --git a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc index 74bbf6fdedd..a85bdc8baf4 100644 --- a/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc +++ b/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper_pybind11.cc @@ -148,8 +148,8 @@ PYBIND11_MODULE(_pywrap_tensorflow_interpreter_wrapper, m) { )pbdoc") .def( "SetNumThreads", - [](InterpreterWrapper& self, int i) { - return tensorflow::PyoOrThrow(self.SetNumThreads(i)); + [](InterpreterWrapper& self, int num_threads) { + return tensorflow::PyoOrThrow(self.SetNumThreads(num_threads)); }, R"pbdoc( ask the interpreter to set the number of threads to use. From b0c869a7eb7a782a71aa672313bd0118f374ed38 Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Thu, 21 May 2020 09:45:58 +0800 Subject: [PATCH 11/12] clean up --- tensorflow/lite/examples/python/label_image.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tensorflow/lite/examples/python/label_image.py b/tensorflow/lite/examples/python/label_image.py index 9d3c47fc4c2..58fddcc188e 100644 --- a/tensorflow/lite/examples/python/label_image.py +++ b/tensorflow/lite/examples/python/label_image.py @@ -100,5 +100,4 @@ if __name__ == '__main__': else: print('{:08.6f}: {}'.format(float(results[i] / 255.0), labels[i])) - #print("time: ", stop_time - start_time) print('time: {:.3f}ms'.format((stop_time - start_time) * 1000)) From fd546daf61fdd5c286445effec68804ab77df5f9 Mon Sep 17 00:00:00 2001 From: Koan-Sin Tan Date: Wed, 27 May 2020 15:32:36 +0800 Subject: [PATCH 12/12] address review comments --- tensorflow/lite/examples/python/label_image.py | 2 +- tensorflow/lite/python/interpreter.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tensorflow/lite/examples/python/label_image.py b/tensorflow/lite/examples/python/label_image.py index 58fddcc188e..b3b1bb91985 100644 --- a/tensorflow/lite/examples/python/label_image.py +++ b/tensorflow/lite/examples/python/label_image.py @@ -57,7 +57,7 @@ if __name__ == '__main__': help='input standard deviation') parser.add_argument( '--num_threads', - default=1, type=int, + default=None, type=int, help='number of threads') args = parser.parse_args() diff --git a/tensorflow/lite/python/interpreter.py b/tensorflow/lite/python/interpreter.py index a34f4f66b6f..f4a9d96da3f 100644 --- a/tensorflow/lite/python/interpreter.py +++ b/tensorflow/lite/python/interpreter.py @@ -182,9 +182,10 @@ class Interpreter(object): experimental_delegates: Experimental. Subject to change. List of [TfLiteDelegate](https://www.tensorflow.org/lite/performance/delegates) objects returned by lite.load_delegate(). - num_threads: Set the number of threads used by TFLite kernels. - If not set, kernels are running single-threaded. Note that currently, - only some kernels, such as conv, are multithreaded. + num_threads: Sets the number of threads used by the interpreter and + available to CPU kernels. If not set, the interpreter will use an + implementation-dependent default number of threads. Currently, + only a subset of kernels, such as conv, support multi-threading. Raises: ValueError: If the interpreter was unable to create. @@ -210,7 +211,7 @@ class Interpreter(object): else: raise ValueError('Can\'t both provide `model_path` and `model_content`') - if num_threads: + if num_threads is not None: if not isinstance(num_threads, int): raise ValueError('type of num_threads should be int') if num_threads < 1: