CMS 3D CMS Logo

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