![]() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Figure 20: Steps in scheduling instance foo. ![]() |
Before the scheduler approaches the collection (step 2 in Figure 20) it must know Foo's specific needs: computing time, any dependency graphs, special requirements, etc. If it is class-specific, the scheduler may explicitly know this information, or it can obtain descriptive information from the class via the attributes interface.
With this information, it asks the collection for a list of the correct and available resources (Figure 21, step 1). Individual resources may limit outside usage to certain types of users, objects, hosts, etc., so the collection has information regarding which resources will accept instances of ClassFoo, on its particular host, started by a particular user. If the scheduler requests a SPARC, for example, the collection searches for a list of those SPARCs that are accessible, available, and have the proper amount of free space.
Figure 21: Collection and scheduler. ![]() |
The collection returns a list of matching resources to the scheduler (step 2). The scheduler builds a set of possible schedules (step 3), prioritizes them, and sends an ordered list of schedules off to the enactor. This can vary, of course, depending on the individual scheduler. A different scheduler might send only one or several possible schedules.
When the enactor is ready to request reservations of time and space on the resources on a chosen schedule it methodically goes down its list and approaches each one individually. If any resource refuses the enactor's request, the enactor either starts on the next one or, if all the schedules on its list have failed, informs the scheduler that it needs a new schedule. In the scenario in Figure 20, host object Beta and vault object Beta are the only resources required, so the enactor approaches each one with the make_reservation() function (this function asks for an instant reservation). It requests reservation for the host and the vault separately. Host object Beta then decides whether or not to accept the reservation. Note that Beta is free to refuse the reservation at any point during the entire scheduling procedure if previous reservations or internal considerations require a cancellation, regardless of its usual policies towards the user and the user's host. If it refuses, the enactor tells the scheduler that the schedule is not possible, and requests another schedule, or, if the scheduler has sent a list of schedules, the enactor moves down to the next schedule. If this happens after other hosts objects on the failed schedule have been contacted and have agreed to make reservations, the enactor contacts them again to release its reservations. The prototype enactor allows schedule expression as a difference set from the previous schedule. Figure 22 shows the scheduler data structure.
This system is intended to avoid "reservation thrashing," i.e., repetitive reservations when an enactor releases a reservation and immediately re-reserves the resource as part of a new schedule.
Figure 22: Legion scheduler data structure. ![]() |
In our example, however, host object Beta allows a reservation and sends the enactor a reservation token. The enactor then contacts vault object Beta. Once all resources on a schedule have been contacted and have sent in reservation tokens, the enactor notifies the scheduler that the task can be completed (Figure 23, step 1).
Figure 23: Legion resource management. ![]() |
The scheduler then tells the enactor to contact ClassFoo (step 2). The enactor sends a call to create_instance(reserved host object name, reservation token) to ClassFoo (step 3), which in turn sends a start_object(reservation token) call to host object Beta (step 4) and the name of the vault Beta should use. Beta then creates instance Foo (step 5).
Both ClassFoo and the resource have veto power throughout the reservation process: Legion's resource management system handles denial or failure at any stage. For example, if a resource object refuses to grant a reservation the enactor asks the scheduler for another schedule and tries again. A reserved resource can also reject a start_object() call. The two parties remain autonomous during this entire procedure and are not obligated to honor each other's commitments.
Depending on the individual resource, a reservation may have a time-out period after which the reservation is released. The reservation guarantees that a block of time and space will remain open for a specific period, beginning with the creation of the token. Note that the token may expire by the time ClassFoo is ready to use it.
A system may have multiple schedulers, for different processes, problems, levels of granularity, etc. For information on writing your own scheduler, or using multiple schedulers, please contact the Legion group.
The scheduler can be called directly from a user-level program or it can be called from a Class Object. Writers of schedulers should support the following interface. For complete information, consult $LEGION/src/ServiceObjects/Schedulers. Scheduler writers are encouraged to derive new schedulers off of the existing schedulers, and to overload the placement generation methods.
virtual LRef<LegionSchedulerResponse> scheduleObjects(
LRef<LegionRequestToScheduler>);
virtual LRef<LPSetLL<InstancePlacementInfo>> getCandidatePlacements(
LRef<LegionObjectClassInfoBlock>);
virtual LRef<LegionLOID> getEnactor();
virtual LRef<LegionLOID> setEnactor(
LRef<LegionLOID>);
virtual LRef<LegionLOID> getCollection();
virtual LRef<LegionLOID> setCollection(
LRef<LegionLOID>);
The primary interface to the enactor is through the enact_schedule() call. There are additional functions for performing lower-level operations (such as making and canceling individual reservations, or to activate or create individual objects), but, from the point-of-view of a typical scheduler, enact_schedule() is the most important method.
LRef<LegionScheduleRequestArray> enact_schedule(
LRef<LegionScheduleRequestArray>);
As soon as a schedule is successful (i.e. reservations are obtained for all placements in the schedule), the schedule is returned to the caller with a success code. If all schedules fail, the return value includes error codes indicating which placements caused each schedule to fail.
For complete information on the data structures passed, schedule writers are encouraged to examine the header file $LEGION/include/legion/ LegionSchedule.h and to look at the source code for the example schedulers in $LEGION/src/ServiceObjects/Schedulers.
The collection supports five methods useful for resource management, although only one of them is used by schedulers. The QueryCollection() method call passes in a string containing a logical expression describing the systems of interest.
The collection then searches its database of system information and returns a set of system description matching that request.
int QueryCollection(
LegionPackableString Query,
LRef<LegionCollectionData> result);
The Legion collection object uses the MESSIAHS Interface Language (MIL) [7]. Collection queries can be constructed using the interface below.
| —> | <bool-expression> | |
| —> | true | TRUE | True | | |
| —> | <comparison-expr> | |
| —> | <expr> == <expr> | |
| —> | <expr> <= <expr> | |
| —> | <expr> >= <expr> | |
| —> | <expr> < <expr> | |
| —> | <expr> > <expr> | |
| —> | <expr> <> <expr> | |
| —> | <expr> != <expr> | |
| —> | <expr> or <expr> | |
| —> | <expr> xor <expr> | |
| —> | <expr> and <expr> | |
| —> | not <expr> | |
| —> | match (<string>, <string>) | |
| —> | <comparison-expr> | |
| —> | <int-const> | |
| —> | <oct-const> | |
| —> | <float-const> | |
| —> | <string> | |
| —> | $<identifier> | |
| —> | - <expr> | |
| —> | ~ <expr> | |
| —> | <expr> + <expr> | |
| —> | <expr> - <expr> | |
| —> | max (<expr>, <expr>) | |
| —> | min (<expr>, <expr>) | |
| —> | <expr> / <expr> | |
| —> | <expr> * <expr> | |
| —> | <expr> mod <expr> | |
| —> | int (<expr>) | |
| —> | float (<expr>) | |
| —> | (<expr>) | |
| —> | __any valid integer constant__ | |
| —> | 0[0-7]* | |
| —> | __any valid float constant__ | |
| —> | ".*" | |
| —> | [a-zA-Z]+ | |
In MIL, variables are of the form $VARNAME (e.g. $system_arch). The official variable names will be those exported by resource objects in their attributes. To get some idea of the current set of attributes, consult the documentation on resource objects (for the most up-to-date information, invoke the retrieve_all_attributes() method on a resource object and examine the results).
1. ClassFoo can also have an associated external scheduler so that a user could call the class and the class would then call its scheduler.back
[Home] [General] [Documentation] [Software] [Testbeds] [Et Cetera] [Map/Search]
|
legion@Virginia.edu
http://legion.virginia.edu/