[haizea-commit] r596 - in branches/TP2.0/src/haizea/core: . scheduler scheduler/preparation_schedulers

haizea-commit at mailman.cs.uchicago.edu haizea-commit at mailman.cs.uchicago.edu
Fri Jul 3 03:47:05 CDT 2009


Author: borja
Date: 2009-07-03 03:46:59 -0500 (Fri, 03 Jul 2009)
New Revision: 596

Modified:
   branches/TP2.0/src/haizea/core/manager.py
   branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py
   branches/TP2.0/src/haizea/core/scheduler/mapper.py
   branches/TP2.0/src/haizea/core/scheduler/policy.py
   branches/TP2.0/src/haizea/core/scheduler/preparation_schedulers/unmanaged.py
   branches/TP2.0/src/haizea/core/scheduler/resourcepool.py
   branches/TP2.0/src/haizea/core/scheduler/slottable.py
   branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py
Log:
Very basic advance reservations (without preemptions) are working in TP2.0. Lots of other stuff is still broken.

Modified: branches/TP2.0/src/haizea/core/manager.py
===================================================================
--- branches/TP2.0/src/haizea/core/manager.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/manager.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -44,7 +44,7 @@
 from haizea.core.scheduler.lease_scheduler import LeaseScheduler
 from haizea.core.scheduler.vm_scheduler import VMScheduler
 from haizea.core.scheduler.slottable import SlotTable
-from haizea.core.scheduler.policy import Policy
+from haizea.core.scheduler.policy import SimplePolicy
 from haizea.core.scheduler.resourcepool import ResourcePool, ResourcePoolWithReusableImages
 from haizea.core.leases import Lease
 from haizea.core.rpcserver import RPCServer
@@ -144,6 +144,9 @@
         slottable = SlotTable()
         for n in resourcepool.get_nodes() + resourcepool.get_aux_nodes():
             slottable.add_node(n)
+
+        # Policy engine
+        self.policy = SimplePolicy(slottable)
         
         # Preparation scheduler
         if preparation_type == constants.PREPARATION_UNMANAGED:
@@ -157,9 +160,6 @@
         # Lease Scheduler
         self.scheduler = LeaseScheduler(vm_scheduler, preparation_scheduler, slottable)
         
-        # Policy engine
-        #self.policy = Policy()
-        
         # Lease request frontends
         if clock == constants.CLOCK_SIMULATED:
             # In pure simulation, we can only use the tracefile frontend
@@ -656,16 +656,7 @@
             
         if nextprematureend != None:
             newtime = min(nextprematureend, newtime)
-            
-        if nextchangepoint == newtime:
-            # Note that, above, we just "peeked" the next changepoint in the slottable.
-            # If it turns out we're skipping to that point in time, then we need to
-            # "get" it (this is because changepoints in the slottable are cached to
-            # minimize access to the slottable. This optimization turned out to
-            # be more trouble than it's worth and will probably be removed sometime
-            # soon.
-            newtime = self.manager.scheduler.slottable.getNextChangePoint(newtime)
-            
+                        
         # If there's no more leases in the system, and no more pending requests,
         # then we're done.
         if not self.manager.exists_leases_in_rm() and not tracefrontend.exists_more_requests():

Modified: branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -481,18 +481,18 @@
         
         # Deployment RRs (if any)
         for rr in preparation_rrs:
-            self.slottable.addReservation(rr)
+            self.slottable.add_reservation(rr)
         
         # Pre-VM RRs (if any)
         for rr in vmrr.pre_rrs:
-            self.slottable.addReservation(rr)
+            self.slottable.add_reservation(rr)
             
         # VM
-        self.slottable.addReservation(vmrr)
+        self.slottable.add_reservation(vmrr)
         
         # Post-VM RRs (if any)
         for rr in vmrr.post_rrs:
-            self.slottable.addReservation(rr)
+            self.slottable.add_reservation(rr)
           
         if lease_state == Lease.STATE_PENDING or lease_state == Lease.STATE_QUEUED:
             lease.set_state(Lease.STATE_SCHEDULED)
