You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2022/01/03 21:57:49 UTC

[airavata-django-portal] branch develop updated: AIRAVATA-3543 Auto update nodeCount/totalCPUCount based on cpuPerNode

This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git


The following commit(s) were added to refs/heads/develop by this push:
     new 510cbe4  AIRAVATA-3543 Auto update nodeCount/totalCPUCount based on cpuPerNode
510cbe4 is described below

commit 510cbe42e22c5b444b2887820d94d1c8be3904a5
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Mon Jan 3 14:47:14 2022 -0500

    AIRAVATA-3543 Auto update nodeCount/totalCPUCount based on cpuPerNode
---
 .../components/experiment/QueueSettingsEditor.vue  |  27 ++++-
 .../js/web-components/QueueSettingsEditor.vue      |   5 +-
 .../js/web-components/store.js                     |  20 +++-
 .../tests/unit/web-components/store.spec.js        | 131 +++++++++++++++++++++
 4 files changed, 179 insertions(+), 4 deletions(-)

diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue
index dc9bb73..b8aeb72 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/QueueSettingsEditor.vue
@@ -73,6 +73,7 @@
               :max="maxNodes"
               v-model="data.nodeCount"
               required
+              @input="nodeCountChanged"
               :state="getValidationState('nodeCount', true)"
             >
             </b-form-input>
@@ -94,12 +95,16 @@
               :max="maxCPUCount"
               v-model="data.totalCPUCount"
               required
+              @input="cpuCountChanged"
               :state="getValidationState('totalCPUCount', true)"
             >
             </b-form-input>
             <div slot="description">
               <i class="fa fa-info-circle" aria-hidden="true"></i>
-              Max Allowed Cores = {{ maxCPUCount }}
+              Max Allowed Cores = {{ maxCPUCount
+              }}<template v-if="queue && queue.cpuPerNode > 0"
+                >. There are {{ queue.cpuPerNode }} cores per node.
+              </template>
             </div>
           </b-form-group>
           <b-form-group
@@ -413,6 +418,26 @@ export default {
         );
       }
     },
