diff --git a/v1/providers/launchpad/instancetype.go b/v1/providers/launchpad/instancetype.go index a66f941..7006114 100644 --- a/v1/providers/launchpad/instancetype.go +++ b/v1/providers/launchpad/instancetype.go @@ -242,7 +242,7 @@ func launchpadGpusToGpus(lpGpus []openapi.InstanceTypeGpu) []v1.GPU { Manufacturer: v1.GetManufacturer(gp.Manufacturer), Count: gp.Count, Memory: gbToBytes(gp.MemoryGb), - MemoryBytes: v1.NewBytes(v1.BytesValue(int64(gp.MemoryGb)), v1.Gigabyte), + MemoryBytes: launchpadGPUMemoryBytes(gp.MemoryGb), NetworkDetails: string(gp.InterconnectionType), Type: strings.ToUpper(gp.Model), } @@ -347,7 +347,7 @@ func launchpadGputoGpu(node openapi.Node) *v1.GPU { var lpGpuMemoryBytes v1.Bytes if lpGpu.Memory != nil { lpGpuMemory = gbToBytes(*lpGpu.Memory) - lpGpuMemoryBytes = v1.NewBytes(v1.BytesValue(*lpGpu.Memory), v1.Gigabyte) + lpGpuMemoryBytes = launchpadGPUMemoryBytes(*lpGpu.Memory) } gpu := &v1.GPU{ @@ -361,6 +361,11 @@ func launchpadGputoGpu(node openapi.Node) *v1.GPU { return gpu } +// Launchpad's GPU memory values are nominal decimal-GB capacities. +func launchpadGPUMemoryBytes(memoryGB int32) v1.Bytes { + return v1.NewBytes(v1.BytesValue(memoryGB), v1.Gigabyte) +} + func launchpadNodeToSupportedStorage(node openapi.Node) []v1.Storage { if len(node.Storage) == 0 { return nil diff --git a/v1/providers/launchpad/instancetype_test.go b/v1/providers/launchpad/instancetype_test.go index 43822f3..51b460e 100644 --- a/v1/providers/launchpad/instancetype_test.go +++ b/v1/providers/launchpad/instancetype_test.go @@ -8,6 +8,7 @@ import ( "github.com/brevdev/cloud/internal/validation" v1 "github.com/brevdev/cloud/v1" + openapi "github.com/brevdev/cloud/v1/providers/launchpad/gen/launchpad" ) func TestGetInstanceTypes(t *testing.T) { @@ -85,6 +86,15 @@ func TestInstanceTypeInfo(t *testing.T) { } } +func TestLaunchpadGpusToGpusUsesNominalGB(t *testing.T) { + t.Parallel() + + gpus := launchpadGpusToGpus([]openapi.InstanceTypeGpu{{MemoryGb: 48}}) + + require.Len(t, gpus, 1) + require.Equal(t, v1.NewBytes(48, v1.Gigabyte), gpus[0].MemoryBytes) +} + func TestMakeGenericInstanceTypeID(t *testing.T) { t.Parallel() diff --git a/v1/providers/nebius/instancetype.go b/v1/providers/nebius/instancetype.go index 07e9a48..4906403 100644 --- a/v1/providers/nebius/instancetype.go +++ b/v1/providers/nebius/instancetype.go @@ -209,7 +209,7 @@ func (c *NebiusClient) getInstanceTypesForLocation(ctx context.Context, platform Name: gpuName, Manufacturer: v1.ManufacturerNVIDIA, // Nebius currently only supports NVIDIA GPUs Memory: memory, // Populate VRAM based on GPU type - MemoryBytes: v1.NewBytes(v1.BytesValue(int64(memory)/int64(units.Gibibyte)), v1.Gibibyte), + MemoryBytes: gpuMemoryBytes(memory), } instanceType.SupportedGPUs = []v1.GPU{gpu} } @@ -615,6 +615,10 @@ func parseBlackwellGPUType(platformName string) string { } } +func gpuMemoryBytes(memory units.Base2Bytes) v1.Bytes { + return v1.NewBytes(v1.BytesValue(int64(memory)/int64(units.Gibibyte)), v1.Gigabyte) +} + // getGPUMemory returns the VRAM for a given GPU type in GiB func getGPUMemory(gpuType string) units.Base2Bytes { // Static mapping of GPU types to their VRAM capacities diff --git a/v1/providers/nebius/instancetype_test.go b/v1/providers/nebius/instancetype_test.go index 4a7915f..e1d41cc 100644 --- a/v1/providers/nebius/instancetype_test.go +++ b/v1/providers/nebius/instancetype_test.go @@ -18,6 +18,14 @@ func TestNebiusPlatformArchitecture(t *testing.T) { require.Equal(t, cloudv1.ArchitectureUnknown, nebiusPlatformArchitecture("future-platform")) } +func TestNebiusGPUMemoryUsesNominalGB(t *testing.T) { + t.Parallel() + + memory := getGPUMemory("L40S") + + require.Equal(t, cloudv1.NewBytes(48, cloudv1.Gigabyte), gpuMemoryBytes(memory)) +} + func TestApplyInstanceTypeFiltersUsesArchitectureMetadata(t *testing.T) { t.Parallel() diff --git a/v1/providers/sfcomputev2/instancetype.go b/v1/providers/sfcomputev2/instancetype.go index ebe9d82..6feef4a 100644 --- a/v1/providers/sfcomputev2/instancetype.go +++ b/v1/providers/sfcomputev2/instancetype.go @@ -42,7 +42,7 @@ var h100InstanceTypeMetadata = func() sfcInstanceTypeMetadata { m := sfcInstanceTypeMetadata{ diskBytes: v1.NewBytes(1500, v1.Gigabyte), memoryBytes: v1.NewBytes(960, v1.Gigabyte), - gpuVRAM: v1.NewBytes(80, v1.Gibibyte), + gpuVRAM: v1.NewBytes(80, v1.Gigabyte), vcpu: sfcVCPU, gpuCount: sfcGPUCount, gpuManufacturer: v1.ManufacturerNVIDIA, diff --git a/v1/providers/sfcomputev2/instancetype_test.go b/v1/providers/sfcomputev2/instancetype_test.go new file mode 100644 index 0000000..a6ecd30 --- /dev/null +++ b/v1/providers/sfcomputev2/instancetype_test.go @@ -0,0 +1,16 @@ +package v2 + +import ( + "testing" + + v1 "github.com/brevdev/cloud/v1" + "github.com/stretchr/testify/require" +) + +func TestH100InstanceTypeUsesNominalGBForVRAM(t *testing.T) { + t.Parallel() + + instanceType := buildInstanceType(h100InstanceTypeMetadata, true) + + require.Equal(t, v1.NewBytes(80, v1.Gigabyte), instanceType.SupportedGPUs[0].MemoryBytes) +}