From 3b4762b33ba492ec6a643cae708e653294bbe3b8 Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Thu, 16 Apr 2009 15:59:27 +0000
Subject: [PATCH] Better support the --contiguous option for job allocations.

---
 NEWS                                      |  1 +
 doc/man/man1/salloc.1                     |  7 ++---
 doc/man/man1/sbatch.1                     |  7 ++---
 doc/man/man1/srun.1                       |  8 +++---
 src/plugins/select/cons_res/job_test.c    | 25 +++++++++++++++++-
 src/plugins/select/linear/select_linear.c | 31 ++++++++++++++++++++---
 6 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/NEWS b/NEWS
index 50373e3335b..d8cfeffa5ca 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ documents those changes that are of interest to users and admins.
 ==============================
  -- Added new partition option AllocNodes which controls the hosts from 
     which jobs can be submitted to this partition. From Matthieu Hautreux, CEA.
+ -- Better support the --contiguous option for job allocations.
 
 * Changes in SLURM 1.4.0-pre12
 ==============================
diff --git a/doc/man/man1/salloc.1 b/doc/man/man1/salloc.1
index d074dbe089a..d1784ba23ff 100644
--- a/doc/man/man1/salloc.1
+++ b/doc/man/man1/salloc.1
@@ -1,4 +1,4 @@
-.TH "salloc" "1" "SLURM 2.0" "February 2009" "SLURM Commands"
+.TH "salloc" "1" "SLURM 2.0" "April 2009" "SLURM Commands"
 .SH "NAME"
 .LP 
 salloc \- Obtain a SLURM job allocation (a set of nodes), execute a command, 
@@ -126,8 +126,9 @@ An arbitrary comment.
 
 .TP
 \fB\-\-contiguous\fR
-Demand a contiguous range of nodes. The default is "yes". Specify
-\-\-contiguous=no if a contiguous range of nodes is not required.
+If set, then the allocated nodes must form a contiguous set.
+Not honored with the \fBtopology/tree\fR or \fBtopology/3d_torus\fR
+plugins, both of which can modify the node ordering.  
 
 .TP
 \fB\-\-cpu_bind\fR=[{\fIquiet,verbose\fR},]\fItype\fR
diff --git a/doc/man/man1/sbatch.1 b/doc/man/man1/sbatch.1
index 763541bf774..5239532eb6d 100644
--- a/doc/man/man1/sbatch.1
+++ b/doc/man/man1/sbatch.1
@@ -1,4 +1,4 @@
-.TH "sbatch" "1" "SLURM 2.0" "March 2009" "SLURM Commands"
+.TH "sbatch" "1" "SLURM 2.0" "April 2009" "SLURM Commands"
 .SH "NAME"
 .LP 
 sbatch \- Submit a batch script to SLURM.
@@ -203,8 +203,9 @@ An arbitrary comment.
 
 .TP
 \fB\-\-contiguous\fR
-Demand a contiguous range of nodes. The default is "yes". Specify
-\-\-contiguous=no if a contiguous range of nodes is not required.
+If set, then the allocated nodes must form a contiguous set.
+Not honored with the \fBtopology/tree\fR or \fBtopology/3d_torus\fR
+plugins, both of which can modify the node ordering.
 
 .TP 
 \fB\-D\fR, \fB\-\-workdir\fR[=]<\fIdirectory\fR>
diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index 72616923065..2b6434f9a04 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -1,4 +1,4 @@
-.TH SRUN "1" "March 2009" "srun 2.0" "slurm components"
+.TH SRUN "1" "April 2009" "srun 2.0" "slurm components"
 
 .SH "NAME"
 srun \- run parallel jobs
@@ -265,8 +265,10 @@ An arbitrary comment.
 
 .TP
 \fB\-\-contiguous\fR
