The user defines a structure job_desc as below. He then calls slurm_job_desc_init(), 
which sets the values to initial values (#ffff, #ffffffff, or NULL for the pointers). 
The user then set any values as desired, likely only a small subset of the values. 
Some of the values can be set only by user root (e.g. groups, priority, and user_id). 
For example, we ignore the request from user "tewk" to run as user "root" with 
group "root" and high priority. The user then calls the appropriate API (allocate, 
submit, update, will_run). The API call packs the values reset by the user, including 
proper values for user_id and group_id. Only the values set by the user are sent, 
packing a uit32_t value first with flags indicating which values are being sent 
(see  "#define JOB_DESC_OPT_CONTIGUOUS" and below). The functions return an error 
code as defined below (see "#define SLURM_SUCCESS" and below). slurm_allocate and 
slurm_submit functions will return a job_id upon success. 

#define	NO_VAL_16	#ffff		/* value of uint16_t variable until user reset */
#define	NO_VAL_32	#ffffffff	/* value of uint32_t variable until user reset */

structure job_desc {	/* Job descriptor for submit, allocate, and update requests */
	uint16_t contiguous;	/* 1 if job requires contiguous nodes, 0 otherwise, 
				 * default=0 */
	char *features;		/* comma separated list of required features, default NONE */
	char *groups;		/* comma separated list of groups the user can access, 
				 * default set output of "/usr/bin/groups" by API, 
				 * can only be set if user is root */
	uint16_t immediate;	/* 1 if job should be initiated immediate or not at all, 
				 * default=0 or queue as needed */
	uint32_t job_id;	/* job ID, default set by SLURM */
	char *name;		/* name of the job, default "" */
	void *partition_key;	/* root key to submit job, format TBD, default NONE */
	uint32_t min_procs;	/* minimum processors required per node, default=0 */
	uint32_t min_memory;	/* minimum real memory required per node, default=0 */
	uint32_t min_tmp_disk;	/* minimum temporary disk required per node, default=0 */
	char *partition;	/* name of requested partition, default in SLURM config */
	uint32_t priority;	/* relative priority of the job, default set by SLURM, 
				 * can only be explicitly set if user is root, maximum
				 * value is #fffffffe */
	char *req_nodes;	/* comma separated list of required nodes, default NONE */
	char *job_script;	/* pathname of required script, default NONE */
	uint16_t shared;	/* 1 if job can share nodes with other jobs, 0 otherwise,
				 * default in SLURM configuration */
	uint32_t time_limit;	/* maximum run time in minutes, default is partition 
				 * limit as defined in SLURM configuration, maximum
				 * value is #fffffffe */
	uint32_t num_procs;	/* number of processors required by job, default=0 */
	uint32_t num_nodes;	/* number of nodes required by job, default=0 */
	uint32_t user_id;	/* set only if different from current UID, default set 
				 * to UID by API, can only be set if user is root */
	uint16_t will_run_test;	/* 1 to test of job would begin immediatly, but do not 
				 * actually initiate the job, default=0 or initiate job */ 
};

int slurm_job_desc_init (structure job_desc *job_info);
int slurm_allocate (structure job_desc *job_info, uint32_t *job_id);
int slurm_job_cancel (uint32_t job_id);		/* user_id passed by API */
int slurm_job_update (structure job_desc *job_info);
int slurm_submit (structure job_desc *job_info, uint32_t *job_id);
int slurm_will_run (structure job_desc *job_info);

/* The following flags indicated which of the job_desc structure entries were set by
 * the user and packed into the communications data structure. These flags are set 
 * in an uint32_t variable in the communications data structure and followed by 
 * those values in order. */
#define JOB_DESC_OPT_CONTIGUOUS		1<<0
#define JOB_DESC_OPT_FEATURES		1<<1
#define JOB_DESC_OPT_GROUPS		1<<2
#define JOB_DEST_OPT_IMMEDIATE		1<<3
#define JOB_DESC_OPT_JOB_ID		1<<4
#define JOB_DESC_OPT_JOB_NAME		1<<5
#define JOB_DESC_OPT_PART_KEY		1<<6
#define JOB_DESC_OPT_MIN_PROCS		1<<7
#define JOB_DESC_OPT_MIN_REAL_MEM	1<<8
#define JOB_DESC_OPT_MIN_TMP_DISK	1<<9
#define JOB_DESC_OPT_PARTITION		1<<10
#define JOB_DESC_OPT_PRIORITY		1<<11
#define JOB_DESC_OPT_REQ_NODES		1<<12
#define JOB_DESC_OPT_SCRIPT		1<<13
#define JOB_DESC_OPT_SHARED		1<<14
#define JOB_DESC_OPT_TIME_LIMIT		1<<15
#define JOB_DESC_OPT_TOTAL_NODES	1<<16
#define JOB_DESC_OPT_TOTAL_PROCS	1<<17
#define JOB_DESC_OPT_SHARED		1<<18
#define JOB_DESC_OPT_USER_ID		1<<19
#define JOB_DESC_OPT_WILL_RUN		1<<20
/* Removed Distribution and ProcsPerTask, they go with a job step only */

#define SLURM_SUCCESS		0	/* API call successfully completed */
#define SLURM_NOCHANGE		1	/* Data requested unchanged since last get call */
#define SLURM_EAGAIN		2	/* Try again later (eg. no nodes for allocate) */
#define SLURM_EACCESS		3	/* Permission denied */
#define SLURM_EINVAL		4	/* Invalid arguments (eg. can never satisfy request) */
#define SLURM_ENOENT		5	/* No such entry (eg. cancel with bad job_id) */
