bestClusters = ({ minClusterMem = 0, minClusterCpus = 0, minInstanceMem = 0, minInstanceCpus = 0, arch = "x86_64", spot = false, currentRuntime, currentThreads } = {}) => {
let clusters = instanceCosts
.params({
minClusterMem,
minClusterCpus,
minInstanceMem,
minInstanceCpus,
arch,
})
.filter(
(d, $) => $.arch === 'both' ? true : d.arch === $.arch
)
.filter(
(d, $) => (d.memoryGib >= $.minInstanceMem) && (d.vcpus >= $.minInstanceCpus)
)
.impute({
hourlyPriceSpot: Infinity
})
.derive({
count: (d, $) => op.greatest(
op.ceil($.minClusterMem / d.memoryGib),
op.ceil($.minClusterCpus / d.vcpus),
)
})
.derive({
totalMemoryGib: d => d.memoryGib * d.count,
totalVcpus: d => d.vcpus * d.count,
totalHourlyPrice: d => d.hourlyPrice * d.count,
totalHourlyPriceSpot: d => d.hourlyPriceSpot * d.count,
})
.derive({
extraMemGiB: (d, $) => d.totalMemoryGib - $.minClusterMem,
extraCpus: (d, $) => d.totalVcpus - $.minClusterCpus,
})
.groupby('totalMemoryGib', 'totalVcpus')
.filter(d => d.totalHourlyPrice === op.min(d.totalHourlyPrice))
.ungroup()
.select(aq.not('hourlyPrice', 'hourlyPriceSpot'))
console.log(currentRuntime);
if (currentRuntime === undefined || currentThreads === undefined) {
clusters = clusters
.orderby((spot ? 'totalHourlyPriceSpot' : 'totalHourlyPrice'), 'extraMemGiB', 'extraCpus')
} else {
clusters = clusters
.params({currentRuntime, currentThreads, spot})
.derive({
runtime: (d, $) => ($.currentThreads / d.totalVcpus) * $.currentRuntime
})
.derive({
cost: (d, $) => d[$.spot ? 'totalHourlyPriceSpot' : 'totalHourlyPrice'] / (3600 / d.runtime)
})
.orderby('cost', (spot ? 'totalHourlyPriceSpot' : 'totalHourlyPrice'), 'extraMemGiB', 'extraCpus')
}
return clusters
}