+    nodeCountChanged() {
+      if (this.selectedQueueDefault.cpuPerNode > 0) {
+        const nodeCount = parseInt(this.data.nodeCount);
+        this.data.totalCPUCount = Math.min(
+          nodeCount * this.selectedQueueDefault.cpuPerNode,
+          this.maxCPUCount
+        );
+      }
+    },
+    cpuCountChanged() {
+      if (this.selectedQueueDefault.cpuPerNode > 0) {
+        const cpuCount = parseInt(this.data.totalCPUCount);
+        if (cpuCount > 0) {
+          this.data.nodeCount = Math.min(
+            Math.ceil(cpuCount / this.selectedQueueDefault.cpuPerNode),
+            this.maxNodes
+          );
+        }
+      }
+    },
   },
   watch: {
     appDeploymentId() {
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue
index 3c2a83d..c62e546 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/QueueSettingsEditor.vue
@@ -75,7 +75,10 @@
         </b-form-input>
         <div slot="description">
           <i class="fa fa-info-circle" aria-hidden="true"></i>
-          Max Allowed Cores = {{ maxAllowedCores }}
+          Max Allowed Cores = {{ maxAllowedCores
+          }}<template v-if="queue && queue.cpuPerNode > 0"
+            >. There are {{ queue.cpuPerNode }} cores per node.
+          </template>
         </div>
       </b-form-group>
       <b-form-group label="Wall Time Limit" label-for="walltime-limit">
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js
index 3ebdf43..2f1be91 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/web-components/store.js
@@ -198,11 +198,27 @@ export const actions = {
       commit("setLazyQueueName", { queueName });
     }
   },
-  updateTotalCPUCount({ commit }, { totalCPUCount }) {
+  updateTotalCPUCount({ commit, getters }, { totalCPUCount }) {
     commit("updateTotalCPUCount", { totalCPUCount });
+    if (getters.queue.cpuPerNode > 0) {
+      const totalCPUCountInt = parseInt(totalCPUCount);
+      const nodeCount = Math.min(
+        Math.ceil(totalCPUCountInt / getters.queue.cpuPerNode),
+        getters.maxAllowedNodes
+      );
+      commit("updateNodeCount", { nodeCount });
+    }
   },
-  updateNodeCount({ commit }, { nodeCount }) {
+  updateNodeCount({ commit, getters }, { nodeCount }) {
     commit("updateNodeCount", { nodeCount });
+    if (getters.queue.cpuPerNode > 0) {
+      const nodeCountInt = parseInt(nodeCount);
+      const totalCPUCount = Math.min(
+        nodeCountInt * getters.queue.cpuPerNode,
+        getters.maxAllowedCores
+      );
+      commit("updateTotalCPUCount", { totalCPUCount });
+    }
   },
   updateWallTimeLimit({ commit }, { wallTimeLimit }) {
     commit("updateWallTimeLimit", { wallTimeLimit });
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/web-components/store.spec.js b/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/web-components/store.spec.js
index f3cf381..8ff8967 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/web-components/store.spec.js
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/web-components/store.spec.js
@@ -706,3 +706,134 @@ test("initializeQueue: when no queue selected, settings are set to 0", (done) =>
     done,
   });
 });
+
+test("updateNodeCount: only update nodeCount when cpuPerNode <= 0", (done) => {
+  const mockGetters = {
+    queue: new models.BatchQueue({
+      cpuPerNode: 0,
+    }),
+  };
+  const expectedMutations = [
+    { type: "updateNodeCount", payload: { nodeCount: 7 } },
+  ];
+  testAction(actions.updateNodeCount, {
+    payload: {
+      nodeCount: 7,
+    },
+    getters: mockGetters,
+    expectedMutations,
+    done,
+  });
+});
+
+test("updateNodeCount: update also totalCPUCount when cpuPerNode > 0", (done) => {
+  const nodeCount = 4;
+  const mockGetters = {
+    queue: new models.BatchQueue({
+      cpuPerNode: 24,
+    }),
+    maxAllowedCores: 1000,
+  };
+  const expectedMutations = [
+    { type: "updateNodeCount", payload: { nodeCount } },
+    { type: "updateTotalCPUCount", payload: { totalCPUCount: 96 } },
+  ];
+  testAction(actions.updateNodeCount, {
+    payload: {
+      nodeCount,
+    },
+    getters: mockGetters,
+    expectedMutations,
+    done,
+  });
+});
+
+test("updateNodeCount: update totalCPUCount when cpuPerNode > 0, but apply maximums", (done) => {
+  const nodeCount = 4;
+  const mockGetters = {
+    queue: new models.BatchQueue({
+      cpuPerNode: 24,
+    }),
+    maxAllowedCores: 50,
+  };
+  const expectedMutations = [
+    { type: "updateNodeCount", payload: { nodeCount } },
+    { type: "updateTotalCPUCount", payload: { totalCPUCount: 50 } },
+  ];
+  testAction(actions.updateNodeCount, {
+    payload: {
+      nodeCount,
+    },
+    getters: mockGetters,
+    expectedMutations,
+    done,
+  });
+});
+
+test("updateTotalCPUCount: only update totalCPUCount when cpuPerNode <= 0", (done) => {
+  const totalCPUCount = 23;
+  const mockGetters = {
+    queue: new models.BatchQueue({
+      cpuPerNode: 0,
+    }),
+  };
+  const expectedMutations = [
+    { type: "updateTotalCPUCount", payload: { totalCPUCount } },
+  ];
+  testAction(actions.updateTotalCPUCount, {
+    payload: {
+      totalCPUCount,
+    },
+    getters: mockGetters,
+    expectedMutations,
+    done,
+  });
+});
+
+test("updateTotalCPUCount: update also nodeCount when cpuPerNode > 0", (done) => {
+  const nodeCount = 4;
+  const totalCPUCount = 96;
+  const mockGetters = {
+    queue: new models.BatchQueue({
+      cpuPerNode: 24,
+    }),
+    maxAllowedNodes: 1000,
+  };
+  const expectedMutations = [
+    { type: "updateTotalCPUCount", payload: { totalCPUCount } },
+    { type: "updateNodeCount", payload: { nodeCount } },
+  ];
+  testAction(actions.updateTotalCPUCount, {
+    payload: {
+      totalCPUCount,
+    },
+    getters: mockGetters,
+    expectedMutations,
+    done,
+  });
+});
+
+test("updateTotalCPUCount: update nodeCount when cpuPerNode > 0, but apply maximums", (done) => {
+  const totalCPUCount = 96;
+  const mockGetters = {
+    queue: new models.BatchQueue({
+      cpuPerNode: 24,
+    }),
+    maxAllowedNodes: 2,
+  };
+  expect(totalCPUCount / mockGetters.queue.cpuPerNode).toBeGreaterThan(
+    mockGetters.maxAllowedNodes
+  );
+  const expectedMutations = [
+    { type: "updateTotalCPUCount", payload: { totalCPUCount } },
+    { type: "updateNodeCount", payload: { nodeCount: 2 } },
+  ];
+  testAction(actions.updateTotalCPUCount, {
+    payload: {
+      totalCPUCount,
+    },
+    getters: mockGetters,
+    expectedMutations,
+    done,
+  });
+});