Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/profiler/model_analyzer.py: 22%

153 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

1# Copyright 2016 The TensorFlow Authors. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14# ============================================================================== 

15"""Model Analyzer. 

16 

17Analyze model, including shape, params, time, memory, structure, etc. 

18""" 

19import sys 

20 

21from google.protobuf import message 

22from tensorflow.core.profiler import tfprof_options_pb2 

23from tensorflow.core.profiler import tfprof_output_pb2 

24from tensorflow.python.eager import context 

25from tensorflow.python.framework import errors 

26from tensorflow.python.framework import ops 

27from tensorflow.python.profiler import option_builder 

28from tensorflow.python.profiler import tfprof_logger 

29from tensorflow.python.util import _pywrap_tfprof as print_mdl 

30from tensorflow.python.util.tf_export import tf_export 

31 

32_DEFAULT_PROFILE_OPTIONS = 0 

33_DEFAULT_ADVISE_OPTIONS = 0 

34 

35# The following options are for 'advise' cmd. 

36# Show all advice. 

37ALL_ADVICE = { 

38 'ExpensiveOperationChecker': {}, 

39 'AcceleratorUtilizationChecker': {}, 

40 'JobChecker': {}, # Only available internally. 

41 'OperationChecker': {}, 

42} 

43 

44 

45def _graph_string(graph): 

46 """Helper to serialize a graph to string.""" 

47 if graph: 

48 return graph.as_graph_def(add_shapes=True).SerializeToString() 

49 else: 

50 return b'' 

51 

52 

53def _build_options(options): 

54 """Build tfprof.OptionsProto. 

55 

56 Args: 

57 options: A dictionary of options. 

58 

59 Returns: 

60 tfprof.OptionsProto. 

61 """ 

62 opts = tfprof_options_pb2.OptionsProto() 

63 opts.max_depth = options.get('max_depth', 10) 

64 opts.min_bytes = options.get('min_bytes', 0) 

65 opts.min_peak_bytes = options.get('min_peak_bytes', 0) 

66 opts.min_residual_bytes = options.get('min_residual_bytes', 0) 

67 opts.min_output_bytes = options.get('min_output_bytes', 0) 

68 opts.min_micros = options.get('min_micros', 0) 

69 opts.min_accelerator_micros = options.get('min_accelerator_micros', 0) 

70 opts.min_cpu_micros = options.get('min_cpu_micros', 0) 

71 opts.min_params = options.get('min_params', 0) 

72 opts.min_float_ops = options.get('min_float_ops', 0) 

73 opts.min_occurrence = options.get('min_occurrence', 0) 

74 

75 opts.step = options.get('step', -1) 

76 

77 opts.order_by = options.get('order_by', 'name') 

78 

79 for p in options.get('account_type_regexes', []): 

80 opts.account_type_regexes.append(p) 

81 for p in options.get('start_name_regexes', []): 

82 opts.start_name_regexes.append(p) 

83 for p in options.get('trim_name_regexes', []): 

84 opts.trim_name_regexes.append(p) 

85 for p in options.get('show_name_regexes', []): 

86 opts.show_name_regexes.append(p) 

87 for p in options.get('hide_name_regexes', []): 

88 opts.hide_name_regexes.append(p) 

89 opts.account_displayed_op_only = options.get('account_displayed_op_only', 

90 False) 

91 

92 for p in options.get('select', []): 

93 opts.select.append(p) 

94 

95 opts.output = options.get('output', 'stdout') 

96 opts.dump_to_file = options.get('dump_to_file', '') 

97 

98 return opts 

99 

100 

101def _build_advisor_options(options): 

102 """Build tfprof.AdvisorOptionsProto. 

103 

104 Args: 

105 options: A dictionary of options. See ALL_ADVICE example. 

106 

107 Returns: 

108 tfprof.AdvisorOptionsProto. 

109 """ 

110 opts = tfprof_options_pb2.AdvisorOptionsProto() 

111 if options is None: 

112 return opts 

113 for checker, checker_opts in options.items(): 

114 checker_ops_pb = tfprof_options_pb2.AdvisorOptionsProto.CheckerOption() 

115 for k, v in checker_opts.items(): 

