CMS 3D CMS Logo

psClasses.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 from __future__ import print_function
3 import os,subprocess,sys,re,time,random
4 from threading import *
5 from subprocess import call
6 #Some Constants
7 STATE_CREATED,STATE_COMPLETED,STATE_ERROR=range(3)
8 
9 ### Classes
10 class BuildThread(Thread):
11 
12  def __init__(self, parent, queue, weight = 1):
13  Thread.__init__(self)
14  self.BuildNode = parent
15  self.QueueList = queue
16  self.Weight = weight
17  self.IsComplete = Condition()
18  self.Queue = None
19 
20  def putInServerQueue(self):
21  self.QueueList.QueueLock.acquire()
22  sSrv=self.QueueList.smallestQueue()
23  tSrv=self.QueueList.thinerQueue()
24  self.Queue=sSrv
25  if sSrv == tSrv:
26  self.QueueList[sSrv].append(self)
27  elif self.Weight + self.QueueList[sSrv].queueWeight() <= (self.QueueList.Cores/self.QueueList.Jay)*1.5:
28  self.QueueList[sSrv].append(self)
29  else:
30  self.QueueList[tSrv].append(self)
31  self.Queue=tSrv
32  self.QueueList.QueueLock.release()
33 
34  def build(self):
35  self.QueueList[self.Queue].QueueSem.acquire()
36  #call(['eval',"scram runtime -sh",";",'EdmPluginRefresh',self.BuildNode.LibName],shell="/bin/bash"))
37  rValue=call(['ssh',self.Queue,'cd ~/CMSSW_3_5_7;scram build -j %d' % self.QueueList.Jay,self.BuildNode.LibName])
38  self.QueueList.EdmRefreshLock.acquire()
39  call(['ssh',self.Queue,'cd ~/CMSSW_3_5_7;eval `scram runtime -sh`;EdmPluginRefresh %s' % self.BuildNode.LibName])
40  self.QueueList.EdmRefreshLock.release()
41  if rValue == 0:
42  self.BuildNode.State=STATE_COMPLETED
43  else:
44  print("Build failed for %s" % self.BuildNode.LibName)
45  self.BuildNode.State=STATE_ERROR
46  self.QueueList[self.Queue].QueueSem.release()
47 
48  def releaseAllLocks(self):
49  #for deps in self.BuildNode.DependsOn:
50  #deps.BThread.IsComplete.release()
51  self.BuildNode.State=STATE_ERROR
52  self.IsComplete.acquire()
53  self.IsComplete.notifyAll()
54  self.IsComplete.release()
55 
56  def run(self):
57  depsCompleted=False
58  while not depsCompleted:
59  depsCompleted=True
60  for deps in self.BuildNode.DependsOn:
61  if deps.State is STATE_ERROR :
62  self.releaseAllLocks()
63  return -1
64  if deps.State is not STATE_COMPLETED :
65  depsCompleted=False
66  deps.BThread.IsComplete.acquire()
67  deps.BThread.IsComplete.wait()
68  #deps.BThread.isAlive() and sys.stdout.write("Wait time exeded %s %s\n" % (deps.LibName,deps.Module))
69  deps.BThread.IsComplete.release()
70 
71  self.putInServerQueue()
72  self.build()
73  self.IsComplete.acquire()
74  self.IsComplete.notifyAll()
75  self.IsComplete.release()
76  return 0
77 
79 
80  def __init__(self,value=None):
81  self.SeenLibs = []
82  self.SeenModules = []
83  self.SeenSubModules = []
84  if value:
85  list.__init__(self,value)
86  else:
87  list.__init__(self)
88 
89  def findLib(self,lib,head=None):
90  if len(self) == 0:
91  return None
92  if head == self:
93  return None
94  if head == None:
95  head = self
96  itP=None
97  for it in self:
98  if lib == it.LibName:
99  return it
100  else:
101  itP=it.AreDependent.findLib(lib,head)
102  if itP is not None:
103  return itP
104  return itP
105 
106  def startThreads(self):
107  for node in self:
108  if not node.BThread.is_alive():
109  try:
110  node.BThread.start()
111  except:
112  pass
113  node.AreDependent.startThreads()
114 
115  def findDep(self,dep):
116  return self.findLib(dep.replace("/",""))
117 
118  def __setitem__(self,index,value):
119  if not value.__class__ == BuildTreeNode:
120  raise TypeError("Expected BuildTreeNode")
121  self.SeenLibs.append(value.LibName)
122  self.SeenModules.append(value.Module)
123  self.SeenSubModules.append(value.SubModule)
124  list.__setitem__(self,index,value)
125 
126  def append(self,value):
127  if not value.__class__ == BuildTreeNode:
128  raise TypeError("Expected BuildTreeNode")
129  value.LibName not in self.SeenLibs and self.SeenLibs.append(value.LibName)
130  value.Module not in self.SeenModules and self.SeenModules.append(value.Module)
131  value.SubModule not in self.SeenSubModules and self.SeenSubModules.append(value.SubModule)
132  list.append(self,value)
133 
134  def __str__(self,topDown=False,direction=False):
135  if not topDown:
136  return "[\n...%s]" % str("\n...".join([str(it).replace("...","......") for it in self]))
137  else:
138  if direction:
139  return "[\n---%s]" % "\n---".join([ "'%s':'%s'\n------State = %d \n------DependsOn : %s " % (it.LibName,it.SubModule or it.Module,it.State,it.DependsOn.__str__(True,True).replace("---","------")) for it in self ])
140  else:
141  return "\n".join([it.__str__(True) for it in self])
142 
144 
145  def __init__(self,libname="",module="",submodule="",depends=None,areDependent=None,weight=1,srvqueue=None):
146  if depends==None:
148  else:
149  self.DependsOn = depends
150  if areDependent==None:
152  else:
153  self.AreDependent = areDependent
154  self.Module = module
155  self.LibName = libname
156  self.SubModule = submodule
157  self.BThread = srvqueue is not None and BuildThread(self,srvqueue,weight) or None
158  self.State = STATE_CREATED
159 
160  def __setattr__(self,name,value):
161  if name is "DependsOn" or name is "AreDependent":
162  if not value.__class__ == BuildTreeNodeList:
163  raise TypeError("Expected BuildTreeNodeList")
164  elif name is "State" or name is "ModulesToDo":
165  if not value.__class__ == int:
166  raise TypeError("Expected int")
167  elif name is "Module" or name is "SubModule" or name is "LibName":
168  if not value.__class__ == str:
169  raise TypeError("Expected str")
170  object.__setattr__(self,name,value)
171 
172  def __str__(self,topDown=False):
173  if not topDown:
174  return "'%s':'%s'\n...State = %d , Is it Done = %s \n...AreDependent : %s " % (self.LibName,self.SubModule or self.Module,self.State,self.BThread.IsComplete,self.AreDependent)
175  else:
176  if len(self.AreDependent)== 0:
177  return "'%s':'%s'\n---State = %d \n---DependsOn : %s " % (self.LibName,self.SubModule or self.Module,self.State,self.DependsOn.__str__(True,True).replace("---","------"))
178  else:
179  return self.AreDependent.__str__(topDown=True)
180 ####
181 # Class to manage server build queues
182 ####
183 class queueNode():
184  def __init__(self,cores = 4,jay = 2):
185  self.QueueSem = BoundedSemaphore(value=cores/jay)
186  self.RunningThreads = []
187  self.ThreadLog = []
188 
189  def append(self,item):
190  self.RunningThreads.append(item)
191  t=time.time()
192  self.ThreadLog.append([t,item.BuildNode.LibName,"INFO: %s thread %s added for Library %s" % (t,item.name,item.BuildNode.LibName)])
193 
194  def pendingThreads(self):
195  return len([x for x in self.RunningThreads if x.is_alive()])
196 
197  def queueWeight(self):
198  return sum([x.Weight for x in self.RunningThreads if x.is_alive()])
199 
200 
201 
203  def __init__(self,servers = [],cores = 4,jay = 2):
204  dict.__init__(self,dict.fromkeys(servers))
205  for srv in self.keys():
206  self[srv]=queueNode(cores,jay)
207  self.Cores = cores
208  self.Jay = jay
209  self.QueueLock = RLock()
210  self.EdmRefreshLock = RLock()
211 
212 
213  def smallestQueue(self):
214  smallest=self.keys()[0]
215  sizeSmallest=self[smallest].pendingThreads()
216  for srv in self.keys()[1:]:
217  size=self[srv].pendingThreads()
218  if size < sizeSmallest:
219  smallest = srv
220  sizeSmallest = size
221  return smallest
222 
223  def thinerQueue(self):
224  thinnest=self.keys()[0]
225  weightThinnest=self[thinnest].queueWeight()
226  for srv in self.keys()[1:]:
227  weight=self[srv].queueWeight()
228  if weight < weightThinnest:
229  thinnest = srv
230  weightThinnest = weight
231  return thinnest
232 
233 
234 
235 
236 
237 
def __str__(self, topDown=False, direction=False)
Definition: psClasses.py:134
def queueWeight(self)
Definition: psClasses.py:197
def findLib(self, lib, head=None)
Definition: psClasses.py:89
def replace(string, replacements)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def findDep(self, dep)
Definition: psClasses.py:115
def __init__(self, cores=4, jay=2)
Definition: psClasses.py:184
def __init__(self, value=None)
Definition: psClasses.py:80
def pendingThreads(self)
Definition: psClasses.py:194
def thinerQueue(self)
Definition: psClasses.py:223
def __setattr__(self, name, value)
Definition: psClasses.py:160
def releaseAllLocks(self)
Definition: psClasses.py:48
def __str__(self, topDown=False)
Definition: psClasses.py:172
def __init__(self, servers=[], cores=4, jay=2)
Definition: psClasses.py:203
def smallestQueue(self)
Definition: psClasses.py:213
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def __setitem__(self, index, value)
Definition: psClasses.py:118
def append(self, value)
Definition: psClasses.py:126
def __init__(self, libname="", module="", submodule="", depends=None, areDependent=None, weight=1, srvqueue=None)
Definition: psClasses.py:145
def putInServerQueue(self)
Definition: psClasses.py:20
def append(self, item)
Definition: psClasses.py:189
#define str(s)
def __init__(self, parent, queue, weight=1)
Definition: psClasses.py:12
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run