diff options
author | Martin Polden <mpolden@mpolden.no> | 2022-11-16 15:36:09 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2022-11-17 11:57:56 +0100 |
commit | de749a8872fd1d96b7ae7b194b80764abe2768ed (patch) | |
tree | 104addc41434e6ea169faf5d754bfd1dfba6212b /config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java | |
parent | d991ae45a85bf5520a5043ccc07d4d21424cba97 (diff) |
Support GPU in node specification
Diffstat (limited to 'config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java')
-rw-r--r-- | config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java index 25771f1906b..e6bd7c70a82 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java @@ -120,10 +120,48 @@ public class NodeResources { } + public record GpuResources(int count, double memoryGb) { + + private static final GpuResources none = new GpuResources(0, 0); + + public GpuResources { + if (count < 0) throw new IllegalArgumentException("GPU count cannot be negative, got " + count); + if (memoryGb < 0) throw new IllegalArgumentException("GPU memory cannot be negative, got " + memoryGb); + validate(memoryGb, "memory"); + } + + private double totalMemory() { + return count * memoryGb; + } + + public boolean lessThan(GpuResources other) { + return totalMemory() < other.totalMemory(); + } + + public boolean isDefault() { return this.equals(getDefault()); } + + public static GpuResources getDefault() { return none; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GpuResources that = (GpuResources) o; + return count == that.count && equal(this.memoryGb, that.memoryGb); + } + + @Override + public int hashCode() { + return Objects.hash(count, memoryGb); + } + + } + private final double vcpu; private final double memoryGb; private final double diskGb; private final double bandwidthGbps; + private final GpuResources gpuResources; private final DiskSpeed diskSpeed; private final StorageType storageType; private final Architecture architecture; @@ -133,18 +171,23 @@ public class NodeResources { } public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed) { - this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, StorageType.getDefault(), Architecture.getDefault()); + this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, StorageType.getDefault(), Architecture.getDefault(), GpuResources.getDefault()); } public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed, StorageType storageType) { - this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, Architecture.getDefault()); + this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, Architecture.getDefault(), GpuResources.getDefault()); } public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed, StorageType storageType, Architecture architecture) { + this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture, GpuResources.getDefault()); + } + + public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed, StorageType storageType, Architecture architecture, GpuResources gpuResources) { this.vcpu = validate(vcpu, "vcpu"); this.memoryGb = validate(memoryGb, "memory"); this.diskGb = validate(diskGb, "disk"); this.bandwidthGbps = validate(bandwidthGbps, "bandwidth"); + this.gpuResources = gpuResources; this.diskSpeed = diskSpeed; this.storageType = storageType; this.architecture = architecture; @@ -157,6 +200,7 @@ public class NodeResources { public DiskSpeed diskSpeed() { return diskSpeed; } public StorageType storageType() { return storageType; } public Architecture architecture() { return architecture; } + public GpuResources gpuResources() { return gpuResources; } /** Returns the standard cost of these resources, in dollars per hour */ public double cost() { @@ -265,6 +309,7 @@ public class NodeResources { if ( ! equal(this.memoryGb, other.memoryGb)) return false; if ( ! equal(this.diskGb, other.diskGb)) return false; if ( ! equal(this.bandwidthGbps, other.bandwidthGbps)) return false; + if ( ! this.gpuResources.equals(other.gpuResources)) return false; if (this.diskSpeed != other.diskSpeed) return false; if (this.storageType != other.storageType) return false; if (this.architecture != other.architecture) return false; @@ -306,6 +351,12 @@ public class NodeResources { sb.append(", storage type: ").append(storageType); } sb.append(", architecture: ").append(architecture); + if ( !gpuResources.isDefault()) { + sb.append(", gpu count: ").append(gpuResources.count()); + sb.append(", gpu memory: "); + appendDouble(sb, memoryGb); + sb.append(" Gb"); + } sb.append(']'); return sb.toString(); } @@ -318,6 +369,7 @@ public class NodeResources { if (this.memoryGb < other.memoryGb) return false; if (this.diskGb < other.diskGb) return false; if (this.bandwidthGbps < other.bandwidthGbps) return false; + if (this.gpuResources.lessThan(other.gpuResources)) return false; // Why doesn't a fast disk satisfy a slow disk? Because if slow disk is explicitly specified // (i.e not "any"), you should not randomly, sometimes get a faster disk as that means you may @@ -339,6 +391,7 @@ public class NodeResources { if ( ! equal(this.memoryGb, other.memoryGb)) return false; if ( ! equal(this.diskGb, other.diskGb)) return false; if ( ! equal(this.bandwidthGbps, other.bandwidthGbps)) return false; + if ( ! this.gpuResources.equals(other.gpuResources)) return false; if ( ! this.diskSpeed.compatibleWith(other.diskSpeed)) return false; if ( ! this.storageType.compatibleWith(other.storageType)) return false; if ( ! this.architecture.compatibleWith(other.architecture)) return false; @@ -371,7 +424,7 @@ public class NodeResources { return this.isUnspecified() ? Optional.empty() : Optional.of(this); } - private boolean equal(double a, double b) { + private static boolean equal(double a, double b) { return Math.abs(a - b) < 0.00000001; } @@ -396,7 +449,7 @@ public class NodeResources { return new NodeResources(cpu, mem, dsk, 0.3, DiskSpeed.getDefault(), StorageType.getDefault(), Architecture.x86_64); } - private double validate(double value, String valueName) { + private static double validate(double value, String valueName) { if (Double.isNaN(value)) throw new IllegalArgumentException(valueName + " cannot be NaN"); if (Double.isInfinite(value)) throw new IllegalArgumentException(valueName + " cannot be infinite"); return value; |