116 checker_ops_pb[k] = v 

117 opts.checkers[checker].MergeFrom(checker_ops_pb) 

118 return opts 

119 

120 

121@tf_export(v1=['profiler.Profiler']) 

122class Profiler: 

123 """TensorFlow multi-step profiler. 

124 

125 

126 ```python 

127 Typical use case: 

128 # Currently we are only allowed to create 1 profiler per process. 

129 profiler = Profiler(sess.graph) 

130 

131 for i in range(total_steps): 

132 if i % 10000 == 0: 

133 run_meta = tf.compat.v1.RunMetadata() 

134 _ = sess.run(..., 

135 options=tf.compat.v1.RunOptions( 

136 trace_level=tf.RunOptions.FULL_TRACE), 

137 run_metadata=run_meta) 

138 profiler.add_step(i, run_meta) 

139 

140 # Profile the parameters of your model. 

141 profiler.profile_name_scope(options=(option_builder.ProfileOptionBuilder 

142 .trainable_variables_parameter())) 

143 

144 # Or profile the timing of your model operations. 

145 opts = option_builder.ProfileOptionBuilder.time_and_memory() 

146 profiler.profile_operations(options=opts) 

147 

148 # Or you can generate a timeline: 

149 opts = (option_builder.ProfileOptionBuilder( 

150 option_builder.ProfileOptionBuilder.time_and_memory()) 

151 .with_step(i) 

152 .with_timeline_output(filename).build()) 

153 profiler.profile_graph(options=opts) 

154 else: 

155 _ = sess.run(...) 

156 # Auto detect problems and generate advice. 

157 profiler.advise() 

158 ``` 

159 """ 

160 

161 def __init__(self, graph=None, op_log=None): 

162 """Constructor. 

163 

164 Args: 

165 graph: tf.Graph. If None and eager execution is not enabled, use default 

166 graph. 

167 op_log: optional. tensorflow::tfprof::OpLogProto proto. Used to define 

168 extra op types. 

169 """ 

170 if not graph and not context.executing_eagerly(): 

171 graph = ops.get_default_graph() 

172 self._coverage = 0.0 

173 self._graph = graph 

174 # pylint: disable=protected-access 

175 op_log = tfprof_logger.merge_default_with_oplog(self._graph, op_log=op_log) 

176 # pylint: enable=protected-access 

177 print_mdl.NewProfiler( 

178 _graph_string(self._graph), op_log.SerializeToString()) 

179 

180 def __del__(self): 

181 print_mdl.DeleteProfiler() 

182 

183 def add_step(self, step, run_meta): 

184 """Add statistics of a step. 

185 

186 Args: 

187 step: int, An id used to group one or more different `run_meta` together. 

188 When profiling with the profile_xxx APIs, user can use the `step` id in 

189 the `options` to profile these `run_meta` together. 

190 run_meta: RunMetadata proto that contains statistics of a session run. 

191 """ 

192 # pylint: disable=protected-access 

193 op_log = tfprof_logger.merge_default_with_oplog( 

194 self._graph, run_meta=run_meta) 

195 # pylint: enable=protected-access 

196 # TODO(xpan): P1: Better to find the current graph. 

197 self._coverage = print_mdl.AddStep(step, _graph_string(self._graph), 

198 run_meta.SerializeToString(), 

199 op_log.SerializeToString()) 

200 

201 def profile_python(self, options): 

202 """Profile the statistics of the Python codes. 

203 

204 By default, it shows the call stack from root. To avoid 

205 redundant output, you may use options to filter as below 

206 options['show_name_regexes'] = ['.*my_code.py.*'] 

207 

208 Args: 

209 options: A dict of options. See core/profiler/g3doc/options.md. 

210 

211 Returns: 

212 a MultiGraphNodeProto that records the results. 

213 """ 

214 opts = _build_options(options) 

215 tfprof_node = tfprof_output_pb2.MultiGraphNodeProto() 

216 try: 

217 tfprof_node.ParseFromString( 

218 print_mdl.Profile('code'.encode('utf-8'), opts.SerializeToString())) 

219 except message.DecodeError as e: 

220 sys.stderr.write('Cannot parse returned proto: %s.\n' % e) 