@@ -626,7 +626,7 @@
         Arguments:
         rr -- Reservation that ended
         """
-        self.slottable.removeReservation(rr)
+        self.slottable.remove_reservation(rr)
         
 
     def _handle_end_lease(self, l):
@@ -641,7 +641,7 @@
         self.preparation_scheduler.cleanup(l)
         self.completed_leases.add(l)
         self.leases.remove(l)
-        if isinstance(l, BestEffortLease):
+        if l.get_type() == Lease.BEST_EFFORT:
             get_accounting().incr_counter(constants.COUNTER_BESTEFFORTCOMPLETED, l.id)
         
 

Modified: branches/TP2.0/src/haizea/core/scheduler/mapper.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/mapper.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/scheduler/mapper.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -45,9 +45,6 @@
         vnodes.reverse()
         leases = aw.get_leases_until(end)
         mapping = {}
-        print "pnodes:", pnodes
-        print "vnodes:", vnodes
-        print "leases:", [l.id for l in leases]
         leases = self.policy.sort_leases(lease, leases)
         preemptable_leases = leases
         preempting = []
@@ -93,7 +90,7 @@
                 preempting.append(preemptable_leases.pop())
             
         if len(mapping) != len(requested_resources):
-            return None
+            return None, None, None
         else:
             return mapping, maxend, preempting
         

Modified: branches/TP2.0/src/haizea/core/scheduler/policy.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/policy.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/scheduler/policy.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -40,3 +40,16 @@
 
 #    def get_host_score(self, node):
 #        abstract()
+
+class SimplePolicy(Policy):
+    def __init__(self, slottable):
+        Policy.__init__(self, slottable)
+    
+    def get_lease_preemptability_score(self, preemptor, preemptee):
+        if preemptor.get_type() == Lease.ADVANCE_RESERVATION and preemptee.get_type() == Lease.BEST_EFFORT:
+            return 1
+        else:
+            return -1
+        
+    def accept_lease(self, lease):
+        return True  

Modified: branches/TP2.0/src/haizea/core/scheduler/preparation_schedulers/unmanaged.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/preparation_schedulers/unmanaged.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/scheduler/preparation_schedulers/unmanaged.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -28,7 +28,7 @@
     # Add dummy disk images
     def schedule(self, lease, vmrr, nexttime):
         for (vnode, pnode) in vmrr.nodes.items():
-            self.resourcepool.add_diskimage(pnode, lease.diskimage_id, lease.diskimage_size, lease.id, vnode)
+            self.resourcepool.add_diskimage(pnode, "foobar", 100, lease.id, vnode)
         return [], True
     
     def find_earliest_starting_times(self, lease, nexttime):

Modified: branches/TP2.0/src/haizea/core/scheduler/resourcepool.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/resourcepool.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/scheduler/resourcepool.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -42,9 +42,9 @@
                 
         for (vnode, pnode) in rr.nodes.items():
             node = self.get_node(pnode)
-            diskimage = node.get_diskimage(lease.id, vnode, lease.diskimage_id)
+            #diskimage = node.get_diskimage(lease.id, vnode, lease.diskimage_id)
             start_action.vnodes[vnode].pnode = node.enactment_info
-            start_action.vnodes[vnode].diskimage = diskimage.filename
+            #start_action.vnodes[vnode].diskimage = diskimage.filename
             start_action.vnodes[vnode].resources = rr.resources_in_pnode[pnode]
 
         try:

Modified: branches/TP2.0/src/haizea/core/scheduler/slottable.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/slottable.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/scheduler/slottable.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -224,7 +224,6 @@
     def __init__(self):
         self.logger = logging.getLogger("SLOT")
         self.nodes = NodeList()
-        self.reservations = []
         self.reservations_by_start = []
         self.reservations_by_end = []
         self.__dirty()
@@ -441,6 +440,28 @@
          
         return self.awcache
 
+    def sanity_check(self):
+        # Get checkpoints
+        changepoints = set()
+        for rr in [x.value for x in self.reservations_by_start]:
+            changepoints.add(rr.start)
+            changepoints.add(rr.end)
+        changepoints = list(changepoints)
+        changepoints.sort()
+        
+        offending_node = None
+        offending_cp = None
+        offending_capacity = None
+        
+        for cp in changepoints:
+            avail = self.get_availability(cp)
+            for node in avail:
+                for resource in avail[node].capacity._res:
+                    if resource < 0:
+                        return False, node, cp, avail[node].capacity
+                
+        return True, None, None, None
+
     # ONLY for simulation
     def get_next_premature_end(self, after):
         from haizea.core.scheduler.vm_scheduler import VMResourceReservation
@@ -475,6 +496,7 @@
         allnodes = set([i+1 for i in range(len(self.nodes.nodelist))])   
         nodes = {} 
         reservations = self.get_reservations_at(time)
+
         # Find how much resources are available on each node
         for r in reservations:
             for node in r.resources_in_pnode:

Modified: branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py	2009-07-02 17:49:43 UTC (rev 595)
+++ branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py	2009-07-03 08:46:59 UTC (rev 596)
@@ -17,10 +17,11 @@
 # -------------------------------------------------------------------------- #
 
 import haizea.common.constants as constants
-from haizea.common.utils import round_datetime_delta, round_datetime, estimate_transfer_time, pretty_nodemap, get_config, get_clock
+from haizea.common.utils import round_datetime_delta, round_datetime, estimate_transfer_time, pretty_nodemap, get_config, get_clock, get_policy
 from haizea.core.leases import Lease
 from haizea.core.scheduler.slottable import ResourceReservation, ResourceTuple
 from haizea.core.scheduler import ReservationEventHandler, RescheduleLeaseException, NormalEndLeaseException, EnactmentError, NotSchedulableException, InconsistentScheduleError, InconsistentLeaseStateError
+from haizea.core.scheduler.mapper import GreedyMapper
 from operator import attrgetter, itemgetter
 from mx.DateTime import TimeDelta
 
@@ -37,6 +38,7 @@
     def __init__(self, slottable, resourcepool):
         self.slottable = slottable
         self.resourcepool = resourcepool
+        self.mapper = GreedyMapper(self.slottable, get_policy())
         self.logger = logging.getLogger("VMSCHED")
         
         self.handlers = {}
@@ -78,145 +80,40 @@
         self.numbesteffortres = 0
 
     def schedule(self, lease, nexttime, earliest):
-        if isinstance(lease, BestEffortLease):
-            (vmrr, preemptions) = self.vm_scheduler.fit_asap(lease, nexttime, earliest)
-        elif isinstance(lease, ARLease):
-            (vmrr, preemptions) = self.vm_scheduler.fit_exact(lease, preemptible=False, canpreempt=True)
-        elif isinstance(lease, ImmediateLease):
-            (vmrr, preemptions) = self.vm_scheduler.fit_asap(lease, nexttime, earliest, allow_reservation_in_future=False)
+        if lease.get_type() == Lease.BEST_EFFORT:
+            return self.__schedule_asap(lease, nexttime, earliest)
+        elif lease.get_type() == Lease.ADVANCE_RESERVATION:
+            return self.__schedule_exact(lease, nexttime, earliest)
+        elif lease.get_type() == Lease.IMMEDIATE:
+            return self.__schedule_asap(lease, nexttime, earliest)
 
-    def fit(self, requested_resources, start, end, strictend):
-        lease_id = leasereq.id
-        start = leasereq.start.requested
-        end = leasereq.start.requested + leasereq.duration.requested + self.__estimate_shutdown_time(leasereq)
-        diskImageID = leasereq.diskimage_id
-        numnodes = leasereq.numnodes
-        resreq = leasereq.requested_resources
-
-        availabilitywindow = self.slottable.availabilitywindow
-
-        availabilitywindow.initWindow(start, resreq, canpreempt=canpreempt)
-        availabilitywindow.printContents(withpreemption = False)
-        availabilitywindow.printContents(withpreemption = True)
-
-        mustpreempt = False
-        unfeasiblewithoutpreemption = False
+    def __schedule_exact(self, lease, nexttime, earliest):
+        start = lease.start.requested
+        end = start + lease.duration.requested
+        mapping, actualend, preemptions = self.mapper.map(lease, 
+                                                          lease.requested_resources,
+                                                          start, 
+                                                          end, 
+                                                          strictend = True)
+        if mapping == None:
+            raise NotSchedulableException, "Not enough resources in specified interval"
         
-        fitatstart = availabilitywindow.fitAtStart(canpreempt = False)
-        if fitatstart < numnodes:
-            if not canpreempt:
-                raise NotSchedulableException, "Not enough resources in specified interval"
-            else:
-                unfeasiblewithoutpreemption = True
-        feasibleend, canfitnopreempt = availabilitywindow.findPhysNodesForVMs(numnodes, end, strictend=True, canpreempt = False)
-        fitatend = sum([n for n in canfitnopreempt.values()])
-        if fitatend < numnodes:
-            if not canpreempt:
-                raise NotSchedulableException, "Not enough resources in specified interval"
-            else:
-                unfeasiblewithoutpreemption = True
-
-        canfitpreempt = None
-        if canpreempt:
-            fitatstart = availabilitywindow.fitAtStart(canpreempt = True)
-            if fitatstart < numnodes:
-                raise NotSchedulableException, "Not enough resources in specified interval"
-            feasibleendpreempt, canfitpreempt = availabilitywindow.findPhysNodesForVMs(numnodes, end, strictend=True, canpreempt = True)
-            fitatend = sum([n for n in canfitpreempt.values()])
-            if fitatend < numnodes:
-                raise NotSchedulableException, "Not enough resources in specified interval"
-            else:
-                if unfeasiblewithoutpreemption:
-                    mustpreempt = True
-                else:
-                    mustpreempt = False
-
-        # At this point we know if the lease is feasible, and if
-        # will require preemption.
-        if not mustpreempt:
-            self.logger.debug("The VM reservations for this lease are feasible without preemption.")
-        else:
-            self.logger.debug("The VM reservations for this lease are feasible but will require preemption.")
-
-        # merge canfitnopreempt and canfitpreempt
-        canfit = {}
-        for node in canfitnopreempt:
-            vnodes = canfitnopreempt[node]
-            canfit[node] = [vnodes, vnodes]
-        for node in canfitpreempt:
-            vnodes = canfitpreempt[node]
-            if canfit.has_key(node):
-                canfit[node][1] = vnodes
-            else:
-                canfit[node] = [0, vnodes]
-
-        orderednodes = self.__choose_nodes(canfit, start, canpreempt, avoidpreempt)
-            
-        self.logger.debug("Node ordering: %s" % orderednodes)
-        
-        # vnode -> pnode
-        nodeassignment = {}
-        
-        # pnode -> resourcetuple
+        # Create VM resource reservations
         res = {}
         
-        # physnode -> how many vnodes
-        preemptions = {}
+        for (vnode,pnode) in mapping.items():
+            vnode_res = lease.requested_resources[vnode]
+            if res.has_key(pnode):
+                res[pnode].incr(vnode_res)
+            else:
+                res[pnode] = ResourceTuple.copy(vnode_res)
         
-        vnode = 1
-        if avoidpreempt:
-            # First pass, without preemption
-            for physnode in orderednodes:
-                canfitinnode = canfit[physnode][0]
-                for i in range(1, canfitinnode+1):
-                    nodeassignment[vnode] = physnode
-                    if res.has_key(physnode):
-                        res[physnode].incr(resreq)
-                    else:
-                        res[physnode] = ResourceTuple.copy(resreq)
-                    canfit[physnode][0] -= 1
-                    canfit[physnode][1] -= 1
-                    vnode += 1
-                    if vnode > numnodes:
-                        break
-                if vnode > numnodes:
-                    break
-            
-        # Second pass, with preemption
-        if mustpreempt or not avoidpreempt:
-            for physnode in orderednodes:
-                canfitinnode = canfit[physnode][1]
-                for i in range(1, canfitinnode+1):
-                    nodeassignment[vnode] = physnode
-                    if res.has_key(physnode):
-                        res[physnode].incr(resreq)
-                    else:
-                        res[physnode] = ResourceTuple.copy(resreq)
-                    canfit[physnode][1] -= 1
-                    vnode += 1
-                    # Check if this will actually result in a preemption
-                    if canfit[physnode][0] == 0:
-                        if preemptions.has_key(physnode):
-                            preemptions[physnode].incr(resreq)
-                        else:
-                            preemptions[physnode] = ResourceTuple.copy(resreq)
-                    else:
-                        canfit[physnode][0] -= 1
-                    if vnode > numnodes:
-                        break
-                if vnode > numnodes:
-                    break
-
-        if vnode <= numnodes:
-            raise InconsistentScheduleError, "Availability window indicated that request is feasible, but could not fit it"
-
-        # Create VM resource reservations
-        vmrr = VMResourceReservation(leasereq, start, end, nodeassignment, res, False)
+        vmrr = VMResourceReservation(lease, start, end, mapping, res, False)
         vmrr.state = ResourceReservation.STATE_SCHEDULED
 
         self.__schedule_shutdown(vmrr)
         
-        preemptions = self.__find_preemptable_leases(preemptions, vmrr.start, vmrr.end)
+       
 
         return vmrr, preemptions
 
@@ -971,9 +868,8 @@
         l.duration.accumulate_duration(diff)
         rr.state = ResourceReservation.STATE_DONE
        
-        if isinstance(l, BestEffortLease):
-            if rr.backfill_reservation == True:
-                self.numbesteffortres -= 1
+        if rr.backfill_reservation == True:
+            self.numbesteffortres -= 1
                 
         self.logger.vdebug("LEASE-%i After:" % l.id)
         l.print_contents()



More information about the Haizea-commit mailing list