basl2c(1B)
π basl2c(1B) π
okay so first thing, bestie: this page is basl2c(1B) from the PBS manual, section 1B. Buckle up, it's a whole journey and we're gonna get through it together π«Ά
β¨ NAME β¨
basl2c β converts a BASL (Batch Atch Scheduling Language) code into a C scheduler code. literally its whole job. that's the girlboss move π
πΈ SYNOPSIS πΈ
basl2c [-d] [-l lexerDebugFile] [-p parserDebugFile] [-y
symtabDebugFile] [-s semanticDebugFile] [-g codegenDebugFile] [-c cFile]
baslFile
π DESCRIPTION π
So basl2c is the BASL-to-C compiler, and what she does is produce an intermediate code β like, code that isn't the final form yet β which you then feed into a regular C compiler and link with the PBS libraries so you get your scheduler executable. no cap, that's the pipeline π¦
She takes as input a baslFile, which is a program written in the BAtch Scheduling Language, and that file contains the main scheduling code. Then basl2c converts all the BASL constructs in the file into C statements, and she also attaches additional code so you end up with the PBS scheduler source code. iconic. By default, the resulting C code gets written into the file pbs_sched.c.
The full pathname to that resulting C file is exactly what you need to specify in the SCHD_CODE variable in local.mk before compiling the BASL scheduler to produce the pbs_sched executable. don't skip that step, she'll be mad π
π₯ OPTIONS π₯
-dβ prints additional debugging messages to the lexer (peep the-loption), the parser (peep-p), the symbol table (peep-y), the semantic analyzer (peep-s), and the code generator (peep-g). the all-in-one debug slay β-llexerDebugFile β lexerDebugFile is the name of a file to write the debugging messages into, the ones generated while scanning for tokens. token hunt era π-pparserDebugFile β parserDebugFile is the name of a file to write the debugging messages into, the ones generated while putting together tokens in a usable way. assembling the fit β¨-ysymtabDebugFile β symtabDebugFile is the name of a file to write the debugging messages related to the symbol table into. π-ssemanticDebugFile β semanticDebugFile is the name of a file to write the debugging messages into, the ones generated while checking to make sure variables and operators are used in a consistent way. she's doing a vibe check on ur types π-gcodegenDebugFile β codegenDebugFile is the name of a file to write the debugging messages into, the ones generated while converting BASL statements to C statements. the glow-up from BASL to C, documented live π₯-ccFile β cFile is the name of a file where the generated C code gets written into. ur output, ur choice π
π MAIN STRUCTURE π
The basic structure of a scheduler code written in BASL is, and I'm quoting the anatomy here:
zero or more FUNCTIONS definitions
zero or more global VARIABLE DECLARATIONS
zero or more assignment statements (to initialize global variables)
sched_main()
{
one or more VARIABLE DECLARATIONS
zero or more STATEMENTS
}
For example:
% cat sched.basl
Int sum(Int a, Int b)
{
Int s;
s = a + b;
return(s);
}
Int glob;
sched_main()
{
Int c;
a = 3;
b = 4;
c = sum(a, b);
print(c);
glob = 5;
print(glob);
}
And the main character herself: sched_main() is the function that gets called at every scheduling iteration. every single one. she never rests π
π§ FUNCTIONS π§
To define a function that can be called in subsequent functions, the syntax is:
ReturnType function-name ( DATATYPE1 IDENTIFIER1,
DATATYPE2 IDENTIFIER2, ... )
{
one or more VARIABLE DECLARATIONS
zero or more STATEMENTS
}
For example:
Void printStuff(Dayofweek dow, DateTime t, String str,
Size sz, CNode cn)
{
print(dow);
print(t);
print(str);
print(sz);
print(cn);
}
Valid function ReturnType are: Void, Int, Float, Dayofweek, DateTime, String, Size, Server, Que, Job, CNode, Set Server, Set Que, Set Job, Set CNode.
Valid data types ( DATATYPE1, DATATYPE2, ... ) for the parameter identifiers are: Int, Float, Dayofweek, DateTime, String, Size, Server, Que, Job, CNode, Set Server, Set Que, Set Job, Set CNode, Range Int, Range Float, Range Dayofweek, Range DateTime, Range Size, Fun Int, Fun Float, Fun Void, Fun Dayofweek, Fun DateTime, Fun String, Fun Size, Fun Server, Fun Que, Fun Job, Fun CNode, Fun Set Server, Fun Set Que, Fun Set Job, Fun Set CNode. These data types will be discussed in the next topic, so hold that thought bestie π«Ά
Functions are invoked by their name and their arguments, as in:
printStuff( MON, (5|1|1997@14:32:00), "sched begins",
30gb, node );
Now here's the sneaky little detail: basl2c will actually add a "basl_" prefix to the function name given by the scheduler writer, to minimize the chance of a name collision β which can happen when the resulting C code gets linked with the PBS, BASL libraries. so if you look at the generated C code for printStuff, you would see:
basl_printStuff( MON, (5|1|1997@14:32:00),
"sched begins", 30gb, node );
As in C, all function calls must have been previously defined. The BASL compiler will check to make sure that arguments in the function call match up exactly (in terms of types) with the parameters in the function definition. no sloppy matches, she will notice π
Two kinds of functions exist in BASL: user-defined functions and predefined functions. User-defined functions are those that the scheduler writer provided a definition for, while predefined functions are those that can immediately be called without a need for defining it. For a list of predefined functions, see section on PREDEFINED FUNCTIONS (coming up later, stay tuned π).
π VARIABLE DECLARATIONS π
Like in C, all variables in a BASL code must be explicitly declared before use. no vibes-based variable creation, sorry π
Those variables declared outside of any function are referred to as global variables, while variables that are declared within a function body are called local variables. Global variables are usable anywhere within the BASL code, while local variables are readable only within the function from which they were declared. local means local bestie.
The syntax of a variable declaration is:
DATATYPE IDENTIFIER ;
where DATATYPE can be: Int, Float, Dayofweek, DateTime, String, Size, Server, Que, Job, CNode, Set Server, Set Que, Set Job, Set CNode, Range Int, Range Float, Range Dayofweek, Range DateTime, Range Size.
𧬠DATA TYPE π§¬
Void
used for functions that don't return a value. the "i have nothing to give" queen β¨
Int
signed, whole numbers given in base 10.
Sample constants: 5, +1, -3, SUCCESS (=1), FAIL (=0), TRUE (=1), FALSE (=0)
Float
real numbers which are represented as doubles in the translated C code.
Sample constants: 4.3, +1.2, -2.6
Dayofweek
constant values: SUN, MON, TUE, WED, THU, FRI, SAT, internally represented as integer valued constants with SUN=0, MON=1, and so on. yes, she's an enum at heart π
DateTime
specify it in one of 3 formats:
(m|d|y)where1 <= m <= 12,1 <= d <= 31,0 <= y, ex.(4|4|1997);(hh:mm:ss)where0 <= hh <= 23,0 <= mm <= 59,0 <= ss <= 61, ex.(12:01:00);(m|d|y@hh:mm:ss), ex.(4|4|1997@12:01:00)
During dates/times comparison, "now" time is substituted if the time portion is not given (format [1]); the "now" date is substituted if the date portion is not given (format [2]). Also, the full year portion must be given (i.e. 1997 instead of 97) in dates to avoid ambiguity. don't be cryptic with ur years fr fr πΈ
String
A string is enclosed in quotes (") and it can contain anything except another quote, a newline, and left and right parentheses.
Sample constants: "a sample string", NULLSTR
Size
format: <integer><suffix> where suffix is a multiplier of the form: <multiplier><unit>:
multiplier unit (bytes or words)
=================== =====================
k,m,g,t,p,K,M,G,T,P b,B,w,W
where k=K=1024, m=M=1,048,576, g=G=1,073,741,824, t=T=1,099,511,627,776, p=P=1,125,899,906,842,624, b=B=1, and word size w=W is locally defined (i.e. 4 bytes in a 32-bit machine).
When operating on 2 size operands that are of different suffixes, the suffix of the "lower" of the two will be the resultant suffix. For example,
10mb + 10gb = 10250mb
Sample constants: -1b, 2w, 1kb, 2mw, +3gb, 4tw, 6Pb
Range Int
format: (low Int value, high Int value) where low Int value <= high Int value.
Sample constant: (1,3)
Range Float
format: (low Float value, high Float value) where low value <= high value.
Sample constant: (2.3, 4.6)
Range Dayofweek
format: (earlier day, later day) where earlier day <= later day.
Sample constant: (WED, FRI)
Range DateTime
format: (earlier date/time, later date/time) where earlier date/time <= later date/time.
NOTE: if range contains only time portions, and earlier time"appears"to be > later time as in"((18:0:0), (6:0:0))", then during date/time comparisons, the"later"time will be adjusted by one day so that it will look like:"( (<now date>@18:0:0), (<tomorrow date>@6:0:0) )"(she does the math for you, lowkey generous π).
Sample constants: ((4|4|1997), (4|10|1997)), ((12:01:00), (12:30:00)), ((4|4|1997@12:01:00), (4|10|1997@12:30:00))
Range Size
format: (low size, high size) where low size <= high size.
Sample constants: (23gb, 50gb)
Server
Maps directly to the PBS server object. A Server manages one or more Que objects.
Sample constant: NOSERVER
CNode
for computational node consisting of a single OS image, a shared memory, and a set of cpus. CNode runs 1 PBS MOM.
Sample constant: NOCNODE
Que
Maps directly to the PBS queue object. A Que object spools one or more Job objects.
Sample constant: NOQUE
Job
Maps directly to the PBS job object. A Job object carries some attributes and resource requirements.
Sample constant: NOJOB
Set Server
list of Server objects.
Sample constant: EMPTYSETSERVER
Set CNode
list of CNode objects.
Sample constant: EMPTYSETCNODE
Set Que
list of Que objects.
Sample constant: EMPTYSETQUE
Set Job
list of Job objects.
Sample constant: EMPTYSETJOB
πΈ BASL-DEFINED CONSTANTS πΈ
Okay so these are the constants that are not allowed to be identifier names (we'll get to identifiers next, bestie). They're always in uppercase. Periodt.
- Dayofweek β
SUN,MON,TUE,WED,THU,FRI,SAT - Int β
SUCCESS,FAIL,FALSE,TRUE,SYNCRUN,ASYNCRUN,DELETE,RERUN,HOLD,RELEASE,SIGNAL,MODIFYATTR,MODIFYRES,SERVER_ACTIVE,SERVER_IDLE,SERVER_SCHED,SERVER_TERM,SERVER_TERMDELAY,QTYPE_E,QTYPE_R,SCHED_DISABLED,SCHED_ENABLED,TRANSIT,QUEUED,HELD,WAITING,RUNNING,EXITING,CNODE_OFFLINE,CNODE_DOWN,CNODE_FREE,CNODE_RESERVE,CNODE_INUSE_EXCLUSIVE,CNODE_INUSE_SHARED,CNODE_TIMESHARED,CNODE_CLUSTER,CNODE_UNKNOWN,OP_EQ,OP_NEQ,OP_LE,OP_LT,OP_GE,OP_GT,OP_MAX,OP_MIN,ASC,DESC - Server β
NOSERVER - Set Server β
EMPTYSETSERVER - CNode β
NOCNODE - Set CNode β
EMPTYSETCNODE - Que β
NOQUE - Set Que β
EMPTYSETQUE - Job β
NOJOB - Set Job β
EMPTYSETJOB - String β
NULLSTR
π¦ IDENTIFIER π¦
Identifiers are what you use for variable names and function names. They're in alphanumeric format, and the special underscore (_) character is allowed. Currently, BASL can only handle identifiers with a length of up to 80 chars. Also, you cannot use the BASL-defined constant names when naming an identifier β that's a hard no, bestie.
β¨ STATEMENTS β¨
In BASL(2), you can have a single statement terminated by a semi-colon, or a group of statements (called a compound statement or block) delimited by { and }. The different kinds of statements that can appear in a BASL code are:
- expression statement β Expression statements are anything of the form:
expr ;
where expr can be:
a) Arithmetic expressions
lexpr + rexpr (add)
lexpr - rexpr (subtract)
lexpr * rexpr (multiply)
lexpr / rexpr (divide)
lexpr % rexpr (modulus or remainder)
NOTE: Adding, subtracting, multiplying, dividing, and remaindering will only be allowed for proper types and if the left and right expressions are of consistent types. The table below illustrates what types are consistent among the various operators:
For +:
lexpr rexpr
============ ============
Int or Float Int or Float
Size Size
String String
For -, *, /:
lexpr rexpr
============ ============
Int or Float Int or Float
Size Size
For %:
lexpr rexpr
============ ============
Int or Float Int or Float
Here are some sample arithmetic expression statements:
Int i1;
Int i2;
Float f1;
Float f2;
Size sz1;
Size sz2;
String str1;
String str2;
i1 + i2;
f1 - i2;
sz1 * sz2 * 2b;
sz1 / 1024b;
str1 = "basl";
str2 = " cool";
// the following is a string concatenation
// operation resulting in the string:
// "basl cool"
str1 + str2;
i1 % 10;
b) Unary expressions
+expr // positive - multiplies by 1 an
// expression that is
// of Int, Float, or
// Size type
-expr // negative - multiplies by -1 an
// expression that is
// of Int, Float, or
// Size type
!expr // not - converts a non-zero expr
// value into 0, and a
// zero expr value into 1
// where expr type must be
// of type Int or Float
Some sample unary expressions:
Int i;
+3;
-(i + 4);
!i;
c) Logical expressions
lexpr EQ rexpr
lexpr NEQ rexpr
lexpr LT rexpr
lexpr LE rexpr
lexpr GT rexpr
lexpr GE rexpr
lexpr AND rexpr
lexpr OR rexpr
lexpr and rexpr must have types that are mutually consistent as shown in the following table:
lterminal-expr rterminal-expr
============== ==============
Int or Float Int or Float
Dayofweek Dayofweek
DateTime DateTime
String String
Size Size
Server Server
Que Que
Job Job
CNode CNode
Set Server Set Server
Set Que Set Que
Set Job Set Job
Set CNode Set CNode
For AND, OR operators, the lexpr, rexpr consistent types are Int or Float.
Some sample logical expressions:
i1 EQ i2;
i1 NEQ f2;
dow1 LE dow2;
d1 LT d2;
str1 GT str2;
sz1 GE sz2;
d) Post-operator expressions
These are expressions that are merely shortcuts to assignment statements.
IDENTIFIER++; // identifier=identifier+1
IDENTIFIER--; // identifier=identifier-1
IDENTIFIER must be of Int or Float type.
Example:
Int i;
Float f;
i++;
f--;
e) Function call
function-name ( arg1 ,arg2 ... , argN )
where arg1, ..., argN can be any constant or variable. You can't have another function call as an argument.
Example:
Void pr(Int a) {
print(a);
}
pr(5);
There are certain predefined functions that a scheduler writer can automatically call in his/her BASL code without a need to define it. These functions are referred to as assist functions (or helper functions) and they are discussed under the PREDEFINED FUNCTIONS topic. π
f) Constants π
okay so constants are just⦠values you can write literally in your code, no big mystery. here are some valid constant expressions, copy-pasted with love:
5;
+1.2;
SUN;
MON;
TUE;
WED;
THU;
FRI;
SAT;
(4|4|1997);
(12:01:00);
(4|4|1997@12:01:00);
"wonderful";
-1b;
SYNCRUN;
ASYNCRUN;
DELETE;
RERUN;
HOLD;
RELEASE;
SIGNAL;
MODIFYATTR;
MODIFYRES;
(1, 3);
(2.3, 4.6);
(WED, FRI);
((4|4|1997), (4|10|1997));
((12:01:00), (12:30:00));
((4|4|1997@12:01:00), (4|10|1997@12:30:00));
(23gb, 50gb);
NOSERVER;
NOCNODE;
NOQUE;
NOJOB;
EMPTYSETSERVER;
EMPTYSETCNODE;
EMPTYSETQUE;
EMPTYSETJOB;
NULLSTR;
SUCCESS;
FAIL;
SERVER_ACTIVE;
SERVER_IDLE;
SERVER_SCHED;
SERVER_TERM;
SERVER_TERMDELAY;
QTYPE_E;
QTYPE_R;
SCHED_DISABLED;
SCHED_ENABLED;
FALSE;
TRUE;
TRANSIT;
QUEUED;
HELD;
WAITING;
RUNNING;
EXITING;
CNODE_OFFLINE;
CNODE_DOWN;
CNODE_FREE;
CNODE_RESERVE;
CNODE_INUSE_EXCLUSIVE;
CNODE_INUSE_SHARED;
CNODE_TIMESHARED;
CNODE_CLUSTER;
CNODE_UNKNOWN;
OP_EQ;
OP_NEQ;
OP_LE;
OP_LT;
OP_GE;
OP_GT;
OP_MAX;
OP_MIN;
like, that's the whole vibe check of literals π
g) Identifier πββοΈ
a plain identifier is just a name, bestie. example:
Int i;
i;
2. Assignment statement βοΈ
the format is literally:
IDENTIFIER = expr ;
and the tea is: IDENTIFIER and expr have to have types that are mutually consistent. here's the whole compatibility grid, no cap:
IntβInt,FloatFloatβInt,FloatDayofweekβDayofweekDateTimeβDateTimeStringβStringSizeβSizeQueβQueJobβJobCNodeβCNodeServerβServerDayofweekβDayofweekDateTimeβDateTimeSet ServerβSet ServerSet QueβSet QueSet JobβSet JobSet CNodeβSet CNodeRange IntβRange IntRange FloatβRange FloatRange DayofweekβRange DayofweekRange DateTimeβRange DateTimeRange SizeβRange Size
(yeah Dayofweek and DateTime show up twice in the original list β iconic of them honestly, we're keeping it fr fr π«Ά)
3. if...else statement π₯Ί
the format of an if statement is similar to C, except the delimiting { and } are always present. no sneaky one-liners, bestie.
if( expr ) {
zero or more (true) STATEMENTS
}
if( expr ) {
zero or more (true) STATEMENTS
} else {
zero or more (false) STATEMENTS
}
expr's type has to be either Int or Float, and after evaluation, if its value is non-zero β the true statements run. in the second form, if expr evaluates to zero β the false statements run. simple as π
some sample if statements for u:
if (2 * x )
{
y = y + 3;
print(y);
}
if (2 * x ) {
y = y + 3;
} else {
if( 3 * x ) {
y = 4;
} else {
y = 5;
}
}
nested else-ifs, we love to see it πβ¨
4. for loop statement π
the format of a for statement is:
for( start; test; action ) {
zero or more STATEMENTS
}
just like in C: for first executes start, then evaluates the test condition to see if it returns a non-zero value. if it does, the for statements are executed. after the for statements are executed, action is evaluated, and then it checks the test condition again, same manner as before. start and action can be a simple assignment expression or a post-operator expression. test is a logical/relational expression. samples, coming right up:
for (i = 0; i LT 3 ; i = i + 1)
{
print(i);
}
for (i = 0; i LT 2 * x; i++)
{
if (x GT 3)
{
y = 99;
} else
{
x = 73;
}
}
(that indentation on the inner { is straight from the original, don't come for me π)
5. foreach loop statement π¦
this one is primarily used for successively retrieving each element of a Set data type: Set Server, Set CNode, Set Job, Set Que. the syntax:
foreach ( IDENTIFIER1 in IDENTIFIER2 ) {
zero or more STATEMENTS
}
where the following pairing of types for the identifiers are allowed:
ServerinSet ServerQueinSet QueJobinSet JobCNodeinSet CNode
example β and yes it's the full set, slay:
Server s;
Que q;
Job j;
CNode c;
Set Server ss;
Set Que sq;
Set Job sj;
Set CNode sc;
foreach(s in ss){
print(s);
}
foreach(q in sq){
print(q);
}
foreach(j in sj){
print(j);
}
foreach(c in sc){
print(c);
}
look at that symmetry. main character energy π
6. while loop statement β³
syntax of a while loop:
while ( expr ) {
zero or more STATEMENTS
}
where expr must be of Int or Float type. if expr is non-zero, then the zero or more STATEMENTS are executed and expr is re-evaluated. that's the whole loop, bestie.
example:
Int i;
i = 3;
while(i) {
if( i EQ 0 ) {
print("break on i = 1");
break;
}
i--;
}
note that EQ β that's how we compare around here, == could never π
7. switch statement ποΈ
the switch statement is a multi-way decision that tests whether an identifier's value matches one of a number of values, and branches to a group of statements accordingly. (the original says "mult-way", keeping the typo energy, we don't gatekeep π)
the syntax for a switch statement is:
so bestie, the shape of a switch is literally this:
switch( IDENTIFIER ) {
case constant-expr :
{
zero or more STATEMENTS
}
case constant-expr :
{
zero or more STATEMENTS
}
...
case in constant-rangeOrSet-expr :
{
zero or more STATEMENTS
}
case in IDENTIFIER-rangeOrSettype :
{
zero or more STATEMENTS
}
default :
{
zero or more STATEMENTS
}
}
okay so where constant-expr is an expr of type Int, Float, Dayofweek, DateTime, Size, String, Server, Que, Job, or CNode. π And constant-rangeOrSet-expr and IDENTIFIER-rangeOrSettype can be of type Set Server, Set CNode, Set Que, Set Job, Range Int, Range Float, Range Dayofweek, Range DateTime, or Range Size.
IDENTIFIER cannot be of type Void. Nope, not allowed, don't even try it. π And IDENTIFIER's type must be consistent with constant-expr's, constant-rangeOrSet-expr's, and IDENTIFIER-rangeOrSettype's type, as illustrated in the following table β which I'm serving to you as a lil list because tables are so 2019:
ServerβSet ServerQueβSet QueJobβSet JobCNodeβSet CNodeIntβRange IntFloatβRange FloatDayofweekβRange DayofweekDateTimeβRange DateTimeSizeβRange Size
If a case expression matches the IDENTIFIER's value, then the corresponding block of statements are executed. And unlike in C, execution does NOT fall through to the next case statement. π The reason for this is that basl2c will translate this switch statement into an if-elseif-else construct. The case labeled default is executed if none of the other cases are satisfied. The default is optional; if it isn't there, and if none of the cases match, no action takes place. β¨
Example time, bestie, look at this beauty:
Dayofweek dow;
switch(dow)
{
case MON:
{
print("case MON");
}
case TUE:
{
print("case TUE");
}
case WED:
{
print("case WED");
}
case THU:
{
print("case THU");
}
case FRI:
{
print("case FRI");
}
case SAT:
{
print("case SAT");
}
case SUN:
{
print("case SUN");
}
default:
{
print("case defaulted");
}
}
Int a;
Range Int ri;
ri = (10, 12);
switch(a)
{
case in (1,5):
{
print("case 1,5");
}
case in (6,9):
{
print("case 6,9");
}
case in ri:
{
print("case ri");
}
}
π¨οΈ 8. print statement
okay the print statement is capable of printing to stdout the value of any identifier or constant of type Int, Float, Dayofweek, DateTime, String, Size, Que, Job, CNode, Server, Range Int, Range Float, Range Dayofweek, Range DateTime, Range Size. Like, it ate and left no crumbs. π
The syntax is as follows:
print ( IDENTIFIER );
print ( constant );
Example:
DateTime dt;
CNode cn;
dt = (4|4|1997@12:13:36);
cn = AllNodesLocalHostGet();
print(dt);
print(cn);
For Set types, use foreach to go through each element and print, as in:
Server s;
Set Server ss;
ss = AllServersGet();
foreach(s in ss) {
print(s);
}
π 9. continue statement
continue ;
The continue statement must have been invoked within a for, foreach, and while loop. It causes the next iteration of the enclosing loop to begin. Basically "skip to the next one, I'm done here" energy. π
π 10. break statement
break ;
The break statement must have been invoked within a for, foreach, and while loop. It provides an early exit from the enclosing loop. Main character move: just leave. πͺβ¨
π 11. return statement
return(IDENTIFIER) ;
return(constant) ;
return() ;
The return statement provides the value (if any) to be returned by a function. The type returned by IDENTIFIER and constant must match the calling function's return type. constant types allowed are anything except Set and Range types. No cap on that one β Set and Range are simply not invited to the return party. The last format, return(), is usually called within a function that doesn't return any value (like sched_main() ). π«Ά
πͺ 12. exit statement
exit(constant);
where constant is of type Int. Calling this will terminate the scheduler. Like, actually terminate it. Not a vibe check, the whole scheduler. π
π¬ 13. Comment statement
These are statements prefixed by // and they are ignored by the BASL compiler. Ghosted by the compiler, fr fr.
// this line is ignored
Int i; // string following the slashes is ignored
βοΈ OPERATOR PRECEDENCE AND ASSOCIATIVITY β¨
The following table shows the various operator precedence levels and associativity defined in the BASL language. The operators are listed in the order of decreasing precedence. The higher the precedence of an operator, the earlier it gets executed. The order in which the operators on the same level are executed depends on the associativity: left means the operators are seen from left to right, while right means they are seen from right to left. π§
So, highest priority first, bestie:
!++--+(unary plus)-(unary minus) β associativity: right*/%β associativity: left+-β associativity: leftLTLEGTGEβ associativity: leftEQNEQβ associativity: leftANDβ associativity: leftORβ associativity: left=β associativity: right
π§ PREDEFINED FUNCTIONS π
In BASL(2), a Server data type maps directly to a batch server object. Similarly, CNode is to mom/resmom, Job is to batch job, and Que is to batch queue. However, not all attributes to the PBS objects can be accessed from BASL. Only a subset of attributes, those that seemed to make sense in the context of a scheduler, are made available, and values to these attributes can be accessed by calling the following predefined functions, known also as assist/helper functions. π οΈβ¨
(1) π₯οΈ Server-related functions
Set Server AllServersGet(void)β Returns the list of servers specified in the configuration file for which the scheduler writer wants the system to periodically check for status, queues and jobs info. Seepbs__sched__basl(8B)for a discussion on the format of the configuration file.
CAUTION: This function must be called from insidesched_main()so that at every scheduling iteration, the most up to dateSet Serverstructure is returned. Do not be out here calling it from random places, bestie. π
Server AllServersLocalHostGet(void)β Returns theServerobject that represents the local host. unset value:NOSERVER. This is a simple function to call for non-cluster environments where only one server host exists. πΈ
CAUTION: This function must be called from insidesched_main()(or from within function called bysched_main) so that at every scheduling iteration, the most up to dateServerstructure is returned.
String ServerInetAddrGet(Server s)β Returns name forServers. unset value:NULLSTR. π
String ServerDefQueGet(Server s)
Hands you the default_queue attribute of Server s. If nobody set it? Unset value is NULLSTR. π«Ά
Int ServerStateGet(Server s)
Returns the server_state attribute of Server s.
Return value:
SERVER_ACTIVESERVER_IDLESERVER_SCHEDSERVER_TERMSERVER_TERMDELAY-1(the unset value β sad times π)
Int ServerMaxRunJobsGet(Server s)
Returns the max_running attribute of Server s. Unset value: 0.
Int ServerMaxRunJobsPerUserGet(Server s)
Returns the max_user_run attribute of Server s. Unset value: 0.
Int ServerMaxRunJobsPerGroupGet(Server s)
Returns the max_group_run attribute of Server s. Unset value: 0.
Set Que ServerQueuesGet(Server s)
Returns the list of queues managed by Server s. π
Set Job ServerJobsGet(Server s)
Returns the list of jobs managed by Server s. Wanting just a subset of this list? Peep QueJobsGet(), bestie.
Int ServerIntResAvailGet(Server s, String name)
Returns the value for the resource named in name that's available to jobs run by this server (that's the Server resources_available.name attribute). Call this one for resources whose values are of Int type. Sample resource names are: cput, pcput, walltime, mppt, pmppt, nice, procs, mppe, ncpus, pncpus, nodect, srfs_assist, mta,..., mth. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
Int cpuAvail;
// return the # of cpus currently available in
// the server
cpuAvail = ServerIntResAvailGet(server, "ncpus");
Size ServerSizeResAvailGet(Server s, String name)
Returns the value for the resource named in name that's available to jobs run by this server (the Server resources_available.name attribute). This is the one you call for resources with values of Size type. Sample resource names are: file, mem, pmem, workingset, pf, ppf, srfs_tmp, srfs_wrk, srfs_big, srfs_fast, sds, psds. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
Size memAvail;
// return the amount of available memory in
// the server
memAvail = ServerSizeResAvailGet(server, "mem");
String ServerStringResAvailGet(Server s, String name)
Returns the value for the resource named in name that's available to jobs run by this server (yep, the Server resources_available.name attribute again). Call this one for resources with values of String type. Sample resource names are: nodes, arch, neednodes. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
String type;
// return the architecture (or os type) of
// the server
type = ServerStringResAvailGet(server, "arch");
Int ServerIntResAssignGet(Server s, String name)
Returns the value for the resource named in name that's allocated to running jobs (the Server resources_assigned.name attribute β notice: assigned, not available, ikyk). Call this for resources with values of Int type. Sample resource names are: cput, pcput, walltime, mppt, pmppt, nice, procs, mppe, ncpus, pncpus, nodect, srfs_assist, mta,..., mth. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
Int cpuAssn;
// return the # of cpus currently assigned in
// the server
cpuAssn = ServerIntResAssignGet(server, "ncpus");
Size ServerSizeResAssignGet(Server s, String name)
Returns the value for the resource named in name that's allocated to running jobs (Server resources_assigned.name attribute). Call this one for resources with values of Size type. Sample resource names are: file, mem, pmem, workingset, pf, ppf, srfs_tmp, srfs_wrk, srfs_big, srfs_fast, sds, psds. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
Size sdsAssn;
// return the amount of sds space currently assigned
// in the server
sdsAssn = ServerSizeResAssignGet(server, "sds");
String ServerStringResAssignGet(Server s, String name)
Returns the value for the resource named in name that's allocated to running jobs (Server resources_assigned.name attribute). Call this one for resources with values of String type. Sample resource names are: nodes, arch, neednodes. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Set CNode ServerNodesGet(Server s)
Returns the set of nodes managed by server s. Unset value: EMPTYSETCNODE. π¦
NOTE: you can usually call the following functions on the nodes this returns:CNodeStateGet(),CNodePropertiesGet(), andCNodeTypeGet().
Int ServerNodesQuery(Server s, String spec)
Slides a request over to the server you named, asking it to query how available the resources in spec are. Right now the only resource specification allowed is one that involves "nodes", and it can be in the format "nodes", "nodes=", or "nodes=<type>". You get at the results by calling: ServerNodesNumAvailGet(), ServerNodesNumAllocGet(), ServerNodesNumRsvdGet(), ServerNodesNumDownGet().
NOTE: this is a wrapper to the pbs_rescquery(3B) server function.
Return value:
SUCCESSFAIL
Int ServerNodesNumAvailGet(Server s)
Returns how many nodes are available out of those managed by the server you named β or as reflected by the most recent query you did with ServerNodesQuery(). If it comes back 0, that means some number of nodes currently needed to satisfy the specification of ServerNodesQuery() are, rn, unavailable, and the request maybe gets satisfied at some later time. If the result is negative, then no combination of known nodes can satisfy the specification. π
Int ServerNodesNumAllocGet(Server s)
Returns how many nodes are allocated out of those managed by the server you named β or as reflected by the most recent query specified by ServerNodesQuery().
Int ServerNodesNumRsvdGet(Server s)
Returns how many nodes are reserved out of those managed by the server you named β or as reflected by the most recent query specified by ServerNodesQuery().
Int ServerNodesNumDownGet(Server s)
Returns how many nodes are down out of those managed by the server you named β or as reflected by the most recent query specified by ServerNodesQuery().
Int ServerNodesReserve(Server s,String spec,Int resId)
Sends a request to the server you named to reserve the resources specified in spec. A resId value of 0 means this is doing a brand-new reservation. Otherwise, that number represents an existing (partial) reservation. Whatever resources are currently reserved for this resId get released, and then the full reservation is attempted again. At the present time the only resources which may be specified are "nodes". It should be specified as nodes=specification where specification is what a user specifies in the -l option argument list for nodes, see qsub (1B).
NOTE: this is a wrapper to the pbs_rescreserve(3B) server function.
Return value:
- a reference number to a successful or partially-successful reservation
- or
FAILπ Int ServerNodesRelease(Server s, Int resId)β this frees/releases the resources that got reserved under the reference number you hand it inresId. reservation cancelled, it's giving closure π«Ά- NOTE: it's just a wrapper around the
pbs_rescrelease(3B)server function, so the actual heavy lifting is over there, iykyk. - Return value:
SUCCESS, orFAIL.
- NOTE: it's just a wrapper around the
(2) Que-related functions π
String QueNameGet( Que que )β gives you the name ofQue que. unset value:NULLSTRInt QueTypeGet( Que que )β gives you thequeue_typeattribute ofQue que.- Return value:
QTYPE_E(Execution),QTYPE_R(Routing),-1(unset value)
- Return value:
Int QueNumJobsGet( Que que )β gives you how many jobs are currently residing inQue que. unset value:0Int QueMaxRunJobsGet( Que que )β gives you themax_runningattribute ofQue que. unset value:0Int QueMaxRunJobsPerUserGet( Que que )β gives you themax_user_runattribute ofQue que. unset value:0Int QueMaxRunJobsPerGroupGet( Que que )β gives you themax_group_runattribute ofQue que. unset value:0Int QuePriorityGet( Que que )β gives you thePriorityattribute ofQue que. unset value:0Int QueStateGet( Que que )β gives you thestartedattribute ofQue que, aka the job execution selection state of the que:SCHED_DISABLED,SCHED_ENABLED. unset value:SCHED_DISABLED(default behaviour era fr)Set Job QueJobsGet( Que que )β gives you the list of jobs currently residing in the que. the whole roster, bestie πInt QueIntResAvailGet(Que q, String name)β gives you the value of the resource named innamethat's available to jobs running from thisq(the Queresources_available.nameattribute). Call this one for resources whose values are of Int type. Sample resource names:cput,pcput,walltime,mppt,pmppt,nice,procs,mppe,ncpus,pncpus,nodect,srfs_assist,mta,..., mth.- For the deets on what these resource names even mean, go read
pbs_resources_irix5(7B),pbs_resources_sp2(7B),pbs_resources_sunos4(7B),pbs_resources_unicos8(7B),pbs_server_attributes(7B),pbs_resources_irix6(7B),pbs_resources_linux(7B). β¨
- For the deets on what these resource names even mean, go read
Size QueSizeResAvailGet(Que q, String name)β gives you the value of the resource named innamethat's available to jobs running from thisq(the Queresources_available.nameattribute). Call this one for resources whose values are of Size type. Sample resource names:file,mem,pmem,workingset,pf,ppf,srfs_tmp,srfs_wrk,srfs_big,srfs_fast,sds,psds.- For the deets on these resource names, see
pbs_resources_irix5(7B),pbs_resources_sp2(7B),pbs_resources_sunos4(7B),pbs_resources_unicos8(7B),pbs_server_attributes(7B),pbs_resources_irix6(7B),pbs_resources_linux(7B). π¦
- For the deets on these resource names, see
String QueStringResAvailGet(Que q, String name)β gives you the value of the resource named innamethat's available to jobs running from thisq(the Queresources_available.nameattribute). Call this one for resources whose values are of String type. Sample resource names:nodes,arch,neednodes.- For the deets on these resource names, see
pbs_resources_irix5(7B),pbs_resources_sp2(7B),pbs_resources_sunos4(7B),pbs_resources_unicos8(7B),pbs_server_attributes(7B),pbs_resources_irix6(7B),pbs_resources_linux(7B). πΈ
- For the deets on these resource names, see
Int QueIntResAssignGet(Que q, String name)β gives you the value of the resource named innamethat's allocated to jobs running from this queue (the Queresources_assigned.nameattribute). Call this one for resources whose values are of Int type. Sample resource names:cput,pcput,walltime,mppt,pmppt,nice,procs,mppe,ncpus,pncpus,nodect,srfs_assist,mta,..., mth.- For the deets on these resource names, see
pbs_resources_irix5(7B),pbs_resources_sp2(7B),pbs_resources_sunos4(7B),pbs_resources_unicos8(7B),pbs_server_attributes(7B),pbs_resources_irix6(7B),pbs_resources_linux(7B). π
- For the deets on these resource names, see
Size QueSizeResAssignGet(Que q, String name)β gives you the value of the resource named innamethat's allocated to jobs running from thisq(the Queresources_assigned.nameattribute). Call this one for resources whose values are of Size type. Sample resource names:file,mem,pmem,workingset,pf,ppf,srfs_tmp,srfs_wrk,srfs_big,srfs_fast,sds,psds.- For the deets on these resource names, see
pbs_resources_irix5(7B),pbs_resources_sp2(7B),pbs_resources_sunos4(7B),pbs_resources_unicos8(7B),pbs_server_attributes(7B),pbs_resources_irix6(7B),pbs_resources_linux(7B). π§
- For the deets on these resource names, see
String QueStringResAssignGet(Que q, String name)β gives you the value of the resource named innamethat's allocated to jobs running from thisq(the Queresources_assigned.nameattribute). Call this one for resources whose values are of String type. Sample resource names:nodes,arch,neednodes.- For the deets on these resource names, see
pbs_resources_irix5(7B),pbs_resources_sp2(7B),pbs_resources_sunos4(7B),pbs_resources_unicos8(7B),pbs_server_attributes(7B),pbs_resources_irix6(7B),pbs_resources_linux(7B). β
- For the deets on these resource names, see
(3) Job-related functions π₯
String JobIdGet( Job job )β gives you the job identifier ofJob job. unset value:NULLSTRString JobNameGet( Job job )β gives you theJob_Nameattribute ofJob job. unset value:NULLSTRString JobOwnerNameGet( Job job )β gives you theJob_Ownerattribute ofJob job. unset value:NULLSTRString JobEffectiveUserNameGet( Job job)β gives you theeuserattribute ofJob job. who even ARE you, effective-user-wise πString JobEffectiveGroupNameGet(Job job)β gives you theegroupattribute ofJob job. unset value:NULLSTRInt JobStateGet ( Job job )β gives you thejob_stateattribute ofJob job.- Return value:
TRANSIT,QUEUED,HELD,WAITING,RUNNING,EXITING,-1(unset value)
- Return value:
Int JobPriorityGet( Job job )β gives you thePriorityattribute ofJob job. unset value:0Int JobRerunFlagGet( Job job )β gives you theRerunableattribute ofJob job.- Return value:
FALSE,TRUE,-1(unset value)
- Return value:
Int JobInteractiveFlagGet( Job job )β gives you theinteractiveattribute ofJob job.- Return value:
FALSE,TRUE. unset value:FALSE
- Return value:
DateTime JobDateTimeCreatedGet(Job job)β gives you thectimeattribute ofJob job. unset value:(0|0|0@-1:-1:-1)(yes that's really the unset value, no cap)String JobEmailAddrGet( Job job )β gives you theMail_Usersattribute ofJob job. unset value:NULLSTRπ§String JobStageinFilesGet( Job job )β gives you thestageinattribute ofJob job. unset value:NULLSTRString JobStageoutFilesGet( Job job )β gives you thestageoutattribute ofJob job. unset value:NULLSTRInt JobIntResReqGet(Job job, String name)β gives you the value of the resource named innameas required by the job (the JobResource_List.nameattribute). Call this one for resources whose values are of Int type. Sample resource names:cput,pcput,walltime,mppt,pmppt,nice,procs,mppe,ncpus,pncpus,nodect,srfs_assist,mta,..., mth.- For the deets on these resource names, see
pbs_resources_irix5(7B),pbs_resources_sp2(7B),pbs_resources_sunos4(7B),pbs_resources_unicos8(7B),pbs_server_attributes(7B),pbs_resources_irix6(7B),pbs_resources_linux(7B). π - Example:
- For the deets on these resource names, see
Int cputReq;
// returns the cput requirement of the job
cputReq = JobIntResReqGet(job, "cput");
πΈ Size JobSizeResReqGet(Job job, String name)
Gives you back the value of the resource named in name as required by the job β like, the Job Resource_List.name attribute, bestie. Call this one for resources whose values are of Size type. Sample resource names are: file, mem, pmem, workingset, pf, ppf, srfs_tmp, srfs_wrk, srfs_big, srfs_fast, sds, psds. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
Size memReq;
// returns the memory requirement of the job
memReq = JobSizeResReqGet(job, "mem");
β¨ String JobStringResReqGet(Job job, String name)
Same energy, but for String-type resources β returns the value of the resource named in name as required by the job (Job Resource_List.name attribute). Sample resource names are: nodes, arch, neednodes. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
String nodes;
// returns the nodes requirement property of
// the job
nodes = JobStringResReqGet(job, "nodes");
π
Int JobIntResUseGet(Job job, String name)
Returns the value of the resource named in name that's been used by the job (Job resources_used.name attribute). Call this one for resources with Int-type values. Sample resource names are: cput, pcput, walltime, mppt, pmppt, nice, procs, mppe, ncpus, pncpus, nodect, srfs_assist, mta,..., mth. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
Int walltUse;
// returns the amount of walltime used by
// the job
walltUse = JobIntResUseGet(job, "walltime");
π¦ Size JobSizeResUseGet(Job job, String name)
Same but for the Size girlies β returns the value of the resource named in name used by the job (Job resources_used.name attribute). Sample resource names are: file, mem, pmem, workingset, pf, ppf, srfs_tmp, srfs_wrk, srfs_big, srfs_fast, sds, psds. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
Example:
Size srfsUse;
// returns the amount of srfs_fast used by
// the job
srfsUse = JobSizeResUseGet(job, "srfs_fast");
π String JobStringResUseGet(Job job, String name)
And for the String besties β returns the value of the resource named in name used by the job (Job resources_used.name attribute). Sample resource names are: nodes, arch, neednodes. For a description of these resource names, see pbs_resources_irix5(7B), pbs_resources_sp2(7B), pbs_resources_sunos4(7B), pbs_resources_unicos8(7B), pbs_server_attributes(7B), pbs_resources_irix6(7B), pbs_resources_linux(7B).
π₯οΈ (4) CNode-related functions
Okay so now we're in node territory, and these are lowkey the main character functions of the whole scheduler situation. Let's get into it π
π Set CNode AllNodesGet(void)
Returns the list of nodes managed by the server running on the local host. This could also include those nodes that were specified in the scheduler configuration file for which the scheduler writer wants the system to periodically check for information like state, property, and so on. See pbs_sched_basl(8B) for a discussion of the configuration file format.
β οΈ CAUTION: This function must be called from insidesched_main()so that at every scheduling iteration, the most up to dateSet CNodestructure is returned. Do not call this from an assignment statement intended to initialize a global variable, because the statement will only be called once. π (fr fr, it'll bite you)
π CNode AllNodesLocalHostGet(void)
Returns the CNode object that represents the local host. This is a simple function to call for non-clustered systems where only 1 CNode exists. unset value: NOCNODE
β οΈ CAUTION: This function must be called from insidesched_main()(or from within functions called bysched_main) so that at every scheduling iteration, the most up to dateCNodestructure is returned. Do not call this from an assignment statement intended to initialize a global variable, as the statement will only be called once.
π·οΈ String CNodeNameGet(CNode node)
Returns the unique (official) name of the node (i.e. ResMom hostname in a 1 mom/node model). This returns the same string that was specified in the configuration file. unset value: NULLSTR
π§ String CNodeOsGet(CNode node)
Returns the os architecture of the node (i.e. "irix5", "sp2"). unset value: NULLSTR
π₯ Int CNodeStateGet( CNode node )
Returns the node's state.
Return value:
CNODE_OFFLINECNODE_DOWNCNODE_FREECNODE_RESERVECNODE_INUSE_EXCLUSIVECNODE_INUSE_SHAREDCNODE_UNKNOWN
π Int CNodeTypeGet( CNode node )
Returns the node's type.
Return value:
CNODE_TIMESHAREDCNODE_CLUSTERCNODE_UNKNOWN
π String CNodePropertiesGet(CNode node)
Returns the comma-separated list of other names the node is known by ( properties, other network name). For example, "babbage.OpenPBS.org" maybe the node name, but it could also be known via "babbage1, babbage2". unset value: NULLSTR
π String CNodeVendorGet(CNode node)
Returns the name of the vendor for the hardware of the machine (i.e. "sgi", "ibm"). unset value: NULLSTR
π§ Int CNodeNumCpusGet(CNode node)
Returns the number of processors attached to the node. unset value: -1
πΎ Size CNodeMemTotalGet( CNode node, String type )
Returns total memory of type for the node. type is an arbitrary string that the scheduler writer defines in the scheduler configuration file. unset value: -1b
Example:
// get total physical memory
CNodeMemTotalGet(node, "real")
// get total virtual memory
CNodeMemTotalGet(node, "virtual")
π Size CNodeMemAvailGet( CNode node, String type )
Returns available memory of type for the node. type is an arbitrary string that the scheduler writer defines in the scheduler configuration file. unset value: -1b
So sample calls will be:
// get available physical memory
CNodeMemAvailGet(node, "real")
// get available virtual memory
CNodeMemAvailGet(node, "virtual")
π΄ Int CNodeIdletimeGet( CNode node )
Returns number of seconds in which no keystroke or mouse movement has taken place on any terminal connected to the node. unset value: -1
π Float CNodeLoadAveGet( CNode node )
Returns node's load average for all cpus. unset value: -1.0
π§ Int CNodeCpuPercentIdleGet( CNode node )
Returns the percent of idle time that all the processors of the node have experienced.
βοΈ Int CNodeCpuPercentSysGet( CNode node )
Returns the percent of time that all the processors of the node have spent running kernel code.
π» Int CNodeCpuPercentUserGet( CNode node )
Returns the percent of time that all the processors of the node have spent running user code.
Int CNodeCpuPercentGuestGet( CNode node )β tells you the percent of time that, like, all the processors on the node have spent running a guest operating system. yes bestie, the whole node. every core. πInt CNodeNetworkBwGet( CNode node, String type )β hands you the bandwidth of the node's network of typetype, in bytes/second. and what even istype? it's defined by the scheduler writer in the scheduler configuration file, so it's giving "ask the person who wrote your config" energy. unset value:-1.
Some sample calls are:
CNodeNetworkBwGet( node, "hippi" );
CNodeNetworkBwGet( node, "fddi" );
Size CNodeDiskSpaceTotalGet(CNode node, String name)β returns the node's total space on disk identified byname, wherenameis the device name arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. π
Example:
CNodeDiskSpaceTotalGet( node, "/scratch2" );
Size CNodeDiskSpaceAvailGet(CNode node, String name)β the node's available space on disk identified byname, andnameis arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. β¨
Example:
CNodeDiskSpaceAvailGet( node, "/scratch1" );
Size CNodeDiskSpaceReservedGet(CNode node, String name)β the node's reserved space on disk (user quota?? like, the manpage literally asks) identified byname, wherenameis arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. π«Ά
Example:
CNodeDiskSpaceReservedGet( node, "/scratch1" );
Int CNodeDiskInBwGet( CNode node, String name )β returns the write bandwidth (bytes/sec) of the node's disk identified byname. unset value:-1. π₯
Example:
CNodeDiskInBwGet( node, "/fast" );
Int CNodeDiskOutBwGet( CNode node, String name )β returns the read bandwidth (bytes/sec) of the node's disk identified byname. unset value:-1. yep,Inis write andOutis read, that's just the lore, we don't question it π
Example:
CNodeDiskOutBwGet( node, "/big" );
Size CNodeSwapSpaceTotalGet( CNode node, String name )β the node's total space on swap identified byname, wherenameis arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. πΈ
Example:
CNodeSwapSpaceTotalGet( node, "primary" );
Size CNodeSwapSpaceAvailGet( CNode node, String name )β the node's available space on swap identified byname, wherenameis the device name arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. π¦
Example:
CNodeSwapSpaceAvailGet( node, "secondary" );
Int CNodeSwapInBwGet( CNode node, String name )β returns the swapin rate of the node's swap device identified byname. (no unset value listed for this one, that's just how it is, don't @ me)
Example:
CNodeSwapInBwGet(node, "secondary");
Int CNodeSwapOutBwGet( CNode node, String name )β returns the swapout rate of the node's swap device identified byname. unset value:-1. π
Example:
CNodeSwapOutBwGet(node, "primary");
Size CNodeTapeSpaceTotalGet( CNode node, String name )β the node's total space on tape identified byname, wherenameis arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. yes we're doing tapes, it's retro-chic π
Example:
CNodeTapeSpaceTotalGet(node, "4mm");
Size CNodeTapeSpaceAvailGet( CNode node, String name )β the node's available space on tape identified byname, wherenameis arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. π§
Example:
CNodeTapeSpaceAvailGet(node, "8mm");
Int CNodeTapeInBwGet( CNode node, String name )β the write bandwidth (bytes/sec) of the node's tape identified byname. unset value:-1. π₯
Example:
CNodeTapeInBwGet( node, "4mm" );
Int CNodeTapeOutBwGet( CNode node, String name )β the read bandwidth (bytes/sec) of the node's tape identified byname. unset value:-1. π
Example:
CNodeTapeOutBwGet( node, "8mm" );
Size CNodeSrfsSpaceTotalGet( CNode node, String name )β the node's total space on srfs device identified byname, wherenameis arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. β
Example:
CNodeSrfsSpaceTotalGet(node, "/fast");
Size CNodeSrfsSpaceAvailGet( CNode node, String name )β the node's available space on srfs device identified byname, wherenameis arbitrarily defined by the scheduler writer in some configuration file (yes, some, iconic vagueness). unset value:-1b. π«
Example:
CNodeSrfsSpaceAvailGet( node, "/big" );
Size CNodeSrfsSpaceReservedGet(CNode node, String name)β the node's total amount of reserved space on srfs device identified byname, wherenameis arbitrarily defined by the scheduler writer in the scheduler configuration file. unset value:-1b. π
Example:
CNodeSrfsSpaceReservedGet( node, "/fast" );
Int CNodeSrfsInBwGet( CNode node, String name )β the write bandwidth (bytes/sec) of the node's srfs device identified byname. unset value:-1. π
Example:
CNodeSrfsInBwGet( node, "/fast" );
Int CNodeSrfsOutBwGet( CNode node, String name )β the read bandwidth (bytes/sec) of the node's srfs device identified byname. unset value:-1. π
Example:
CNodeSrfsOutBwGet( node, "/big" );
π (5) Miscellaneous Functions π
DateTime datetimeGet()β gets the current date/time. that's it. that's the function. main character of doing exactly one thing β¨Int datetimeToSecs(DateTime dt)β returns the # of seconds since epoch (beginning of UNIX time -00:00:00, January 1, 1970) for the given date/timedt. classic "how many seconds since 1970" moment, we love a timestamp π°οΈInt JobAction( Job job, Int action, String param )β performsactiononjobwith aparamspecified depending on the action. lowkey this is the boss function of this whole section ngl π
action can be: SYNCRUN, ASYNCRUN, DELETE, RERUN, HOLD, RELEASE, SIGNAL, MODIFYATTR, MODIFYRES β where:
SYNCRUNβ runs the job synchronously, meaning the call toJobAction()will only return when the job has started running or when an error has been encountered. like it waits for you, bestie, it's loyal π«Ά Param value: name of host(s) to run job under.ASYNCRUNβ runs the job asynchronously, meaning the call toJobAction()will return immediately as soon as the run request is validated by the PBS server, and not necessarily when the job has started execution. no waiting, we're ghosts π» Param value: name of host(s) to run job under.DELETEβ deletes the job. bye bestie π Param value:"deldelay=<# of secs>"- delay # of seconds between the sending ofSIGTERMandSIGKILLto the job before getting deleted.RERUNβ reruns the running job, which involves terminating the session leader of the job and returning the job to the queued state. it's giving "reset and try again" energy π
HOLDβ puts one or more holds on the job, like slapping a "do not touch" sticky note on it π Param value:"u","o","s","uo","os","uos"- the kind of holds to place on the job:
u(ser),o(ther),s(ystem).
- the kind of holds to place on the job:
RELEASEβ takes those holds back off, freeing the job π¦ Param value:"u","o","s","uo","os","uos"- the kind of holds to remove from the job:
u(ser),o(ther),s(ystem).
- the kind of holds to remove from the job:
SIGNALβ sends a signal to the job that's currently executing, lil nudge (or a big one) π Param value:"HUP","SIGHUP",...MODIFYATTRβ changes the specified attribute of the job to the value you give it, but only whenattrib_nameis!="Resource_List"or"resources_used"π Param value:"attrib_name=value"MODIFYRESβ changes the job'sResource_Listattribute, givenres_nameandres_value, so it ends up asResource_List.res_name=res_valueβ¨ Param value:"res_name=res_val"
So yeah β the param value totally depends on which action you picked. Pass NULLSTR if you don't want a value for that parameter. Return value is SUCCESS or FAIL.
NOTE: any action it doesn't recognize just gets ignored. No error, no drama, it simply looks away π
Examples, because seeing it is believing:
// run Job j synchronously
JobAction(j, SYNCRUN, NULLSTR);
// run Job j asynchronously on host "db"
JobAction(j, ASYNCRUN, "db");
// delete Job j
JobAction(j, DELETE, NULLSTR);
// delete Job j with a delay of 5 secs
// between the sending of SIGTERM and
// SIGKILL
JobAction(j, DELETE, "deldelay=5");
// rerun Job j
JobAction(j, RERUN, NULLSTR);
// place a u(ser) hold on Job j
JobAction(j, HOLD, "u");
// place an o(ther) hold on Job j
JobAction(j, HOLD, "o");
// place a s(ystem) hold on Job j
JobAction(j, HOLD, "s");
// place a default hold (u) on Job j
JobAction(j, HOLD, NULLSTR);
// release u(ser) hold from Job j
JobAction(j, RELEASE, "u");
// release o(ther) hold from Job j
JobAction(j, RELEASE, "o");
// release s(ystem) hold from Job j
JobAction(j, RELEASE, "s");
// release default hold (u) from Job j
JobAction(j, RELEASE, NULLSTR);
// send SIGHUP signal to Job j
JobAction(j, SIGNAL, "SIGHUP");
// update the comment attribute of Job
// j to "a message".
// The param format is: attribute_name=new_value
// Consult PBS documentation for a list of job
// attribute names that can be specified.
JobAction(j, MODIFYATTR, "comment=a message");
// update the Resource_List.cput attribute of Job
// j to 3600 seconds.
// The param format is: resource_name=new_value
// See pbs_resources* man page for a list of
// resource_names that can be specified.
JobAction(j, MODIFYRES, "cput=3600");
πΈ QueJobFind β the finder one πΈ
Okay so there's a whole lil family of these, one per type. Signatures:
QueJobFind(Que que,Fun Int func,Int cpr,Int value);
QueJobFind(Que que,Fun String func,Int cpr,String value);
QueJobFind(Que que,Fun DateTime func,Int cpr,DateTime
value);
QueJobFind(Que que,Fun Size func,Int cpr,Size value);
where cpr is one of: OP_EQ, OP_NEQ, OP_LE, OP_LT, OP_GE, OP_GT. And func is a function whose ONLY argument is of Job type. Job is the return type, bestie β don't forget that π
Description: it applies func to every job in que, and returns the first job that satisfies the logical comparison func(job) cpr value.
Example:
Size JobVirtualMemAvailGet(Job job)
{
Size sz;
sz = JobSizeResReqGet(job, "mem");
return(sz);
}
Int JobWallTimeReqGet(Job job)
{
Int wallt;
wallt = JobIntResReqGet(job, "walltime");
return(wallt);
}
Int JobCpuTimeUsedGet(Job job)
{
Int cput;
cput = JobIntResUseGet(job, "cput");
return(cput);
}
Que findQueByName(Set Que queues, String qname)
{
Que q;
foreach(q in queues) {
if( QueNameGet(q) EQ qname ) {
return(q);
}
}
return(NOQUE);
}
sched_main()
{
Server s;
Que que;
Set Que sq;
// get local server
s = AllServersLocalHostGet();
// get the queues of the Server s
sq = ServerQueuesGet(s);
// get the queue named "fast" from the
// local server
que = findQueByName( sq, "fast" );
// Find the 1st job whose walltime requirement
// is == 300s:
QueJobFind(que, JobWallTimeReqGet, OP_EQ, 300);
// Find the 1st job whose email address to
// notify about job activity != "bayucan":
QueJobFind(que, JobEmailAddrGet, OP_NEQ,
"bayucan");
// Find the 1st job that was created after
// or on 3/3/1997:
QueJobFind(que, JobDateTimeCreatedGet, OP_GE,
(3|3|1997));
// Find the 1st job that was created after
// 3:3:44:
QueJobFind(que, JobDateTimeCreatedGet, OP_GT,
(3:3:44));
// Find the 1st job that was created after
// 3:3:44 on 3/3/1997:
QueJobFind(que, JobDateTimeCreatedGet, OP_GT,
(3|3|1997@3:3:44));
// Find the 1st job whose cpu time used < 1600s:
QueJobFind(que, JobCpuTimeUsedGet, OP_LT, 1600);
// Find the 1st job whose virtual memory
// requirement <= 300mb:
QueJobFind(que, JobVirtualMemAvailGet, OP_LE,
300mb);
}
π
QueJobFind β the max/min one π
Different vibe, same name. Signatures:
Job QueJobFind( Que que, Fun Int func, Int cpr)
Job QueJobFind( Que que, Fun String func, Int cpr)
Job QueJobFind( Que que, Fun DateTime func, Int cpr)
Job QueJobFind( Que que, Fun Size func, Int cpr)
where cpr can be one of the following: OP_MAX, OP_MIN, and func is a function whose only argument is of Job type.
Description: returns the Job with the max or min value found for func(job) as it's applied to every job in que. Basically it's the "who's the most/least" of the whole queue π
Example:
Int JobCpuTimeReqGet(Job job)
{
Int cput;
cput = JobIntResReqGet(job, "cput");
return(cput);
}
sched_main()
{
Que que;
Job job;
// Find the Job with the highest cpu time
// requirement:
job = QueJobFind(que, JobCpuTimeReqGet, OP_MAX);
// Find the Job with the minimum cpu time
// requirement:
job = QueJobFind(que, JobCpuTimeReqGet, OP_MIN);
}
π¦ QueFilter β the filtering era begins π¦
Que QueFilter(Que que,Fun Int func,Int cpr,Int value)
Que QueFilter(Que que,Fun String func,Int cpr,String
value)
Okay so next up is QueFilter β sheβs giving filtered queen energy π
β¨
Que QueFilter(Que que,Fun DateTime func,Int cpr,Date value)
Que QueFilter(Que que,Fun Size func,Int cpr,Size value)
where cpr can be one of the following: OP_EQ, OP_NEQ, OP_LE, OP_LT, OP_GE, OP_GT, and func is a function whose only argument is of Job type.
Description: applies func to every job in que, and returns a new que containing all jobs that satisfy the comparison condition: func(job) cpr value
Example:
Int JobWallTimeReqGet(Job job)
{
Int wallt;
wallt = JobIntResReqGet(job, "walltime");
return(wallt);
}
sched_main()
{
Que que;
Que newq;
// Returns a new que containing all jobs in "que"
// with a walltime requirement == 300s:
newq = QueFilter(que, JobWallTimeReqGet, OP_EQ, 300);
// Returns a new que containing all jobs in "que"
// with an email address != "bayucan":
newq = QueFilter(que, JobEmailAddrGet, OP_NEQ, "bayucan");
// Returns a new que containing all jobs in "que"
// created after or on 3/3/1997:
newq = QueFilter(que, JobDateTimeCreatedGet, OP_GE,
(3|3|1997));
// Returns a new que containing all jobs in "que"
// created after 3:3:44:
newq = QueFilter(que, JobDateTimeCreatedGet, OP_GT,
(3:3:44));
// Returns a new que containing all jobs in "que"
// created after 3:3:44 on 3/3/1997:
newq = QueFilter(que, JobDateTimeCreatedGet, OP_GT,
(3|3|1997@3:3:44));
// NOTE: The original "que" is not modified
// whatsoever.
}
And yes bestie, that note is important: the original que is not modified whatsoever β no cap, she stays untouched π
π«Ά Sort for Set Job β sorting the job girlies
Int Sort(Set Job s, Fun Int key, Int order)
Int Sort(Set Job s, Fun String key, Int order)
Int Sort(Set Job s, Fun Float key, Int order)
Int Sort(Set Job s, Fun DateTime key, Int order)
Int Sort(Set Job s, Fun Size key, Int order)
where s is the set of jobs to sort. key is the sorting key, which is a function whose only argument is of Job type, and order is the sorting order: ASC, DESC.
Description: sorts the elements of s, in either ASCending or DESCending order of values that were returned by the key function, as applied to every member of the set of jobs. The s object is modified with this call. This returns SUCCESS or FAIL depending on outcome of the sort.
Examples:
Size JobMemReqGet(Job job)
{
Size mem;
mem = JobSizeResReqGet(job, "mem");
return(mem);
}
sched_main()
{
Server master;
Set Job jobs;
Int order;
// get local server
master = AllServersLocalHostGet();
jobs = ServerJobsGet(master);
Sort(jobs, JobPriorityGet, ASC);
Sort(jobs, JobIdGet, DESC);
order = ASC;
Sort(jobs, JobDateTimeCreatedGet, order);
order = DESC;
Sort(jobs, JobMemReqGet, order);
}
πΈ Sort for Set Que β queue edition
Int Sort(Set Que s, Fun Int key, Int order)
Int Sort(Set Que s, Fun String key, Int order)
Int Sort(Set Que s, Fun Float key, Int order)
Int Sort(Set Que s, Fun DateTime key, Int order)
Int Sort(Set Que s, Fun Size key, Int order)
where s is the set of queues to sort. key is the sorting key, which is a function whose only argument is of Que type, and order is the sorting order: ASC, DESC.
Description: sorts the elements of s, in either ASCending or DESCending order of values that were returned by the key function, as applied to every member of the set of queues. The s object is modified with this call. This returns SUCCESS or FAIL depending on outcome of the sort.
Examples:
Size QueMemAvailGet(Que que)
{
Size mem;
mem = QueSizeResAvailGet(que, "mem");
return(mem);
}
sched_main()
{
Server master;
Set Que ques;
Int order;
// get local server
master = AllServersLocalHostGet();
ques = ServerQueuesGet(master);
Sort(ques, QuePriorityGet, ASC);
Sort(ques, QueNameGet, ASC);
order = DESC;
Sort(ques, QueMemAvailGet, order);
}
π¦ Sort for Set Server β server sorting supremacy
Int Sort(Set Server s, Fun Int key, Int order)
Int Sort(Set Server s, Fun String key, Int order)
Int Sort(Set Server s, Fun Float key, Int order)
Int Sort(Set Server s, Fun DateTime key, Int order)
Int Sort(Set Server s, Fun Size key, Int order)
where s is the set of servers to sort. key is the sorting key, which is a function whose only argument is of Server type, and order is the sorting order: ASC, DESC.
Description: sorts the elements of s, in either ASCending or DESCending order of values that were returned by the key function, as applied to every member of the set of servers. The s object is modified with this call. This returns SUCCESS or FAIL depending on outcome of the sort.
Examples:
Size ServerMemAvailGet(Server serv)
{
Size mem;
mem = ServerSizeResAvailGet(serv, "mem");
return(mem);
}
sched_main()
{
Set Server sserver;
Int order;
Int ret;
sserver = AllServersGet();
ret = Sort(sserver, ServerMaxRunJobsGet, ASC);
Sort(sserver, ServerInetAddrGet, ASC);
order = DESC;
Sort(sserver, ServerMemAvailGet, order);
}
π Sort for Set CNode β node behavior, but make it cute
Int Sort(Set CNode s, Fun Int key, Int order)
Int Sort(Set CNode s, Fun String key, Int order)
Int Sort(Set CNode s, Fun Float key, Int order)
Int Sort(Set CNode s, Fun DateTime key, Int order)
Int Sort(Set CNode s, Fun Size key, Int order)
where s is the set of nodes to sort. key is the sorting key, which is a function whose only argument is of CNode type, and order is the sorting order: ASC, DESC.
Description: sorts the elements of s, in either ASCending or DESCending order of values that were returned by the key function, as applied to every member of the set of nodes. The s object is modified with this call. This returns SUCCESS or FAIL depending on outcome of the sort.
Examples:
Size CNodeMyMemAvailGet(CNode cn)
{
Size mem;
mem = CNodeMemAvailGet(cn, "virtual");
return(mem);
}
sched_main()
{
Set CNode scnode;
Int order;
scnode = AllNodesGet();
Sort(scnode, CNodeIdletimeGet, ASC);
Sort(scnode, CNodeNameGet, ASC);
order = DESC;
Sort(scnode, CNodeMyMemAvailGet, order);
}
β¨ CNode..Get() FUNCTIONS β¨
okay so bestie, remember the CNode..Get() functions we were just talking about? Their return values don't just magically appear β nope β they're obtained by sending resource queries to the CNode's MOM at every single scheduling iteration. Like, every. single. one. π
For example, CNodeLoadAveGet(node) will return the value you get from some <host resource> query (this could be the string "loadave") as sent to the node's MOM. Cute, right? π«Ά
The <host resource> -> CNode..Get() mappings are established internally, but lowkey you can modify them, or add more mappings, via the scheduler configuration file. That config file is discussed over in pbs_sched_basl(8B) β go read it, iykyk. πβ¨
The mappings that are already established are giving:
For all architectures:
CNode..Get() actual call host resource
======================== =============
CNodeOsGet(node) arch
CNodeLoadAveGet(node) loadave
CNodeIdletimeGet(node) idletime
No cap, those three are just sitting there ready for you. π
πΈ SEE ALSO πΈ
pbs_sched_basl(8B)pbs_job_attributes(7B)pbs_queue_attributes(7B)pbs_resources_irix5(7B)pbs_resources_sp2(7B)pbs_resources_sunos4(7B)pbs_resources_unicos8(7B)pbs_server_attributes(7B)pbs_server(8B)pbs_resources_irix6(7B)pbs_resources_linux(7B)
and that's the whole page, bestie!! ππ this iconic lil manual page lives in the Local section and it's basl2c(1B) β periodt. go forth and slay your scheduling. ππ₯π
π¦ where this page comes from
- nixos 26.05: torque 6.1.3h2
- nixpkgs unstable: torque 6.1.3h2
- Copyright (c) 1999-2000 Veridian Information Solutions, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms