Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
abstract:farber:runjobs:queues [2018-02-13 12:23] – [Farber exclusive access] sraskar | abstract:farber:runjobs:queues [2018-10-08 16:01] (current) – anita | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== The job queues on Farber ====== | ||
+ | Each investing-entity on a cluster an //owner queue// that exclusively use the investing-entity' | ||
+ | |||
+ | There are also node-wise queues, // | ||
+ | |||
+ | When submitting a batch job to Grid Engine, you specify the resources you need or want for your job. **//You don't typically specify the name of the queue//**. Instead, you include a set of directives that specify your job's characteristics. Grid Engine then chooses the most appropriate queue that meets those needs. | ||
+ | |||
+ | The queue to which a job is assigned depends primarily on six factors: | ||
+ | |||
+ | * Whether the job is serial or parallel | ||
+ | * Which parallel environment (e.g., mpi, threads) is needed | ||
+ | * Which or how much of a resource is needed (e.g., max clock time, memory requirements) | ||
+ | * Resources your job will consume (e.g. an entire node, max memory usage) | ||
+ | * Whether the job is non-interactive or interactive | ||
+ | |||
+ | For each investing-entity, | ||
+ | |||
+ | ^ <<// | ||
+ | ^ '' | ||
+ | ^ ::: | You must specify **–l standby=1** as a **qsub** option. You must also use the **-notify** option if your jobs traps the USR2 termination signal.| | ||
+ | ^ '' | ||
+ | ^ ::: | You must specify **–l standby=1** as a **qsub** option. And, if more than 200 slots are requested, you must also specify a maximum run-time of 4 hours or less via the **-l h_rt=// | ||
+ | ^ '' | ||
+ | |||
+ | <note important> | ||
+ | In addition to the required run-time limit, the standby queues differ by how many jobs each user can be concurrently running. | ||
+ | </ | ||
+ | |||
+ | ===== Farber " | ||
+ | |||
+ | Farber has two standby queues, '' | ||
+ | |||
+ | The " | ||
+ | |||
+ | Grid Engine preferentially allocates standby slots on nodes that are lightly loaded. It assigns these jobs a lower queue-priority than jobs submitted by members of the group owning the node. Consequently, | ||
+ | |||
+ | Specify the '' | ||
+ | |||
+ | <code text> | ||
+ | qsub -l standby=1 ... | ||
+ | </ | ||
+ | |||
+ | ==== Grid Engine resources governing these queues ==== | ||
+ | |||
+ | The " | ||
+ | |||
+ | The differences between the two queues is tied to the number of slots and the maximum (wall-clock) //hard// run-time you specify. | ||
+ | |||
+ | * If you specify a maximum run-time of 4 hours or less (e.g.,'' | ||
+ | |||
+ | * If you do **not** specify a maximum run-time **or** if you specify a run-time greater than 4 hours but not exceeding 8 hours, then you may request up to 200 slots for any job. The job will be assigned to '' | ||
+ | |||
+ | The total number of concurrent slots in the '' | ||
+ | |||
+ | For example, you could concurrently run 25 20-slot jobs (500 slots). This would leave 300 slots available for any other concurrent standby jobs you may submit. | ||
+ | |||
+ | Job script example: | ||
+ | <code bash> | ||
+ | # | ||
+ | # The standby flag asks to run the job in a standby queue. | ||
+ | #$ -l standby=1 | ||
+ | # | ||
+ | # This job needs an openmpi parallel environment using 500 slots. | ||
+ | #$ -pe openmpi 500 | ||
+ | # | ||
+ | # The h_rt flag specifies a 4-hr maximum (hard) run-time limit. | ||
+ | # The flag is required because the job needs more than 240 slots. | ||
+ | #$ -l h_rt=4: | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | ==== Mapping jobs to nodes ==== | ||
+ | |||
+ | Once Grid Engine determines the appropriate standby queue, it maps the job to available, idle, nodes (hosts) to fill all the slots. For openmpi jobs, Grid Engine is configured to use the //fill up// allocation rule, by default. | ||
+ | |||
+ | It may be useful to control the number of nodes and the number of processes per node. | ||
+ | For example: | ||
+ | qsub -l standby, | ||
+ | The MPI processes (ranks) will be mapped to **'' | ||
+ | The MPI_FLAG '' | ||
+ | |||
+ | <note important> | ||
+ | If these jobs are assigned to your nodes (you have them for up to 8 hours), they will compete for shared resources: | ||
+ | ^ Resource ^ Shared ^ | ||
+ | | cores | 20 | | ||
+ | | memory |64 GBs | | ||
+ | If you add the '' | ||
+ | #$ -l exclusive=1 | ||
+ | then Grid Engine will round up your slot request to a multiple of 20 and thus keep other jobs off the node. | ||
+ | </ | ||
+ | |||
+ | <note tip>The allocation rule and the group names are configured in Grid Engine. | ||
+ | the current configuration. | ||
+ | |||
+ | To see the current allocation rule for '' | ||
+ | |||
+ | $ qconf -sp mpi | grep allocation_rule | ||
+ | | ||
+ | |||
+ | To see a list of all group names: | ||
+ | |||
+ | $ qconf -shgrpl | ||
+ | @128G | ||
+ | @256G | ||
+ | | ||
+ | |||
+ | To see the nodes in a group name: | ||
+ | $ qconf -shgrp @128G | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ==== Actions at the run-time limit ===== | ||
+ | When a standby job reaches its maximum run time, Grid Engine kills the job. The process depends on your use of Grid Engine' | ||
+ | |||
+ | * **Deferred termination**: | ||
+ | * **Immediate termination**: | ||
+ | |||
+ | <note information> | ||
+ | Jobs that can react to kill-notification (the USR2 signal) should supply the '' | ||
+ | </ | ||
+ | |||
+ | This bash script example catches '' | ||
+ | <code bash> | ||
+ | # | ||
+ | # The -notify flag to qsub asks that we get a USR2 signal before being killed: | ||
+ | #$ -notify | ||
+ | # | ||
+ | # The -l standby=1 flag asks to run in a standby queue. | ||
+ | #$ -l standby=1 | ||
+ | # | ||
+ | #$ -m eas | ||
+ | #$ -M traine@udel.edu | ||
+ | # | ||
+ | |||
+ | function copyScratchToLocal { | ||
+ | echo -n `date` | ||
+ | echo " | ||
+ | cp -R $TMPDIR . | ||
+ | } | ||
+ | |||
+ | trap copyScratchToLocal SIGUSR2 | ||
+ | |||
+ | date | ||
+ | ls /etc > $TMPDIR/ | ||
+ | while [ 1 -eq 1 ]; do | ||
+ | sleep 10000 | ||
+ | done | ||
+ | </ | ||
+ | Submitting this job, the following output is produced: | ||
+ | <code text> | ||
+ | Fri Jun 1 12:38:51 EDT 2012 | ||
+ | User defined signal 2 | ||
+ | Fri Jun 1 16:38:53 EDT 2012 Copying / | ||
+ | </ | ||
+ | |||
+ | At two seconds past the max run time (8 hours in this case), the USR2 signal was delivered and the '' | ||
+ | |||
+ | <code text> | ||
+ | Job 39866.1 (basic.qs) Aborted | ||
+ | Exit Status | ||
+ | Signal | ||
+ | User = traine | ||
+ | Queue = standby.q@n015 | ||
+ | Host = n015.farber.hpc.udel.edu | ||
+ | Start Time = 06/01/2012 12:38:51 | ||
+ | End Time = 06/01/2012 16:43:53 | ||
+ | CPU = 00:00:00 | ||
+ | Max vmem = 17.055M | ||
+ | failed assumedly after job because: | ||
+ | job 39866.1 died through signal KILL (9) | ||
+ | </ | ||
+ | The job ran 5 minutes beyond the 8-hour mark, demonstrating that Grid Engine will indeed wait a full 5 minutes before delivering the KILL signal to end the job. | ||
+ | <note warning> | ||
+ | The default reaction of a program to the '' | ||
+ | </ | ||
+ | |||
+ | ==== What if my program does not catch USR2? ==== | ||
+ | |||
+ | < | ||
+ | |||
+ | When a program that does not handle the '' | ||
+ | |||
+ | Consider an MPI program that does not include the additional code necessary to catch the '' | ||
+ | |||
+ | <code bash> | ||
+ | : | ||
+ | function runtimeLimitReached { | ||
+ | # Do some cleanup, job archiving, whatever, then exit | ||
+ | # to end the job | ||
+ | | ||
+ | exit 0 | ||
+ | } | ||
+ | : | ||
+ | trap runtimeLimitIsReached SIGUSR2 | ||
+ | mpirun {arguments to mpirun...} | ||
+ | |||
+ | # Do any cleanup that should be done if the job finished prior | ||
+ | # to the runtime limit... | ||
+ | |||
+ | </ | ||
+ | |||
+ | What happens when the runtime limit is reached? | ||
+ | |||
+ | - The job script and its child '' | ||
+ | * The job script is blocked waiting on the '' | ||
+ | - Meanwhile, the '' | ||
+ | - The worker processes do NOT handle '' | ||
+ | - The '' | ||
+ | - The job script sees the '' | ||
+ | |||
+ | So the job script never gets a chance to react to the '' | ||
+ | |||
+ | If the job script ignores '' | ||
+ | |||
+ | Without altering the MPI program to handle '' | ||
+ | |||
+ | - The job shell has a '' | ||
+ | - The '' | ||
+ | - The '' | ||
+ | |||
+ | The sequencing of the commands is the important part: | ||
+ | |||
+ | <code bash> | ||
+ | : | ||
+ | function runtimeLimitReached { | ||
+ | # Do some cleanup, job archiving, whatever, then exit | ||
+ | # to end the job | ||
+ | | ||
+ | exit 0 | ||
+ | } | ||
+ | : | ||
+ | trap "" | ||
+ | mpirun {arguments to mpirun...} & | ||
+ | trap runtimeLimitReached SIGUSR2 | ||
+ | wait | ||
+ | |||
+ | # Do any cleanup that should be done if the job finished prior | ||
+ | # to the runtime limit... | ||
+ | |||
+ | </ | ||
+ | |||
+ | The first '' | ||
+ | |||
+ | ===== Farber Exclusive access ===== | ||
+ | |||
+ | If a job is submitted with the '' | ||
+ | |||
+ | * promote any serial jobs to 20-core threaded (-pe threads 20) | ||
+ | * modify any parallel jobs to round-up the slot count to the nearest multiple of 20 | ||
+ | * ignore any memory resources and make all memory available on all nodes assigned to the job | ||
+ | |||
+ | A job running on a node with '' | ||
+ | |||
+ | Job script example: | ||
+ | <code bash> | ||
+ | # | ||
+ | # The exclusive flag asks to run this job only on all nodes required to fulfill requested slots | ||
+ | #$ -l exclusive=1 | ||
+ | # | ||
+ | # This job needs an openmpi parallel environment using 32 slots = 2 nodes exclusively. | ||
+ | #$ -pe openmpi 32 | ||
+ | # | ||
+ | # By default the slot count granted by Grid Engine will be | ||
+ | # used, one MPI worker per slot. Set this variable if you | ||
+ | # want to use fewer cores than Grid Engine granted you (e.g. | ||
+ | # when using exclusive=1): | ||
+ | # | ||
+ | # | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | |||
+ | <note tip>In the script example, this job would be rounded up to 40 and would be assigned 2 nodes. If you really want your job to run with only 32 slots, uncomment and set '' | ||
+ | |||
+ | Grid Engine is configured to "fill up" nodes by allocating as many slots as possible before proceeding to another node to fulfill the total number of requested slots for the job. Unfortunately, | ||
+ | |||
+ | To assure that your job will be the only job running on a node (or all nodes needed to satisfy the slots requested), specify the '' | ||
+ | |||
+ | <code text> | ||
+ | qsub -l exclusive=1 ... | ||
+ | </ | ||
+ | |||
+ | |||
+ | If a job is submitted with the general resource, Grid Engine will | ||
+ | |||
+ | * promote any serial jobs to 20-core threaded (-pe threads 20) | ||
+ | * modify any parallel jobs to round-up the slot count to the nearest multiple of 20 | ||
+ | * ignore any memory resources and make all memory available on all nodes assigned to the job | ||
+ | |||
+ | A job running on a node with '' | ||
+ | |||
+ | Job script example: | ||
+ | <code bash> | ||
+ | # | ||
+ | # The exclusive flag asks to run this job only on all nodes required to fulfill requested slots | ||
+ | #$ -l exclusive=1 | ||
+ | # | ||
+ | # This job needs an openmpi parallel environment using 32 slots = 2 nodes exclusively. | ||
+ | #$ -pe openmpi 32 | ||
+ | # | ||
+ | # By default the slot count granted by Grid Engine will be | ||
+ | # used, one MPI worker per slot. Set this variable if you | ||
+ | # want to use fewer cores than Grid Engine granted you (e.g. | ||
+ | # when using exclusive=1): | ||
+ | # | ||
+ | # | ||
+ | |||
+ | ... | ||
+ | </ | ||
+ | |||
+ | <note tip>In the script example, this job would be rounded up to 40 and would be assigned 2 nodes. If you really want your job to run with only 32 slots, uncomment and set '' |