#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2023 The Uncertainty Quantification Foundation.
# License: 3-clause BSD.  The full license text is available at:
#  - https://github.com/uqfoundation/dill/blob/master/LICENSE
'''
build profile graph for the given instance

running:
  $ get_gprof <args> <instance>

executes:
  gprof2dot -f pstats <args> <type>.prof | dot -Tpng -o <type>.call.png

where:
  <args> are arguments for gprof2dot, such as "-n 5 -e 5"
  <instance> is code to create the instance to profile
  <type> is the class of the instance (i.e. type(instance))

For example:
  $ get_gprof -n 5 -e 1 "import numpy; numpy.array([1,2])"

will create 'ndarray.call.png' with the profile graph for numpy.array([1,2]),
where '-n 5' eliminates nodes below 5% threshold, similarly '-e 1' eliminates
edges below 1% threshold
'''

import sys
# grab args for gprof2dot
args = sys.argv[1:-1]
args = ' '.join(args)
# last arg builds the object
obj = sys.argv[-1]
obj = obj.split(';')
# multi-line prep for generating an instance
for line in obj[:-1]:
    exec(line)
# one-line generation of an instance
obj = eval(obj[-1])

# get object 'name'
objtype = type(obj)
name = getattr(objtype, '__name__', getattr(objtype, '__class__', objtype))

# profile dumping an object
import dill
import os
import cProfile
#name = os.path.splitext(os.path.basename(__file__))[0]
cProfile.run("dill.dumps(obj)", filename="%s.prof" % name)
msg = "gprof2dot -f pstats %s %s.prof | dot -Tpng -o %s.call.png" % (args, name, name)
os.system(msg)

# get stats
f_prof = "%s.prof" % name
import pstats
stats = pstats.Stats(f_prof, stream=sys.stdout)
stats.strip_dirs().sort_stats('cumtime')
stats.print_stats(20) #XXX: save to file instead of print top 20?
os.remove(f_prof)
