From c238ad528250533981d68ac76c234ec4649a371e Mon Sep 17 00:00:00 2001 From: Joon-Klaps Date: Wed, 11 Mar 2026 13:37:32 +0100 Subject: [PATCH 1/5] Expand available resources to also support other resourcers then nvidia Signed-off-by: Joon-Klaps --- .../nextflow/k8s/model/PodSpecBuilder.groovy | 28 ++++++--- .../k8s/model/PodSpecBuilderTest.groovy | 57 ++++++------------- 2 files changed, 36 insertions(+), 49 deletions(-) diff --git a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy index 2c70832039..abe7034ddb 100644 --- a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy +++ b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy @@ -680,19 +680,29 @@ class PodSpecBuilder { @PackageScope String getAcceleratorType(AcceleratorResource accelerator) { - def type = accelerator.type ?: 'nvidia.com' - - if ( type.contains('/') ) - // Assume the user has fully specified the resource type. - return type - - // Assume we're using GPU and update as necessary. - if( !type.contains('.') ) type += '.com' - type += '/gpu' + // Default to standard NVIDIA GPU if left entirely blank. + def type = accelerator.type?.toLowerCase() ?: 'nvidia.com/gpu' + if (type.contains('/')) { + // Assume the user has fully specified the resource type. return type } + // Map common vendor shorthands to their standard K8s Extended Resource strings. + if (type =~ /\b(nvidia|tesla|ampere|h100|a100)\b/) return 'nvidia.com/gpu' + if (type =~ /\b(amd|radeon|instinct)\b/) return 'amd.com/gpu' + if (type =~ /\b(tpu|google)\b/) return 'google.com/tpu' + if (type =~ /\b(neuron|inferentia|trainium|aws)\b/) return 'aws.amazon.com/neuron' + if (type =~ /\b(intel|gaudi)\b/) return 'gpu.intel.com/i915' + + // keep custom domain names + if( !type.contains('.') ) type += '.com' + + // Append /gpu if not there yet + return "${type}/gpu" + +} + @PackageScope Map addAcceleratorResources(AcceleratorResource accelerator, Map res) { diff --git a/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy b/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy index d3ea3f9d57..607371b751 100644 --- a/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy +++ b/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy @@ -613,47 +613,24 @@ class PodSpecBuilderTest extends Specification { given: def builder = new PodSpecBuilder() - when: - def res = builder.addAcceleratorResources(new AcceleratorResource(request:2, limit: 5), null) - then: - res.requests == ['nvidia.com/gpu': 2] - res.limits == ['nvidia.com/gpu': 5] - - when: - res = builder.addAcceleratorResources(new AcceleratorResource(limit: 5, type:'foo'), null) - then: - res.requests == ['foo.com/gpu': 5] - res.limits == ['foo.com/gpu': 5] - - when: - res = builder.addAcceleratorResources(new AcceleratorResource(request: 5, type:'foo.org'), null) - then: - res.requests == ['foo.org/gpu': 5] - res.limits == null - - when: - res = builder.addAcceleratorResources(new AcceleratorResource(request: 5, type: 'foo.org'), [requests: [cpu: 2]]) - then: - res.requests == [cpu: 2, 'foo.org/gpu': 5] - res.limits == null - - when: - res = builder.addAcceleratorResources(new AcceleratorResource(request: 5, limit: 10, type: 'foo.org'), [requests: [cpu: 2]]) - then: - res.requests == [cpu: 2, 'foo.org/gpu': 5] - res.limits == ['foo.org/gpu': 10] - - when: - res = builder.addAcceleratorResources(new AcceleratorResource(request: 5, type:'example.com/fpga'), null) - then: - res.requests == ['example.com/fpga': 5] - res.limits == null + expect: + def res = builder.addAcceleratorResources(new AcceleratorResource(request: req, limit: lim, type: inputType), existing) + res.requests == expectedReq + res.limits == expectedLim - when: - res = builder.addAcceleratorResources(new AcceleratorResource(request: 5, limit: 10, type: 'example.com/fpga'), [requests: [cpu: 2]]) - then: - res.requests == [cpu: 2, 'example.com/fpga': 5] - res.limits == ['example.com/fpga': 10] + where: + inputType | req | lim | existing | expectedReq | expectedLim + null | 2 | 5 | null | ['nvidia.com/gpu': 2] | ['nvidia.com/gpu': 5] + 'foo' | null| 5 | null | ['foo.com/gpu': 5] | ['foo.com/gpu': 5] + 'foo.org' | 5 | null| null | ['foo.org/gpu': 5] | null + 'foo.org' | 5 | null| [requests: [cpu: 2]] | [cpu: 2, 'foo.org/gpu': 5] | null + 'foo.org' | 5 | 10 | [requests: [cpu: 2]] | [cpu: 2, 'foo.org/gpu': 5] | ['foo.org/gpu': 10] + 'example.com/fpga' | 5 | null| null | ['example.com/fpga': 5] | null + 'nvidia-tesla-k80' | 4 | 4 | null | ['nvidia.com/gpu': 4] | ['nvidia.com/gpu': 4] + 'tpu-v5-lite-podslice' | 8 | 8 | null | ['google.com/tpu': 8] | ['google.com/tpu': 8] + 'amd-instinct-mi300' | 2 | 2 | null | ['amd.com/gpu': 2] | ['amd.com/gpu': 2] + 'aws-trn1-32xlarge' | 8 | 8 | null | ['aws.amazon.com/neuron': 8] | ['aws.amazon.com/neuron': 8] + 'intel-gaudi-3' | 1 | 1 | null | ['gpu.intel.com/i915': 1] | ['gpu.intel.com/i915': 1] } def 'should add resources limits' () { From 971e90c967b98b28e0bc56945f95f119f8bf7f8a Mon Sep 17 00:00:00 2001 From: Joon-Klaps Date: Wed, 11 Mar 2026 13:59:01 +0100 Subject: [PATCH 2/5] fix indent Signed-off-by: Joon-Klaps --- .../nextflow/k8s/model/PodSpecBuilder.groovy | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy index abe7034ddb..489ed3902d 100644 --- a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy +++ b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy @@ -680,28 +680,28 @@ class PodSpecBuilder { @PackageScope String getAcceleratorType(AcceleratorResource accelerator) { - // Default to standard NVIDIA GPU if left entirely blank. - def type = accelerator.type?.toLowerCase() ?: 'nvidia.com/gpu' + // Default to standard NVIDIA GPU if left entirely blank. + def type = accelerator.type?.toLowerCase() ?: 'nvidia.com' - if (type.contains('/')) { - // Assume the user has fully specified the resource type. - return type - } + if (type.contains('/')) { + // Assume the user has fully specified the resource type. + return type + } - // Map common vendor shorthands to their standard K8s Extended Resource strings. - if (type =~ /\b(nvidia|tesla|ampere|h100|a100)\b/) return 'nvidia.com/gpu' - if (type =~ /\b(amd|radeon|instinct)\b/) return 'amd.com/gpu' - if (type =~ /\b(tpu|google)\b/) return 'google.com/tpu' - if (type =~ /\b(neuron|inferentia|trainium|aws)\b/) return 'aws.amazon.com/neuron' - if (type =~ /\b(intel|gaudi)\b/) return 'gpu.intel.com/i915' + // Map common vendor shorthands to their standard K8s Extended Resource strings. + if (type =~ /\b(nvidia|tesla|ampere|h100|a100)\b/) return 'nvidia.com/gpu' + if (type =~ /\b(amd|radeon|instinct)\b/) return 'amd.com/gpu' + if (type =~ /\b(tpu|google)\b/) return 'google.com/tpu' + if (type =~ /\b(neuron|inferentia|trainium|aws)\b/) return 'aws.amazon.com/neuron' + if (type =~ /\b(intel|gaudi)\b/) return 'gpu.intel.com/i915' - // keep custom domain names - if( !type.contains('.') ) type += '.com' + // keep custom domain names + if( !type.contains('.') ) type += '.com' - // Append /gpu if not there yet - return "${type}/gpu" + // Append /gpu if not there yet + return "${type}/gpu" -} + } @PackageScope From 77894ab702ee08ea35364d43f738c503488f0ac4 Mon Sep 17 00:00:00 2001 From: Joon-Klaps Date: Wed, 11 Mar 2026 14:00:14 +0100 Subject: [PATCH 3/5] minimise changes Signed-off-by: Joon-Klaps --- .../src/main/nextflow/k8s/model/PodSpecBuilder.groovy | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy index 489ed3902d..a6f8f529f9 100644 --- a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy +++ b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy @@ -695,12 +695,11 @@ class PodSpecBuilder { if (type =~ /\b(neuron|inferentia|trainium|aws)\b/) return 'aws.amazon.com/neuron' if (type =~ /\b(intel|gaudi)\b/) return 'gpu.intel.com/i915' - // keep custom domain names + // Assume we're using GPU and update as necessary. if( !type.contains('.') ) type += '.com' + type += '/gpu' - // Append /gpu if not there yet - return "${type}/gpu" - + return type } From 4585a143399a62c99c47b536dfe0f5d8d262669d Mon Sep 17 00:00:00 2001 From: Joon-Klaps Date: Wed, 11 Mar 2026 14:02:08 +0100 Subject: [PATCH 4/5] other minimal changes Signed-off-by: Joon-Klaps --- .../nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy index a6f8f529f9..41b57545e5 100644 --- a/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy +++ b/plugins/nf-k8s/src/main/nextflow/k8s/model/PodSpecBuilder.groovy @@ -683,10 +683,9 @@ class PodSpecBuilder { // Default to standard NVIDIA GPU if left entirely blank. def type = accelerator.type?.toLowerCase() ?: 'nvidia.com' - if (type.contains('/')) { + if ( type.contains('/') ) // Assume the user has fully specified the resource type. return type - } // Map common vendor shorthands to their standard K8s Extended Resource strings. if (type =~ /\b(nvidia|tesla|ampere|h100|a100)\b/) return 'nvidia.com/gpu' From 163f1c7f0687e68df407cf0ed6d81f6c6904e9c9 Mon Sep 17 00:00:00 2001 From: Joon-Klaps Date: Wed, 11 Mar 2026 14:03:44 +0100 Subject: [PATCH 5/5] align space Signed-off-by: Joon-Klaps --- .../src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy b/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy index 607371b751..3069fd9760 100644 --- a/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy +++ b/plugins/nf-k8s/src/test/nextflow/k8s/model/PodSpecBuilderTest.groovy @@ -622,7 +622,7 @@ class PodSpecBuilderTest extends Specification { inputType | req | lim | existing | expectedReq | expectedLim null | 2 | 5 | null | ['nvidia.com/gpu': 2] | ['nvidia.com/gpu': 5] 'foo' | null| 5 | null | ['foo.com/gpu': 5] | ['foo.com/gpu': 5] - 'foo.org' | 5 | null| null | ['foo.org/gpu': 5] | null + 'foo.org' | 5 | null| null | ['foo.org/gpu': 5] | null 'foo.org' | 5 | null| [requests: [cpu: 2]] | [cpu: 2, 'foo.org/gpu': 5] | null 'foo.org' | 5 | 10 | [requests: [cpu: 2]] | [cpu: 2, 'foo.org/gpu': 5] | ['foo.org/gpu': 10] 'example.com/fpga' | 5 | null| null | ['example.com/fpga': 5] | null