221 return tfprof_node 

222 

223 def profile_operations(self, options): 

224 """Profile the statistics of the Operation types (e.g. 

225 

226 MatMul, Conv2D). 

227 

228 Args: 

229 options: A dict of options. See core/profiler/g3doc/options.md. 

230 

231 Returns: 

232 a MultiGraphNodeProto that records the results. 

233 """ 

234 opts = _build_options(options) 

235 tfprof_node = tfprof_output_pb2.MultiGraphNodeProto() 

236 try: 

237 tfprof_node.ParseFromString( 

238 print_mdl.Profile('op'.encode('utf-8'), opts.SerializeToString())) 

239 except message.DecodeError as e: 

240 sys.stderr.write('Cannot parse returned proto: %s.\n' % e) 

241 return tfprof_node 

242 

243 def profile_name_scope(self, options): 

244 """Profile the statistics of graph nodes, organized by name scope. 

245 

246 Args: 

247 options: A dict of options. See core/profiler/g3doc/options.md. 

248 

249 Returns: 

250 a GraphNodeProto that records the results. 

251 """ 

252 opts = _build_options(options) 

253 tfprof_node = tfprof_output_pb2.GraphNodeProto() 

254 try: 

255 tfprof_node.ParseFromString( 

256 print_mdl.Profile('scope'.encode('utf-8'), opts.SerializeToString())) 

257 except message.DecodeError as e: 

258 sys.stderr.write('Cannot parse returned proto: %s.\n' % e) 

259 return tfprof_node 

260 

261 def profile_graph(self, options): 

262 """Profile the statistics of graph nodes, organized by dataflow graph. 

263 

264 Args: 

265 options: A dict of options. See core/profiler/g3doc/options.md. 

266 

267 Returns: 

268 a GraphNodeProto that records the results. 

269 """ 

270 opts = _build_options(options) 

271 tfprof_node = tfprof_output_pb2.GraphNodeProto() 

272 try: 

273 tfprof_node.ParseFromString( 

274 print_mdl.Profile('graph'.encode('utf-8'), opts.SerializeToString())) 

275 except message.DecodeError as e: 

276 sys.stderr.write('Cannot parse returned proto: %s.\n' % e) 

277 return tfprof_node 

278 

279 def advise(self, options): 

280 """Automatically detect problems and generate reports. 

281 

282 Args: 

283 options: A dict of options. See ALL_ADVICE example above. 

284 

285 Returns: 

286 An Advise proto that contains the reports from all checkers. 

287 """ 

288 advise_pb = tfprof_output_pb2.AdviceProto() 

289 opts = _build_advisor_options(options) 

290 advise_pb.ParseFromString( 

291 print_mdl.Profile('advise'.encode('utf-8'), opts.SerializeToString())) 

292 return advise_pb 

293 

294 def serialize_to_string(self): 

295 """Serialize the ProfileProto to a binary string. 

296 

297 Users can write it to file for offline analysis by tfprof commandline 

298 or graphical interface. 

299 

300 Returns: 

301 ProfileProto binary string. 

302 """ 

303 return print_mdl.SerializeToString() 

304 

305 def _write_profile(self, filename): 

306 """Writes the profile to a file.""" 

307 print_mdl.WriteProfile(filename) 

308 

309 

310@tf_export(v1=['profiler.profile']) 

311def profile(graph=None, 

312 run_meta=None, 

313 op_log=None, 

314 cmd='scope', 

315 options=_DEFAULT_PROFILE_OPTIONS): 

316 """Profile model. 

317 

318 Tutorials and examples can be found in: 

319 https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/profiler/g3doc/python_api.md 

320 

321 Args: 

322 graph: tf.Graph. If None and eager execution is not enabled, use default 

323 graph. 

324 run_meta: optional tensorflow.RunMetadata proto. It is necessary to 

325 support run time information profiling, such as time and memory. 

326 op_log: tensorflow.tfprof.OpLogProto proto. User can assign "types" to graph 

327 nodes with op_log. "types" allow user to flexibly group and account 

328 profiles using options['accounted_type_regexes']. 

329 cmd: string. Either 'op', 'scope', 'graph' or 'code'. 'op' view organizes 

330 profile using operation type. (e.g. MatMul) 'scope' view organizes profile 

331 using graph node name scope. 'graph' view organizes profile using graph 

332 node inputs/outputs. 'code' view organizes profile using Python call 

333 stack. 

334 options: A dict of options. See core/profiler/g3doc/options.md. 

335 

336 Returns: 

337 If cmd is 'scope' or 'graph', returns GraphNodeProto proto. 

338 If cmd is 'op' or 'code', returns MultiGraphNodeProto proto. 

339 Side effect: stdout/file/timeline.json depending on options['output'] 

340 """ 

