1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
|
[See also IZ615]
Complex Attribute Specification
Stephan Grell
September 16, 2003
0. Introduction:
----------------
The purpose of this document is to describe how the attributes in the
new SGE V6.0 system. The behavior to the previous one has changed in some
aspects. It also describes how the attributes can be used and which work
packages are still pending. Therefor this document is under construction
itself and will be changed while the work packages are implemented.
Acknowledgements
I gratefully acknowledge useful conversations and input in other
forms with Andre Alefeld, Ernst Bablick, Andreas Dorr, Fritz Ferstl,
Andreas Haas, Christian Reissmann, and Andy Schwierskott.
1. Attributes:
--------------
- We have the possibility to specify attributes on global level, host level,
and queue level.
- The values for an attribute can be fixed or changeable.
- The values can be a load value, custom defined or a resource limit.
- Resource limits exist only on queue level
- Load values only on global or host level
- The type of an attribute can be: string, host, cstring, int,double,
boolean, memory, and time.
- A consumable can have a default value, thus the user can, but does not
have to specify the attribute.
- An attribute can be requestable, has to be requested, or cannot be
requested at all.
- An attribute can be build-in or a user defined.
- Most load values and all of the resource limits are build in.
- A user can define consumables, load values, or fixed values.
- An attribute has one of many relational operations: ==, !=, >=, =<, >,<
- An attribute can be a per job attribute or per slot attribute:
- all load values and consumables are per job attributes except string,
cstring, host values. They are per slot attributes.
- all resource limits and user defined fixed values are per slot
attributes.
- An attribute can only be a job attribute or a slot attribute, but not
both.
The user can change every aspect of an attribute at any time. The current
definition of an attribute looks like:
- name
- Short cut
- Type
- Consumable
- Relational operator
- Requestable
- default value
Using per slot attributes:
--------------------------
All fixed values in the system are per slot attributes. This means, that
a parallel job existing of 4 parallel tasks (needing 4 slots to run)
requires the attribute for each task.
Example E1:
one job j1 requests t01 = 10 with 4 slots
queue q1 has 5 slots and t01 is set to <=20
j1 does fit on q1 since it has enough slots and t01 allows to run
jobs with t01 requests between 0 and 20.
The configuration of q1 after j1 has started is slots = 1 and
t01 <= 20.
Using per job attributes:
-------------------------
All changeable values in the system are per job attributes like the
"slots" attribute in E1. This means, that a parallel job requests a
resource n times (n is the number of slots it will use).
Example E2:
one job j2 requests t02 = 20 with 4 slots
queue q2 offers 5 slots with t02 <= 40
queue q3 offers 1 slot with t02 <= 40
queue q4 offers 3 slots with t02 <= 40
The system will start two instances of the job on q2, one on q3 and
one on q4
The configuration of the queues afterwards looks like:
q2 offers 3 slots with t02 <= 0 (q2.t02 - 2*j2.t02)
q1 offers 0 slots with t02 <= 20 (q2.t02 - 1*j2.t02)
q3 offers 2 slots with t02 <= 20(q2.t02 - 1*j2.t02)
This example shows how consumables are handled. With load values is
will take some time, before they are updated, depending on the
load_value_report interval.
It is possible to override attributes on a lower level or on the same
level. More about it later.
The fact, that all consumables are per job attributes posses a problem,
when one wants to do licence managing with parallel jobs. Therefor it
would be nice to have it configurable if a consumable is a per job
attribute or per slot attribute.
Wor kpackage:
=> Decide, what is the right way of doing it
=> Adding a flag which can be set by a user, if an attribute is a per
slot or perjob attribute.
2. Restrictions:
----------------
Not all of the above described combinations make sense. Till now, there are
no restrictions on how an attribute is defined, but the code working on them
has the restrictions already build in. Therefore it will aid the user in
configuring SGE when the system allows only valid specifications:
name : has to be unique
Short cu : has to be unique
Type : every type from the list (string, host, cstring, int, double,
boolean, memory, time, restring)
Consumable : can only be defined for: int, double, memory, time
If a consumable is not requestable, it has to have a default
value.
If a consumable is forced, it must not have a default value.
Relational operator:
- for consumables: only <=
- for non consumables:
- string, host, cstring: only ==, !=
- boolean: only ==
- int, double, memory, time: ==, !=, <=, <, =>, >
Requestable : for all attribute
default value : only for consumables
The qmon interface should only provied valid options. The choice of the
type limites the choice of operators and if it can be a consumable or not.
Haveing a consumable also limites the relational operators to one. This
makes it easier and more convieniend for the user to add new attributes.
Default values can only be added, when it makes sense (for consumables).
Build in values:
----------------
Besides the overall attribute restrictions, we have one additional one for
the system build-in attributes. One can not change the type of a build in
attribute. The system relies on the type and will not function anymore, if
one changes the type. A build-in value can also not be deleted.
The only exception are the strings. A string can be changed into a cstring
or restring and back.
3. Overriding attributes:
-------------------------
In general an attribute can be overridden on a lower level
- global by hosts and queues
- hosts by queues
and load values or resource limits on the same level. Overriding a per slot
attribute with a per slot attribute and a per job attribute with an per slot
attribute is no problem. Based on the specification does a per job attribute
never be override with a per slot attribute. But a per job attribute can be
overridden with a per slot attribute. In this case the per slot attribute
changes into a per job attribute. This happens, when a load value is
overridden with a fixed value.
We have one limitation for overriding attributes based on its relational
operator:
- !=, == operators can only be overridden on the same level, but not on a
lower level
- >=, >, <=, < operators can only be overridden, when the new value is more
restrictive than the old one.
Examples:
1. We have a load value arch on host level. One can override it in the host
definition with another value, but not in a queue.
2. We have a load value mem_free with a relop <= on host level. One can
override it on host or queue level with a value, which is smaller than
the reported one.
mem_free: custom / load report / result:
1 GB / 4 GB / 1 GB
1 GB / 0.9 GB / 0.9 GB
The reason why we have the override limitation is buried in the algorithm
how we match the job requests with available resources. The algorithm is
strict hierarchical, which means, if it finds a attribute on one level,
which does not match, the other levels are not further evaluated. It starts
with the global host and ends with a queue. When a attribute is missing on
one level it will go one with the next levels. But an existing attribute,
which does not match results in an abort.
4. Internal representation:
---------------------------
One could say, that we have three different lists. which are used to match
the requests with the existing resources. These are:
- the job request list (hart and soft)
- the attribute configuration list
- and the elements (of a list), which are generated for matching and output
purposes. It is generated from the first two lists. All list entries share
the same CULL list structure, which is never fully used.
request list / configuration list / match list
Name X / X / X
Shortcut --- / X / ---
type --- / X / X
val (as doulbe) --- / --- / X
val (as string) X / --- / X
relop --- / X / X
consumable --- / X / X
default --- / X / ---
dominant --- / --- / X
pj val (as double) --- / --- / X
pj val (as string) --- / --- / X
pj dominant --- / --- / X
requestable --- / --- / X
tagged X / --- / ---
Splitting this one CULL definition into multiple ones will reduce the amount
of used memory, the time for copying the lists ,and enhance the readability
within the source code.
Though the new structures will look like:
RL_type:
- RL_name - name or shortcut
- RL_stringval - requested value
- RL_tagged - matched a existing resource
(saving 11 elements)
CL_type:
- CE_name - name
- CE_shortcut - short name
- CE_type - type (int, string, ....)
- CE_relop - relational operator (==, !=, ...)
- CE_consumable - boolean flag
- CE_default - default value, only consumables
(saving 8 elements)
CM_type:
- CE_name - requested name (name or shortcut)
- CE_valtype - type
- CE_doubleval - fixed value
- CE_stringval - fixed value as string
- CE_relop - relational operator
- CE_consumable - is consumable?
- CE_dominant - from which level , of which type (fixed, ...)
- CE_pj_stringval - changeable value
- CE_pj_doubleval - changeable value as string
- CE_pj_dominant - from which level , of which type (load, ...)
- CE_requestable - is it requestable
(saving 3 elements)
Work package:
=> Phase 1: changing the request matching structure (CM_type)
=> Phase 2: changing the job request structure (CL_type)
=> Phase 3: changing the attribute configuration structure (RL_type)
5. Scheduler attribute matching:
--------------------------------
As written before, the matching of attribute requests by a job a matched in
in a strict hierarchy. When a match fails, the underlying levels are not
evaluated any further. Right now, this is done for every job, even so the
jobs might be in the same job category, which means, that they have the same
requests.
To speed up this process, one can store the information, which queue cannot
run which job category. When this is known, the jobs are only tested against
the queues, which were capable of running the jobs from the previous
dispatch cycle. List of queues to test will get shorter and shorter, while
jobs are dispatched.
The same is true for soft requests. Once all queues are validated and the
number of mismatches are computed, they are the same for all other jobs in
the same job category. This saves a lot of matching time with the soft
requests.
String matching:
----------------
The string matching has some specialties. A string can have one of three
different types:
- plain string
- caseless string
- regular expression string
1. Plain strings (STRING):
Matches only, when the requested and the provided string are exactly
the same.
2. Caseless strings (CSTRING):
The upper- and lowercase of the characters in a string is ignored.
3. Regular expression string (RESTRING):
The user can use a regular expression to ask for a resource. The
syntax follows the following rules:
- "*" : matches any character and any number of chars (between 0
and inv).
- "?" : matches any character. It cannot be no character
- "." : is the character ".". It has no other meaning
- "\" : escape character. "\\" = "\", "\*" = "*", "\?" = "?"
- "[xx]": specifies an array or a range of allowed characters
- "|" : logical "or". Can only be used on the highest level and
cannot be escaped.
Not supported:
- "x+" : to specify, that the character "x" has to appear at least
once
- "[xx|yy]" : to specify xx or yy
Examples:
-l arch="linux|solaris" : results in "arch=linux" OR
"arch=solaris"
-l arch="[linux|solaris]" : results in "arch=[linux" OR
"arch=solaris]"
Result caching:
---------------
When ever resource matching is done with jobs, which have pre-calculated
job categories, the matching results will be stored in the job categories.
This can be done because all jobs in the same category have the same requests,
the same user, the same department,...
What is cached depends on the job kind (if it is a job with only hard requests,
or if its one with hard, soft, pe and other requests)
Jobs with only hard requests:
All queues and hosts on which the job cannot run are stored in the job
category. This information is used to limit the possible target queues.
other jobs:
All unfitting queues and the soft violation results are stored in the job
category. This means, that the soft violations are only computed once and
reused for all other jobs in the same category. The queue information
limits the possible target queues.
|