| Writing Jobs |
|
|
|
Job Description FilesA job description file, or jdf for short, is a plain text file that contains a job description. Each job description file describes a single job. You can edit a jdf in the text editor of your choice. By convention, we use the .jdf extension to name all job description files. The job clauseA job clause contains a (possibly empty) list of sub-clauses. For instance, the requirements sub-clause encompasses the list of requirements that need to be fulfilled by a worker node, so that it can be selected to run tasks of the job, while the label sub-clause associates a name to the job. This sub-clause is useful for tracking the execution of the job and also to associate the name of the output files to the job that has generated it. job :
label : myjob1
requirements : ( os == linux and mem >= 100 )
task :
remote : mytask
As we mentioned before, all sub-clauses of a job clause are optional. If the label sub-clause does not exist in the jdf, an internal job id is used to identify it. If there is no requirements sub-clause, the Broker assumes that all worker nodes in your grid are able to run the tasks of your job. The task clauseThere is one task clause to describe each task of a job. The number of tasks in a job is determined by the number of task clauses in the jdf. Transferring Files to/from Workers
OurGrid provides a useful set of abstractions that allow you to write BoT applications without knowing details of the worker node file system. The basic idea is that you can have OurGrid transferring and retrieving files to/from the worker nodes in a per task basis. OurGrid defines two virtual directories for each task, called playpen and storage. In the task description you can instruct OurGrid to copy files to these directories. This assures that the worker nodes will have all necessary files stored locally, before the tasks are run. Analogously, you can instruct OurGrid to copy files from those directories back to the user's machine after the successful execution of the task. This allows you to gather the results. put/store localfile remotefile
The get command is used in the final sub-clause to fetch files from the worker node. The general form of a get command is:
get remotefile localfile
In all above commands, localfile is the name of the file on the user's machine. If relative names are used, the Broker will consider the job description file directory as the base directory, whereas remotefile is the name of the file on the worker node. All remote file names are associated to the $PLAYPEN directory, if this is a put or get operation. In the case of store, the default directory is $STORAGE. job :
label : myjob2
task :
init : put input input
store mytask mytask
remote : $STORAGE/mytask < input > output
final : get output output
The job contains only one task that starts by transferring a file named input to $PLAYPEN and a file named mytask to $STORAGE. The task then runs mytask in a worker node, reading the standard input from the file input, and writting the standard output in the output file. When the execution of mytask finishes, the final phase of the task is executed, fetching the output file back to the user's machine.
Using Environment VariablesOurGrid automatically defines the environment variables $JOB, $TASK, $PROC, $PLAYPEN and $STORAGE and they respectively contain a unique job number, a unique task number, the worker node chosen to run the task, the directory created as the playpen, and the storage directory name. These variables are useful to define unique names for the input and output files of each task. For instance: job : label : myjob5
task:
init : put input input
store mytask mytask
remote : mytask < input > output-$TASK
final : get output-$TASK output-$TASK
task:
init : put input input
store mytask mytask
remote : mytask < input > output-$TASK
final : get output-$TASK output-$TASK
Appending the task number to a file is useful for the common case where the tasks that comprise the job produce output with the same name. Appending the task number ensures the uniqueness of each output.
Table 1: Environment Variables Using DefaultsIn the last example, we showed how to use the OurGrid environment variables to write tasks. What they really enable you to do is to have tasks that are literally the same. However, doing a cut-and-paste for each task in your job does not sound good. It is much easier to use the job section to define defaults for all phases of its tasks. Consequently, the last example can be much easily written as:
job :
label : myjob6
init : put input input
store mytask mytask
remote : mytask < input > output-$TASK
final : get output-$TASK output-$TASK
task :
task :
Note that the empty task sections are needed to inform OurGrid how many tasks the job contains. As the name suggests, the default values set in the job clause can be overwritten in the task clauses. Consider the example:
job :
label : myjob7
init : put input input
store mytask mytask
remote : mytask < input > output-$TASK
final : get output-$TASK output-$TASK
task :
init :put alpha input
store mytask mytask
task :
Here, the first task copies the file alpha at the user's machine into file input at the worker node, and proceeds as before. The second task remains unchanged. Attribute MatchingWorker node's attributes are user-defined strings that express the characteristics of the worker node. They can be used to define the job requirements. Job requirements are described by means of expressions involving these attributes. Most common arithmetic and logical operators are supported. Operators with higher precedence are evaluated before operators with lower precedence. Evaluation of operators with the same precedence is from left to right. This evaluation order can be changed by using parentheses. Table 2 lists all operators supported by OurGrid.
Table 2: Requirements Operators |