From 73c1655f17a3d28abe2660f768a0aa75aef320a7 Mon Sep 17 00:00:00 2001 From: Ahmed Hany Date: Thu, 18 Jul 2019 15:04:42 +0200 Subject: [PATCH 1/6] Fix ntasks job option,work_dir job option and slurmdb_jobs db connection --- pyslurm/pyslurm.pyx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pyslurm/pyslurm.pyx b/pyslurm/pyslurm.pyx index 00d6e24d..b5cd6ebb 100644 --- a/pyslurm/pyslurm.pyx +++ b/pyslurm/pyslurm.pyx @@ -2746,6 +2746,10 @@ cdef class job: # desc.min_cpus = job_opts.get("ntasks") # TODO: ntasks_set, cpus_set + + if job_opts.get("ntasks"): + desc.min_cpus = job_opts.get("ntasks") * job_opts.get("cpus_per_task") + if job_opts.get("ntasks_per_socket"): desc.ntasks_per_socket = job_opts.get("ntasks_per_socket") @@ -2833,8 +2837,13 @@ cdef class job: # FIXME: should this be python's getcwd or C's getcwd? # also, allow option to specify work_dir, if not, set default - cwd = os.getcwd().encode("UTF-8", "replace") - desc.work_dir = cwd + + if job_opts.get("work_dir"): + work_dir = job_opts.get("work_dir").encode("UTF-8", "replace") + desc.work_dir = work_dir + else: + cwd = os.getcwd().encode("UTF-8", "replace") + desc.work_dir = cwd if job_opts.get("requeue"): desc.requeue = job_opts.get("requeue") @@ -5592,6 +5601,7 @@ cdef class slurmdb_jobs: dict J_dict = {} slurm.List JOBSList slurm.ListIterator iters = NULL + void* db_conn = slurm.slurmdb_connection_get() if jobids: self.job_cond.step_list = slurm.slurm_list_create(NULL) @@ -5616,6 +5626,8 @@ cdef class slurmdb_jobs: JOBSList = slurm.slurmdb_jobs_get(self.db_conn, self.job_cond) + slurm.slurmdb_connection_close(&db_conn) + if JOBSList is NULL: apiError = slurm.slurm_get_errno() raise ValueError(slurm.slurm_strerror(apiError), apiError) From 1db99965eff33248ab4eb9cb2bd94722d2cbd472 Mon Sep 17 00:00:00 2001 From: Sven Willner Date: Fri, 25 Oct 2019 10:38:21 +0200 Subject: [PATCH 2/6] Add options involving ntasks_set and cpus_set --- pyslurm/pyslurm.pyx | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/pyslurm/pyslurm.pyx b/pyslurm/pyslurm.pyx index b5cd6ebb..3cbdf045 100644 --- a/pyslurm/pyslurm.pyx +++ b/pyslurm/pyslurm.pyx @@ -2580,6 +2580,7 @@ cdef class job: wckey = job_opts.get("wckey").encode("UTF-8", "replace") desc.wckey = wckey + # TODO when nodelist is set, min_nodes needs to be adjusted accordingly if job_opts.get("nodelist"): req_nodes = job_opts.get("nodelist").encode("UTF-8", "replace") desc.req_nodes = req_nodes @@ -2601,7 +2602,12 @@ cdef class job: licenses = job_opts.get("licenses").encode("UTF-8", "replace") desc.licenses = licenses - # TODO: nodes_set + if job_opts.get("min_nodes"): + desc.min_nodes = job_opts.get("min_nodes") + if job_opts.get("max_nodes"): + desc.max_nodes = job_opts.get("max_nodes") + elif "ntasks" in job_opts and job_opts.get("min_nodes") == 0: + desc.min_nodes = 0 if job_opts.get("ntasks_per_node"): ntasks_per_node = job_opts.get("ntasks_per_node") @@ -2732,23 +2738,21 @@ cdef class job: if job_opts.get("tmpdisk"): desc.pn_min_tmp_disk = job_opts.get("tmpdisk") - # TODO: declare and use MAX macro or use python max()? -# if job_opts.get("overcommit"): -# desc.min_cpus = max(job_opts.get("min_nodes", 1) -# desc.overcommit = job_opts.get("overcommit") -# elif job_opts.get("cpus_set"): -# # TODO: cpus_set -# # check for ntasks and cpus_per_task before multiplying -# desc.min_cpus = job_opts.get("ntasks") * job_opts.get("cpus_per_task") -# elif job_opts.get("nodes_set") and job_opts.get("min_nodes") == 0: -# desc.min_cpus = 0 -# else: -# desc.min_cpus = job_opts.get("ntasks") - - # TODO: ntasks_set, cpus_set + if job_opts.get("overcommit"): + desc.min_cpus = max(job_opts.get("min_nodes", 1), 1) + desc.overcommit = job_opts.get("overcommit") + elif job_opts.get("cpus_per_task"): + desc.min_cpus = job_opts.get("ntasks", 1) * job_opts.get("cpus_per_task") + elif job_opts.get("nodelist") and job_opts.get("min_nodes") == 0: + desc.min_cpus = 0 + else: + desc.min_cpus = job_opts.get("ntasks", 1) + + if job_opts.get("cpus_per_task"): + desc.cpus_per_task = job_opts.get("cpus_per_task") if job_opts.get("ntasks"): - desc.min_cpus = job_opts.get("ntasks") * job_opts.get("cpus_per_task") + desc.num_tasks = job_opts.get("ntasks") if job_opts.get("ntasks_per_socket"): desc.ntasks_per_socket = job_opts.get("ntasks_per_socket") From 0710eb9f71dd332f4a1a6afbcbac3fb2a4021d21 Mon Sep 17 00:00:00 2001 From: Sven Willner Date: Fri, 25 Oct 2019 11:54:51 +0200 Subject: [PATCH 3/6] Use db_conn of class and fix cleanup --- pyslurm/pyslurm.pyx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pyslurm/pyslurm.pyx b/pyslurm/pyslurm.pyx index 3cbdf045..0aa2ebb6 100644 --- a/pyslurm/pyslurm.pyx +++ b/pyslurm/pyslurm.pyx @@ -5574,9 +5574,14 @@ cdef class slurmdb_jobs: def __cinit__(self): self.job_cond = slurm.xmalloc(sizeof(slurm.slurmdb_job_cond_t)) + self.db_conn = slurm.slurmdb_connection_get() def __dealloc__(self): - pass + self.__free() + + cpdef __free(self): + slurm.xfree(self.job_cond) + slurm.slurmdb_connection_close(&self.db_conn) def get(self, jobids=[], starttime=0, endtime=0): u"""Get Slurmdb information about some jobs. @@ -5605,7 +5610,6 @@ cdef class slurmdb_jobs: dict J_dict = {} slurm.List JOBSList slurm.ListIterator iters = NULL - void* db_conn = slurm.slurmdb_connection_get() if jobids: self.job_cond.step_list = slurm.slurm_list_create(NULL) @@ -5630,8 +5634,6 @@ cdef class slurmdb_jobs: JOBSList = slurm.slurmdb_jobs_get(self.db_conn, self.job_cond) - slurm.slurmdb_connection_close(&db_conn) - if JOBSList is NULL: apiError = slurm.slurm_get_errno() raise ValueError(slurm.slurm_strerror(apiError), apiError) From de14f3a037b5ecfaba555bfb5c48600d0c072ba2 Mon Sep 17 00:00:00 2001 From: Sven Willner Date: Mon, 28 Oct 2019 15:52:40 +0100 Subject: [PATCH 4/6] Merge slurmdb_jobs.__free into slurmdb_jobs.__dealloc__ --- pyslurm/pyslurm.pyx | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyslurm/pyslurm.pyx b/pyslurm/pyslurm.pyx index 0aa2ebb6..1a2c9484 100644 --- a/pyslurm/pyslurm.pyx +++ b/pyslurm/pyslurm.pyx @@ -5577,9 +5577,6 @@ cdef class slurmdb_jobs: self.db_conn = slurm.slurmdb_connection_get() def __dealloc__(self): - self.__free() - - cpdef __free(self): slurm.xfree(self.job_cond) slurm.slurmdb_connection_close(&self.db_conn) From 7c5e9495a40d467641553afd02fa6bf6dfde0570 Mon Sep 17 00:00:00 2001 From: Sven Willner Date: Mon, 28 Oct 2019 16:02:54 +0100 Subject: [PATCH 5/6] Add num_tasks output --- pyslurm/pyslurm.pyx | 1 + tests/test-job.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pyslurm/pyslurm.pyx b/pyslurm/pyslurm.pyx index 1a2c9484..4a198c44 100644 --- a/pyslurm/pyslurm.pyx +++ b/pyslurm/pyslurm.pyx @@ -2182,6 +2182,7 @@ cdef class job: Job_dict[u'ntasks_per_board'] = self._record.ntasks_per_board Job_dict[u'num_cpus'] = self._record.num_cpus Job_dict[u'num_nodes'] = self._record.num_nodes + Job_dict[u'num_tasks'] = self._record.num_tasks if self._record.pack_job_id: Job_dict[u'pack_job_id'] = self._record.pack_job_id diff --git a/tests/test-job.py b/tests/test-job.py index 43b3b34b..055b9a7f 100644 --- a/tests/test-job.py +++ b/tests/test-job.py @@ -58,6 +58,7 @@ def test_job_scontrol(): assert_equals(test_job_info["nice"], int(sctl_dict["Nice"])) assert_equals(test_job_info["num_cpus"], int(sctl_dict["NumCPUs"])) assert_equals(test_job_info["num_nodes"], int(sctl_dict["NumNodes"])) + assert_equals(test_job_info["num_tasks"], int(sctl_dict["NumTasks"])) assert_equals(test_job_info["partition"], sctl_dict["Partition"]) assert_equals(test_job_info["priority"], int(sctl_dict["Priority"])) assert_equals(test_job_info["state_reason"], sctl_dict["Reason"]) From cf0e4c0ae95228ce6fb331d66e8c907e27f6bd91 Mon Sep 17 00:00:00 2001 From: Sven Willner Date: Mon, 28 Oct 2019 16:03:21 +0100 Subject: [PATCH 6/6] Add simple test for submitting with ntasks and cpus_per_task --- tests/test-job.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test-job.py b/tests/test-job.py index 055b9a7f..ca96a6e5 100644 --- a/tests/test-job.py +++ b/tests/test-job.py @@ -7,10 +7,17 @@ def test_job_submit(): """Job: Test job().submit_batch_job().""" - test_job = {"wrap": "sleep 3600", "job_name": "pyslurm_test_job"} + test_job = { + "wrap": "sleep 3600", + "job_name": "pyslurm_test_job", + "ntasks": 2, + "cpus_per_task": 3, + } test_job_id = pyslurm.job().submit_batch_job(test_job) test_job_search = pyslurm.job().find(name="name", val="pyslurm_test_job") assert_true(test_job_id in test_job_search) + assert_equals(test_job_search["cpus_per_task"], 3) + assert_equals(test_job_search["num_tasks"], 2) def test_job_get():