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,
+ });
+});