peek_objs and peek_traceable_objs are only used in ops.py. In most cases, they are iterated over, so there is no benefit to returning a list. In the other cases, just the first obj is required, so rather than returning the entire list, I add a peek_top_obj method. Profile before: ncalls tottime percall cumtime percall filename:lineno(function) 172162 0.171 0.000 0.171 0.000 traceable_stack.py:113(peek_objs) 197806 0.317 0.000 0.317 0.000 traceable_stack.py:117(peek_traceable_objs) Profile after: ncalls tottime percall cumtime percall filename:lineno(function) 143292 0.170 0.000 0.170 0.000 traceable_stack.py:117(peek_objs) 197806 0.080 0.000 0.080 0.000 traceable_stack.py:121(peek_traceable_objs) 28870 0.008 0.000 0.008 0.000 traceable_stack.py:113(peek_top_obj) PiperOrigin-RevId: 240965521
140 lines
5.1 KiB
Python
140 lines
5.1 KiB
Python
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# ==============================================================================
|
|
"""Tests for tensorflow.python.framework.traceable_stack."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
|
|
from tensorflow.python.framework import test_util
|
|
from tensorflow.python.framework import traceable_stack
|
|
from tensorflow.python.platform import googletest
|
|
from tensorflow.python.util import tf_inspect as inspect
|
|
|
|
_LOCAL_OBJECT = lambda x: x
|
|
_THIS_FILENAME = inspect.getsourcefile(_LOCAL_OBJECT)
|
|
|
|
|
|
class TraceableObjectTest(test_util.TensorFlowTestCase):
|
|
|
|
def testSetFilenameAndLineFromCallerUsesCallersStack(self):
|
|
t_obj = traceable_stack.TraceableObject(17)
|
|
|
|
# Do not separate placeholder from the set_filename_and_line_from_caller()
|
|
# call one line below it as it is used to calculate the latter's line
|
|
# number.
|
|
placeholder = lambda x: x
|
|
result = t_obj.set_filename_and_line_from_caller()
|
|
|
|
expected_lineno = inspect.getsourcelines(placeholder)[1] + 1
|
|
self.assertEqual(expected_lineno, t_obj.lineno)
|
|
self.assertEqual(_THIS_FILENAME, t_obj.filename)
|
|
self.assertEqual(t_obj.SUCCESS, result)
|
|
|
|
def testSetFilenameAndLineFromCallerRespectsOffset(self):
|
|
|
|
def call_set_filename_and_line_from_caller(t_obj):
|
|
# We expect to retrieve the line number from _our_ caller.
|
|
return t_obj.set_filename_and_line_from_caller(offset=1)
|
|
|
|
t_obj = traceable_stack.TraceableObject(None)
|
|
# Do not separate placeholder from the
|
|
# call_set_filename_and_line_from_caller() call one line below it as it is
|
|
# used to calculate the latter's line number.
|
|
placeholder = lambda x: x
|
|
result = call_set_filename_and_line_from_caller(t_obj)
|
|
|
|
expected_lineno = inspect.getsourcelines(placeholder)[1] + 1
|
|
self.assertEqual(expected_lineno, t_obj.lineno)
|
|
self.assertEqual(t_obj.SUCCESS, result)
|
|
|
|
def testSetFilenameAndLineFromCallerHandlesRidiculousOffset(self):
|
|
t_obj = traceable_stack.TraceableObject('The quick brown fox.')
|
|
# This line shouldn't die.
|
|
result = t_obj.set_filename_and_line_from_caller(offset=300)
|
|
|
|
# We expect a heuristic to be used because we are not currently 300 frames
|
|
# down on the stack. The filename and lineno of the outermost frame are not
|
|
# predictable -- in some environments the filename is this test file, but in
|
|
# other environments it is not (e.g. due to a test runner calling this
|
|
# file). Therefore we only test that the called function knows it applied a
|
|
# heuristic for the ridiculous stack offset.
|
|
self.assertEqual(t_obj.HEURISTIC_USED, result)
|
|
|
|
|
|
class TraceableStackTest(test_util.TensorFlowTestCase):
|
|
|
|
def testPushPeekPopObj(self):
|
|
t_stack = traceable_stack.TraceableStack()
|
|
t_stack.push_obj(42.0)
|
|
t_stack.push_obj('hope')
|
|
|
|
expected_lifo_peek = ['hope', 42.0]
|
|
self.assertEqual(expected_lifo_peek, list(t_stack.peek_objs()))
|
|
|
|
self.assertEqual('hope', t_stack.pop_obj())
|
|
self.assertEqual(42.0, t_stack.pop_obj())
|
|
|
|
def testPushPeekTopObj(self):
|
|
t_stack = traceable_stack.TraceableStack()
|
|
t_stack.push_obj(42.0)
|
|
t_stack.push_obj('hope')
|
|
self.assertEqual('hope', t_stack.peek_top_obj())
|
|
|
|
def testPushPopPreserveLifoOrdering(self):
|
|
t_stack = traceable_stack.TraceableStack()
|
|
t_stack.push_obj(0)
|
|
t_stack.push_obj(1)
|
|
t_stack.push_obj(2)
|
|
t_stack.push_obj(3)
|
|
|
|
obj_3 = t_stack.pop_obj()
|
|
obj_2 = t_stack.pop_obj()
|
|
obj_1 = t_stack.pop_obj()
|
|
obj_0 = t_stack.pop_obj()
|
|
|
|
self.assertEqual(3, obj_3)
|
|
self.assertEqual(2, obj_2)
|
|
self.assertEqual(1, obj_1)
|
|
self.assertEqual(0, obj_0)
|
|
|
|
def testPushObjSetsFilenameAndLineInfoForCaller(self):
|
|
t_stack = traceable_stack.TraceableStack()
|
|
|
|
# We expect that the line number recorded for the 1-object will come from
|
|
# the call to t_stack.push_obj(1). Do not separate the next two lines!
|
|
placeholder_1 = lambda x: x
|
|
t_stack.push_obj(1)
|
|
|
|
# We expect that the line number recorded for the 2-object will come from
|
|
# the call to call_push_obj() and _not_ the call to t_stack.push_obj().
|
|
def call_push_obj(obj):
|
|
t_stack.push_obj(obj, offset=1)
|
|
|
|
# Do not separate the next two lines!
|
|
placeholder_2 = lambda x: x
|
|
call_push_obj(2)
|
|
|
|
expected_lineno_1 = inspect.getsourcelines(placeholder_1)[1] + 1
|
|
expected_lineno_2 = inspect.getsourcelines(placeholder_2)[1] + 1
|
|
|
|
t_obj_2, t_obj_1 = t_stack.peek_traceable_objs()
|
|
self.assertEqual(expected_lineno_2, t_obj_2.lineno)
|
|
self.assertEqual(expected_lineno_1, t_obj_1.lineno)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
googletest.main()
|