Package nukescripts :: Module nukeprofiler
[hide private]
[frames] | no frames]

Source Code for Module nukescripts.nukeprofiler

  1  import nuke 
  2  import socket 
  3  import datetime 
  4  import platform 
  5  import hardwareinfo 
  6   
  7   
  8  profileCategories = { 
  9      "ProfileStore" : nuke.PROFILE_STORE, 
 10      "ProfileValidate" : nuke.PROFILE_VALIDATE, 
 11      "ProfileRequest": nuke.PROFILE_REQUEST, 
 12      "ProfileEngine" : nuke.PROFILE_ENGINE, 
 13      } 
 14   
15 -class NukeProfiler:
16 - def __init__(self):
17 self._pathToFile = nuke.performanceProfileFilename() 18 self._profileDesc = None 19 self._file = None 20 self._indent = 0
21
22 - def setPathToFile(self, filename):
23 self._pathToFile = filename
24
25 - def indentString(self):
26 return " " * self._indent
27
28 - def OpenTag(self, tagName, optionsDict = {}, closeTag = False):
29 xmlString = self.indentString() + "<" + tagName + ">\n" 30 if closeTag: 31 xmlString += "\n" 32 self._indent += 1 33 for dictKey, dictValue in optionsDict.iteritems(): 34 xmlString += self.indentString() + "<" + dictKey + ">" + str(dictValue) + "</" + dictKey + ">\n" 35 if closeTag: 36 self._indent -= 1 37 xmlString += self.indentString() + "</" + tagName + ">\n" 38 return xmlString
39
40 - def CloseTag(self, tagName):
41 self._indent -= 1 42 closeTagString = self.indentString() + "</" + tagName + ">\n" 43 return closeTagString
44
45 - def WriteDictInner(self, dictToWrite):
46 xmlString = "" 47 for dictKey, dictValue in dictToWrite.iteritems(): 48 xmlString += self.indentString() + "<" + dictKey + ">" + str(dictValue) + "</" + dictKey + ">\n" 49 return xmlString
50
51 - def NodeProfile(self, nukeNode, maxEngineVal):
52 nodeTag = "Node" 53 if nukeNode.Class() == "Group": 54 # Use a different tag for Group nodes, which contain combined performance statistics for all the nodes within the group. 55 # The internal nodes are also output separately so including group nodes as well means these nodes get counted twice. 56 # Using a different tag makes it clear that these should be treated differently to other nodes when parsing the xml 57 # for analysis or display. 58 nodeTag = "GroupNode" 59 nodeInfoDict = { "Name" : nukeNode.fullName(), "Class" : nukeNode.Class() } 60 # Add the file path if the node is a Reader or Writer 61 if nukeNode.Class() == "Read" or nukeNode.Class() == "Write": 62 nodeInfoDict["File"] = nukeNode["file"].value() 63 xmlString = self.OpenTag(nodeTag, nodeInfoDict) 64 for catName, catVal in profileCategories.iteritems(): 65 xmlString += self.OpenTag(catName) 66 if catName == "ProfileEngine": 67 info = nukeNode.performanceInfo(catVal).copy() 68 if maxEngineVal > 0: 69 perfVal = float(info["timeTakenWall"]) / float(maxEngineVal) 70 else: 71 perfVal = -1.0 72 info.update({ "ProfileEngineRelativeToMax" : perfVal }) 73 xmlString += self.WriteDictInner(info) 74 else: 75 xmlString += self.WriteDictInner(nukeNode.performanceInfo(catVal)) 76 xmlString += self.CloseTag(catName) 77 xmlString += self.CloseTag(nodeTag) 78 return xmlString
79
80 - def initProfileDesc(self):
81 commandLineString = "" 82 for i in nuke.rawArgs: 83 commandLineString += i + " " 84 self._profileDesc = { 85 "ScriptName" : nuke.root().name(), 86 "NumThreads" : nuke.env["threads"], 87 "TimeStored" : str(datetime.datetime.now().replace(microsecond = 0)), 88 "CommandLine" : commandLineString 89 }
90
91 - def writeXMLInfo(self):
92 self._file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") 93 self._file.write("<?xml-stylesheet type=\"text/xsl\" href=\"testStylesheet.xsl\"?>\n")
94
96 nuke.resetPerformanceTimers() 97 self.initProfileDesc() 98 self._file = open(self._pathToFile, "w") 99 self.writeXMLInfo() 100 self.writeProfileDesc()
101
102 - def writeProfileDesc(self):
103 self._file.write(self.OpenTag("PerformanceProfile", self._profileDesc)) 104 self._file.write(self.OpenTag("MachineInfo")) 105 hardwareinfo.PrintMachineInfoToFile(self._file, self._indent) 106 self._file.write(self.CloseTag("MachineInfo"))
107
109 self._file.write(self.OpenTag("Frame", { "Time" : nuke.frame() })) 110 self._file.write(self.OpenTag("MaxPerformance")) 111 # Store max engine value for calculating relative performance: 112 maxInfo = nuke.maxPerformanceInfo() 113 maxEngineVal = maxInfo["timeTakenWall"]["value"] 114 for key, value in maxInfo.iteritems(): 115 self._file.write(self.OpenTag(key)) 116 self._file.write(self.WriteDictInner(value)) 117 self._file.write(self.CloseTag(key)) 118 self._file.write(self.CloseTag("MaxPerformance")) 119 # Fill in node profile 120 for n in nuke.allNodes(recurseGroups = True): 121 self._file.write(self.NodeProfile(n, maxEngineVal)); 122 self._file.write(self.CloseTag("Frame")) 123 # Reset performance timers after writing the profile for this frame: 124 nuke.resetPerformanceTimers()
125
126 - def endProfile(self):
127 # If in a GUI session and nothing has been rendered out to a 128 # file, the profile file will not have been opened yet, so 129 # check that the file exists before trying to close it: 130 if self._file != None: 131 self._file.write(self.CloseTag("PerformanceProfile")) 132 self._file.close()
133