-Demand a contiguous range of nodes. The default is "yes". Specify
-\-\-contiguous=no if a contiguous range of nodes is not a constraint.
+If set, then the job's allocated nodes must form a contiguous set.
+Not honored with the \fBtopology/tree\fR or \fBtopology/3d_torus\fR
+plugins, both of which can modify the node ordering.
+Not honored for a job step's allocation.
 
 .TP
 \fB\-\-core\fR=\fItype\fR
diff --git a/src/plugins/select/cons_res/job_test.c b/src/plugins/select/cons_res/job_test.c
index 8aa93c5f93d..7e003273c91 100644
--- a/src/plugins/select/cons_res/job_test.c
+++ b/src/plugins/select/cons_res/job_test.c
@@ -1043,7 +1043,13 @@ static int _eval_nodes(struct job_record *job_ptr, bitstr_t *node_map,
 		best_fit_req = -1;	/* first required node, -1 if none */
 		for (i = 0; i < consec_index; i++) {
 			if (consec_nodes[i] == 0)
-				continue;
+				continue;	/* no usable nodes here */
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap &&
+			    (consec_req[i] == -1))
+				break;  /* not required nodes */
+
 			sufficient = (consec_cpus[i] >= rem_cpus) &&
 				     _enough_nodes(consec_nodes[i], rem_nodes,
 						   min_nodes, req_nodes);
@@ -1064,6 +1070,23 @@ static int _eval_nodes(struct job_record *job_ptr, bitstr_t *node_map,
 				best_fit_req = consec_req[i];
 				best_fit_sufficient = sufficient;
 			}
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap) {
+				/* Must wait for all required nodes to be 
+				 * in a single consecutive block */
+				int j, other_blocks = 0;
+				for (j = (i+1); j < consec_index; j++) {
+					if (consec_req[j] != -1) {
+						other_blocks = 1;
+						break;
+					}
+				}
+				if (other_blocks) {
+					best_fit_nodes = 0;
+					break;
+				}
+			}
 		}
 		if (best_fit_nodes == 0)
 			break;
diff --git a/src/plugins/select/linear/select_linear.c b/src/plugins/select/linear/select_linear.c
index 76d87c29dcb..14acb9436bb 100644
--- a/src/plugins/select/linear/select_linear.c
+++ b/src/plugins/select/linear/select_linear.c
@@ -978,10 +978,16 @@ static int _job_test(struct job_record *job_ptr, bitstr_t *bitmap,
 		best_fit_req = -1;	/* first required node, -1 if none */
 		for (i = 0; i < consec_index; i++) {
 			if (consec_nodes[i] == 0)
-				continue;
-			sufficient = (consec_cpus[i] >= rem_cpus)
-			&& _enough_nodes(consec_nodes[i], rem_nodes,
-					 min_nodes, req_nodes);
+				continue;	/* no usable nodes here */
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap &&
+			    (consec_req[i] == -1))
+				break;	/* not required nodes */
+
+			sufficient = (consec_cpus[i] >= rem_cpus) &&
+				     _enough_nodes(consec_nodes[i], rem_nodes,
+						   min_nodes, req_nodes);
 
 			/* if first possibility OR */
 			/* contains required nodes OR */
@@ -1000,6 +1006,23 @@ static int _job_test(struct job_record *job_ptr, bitstr_t *bitmap,
 				best_fit_req = consec_req[i];
 				best_fit_sufficient = sufficient;
 			}
+
+			if (job_ptr->details->contiguous &&
+			    job_ptr->details->req_node_bitmap) {
+				/* Must wait for all required nodes to be 
+				 * in a single consecutive block */
+				int j, other_blocks = 0;
+				for (j = (i+1); j < consec_index; j++) {
+					if (consec_req[j] != -1) {
+						other_blocks = 1;
+						break;
+					}
+				}
+				if (other_blocks) {
+					best_fit_nodes = 0;
+					break;
+				}
+			}
 		}
 		if (best_fit_nodes == 0)
 			break;
-- 
GitLab