341 if not graph and not context.executing_eagerly(): 

342 graph = ops.get_default_graph() 

343 

344 if options == _DEFAULT_PROFILE_OPTIONS: 

345 options = ( 

346 option_builder.ProfileOptionBuilder.trainable_variables_parameter()) 

347 # pylint: disable=protected-access 

348 op_log = tfprof_logger.merge_default_with_oplog( 

349 graph, op_log, run_meta, add_trace=cmd == 'code') 

350 # pylint: enable=protected-access 

351 

352 opts = _build_options(options) 

353 

354 run_meta_str = run_meta.SerializeToString() if run_meta else b'' 

355 

356 graph_str = _graph_string(graph) 

357 

358 if cmd == 'code' or cmd == 'op': 

359 tfprof_node = tfprof_output_pb2.MultiGraphNodeProto() 

360 ret = print_mdl.PrintModelAnalysis(graph_str, run_meta_str, 

361 op_log.SerializeToString(), 

362 cmd.encode('utf-8'), 

363 opts.SerializeToString()) 

364 try: 

365 tfprof_node.ParseFromString(ret) 

366 except message.DecodeError as e: 

367 sys.stderr.write('Cannot parse returned proto: %s.\n' % e) 

368 

369 elif cmd == 'graph' or cmd == 'scope': 

370 tfprof_node = tfprof_output_pb2.GraphNodeProto() 

371 ret = print_mdl.PrintModelAnalysis(graph_str, run_meta_str, 

372 op_log.SerializeToString(), 

373 cmd.encode('utf-8'), 

374 opts.SerializeToString()) 

375 try: 

376 tfprof_node.ParseFromString(ret) 

377 except message.DecodeError as e: 

378 sys.stderr.write('Cannot parse returned proto: %s.\n' % e) 

379 else: 

380 raise errors.InvalidArgumentError(None, None, 'unknown cmd: %s\n' % cmd) 

381 

382 return tfprof_node 

383 

384 

385@tf_export(v1=['profiler.advise']) 

386def advise(graph=None, run_meta=None, options=_DEFAULT_ADVISE_OPTIONS): 

387 """Auto profile and advise. 

388 

389 Builds profiles and automatically check anomalies of various 

390 aspects. For more details: 

391 https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/profiler/README.md 

392 

393 Args: 

394 graph: tf.Graph. If None and eager execution is not enabled, use default 

395 graph. 

396 run_meta: optional tensorflow.RunMetadata proto. It is necessary to 

397 support run time information profiling, such as time and memory. 

398 options: see ALL_ADVICE example above. Default checks everything. 

399 

400 Returns: 

401 Returns AdviceProto proto 

402 """ 

403 if not graph and not context.executing_eagerly(): 

404 graph = ops.get_default_graph() 

405 

406 if options == _DEFAULT_ADVISE_OPTIONS: 

407 options = ALL_ADVICE.copy() 

408 

409 # pylint: disable=protected-access 

410 op_log = tfprof_logger.merge_default_with_oplog( 

411 graph, None, run_meta, add_trace=True) 

412 # pylint: enable=protected-access 

413 

414 run_meta_str = run_meta.SerializeToString() if run_meta else b'' 

415 

416 opts = _build_advisor_options(options) 

417 ret = tfprof_output_pb2.AdviceProto() 

418 ret.ParseFromString( 

419 print_mdl.PrintModelAnalysis( 

420 _graph_string(graph), run_meta_str, op_log.SerializeToString(), 

421 'advise'.encode('utf-8'), opts.SerializeToString())) 

422 return ret