Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/compute/cloud/hyperstack/gpu.tsx
Views: 687
/*1NOT USED RIGHT NOW -- It's in compeition with machine-types.tsx2but that made more progress and is perhaps better overall, with3a filter, than this.4*/56import { Select } from "antd";7import { getModelLinks } from "./util";8import { useMemo } from "react";9import { A } from "@cocalc/frontend/components/A";10import { Icon } from "@cocalc/frontend/components/icon";11import { r_join } from "@cocalc/frontend/components/r_join";12import { filterOption } from "@cocalc/frontend/compute/util";13import { markup } from "@cocalc/util/compute/cloud/hyperstack/pricing";14import {15DEFAULT_FLAVOR,16DEFAULT_REGION,17} from "@cocalc/util/compute/cloud/hyperstack/api-types";18import {19bestCount,20getModelOptions,21getCountOptions,22parseFlavor,23encodeFlavor,24} from "./flavor";25import { capitalize, currency, plural } from "@cocalc/util/misc";26import { GPU_SPECS } from "@cocalc/util/compute/gpu-specs";27import { toGPU } from "./util";2829export default function GPU({30priceData,31setConfig,32configuration,33disabled,34state,35}) {36const region_name = configuration.region_name ?? DEFAULT_REGION;37const flavor_name = configuration.flavor_name ?? DEFAULT_FLAVOR;3839// Links is cosmetic to give an overview for users of what range of GPU models40// are available.41const links = useMemo(42() => (priceData == null ? null : getModelLinks(priceData)),43[priceData],44);4546const modelOptions = useMemo(() => {47if (priceData == null) {48return null;49}50return getModelOptions(priceData).map(51({ region, model, available, cost_per_hour, gpu }) => {52const disabled =53(state != "deprovisioned" && region != region_name) || available == 0;54const i = model.indexOf("-");55const display = model.slice(i + 1);56const gpuSpec = GPU_SPECS[toGPU(gpu)];57return {58disabled,59label: (60<div style={{ display: "flex" }}>61<div style={{ flex: 1.25 }}>NVIDIA {display}</div>62<div style={{ flex: 1.25 }}>63~{currency(markup({ cost: cost_per_hour, priceData }))}/hour per64GPU65</div>66<div style={{ flex: 1 }}>67{gpuSpec != null && <>GPU RAM: {gpuSpec.memory} GB</>}68</div>69<div style={{ flex: 0.75 }}>70{capitalize(region.toLowerCase().split("-")[0])} š71</div>72</div>73),74value: `${region}|${model}`,75search: `${display} ${region.toLowerCase()} ram:${gpuSpec?.memory}`,76};77},78);79}, [priceData, configuration.region_name]);8081const countOptions = useMemo(() => {82if (priceData == null) {83return null;84}85return getCountOptions({86flavor_name: configuration.flavor_name,87priceData,88region_name,89}).map(({ count, available = 0, cost_per_hour, gpu, quantity }) => {90const gpuSpec = GPU_SPECS[toGPU(gpu)];91return {92value: count,93label: (94<div style={{ display: "flex" }}>95<div style={{ flex: 1 }}>Ć {count} </div>96<div style={{ flex: 1 }}>97{currency(markup({ cost: cost_per_hour, priceData }))}/hour98</div>99<div style={{ flex: 1 }}>100{gpuSpec?.memory != null && (101<>GPU RAM: {quantity * gpuSpec.memory} GB</>102)}103</div>104<div style={{ flex: 1 }}>105{available} {plural(available, "GPU")} available106</div>107</div>108),109search: `${count} available:${available} ram:${110quantity * (gpuSpec?.memory ?? 0)111}`,112disabled: !available,113};114});115}, [priceData, configuration.region_name, configuration.flavor_name]);116117if (priceData == null || links == null || modelOptions == null) {118return null;119}120121const head = (122<div style={{ color: "#666", marginBottom: "5px" }}>123<b>124<Icon name="cube" /> NVIDIA GPU:{" "}125{r_join(126links.map(({ name, url }) => {127return url ? (128<A key={name} href={url}>129{name}130</A>131) : (132<span key={name}>{name}</span>133);134}),135)}136</b>137<br />138{state == "running"139? "You can only change the GPU model or quantity when the compute server is off or deprovisioned."140: "Configure your server by selecting your GPU and quantity here, or select a machine type below."}141{state == "off"142? " You can only change the region if your compute server is deprovisioned."143: ""}144<div style={{ marginTop: "10px" }}>145<Select146disabled={disabled}147style={{ width: "100%" }}148options={modelOptions as any}149value={`${region_name}|${parseFlavor(flavor_name).model}`}150onChange={(value) => {151const [region, model] = value.split("|");152setConfig({153region_name: region,154flavor_name: encodeFlavor({155model,156count: bestCount({157model,158region,159count: parseFlavor(flavor_name).count,160priceData,161}),162}),163});164}}165showSearch166optionFilterProp="children"167filterOption={filterOption}168/>169<div style={{ display: "flex", marginTop: "10px" }}>170<div171style={{172marginRight: "30px",173display: "flex",174alignItems: "center",175fontSize: "11pt",176}}177>178Number of GPUs179</div>180<div style={{ flex: 1 }}>181<Select182disabled={disabled}183style={{ width: "100%" }}184options={countOptions as any}185value={parseFlavor(flavor_name).count}186onChange={(count) => {187setConfig({188flavor_name: encodeFlavor({189...parseFlavor(flavor_name),190count,191}),192});193}}194showSearch195optionFilterProp="children"196filterOption={filterOption}197/>198</div>199</div>200</div>201</div>202);203return head;204}205206207208209