1use std::borrow::Cow;
40use std::str::FromStr;
41use std::sync::LazyLock;
42
43use either::Either;
44use url::Url;
45
46use uv_distribution_types::IndexUrl;
47use uv_normalize::PackageName;
48use uv_pep440::Version;
49use uv_platform_tags::Os;
50use uv_static::EnvVars;
51
52use crate::{Accelerator, AcceleratorError, AmdGpuArchitecture};
53
54#[derive(Debug, Copy, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
56#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
57#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
58#[serde(rename_all = "kebab-case")]
59pub enum TorchMode {
60 Auto,
62 Cpu,
64 Cu130,
66 Cu129,
68 Cu128,
70 Cu126,
72 Cu125,
74 Cu124,
76 Cu123,
78 Cu122,
80 Cu121,
82 Cu120,
84 Cu118,
86 Cu117,
88 Cu116,
90 Cu115,
92 Cu114,
94 Cu113,
96 Cu112,
98 Cu111,
100 Cu110,
102 Cu102,
104 Cu101,
106 Cu100,
108 Cu92,
110 Cu91,
112 Cu90,
114 Cu80,
116 #[serde(rename = "rocm6.4")]
118 #[cfg_attr(feature = "clap", clap(name = "rocm6.4"))]
119 Rocm64,
120 #[serde(rename = "rocm6.3")]
122 #[cfg_attr(feature = "clap", clap(name = "rocm6.3"))]
123 Rocm63,
124 #[serde(rename = "rocm6.2.4")]
126 #[cfg_attr(feature = "clap", clap(name = "rocm6.2.4"))]
127 Rocm624,
128 #[serde(rename = "rocm6.2")]
130 #[cfg_attr(feature = "clap", clap(name = "rocm6.2"))]
131 Rocm62,
132 #[serde(rename = "rocm6.1")]
134 #[cfg_attr(feature = "clap", clap(name = "rocm6.1"))]
135 Rocm61,
136 #[serde(rename = "rocm6.0")]
138 #[cfg_attr(feature = "clap", clap(name = "rocm6.0"))]
139 Rocm60,
140 #[serde(rename = "rocm5.7")]
142 #[cfg_attr(feature = "clap", clap(name = "rocm5.7"))]
143 Rocm57,
144 #[serde(rename = "rocm5.6")]
146 #[cfg_attr(feature = "clap", clap(name = "rocm5.6"))]
147 Rocm56,
148 #[serde(rename = "rocm5.5")]
150 #[cfg_attr(feature = "clap", clap(name = "rocm5.5"))]
151 Rocm55,
152 #[serde(rename = "rocm5.4.2")]
154 #[cfg_attr(feature = "clap", clap(name = "rocm5.4.2"))]
155 Rocm542,
156 #[serde(rename = "rocm5.4")]
158 #[cfg_attr(feature = "clap", clap(name = "rocm5.4"))]
159 Rocm54,
160 #[serde(rename = "rocm5.3")]
162 #[cfg_attr(feature = "clap", clap(name = "rocm5.3"))]
163 Rocm53,
164 #[serde(rename = "rocm5.2")]
166 #[cfg_attr(feature = "clap", clap(name = "rocm5.2"))]
167 Rocm52,
168 #[serde(rename = "rocm5.1.1")]
170 #[cfg_attr(feature = "clap", clap(name = "rocm5.1.1"))]
171 Rocm511,
172 #[serde(rename = "rocm4.2")]
174 #[cfg_attr(feature = "clap", clap(name = "rocm4.2"))]
175 Rocm42,
176 #[serde(rename = "rocm4.1")]
178 #[cfg_attr(feature = "clap", clap(name = "rocm4.1"))]
179 Rocm41,
180 #[serde(rename = "rocm4.0.1")]
182 #[cfg_attr(feature = "clap", clap(name = "rocm4.0.1"))]
183 Rocm401,
184 Xpu,
186}
187
188#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
189pub enum TorchSource {
190 #[default]
192 PyTorch,
193 Pyx,
195}
196
197#[derive(Debug, Clone, Eq, PartialEq)]
199pub enum TorchStrategy {
200 Cuda {
202 os: Os,
203 driver_version: Version,
204 source: TorchSource,
205 },
206 Amd {
208 os: Os,
209 gpu_architecture: AmdGpuArchitecture,
210 source: TorchSource,
211 },
212 Xpu { os: Os, source: TorchSource },
214 Backend {
216 backend: TorchBackend,
217 source: TorchSource,
218 },
219}
220
221impl TorchStrategy {
222 pub fn from_mode(
224 mode: TorchMode,
225 source: TorchSource,
226 os: &Os,
227 ) -> Result<Self, AcceleratorError> {
228 let backend = match mode {
229 TorchMode::Auto => match Accelerator::detect()? {
230 Some(Accelerator::Cuda { driver_version }) => {
231 return Ok(Self::Cuda {
232 os: os.clone(),
233 driver_version: driver_version.clone(),
234 source,
235 });
236 }
237 Some(Accelerator::Amd { gpu_architecture }) => {
238 return Ok(Self::Amd {
239 os: os.clone(),
240 gpu_architecture,
241 source,
242 });
243 }
244 Some(Accelerator::Xpu) => {
245 return Ok(Self::Xpu {
246 os: os.clone(),
247 source,
248 });
249 }
250 None => TorchBackend::Cpu,
251 },
252 TorchMode::Cpu => TorchBackend::Cpu,
253 TorchMode::Cu130 => TorchBackend::Cu130,
254 TorchMode::Cu129 => TorchBackend::Cu129,
255 TorchMode::Cu128 => TorchBackend::Cu128,
256 TorchMode::Cu126 => TorchBackend::Cu126,
257 TorchMode::Cu125 => TorchBackend::Cu125,
258 TorchMode::Cu124 => TorchBackend::Cu124,
259 TorchMode::Cu123 => TorchBackend::Cu123,
260 TorchMode::Cu122 => TorchBackend::Cu122,
261 TorchMode::Cu121 => TorchBackend::Cu121,
262 TorchMode::Cu120 => TorchBackend::Cu120,
263 TorchMode::Cu118 => TorchBackend::Cu118,
264 TorchMode::Cu117 => TorchBackend::Cu117,
265 TorchMode::Cu116 => TorchBackend::Cu116,
266 TorchMode::Cu115 => TorchBackend::Cu115,
267 TorchMode::Cu114 => TorchBackend::Cu114,
268 TorchMode::Cu113 => TorchBackend::Cu113,
269 TorchMode::Cu112 => TorchBackend::Cu112,
270 TorchMode::Cu111 => TorchBackend::Cu111,
271 TorchMode::Cu110 => TorchBackend::Cu110,
272 TorchMode::Cu102 => TorchBackend::Cu102,
273 TorchMode::Cu101 => TorchBackend::Cu101,
274 TorchMode::Cu100 => TorchBackend::Cu100,
275 TorchMode::Cu92 => TorchBackend::Cu92,
276 TorchMode::Cu91 => TorchBackend::Cu91,
277 TorchMode::Cu90 => TorchBackend::Cu90,
278 TorchMode::Cu80 => TorchBackend::Cu80,
279 TorchMode::Rocm64 => TorchBackend::Rocm64,
280 TorchMode::Rocm63 => TorchBackend::Rocm63,
281 TorchMode::Rocm624 => TorchBackend::Rocm624,
282 TorchMode::Rocm62 => TorchBackend::Rocm62,
283 TorchMode::Rocm61 => TorchBackend::Rocm61,
284 TorchMode::Rocm60 => TorchBackend::Rocm60,
285 TorchMode::Rocm57 => TorchBackend::Rocm57,
286 TorchMode::Rocm56 => TorchBackend::Rocm56,
287 TorchMode::Rocm55 => TorchBackend::Rocm55,
288 TorchMode::Rocm542 => TorchBackend::Rocm542,
289 TorchMode::Rocm54 => TorchBackend::Rocm54,
290 TorchMode::Rocm53 => TorchBackend::Rocm53,
291 TorchMode::Rocm52 => TorchBackend::Rocm52,
292 TorchMode::Rocm511 => TorchBackend::Rocm511,
293 TorchMode::Rocm42 => TorchBackend::Rocm42,
294 TorchMode::Rocm41 => TorchBackend::Rocm41,
295 TorchMode::Rocm401 => TorchBackend::Rocm401,
296 TorchMode::Xpu => TorchBackend::Xpu,
297 };
298 Ok(Self::Backend { backend, source })
299 }
300
301 pub fn applies_to(&self, package_name: &PackageName) -> bool {
303 let source = match self {
304 Self::Cuda { source, .. } => *source,
305 Self::Amd { source, .. } => *source,
306 Self::Xpu { source, .. } => *source,
307 Self::Backend { source, .. } => *source,
308 };
309 match source {
310 TorchSource::PyTorch => {
311 matches!(
312 package_name.as_str(),
313 "pytorch-triton"
314 | "pytorch-triton-rocm"
315 | "pytorch-triton-xpu"
316 | "torch"
317 | "torch-tensorrt"
318 | "torchao"
319 | "torcharrow"
320 | "torchaudio"
321 | "torchcsprng"
322 | "torchdata"
323 | "torchdistx"
324 | "torchserve"
325 | "torchtext"
326 | "torchvision"
327 | "triton"
328 )
329 }
330 TorchSource::Pyx => {
331 matches!(
332 package_name.as_str(),
333 "deepspeed"
334 | "flash-attn"
335 | "flash-attn-3"
336 | "megablocks"
337 | "natten"
338 | "pyg-lib"
339 | "pytorch-triton"
340 | "pytorch-triton-rocm"
341 | "pytorch-triton-xpu"
342 | "torch"
343 | "torch-cluster"
344 | "torch-scatter"
345 | "torch-sparse"
346 | "torch-spline-conv"
347 | "torch-tensorrt"
348 | "torchao"
349 | "torcharrow"
350 | "torchaudio"
351 | "torchcsprng"
352 | "torchdata"
353 | "torchdistx"
354 | "torchserve"
355 | "torchtext"
356 | "torchvision"
357 | "triton"
358 | "vllm"
359 )
360 }
361 }
362 }
363
364 pub fn has_system_dependency(&self, package_name: &PackageName) -> bool {
370 matches!(
371 package_name.as_str(),
372 "deepspeed"
373 | "flash-attn"
374 | "flash-attn-3"
375 | "megablocks"
376 | "natten"
377 | "torch"
378 | "torch-tensorrt"
379 | "torchao"
380 | "torcharrow"
381 | "torchaudio"
382 | "torchcsprng"
383 | "torchdata"
384 | "torchdistx"
385 | "torchtext"
386 | "torchvision"
387 | "vllm"
388 )
389 }
390
391 pub fn index_urls(&self) -> impl Iterator<Item = &IndexUrl> {
393 match self {
394 Self::Cuda {
395 os,
396 driver_version,
397 source,
398 } => {
399 match os {
404 Os::Manylinux { .. } | Os::Musllinux { .. } => {
405 Either::Left(Either::Left(Either::Left(
406 LINUX_CUDA_DRIVERS
407 .iter()
408 .filter_map(move |(backend, version)| {
409 if driver_version >= version {
410 Some(backend.index_url(*source))
411 } else {
412 None
413 }
414 })
415 .chain(std::iter::once(TorchBackend::Cpu.index_url(*source))),
416 )))
417 }
418 Os::Windows => Either::Left(Either::Left(Either::Right(
419 WINDOWS_CUDA_VERSIONS
420 .iter()
421 .filter_map(move |(backend, version)| {
422 if driver_version >= version {
423 Some(backend.index_url(*source))
424 } else {
425 None
426 }
427 })
428 .chain(std::iter::once(TorchBackend::Cpu.index_url(*source))),
429 ))),
430 Os::Macos { .. }
431 | Os::FreeBsd { .. }
432 | Os::NetBsd { .. }
433 | Os::OpenBsd { .. }
434 | Os::Dragonfly { .. }
435 | Os::Illumos { .. }
436 | Os::Haiku { .. }
437 | Os::Android { .. }
438 | Os::Pyodide { .. }
439 | Os::Ios { .. } => Either::Right(Either::Left(std::iter::once(
440 TorchBackend::Cpu.index_url(*source),
441 ))),
442 }
443 }
444 Self::Amd {
445 os,
446 gpu_architecture,
447 source,
448 } => match os {
449 Os::Manylinux { .. } | Os::Musllinux { .. } => Either::Left(Either::Right(
450 LINUX_AMD_GPU_DRIVERS
451 .iter()
452 .filter_map(move |(backend, architecture)| {
453 if gpu_architecture == architecture {
454 Some(backend.index_url(*source))
455 } else {
456 None
457 }
458 })
459 .chain(std::iter::once(TorchBackend::Cpu.index_url(*source))),
460 )),
461 Os::Windows
462 | Os::Macos { .. }
463 | Os::FreeBsd { .. }
464 | Os::NetBsd { .. }
465 | Os::OpenBsd { .. }
466 | Os::Dragonfly { .. }
467 | Os::Illumos { .. }
468 | Os::Haiku { .. }
469 | Os::Android { .. }
470 | Os::Pyodide { .. }
471 | Os::Ios { .. } => Either::Right(Either::Left(std::iter::once(
472 TorchBackend::Cpu.index_url(*source),
473 ))),
474 },
475 Self::Xpu { os, source } => match os {
476 Os::Manylinux { .. } | Os::Windows => Either::Right(Either::Right(Either::Left(
477 std::iter::once(TorchBackend::Xpu.index_url(*source)),
478 ))),
479 Os::Musllinux { .. }
480 | Os::Macos { .. }
481 | Os::FreeBsd { .. }
482 | Os::NetBsd { .. }
483 | Os::OpenBsd { .. }
484 | Os::Dragonfly { .. }
485 | Os::Illumos { .. }
486 | Os::Haiku { .. }
487 | Os::Android { .. }
488 | Os::Pyodide { .. }
489 | Os::Ios { .. } => Either::Right(Either::Left(std::iter::once(
490 TorchBackend::Cpu.index_url(*source),
491 ))),
492 },
493 Self::Backend { backend, source } => Either::Right(Either::Right(Either::Right(
494 std::iter::once(backend.index_url(*source)),
495 ))),
496 }
497 }
498}
499
500#[derive(Debug, Copy, Clone, Eq, PartialEq)]
502pub enum TorchBackend {
503 Cpu,
504 Cu130,
505 Cu129,
506 Cu128,
507 Cu126,
508 Cu125,
509 Cu124,
510 Cu123,
511 Cu122,
512 Cu121,
513 Cu120,
514 Cu118,
515 Cu117,
516 Cu116,
517 Cu115,
518 Cu114,
519 Cu113,
520 Cu112,
521 Cu111,
522 Cu110,
523 Cu102,
524 Cu101,
525 Cu100,
526 Cu92,
527 Cu91,
528 Cu90,
529 Cu80,
530 Rocm64,
531 Rocm63,
532 Rocm624,
533 Rocm62,
534 Rocm61,
535 Rocm60,
536 Rocm57,
537 Rocm56,
538 Rocm55,
539 Rocm542,
540 Rocm54,
541 Rocm53,
542 Rocm52,
543 Rocm511,
544 Rocm42,
545 Rocm41,
546 Rocm401,
547 Xpu,
548}
549
550impl TorchBackend {
551 fn index_url(self, source: TorchSource) -> &'static IndexUrl {
553 match self {
554 Self::Cpu => match source {
555 TorchSource::PyTorch => &PYTORCH_CPU_INDEX_URL,
556 TorchSource::Pyx => &PYX_CPU_INDEX_URL,
557 },
558 Self::Cu130 => match source {
559 TorchSource::PyTorch => &PYTORCH_CU130_INDEX_URL,
560 TorchSource::Pyx => &PYX_CU130_INDEX_URL,
561 },
562 Self::Cu129 => match source {
563 TorchSource::PyTorch => &PYTORCH_CU129_INDEX_URL,
564 TorchSource::Pyx => &PYX_CU129_INDEX_URL,
565 },
566 Self::Cu128 => match source {
567 TorchSource::PyTorch => &PYTORCH_CU128_INDEX_URL,
568 TorchSource::Pyx => &PYX_CU128_INDEX_URL,
569 },
570 Self::Cu126 => match source {
571 TorchSource::PyTorch => &PYTORCH_CU126_INDEX_URL,
572 TorchSource::Pyx => &PYX_CU126_INDEX_URL,
573 },
574 Self::Cu125 => match source {
575 TorchSource::PyTorch => &PYTORCH_CU125_INDEX_URL,
576 TorchSource::Pyx => &PYX_CU125_INDEX_URL,
577 },
578 Self::Cu124 => match source {
579 TorchSource::PyTorch => &PYTORCH_CU124_INDEX_URL,
580 TorchSource::Pyx => &PYX_CU124_INDEX_URL,
581 },
582 Self::Cu123 => match source {
583 TorchSource::PyTorch => &PYTORCH_CU123_INDEX_URL,
584 TorchSource::Pyx => &PYX_CU123_INDEX_URL,
585 },
586 Self::Cu122 => match source {
587 TorchSource::PyTorch => &PYTORCH_CU122_INDEX_URL,
588 TorchSource::Pyx => &PYX_CU122_INDEX_URL,
589 },
590 Self::Cu121 => match source {
591 TorchSource::PyTorch => &PYTORCH_CU121_INDEX_URL,
592 TorchSource::Pyx => &PYX_CU121_INDEX_URL,
593 },
594 Self::Cu120 => match source {
595 TorchSource::PyTorch => &PYTORCH_CU120_INDEX_URL,
596 TorchSource::Pyx => &PYX_CU120_INDEX_URL,
597 },
598 Self::Cu118 => match source {
599 TorchSource::PyTorch => &PYTORCH_CU118_INDEX_URL,
600 TorchSource::Pyx => &PYX_CU118_INDEX_URL,
601 },
602 Self::Cu117 => match source {
603 TorchSource::PyTorch => &PYTORCH_CU117_INDEX_URL,
604 TorchSource::Pyx => &PYX_CU117_INDEX_URL,
605 },
606 Self::Cu116 => match source {
607 TorchSource::PyTorch => &PYTORCH_CU116_INDEX_URL,
608 TorchSource::Pyx => &PYX_CU116_INDEX_URL,
609 },
610 Self::Cu115 => match source {
611 TorchSource::PyTorch => &PYTORCH_CU115_INDEX_URL,
612 TorchSource::Pyx => &PYX_CU115_INDEX_URL,
613 },
614 Self::Cu114 => match source {
615 TorchSource::PyTorch => &PYTORCH_CU114_INDEX_URL,
616 TorchSource::Pyx => &PYX_CU114_INDEX_URL,
617 },
618 Self::Cu113 => match source {
619 TorchSource::PyTorch => &PYTORCH_CU113_INDEX_URL,
620 TorchSource::Pyx => &PYX_CU113_INDEX_URL,
621 },
622 Self::Cu112 => match source {
623 TorchSource::PyTorch => &PYTORCH_CU112_INDEX_URL,
624 TorchSource::Pyx => &PYX_CU112_INDEX_URL,
625 },
626 Self::Cu111 => match source {
627 TorchSource::PyTorch => &PYTORCH_CU111_INDEX_URL,
628 TorchSource::Pyx => &PYX_CU111_INDEX_URL,
629 },
630 Self::Cu110 => match source {
631 TorchSource::PyTorch => &PYTORCH_CU110_INDEX_URL,
632 TorchSource::Pyx => &PYX_CU110_INDEX_URL,
633 },
634 Self::Cu102 => match source {
635 TorchSource::PyTorch => &PYTORCH_CU102_INDEX_URL,
636 TorchSource::Pyx => &PYX_CU102_INDEX_URL,
637 },
638 Self::Cu101 => match source {
639 TorchSource::PyTorch => &PYTORCH_CU101_INDEX_URL,
640 TorchSource::Pyx => &PYX_CU101_INDEX_URL,
641 },
642 Self::Cu100 => match source {
643 TorchSource::PyTorch => &PYTORCH_CU100_INDEX_URL,
644 TorchSource::Pyx => &PYX_CU100_INDEX_URL,
645 },
646 Self::Cu92 => match source {
647 TorchSource::PyTorch => &PYTORCH_CU92_INDEX_URL,
648 TorchSource::Pyx => &PYX_CU92_INDEX_URL,
649 },
650 Self::Cu91 => match source {
651 TorchSource::PyTorch => &PYTORCH_CU91_INDEX_URL,
652 TorchSource::Pyx => &PYX_CU91_INDEX_URL,
653 },
654 Self::Cu90 => match source {
655 TorchSource::PyTorch => &PYTORCH_CU90_INDEX_URL,
656 TorchSource::Pyx => &PYX_CU90_INDEX_URL,
657 },
658 Self::Cu80 => match source {
659 TorchSource::PyTorch => &PYTORCH_CU80_INDEX_URL,
660 TorchSource::Pyx => &PYX_CU80_INDEX_URL,
661 },
662 Self::Rocm64 => match source {
663 TorchSource::PyTorch => &PYTORCH_ROCM64_INDEX_URL,
664 TorchSource::Pyx => &PYX_ROCM64_INDEX_URL,
665 },
666 Self::Rocm63 => match source {
667 TorchSource::PyTorch => &PYTORCH_ROCM63_INDEX_URL,
668 TorchSource::Pyx => &PYX_ROCM63_INDEX_URL,
669 },
670 Self::Rocm624 => match source {
671 TorchSource::PyTorch => &PYTORCH_ROCM624_INDEX_URL,
672 TorchSource::Pyx => &PYX_ROCM624_INDEX_URL,
673 },
674 Self::Rocm62 => match source {
675 TorchSource::PyTorch => &PYTORCH_ROCM62_INDEX_URL,
676 TorchSource::Pyx => &PYX_ROCM62_INDEX_URL,
677 },
678 Self::Rocm61 => match source {
679 TorchSource::PyTorch => &PYTORCH_ROCM61_INDEX_URL,
680 TorchSource::Pyx => &PYX_ROCM61_INDEX_URL,
681 },
682 Self::Rocm60 => match source {
683 TorchSource::PyTorch => &PYTORCH_ROCM60_INDEX_URL,
684 TorchSource::Pyx => &PYX_ROCM60_INDEX_URL,
685 },
686 Self::Rocm57 => match source {
687 TorchSource::PyTorch => &PYTORCH_ROCM57_INDEX_URL,
688 TorchSource::Pyx => &PYX_ROCM57_INDEX_URL,
689 },
690 Self::Rocm56 => match source {
691 TorchSource::PyTorch => &PYTORCH_ROCM56_INDEX_URL,
692 TorchSource::Pyx => &PYX_ROCM56_INDEX_URL,
693 },
694 Self::Rocm55 => match source {
695 TorchSource::PyTorch => &PYTORCH_ROCM55_INDEX_URL,
696 TorchSource::Pyx => &PYX_ROCM55_INDEX_URL,
697 },
698 Self::Rocm542 => match source {
699 TorchSource::PyTorch => &PYTORCH_ROCM542_INDEX_URL,
700 TorchSource::Pyx => &PYX_ROCM542_INDEX_URL,
701 },
702 Self::Rocm54 => match source {
703 TorchSource::PyTorch => &PYTORCH_ROCM54_INDEX_URL,
704 TorchSource::Pyx => &PYX_ROCM54_INDEX_URL,
705 },
706 Self::Rocm53 => match source {
707 TorchSource::PyTorch => &PYTORCH_ROCM53_INDEX_URL,
708 TorchSource::Pyx => &PYX_ROCM53_INDEX_URL,
709 },
710 Self::Rocm52 => match source {
711 TorchSource::PyTorch => &PYTORCH_ROCM52_INDEX_URL,
712 TorchSource::Pyx => &PYX_ROCM52_INDEX_URL,
713 },
714 Self::Rocm511 => match source {
715 TorchSource::PyTorch => &PYTORCH_ROCM511_INDEX_URL,
716 TorchSource::Pyx => &PYX_ROCM511_INDEX_URL,
717 },
718 Self::Rocm42 => match source {
719 TorchSource::PyTorch => &PYTORCH_ROCM42_INDEX_URL,
720 TorchSource::Pyx => &PYX_ROCM42_INDEX_URL,
721 },
722 Self::Rocm41 => match source {
723 TorchSource::PyTorch => &PYTORCH_ROCM41_INDEX_URL,
724 TorchSource::Pyx => &PYX_ROCM41_INDEX_URL,
725 },
726 Self::Rocm401 => match source {
727 TorchSource::PyTorch => &PYTORCH_ROCM401_INDEX_URL,
728 TorchSource::Pyx => &PYX_ROCM401_INDEX_URL,
729 },
730 Self::Xpu => match source {
731 TorchSource::PyTorch => &PYTORCH_XPU_INDEX_URL,
732 TorchSource::Pyx => &PYX_XPU_INDEX_URL,
733 },
734 }
735 }
736
737 pub fn from_index(index: &Url) -> Option<Self> {
739 let backend_identifier = if index.host_str() == Some("download.pytorch.org") {
740 let mut path_segments = index.path_segments()?;
742 if path_segments.next() != Some("whl") {
743 return None;
744 }
745 path_segments.next()?
746 } else if index.host_str() == PYX_API_BASE_URL.strip_prefix("https://") {
748 let mut path_segments = index.path_segments()?;
750 if path_segments.next() != Some("simple") {
751 return None;
752 }
753 if path_segments.next() != Some("astral-sh") {
754 return None;
755 }
756 path_segments.next()?
757 } else {
758 return None;
759 };
760 Self::from_str(backend_identifier).ok()
761 }
762
763 pub fn cuda_version(&self) -> Option<Version> {
765 match self {
766 Self::Cpu => None,
767 Self::Cu130 => Some(Version::new([13, 0])),
768 Self::Cu129 => Some(Version::new([12, 9])),
769 Self::Cu128 => Some(Version::new([12, 8])),
770 Self::Cu126 => Some(Version::new([12, 6])),
771 Self::Cu125 => Some(Version::new([12, 5])),
772 Self::Cu124 => Some(Version::new([12, 4])),
773 Self::Cu123 => Some(Version::new([12, 3])),
774 Self::Cu122 => Some(Version::new([12, 2])),
775 Self::Cu121 => Some(Version::new([12, 1])),
776 Self::Cu120 => Some(Version::new([12, 0])),
777 Self::Cu118 => Some(Version::new([11, 8])),
778 Self::Cu117 => Some(Version::new([11, 7])),
779 Self::Cu116 => Some(Version::new([11, 6])),
780 Self::Cu115 => Some(Version::new([11, 5])),
781 Self::Cu114 => Some(Version::new([11, 4])),
782 Self::Cu113 => Some(Version::new([11, 3])),
783 Self::Cu112 => Some(Version::new([11, 2])),
784 Self::Cu111 => Some(Version::new([11, 1])),
785 Self::Cu110 => Some(Version::new([11, 0])),
786 Self::Cu102 => Some(Version::new([10, 2])),
787 Self::Cu101 => Some(Version::new([10, 1])),
788 Self::Cu100 => Some(Version::new([10, 0])),
789 Self::Cu92 => Some(Version::new([9, 2])),
790 Self::Cu91 => Some(Version::new([9, 1])),
791 Self::Cu90 => Some(Version::new([9, 0])),
792 Self::Cu80 => Some(Version::new([8, 0])),
793 Self::Rocm64 => None,
794 Self::Rocm63 => None,
795 Self::Rocm624 => None,
796 Self::Rocm62 => None,
797 Self::Rocm61 => None,
798 Self::Rocm60 => None,
799 Self::Rocm57 => None,
800 Self::Rocm56 => None,
801 Self::Rocm55 => None,
802 Self::Rocm542 => None,
803 Self::Rocm54 => None,
804 Self::Rocm53 => None,
805 Self::Rocm52 => None,
806 Self::Rocm511 => None,
807 Self::Rocm42 => None,
808 Self::Rocm41 => None,
809 Self::Rocm401 => None,
810 Self::Xpu => None,
811 }
812 }
813
814 pub fn rocm_version(&self) -> Option<Version> {
816 match self {
817 Self::Cpu => None,
818 Self::Cu130 => None,
819 Self::Cu129 => None,
820 Self::Cu128 => None,
821 Self::Cu126 => None,
822 Self::Cu125 => None,
823 Self::Cu124 => None,
824 Self::Cu123 => None,
825 Self::Cu122 => None,
826 Self::Cu121 => None,
827 Self::Cu120 => None,
828 Self::Cu118 => None,
829 Self::Cu117 => None,
830 Self::Cu116 => None,
831 Self::Cu115 => None,
832 Self::Cu114 => None,
833 Self::Cu113 => None,
834 Self::Cu112 => None,
835 Self::Cu111 => None,
836 Self::Cu110 => None,
837 Self::Cu102 => None,
838 Self::Cu101 => None,
839 Self::Cu100 => None,
840 Self::Cu92 => None,
841 Self::Cu91 => None,
842 Self::Cu90 => None,
843 Self::Cu80 => None,
844 Self::Rocm64 => Some(Version::new([6, 4])),
845 Self::Rocm63 => Some(Version::new([6, 3])),
846 Self::Rocm624 => Some(Version::new([6, 2, 4])),
847 Self::Rocm62 => Some(Version::new([6, 2])),
848 Self::Rocm61 => Some(Version::new([6, 1])),
849 Self::Rocm60 => Some(Version::new([6, 0])),
850 Self::Rocm57 => Some(Version::new([5, 7])),
851 Self::Rocm56 => Some(Version::new([5, 6])),
852 Self::Rocm55 => Some(Version::new([5, 5])),
853 Self::Rocm542 => Some(Version::new([5, 4, 2])),
854 Self::Rocm54 => Some(Version::new([5, 4])),
855 Self::Rocm53 => Some(Version::new([5, 3])),
856 Self::Rocm52 => Some(Version::new([5, 2])),
857 Self::Rocm511 => Some(Version::new([5, 1, 1])),
858 Self::Rocm42 => Some(Version::new([4, 2])),
859 Self::Rocm41 => Some(Version::new([4, 1])),
860 Self::Rocm401 => Some(Version::new([4, 0, 1])),
861 Self::Xpu => None,
862 }
863 }
864}
865
866impl FromStr for TorchBackend {
867 type Err = String;
868
869 fn from_str(s: &str) -> Result<Self, Self::Err> {
870 match s {
871 "cpu" => Ok(Self::Cpu),
872 "cu130" => Ok(Self::Cu130),
873 "cu129" => Ok(Self::Cu129),
874 "cu128" => Ok(Self::Cu128),
875 "cu126" => Ok(Self::Cu126),
876 "cu125" => Ok(Self::Cu125),
877 "cu124" => Ok(Self::Cu124),
878 "cu123" => Ok(Self::Cu123),
879 "cu122" => Ok(Self::Cu122),
880 "cu121" => Ok(Self::Cu121),
881 "cu120" => Ok(Self::Cu120),
882 "cu118" => Ok(Self::Cu118),
883 "cu117" => Ok(Self::Cu117),
884 "cu116" => Ok(Self::Cu116),
885 "cu115" => Ok(Self::Cu115),
886 "cu114" => Ok(Self::Cu114),
887 "cu113" => Ok(Self::Cu113),
888 "cu112" => Ok(Self::Cu112),
889 "cu111" => Ok(Self::Cu111),
890 "cu110" => Ok(Self::Cu110),
891 "cu102" => Ok(Self::Cu102),
892 "cu101" => Ok(Self::Cu101),
893 "cu100" => Ok(Self::Cu100),
894 "cu92" => Ok(Self::Cu92),
895 "cu91" => Ok(Self::Cu91),
896 "cu90" => Ok(Self::Cu90),
897 "cu80" => Ok(Self::Cu80),
898 "rocm6.4" => Ok(Self::Rocm64),
899 "rocm6.3" => Ok(Self::Rocm63),
900 "rocm6.2.4" => Ok(Self::Rocm624),
901 "rocm6.2" => Ok(Self::Rocm62),
902 "rocm6.1" => Ok(Self::Rocm61),
903 "rocm6.0" => Ok(Self::Rocm60),
904 "rocm5.7" => Ok(Self::Rocm57),
905 "rocm5.6" => Ok(Self::Rocm56),
906 "rocm5.5" => Ok(Self::Rocm55),
907 "rocm5.4.2" => Ok(Self::Rocm542),
908 "rocm5.4" => Ok(Self::Rocm54),
909 "rocm5.3" => Ok(Self::Rocm53),
910 "rocm5.2" => Ok(Self::Rocm52),
911 "rocm5.1.1" => Ok(Self::Rocm511),
912 "rocm4.2" => Ok(Self::Rocm42),
913 "rocm4.1" => Ok(Self::Rocm41),
914 "rocm4.0.1" => Ok(Self::Rocm401),
915 "xpu" => Ok(Self::Xpu),
916 _ => Err(format!("Unknown PyTorch backend: {s}")),
917 }
918 }
919}
920
921static LINUX_CUDA_DRIVERS: LazyLock<[(TorchBackend, Version); 26]> = LazyLock::new(|| {
925 [
926 (TorchBackend::Cu130, Version::new([580])),
929 (TorchBackend::Cu129, Version::new([525, 60, 13])),
930 (TorchBackend::Cu128, Version::new([525, 60, 13])),
931 (TorchBackend::Cu126, Version::new([525, 60, 13])),
932 (TorchBackend::Cu125, Version::new([525, 60, 13])),
933 (TorchBackend::Cu124, Version::new([525, 60, 13])),
934 (TorchBackend::Cu123, Version::new([525, 60, 13])),
935 (TorchBackend::Cu122, Version::new([525, 60, 13])),
936 (TorchBackend::Cu121, Version::new([525, 60, 13])),
937 (TorchBackend::Cu120, Version::new([525, 60, 13])),
938 (TorchBackend::Cu118, Version::new([450, 80, 2])),
941 (TorchBackend::Cu117, Version::new([450, 80, 2])),
942 (TorchBackend::Cu116, Version::new([450, 80, 2])),
943 (TorchBackend::Cu115, Version::new([450, 80, 2])),
944 (TorchBackend::Cu114, Version::new([450, 80, 2])),
945 (TorchBackend::Cu113, Version::new([450, 80, 2])),
946 (TorchBackend::Cu112, Version::new([450, 80, 2])),
947 (TorchBackend::Cu111, Version::new([450, 80, 2])),
948 (TorchBackend::Cu110, Version::new([450, 36, 6])),
949 (TorchBackend::Cu102, Version::new([440, 33])),
952 (TorchBackend::Cu101, Version::new([418, 39])),
953 (TorchBackend::Cu100, Version::new([410, 48])),
954 (TorchBackend::Cu92, Version::new([396, 26])),
955 (TorchBackend::Cu91, Version::new([390, 46])),
956 (TorchBackend::Cu90, Version::new([384, 81])),
957 (TorchBackend::Cu80, Version::new([375, 26])),
958 ]
959});
960
961static WINDOWS_CUDA_VERSIONS: LazyLock<[(TorchBackend, Version); 26]> = LazyLock::new(|| {
965 [
966 (TorchBackend::Cu130, Version::new([580])),
969 (TorchBackend::Cu129, Version::new([528, 33])),
970 (TorchBackend::Cu128, Version::new([528, 33])),
971 (TorchBackend::Cu126, Version::new([528, 33])),
972 (TorchBackend::Cu125, Version::new([528, 33])),
973 (TorchBackend::Cu124, Version::new([528, 33])),
974 (TorchBackend::Cu123, Version::new([528, 33])),
975 (TorchBackend::Cu122, Version::new([528, 33])),
976 (TorchBackend::Cu121, Version::new([528, 33])),
977 (TorchBackend::Cu120, Version::new([528, 33])),
978 (TorchBackend::Cu118, Version::new([452, 39])),
981 (TorchBackend::Cu117, Version::new([452, 39])),
982 (TorchBackend::Cu116, Version::new([452, 39])),
983 (TorchBackend::Cu115, Version::new([452, 39])),
984 (TorchBackend::Cu114, Version::new([452, 39])),
985 (TorchBackend::Cu113, Version::new([452, 39])),
986 (TorchBackend::Cu112, Version::new([452, 39])),
987 (TorchBackend::Cu111, Version::new([452, 39])),
988 (TorchBackend::Cu110, Version::new([451, 22])),
989 (TorchBackend::Cu102, Version::new([441, 22])),
992 (TorchBackend::Cu101, Version::new([418, 96])),
993 (TorchBackend::Cu100, Version::new([411, 31])),
994 (TorchBackend::Cu92, Version::new([398, 26])),
995 (TorchBackend::Cu91, Version::new([391, 29])),
996 (TorchBackend::Cu90, Version::new([385, 54])),
997 (TorchBackend::Cu80, Version::new([376, 51])),
998 ]
999});
1000
1001static LINUX_AMD_GPU_DRIVERS: LazyLock<[(TorchBackend, AmdGpuArchitecture); 55]> =
1014 LazyLock::new(|| {
1015 [
1016 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx900),
1018 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx906),
1019 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx908),
1020 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx90a),
1021 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx942),
1022 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx1030),
1023 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx1100),
1024 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx1101),
1025 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx1102),
1026 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx1200),
1027 (TorchBackend::Rocm64, AmdGpuArchitecture::Gfx1201),
1028 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx900),
1030 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx906),
1031 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx908),
1032 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx90a),
1033 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx942),
1034 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx1030),
1035 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx1100),
1036 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx1101),
1037 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx1102),
1038 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx1200),
1039 (TorchBackend::Rocm63, AmdGpuArchitecture::Gfx1201),
1040 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx900),
1042 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx906),
1043 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx908),
1044 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx90a),
1045 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx942),
1046 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx1030),
1047 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx1100),
1048 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx1101),
1049 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx1102),
1050 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx1200),
1051 (TorchBackend::Rocm624, AmdGpuArchitecture::Gfx1201),
1052 (TorchBackend::Rocm62, AmdGpuArchitecture::Gfx900),
1054 (TorchBackend::Rocm62, AmdGpuArchitecture::Gfx906),
1055 (TorchBackend::Rocm62, AmdGpuArchitecture::Gfx908),
1056 (TorchBackend::Rocm62, AmdGpuArchitecture::Gfx90a),
1057 (TorchBackend::Rocm62, AmdGpuArchitecture::Gfx1030),
1058 (TorchBackend::Rocm62, AmdGpuArchitecture::Gfx1100),
1059 (TorchBackend::Rocm62, AmdGpuArchitecture::Gfx942),
1060 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx900),
1062 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx906),
1063 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx908),
1064 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx90a),
1065 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx942),
1066 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx1030),
1067 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx1100),
1068 (TorchBackend::Rocm61, AmdGpuArchitecture::Gfx1101),
1069 (TorchBackend::Rocm60, AmdGpuArchitecture::Gfx900),
1071 (TorchBackend::Rocm60, AmdGpuArchitecture::Gfx906),
1072 (TorchBackend::Rocm60, AmdGpuArchitecture::Gfx908),
1073 (TorchBackend::Rocm60, AmdGpuArchitecture::Gfx90a),
1074 (TorchBackend::Rocm60, AmdGpuArchitecture::Gfx1030),
1075 (TorchBackend::Rocm60, AmdGpuArchitecture::Gfx1100),
1076 (TorchBackend::Rocm60, AmdGpuArchitecture::Gfx942),
1077 ]
1078 });
1079
1080static PYTORCH_CPU_INDEX_URL: LazyLock<IndexUrl> =
1081 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cpu").unwrap());
1082static PYTORCH_CU130_INDEX_URL: LazyLock<IndexUrl> =
1083 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu130").unwrap());
1084static PYTORCH_CU129_INDEX_URL: LazyLock<IndexUrl> =
1085 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu129").unwrap());
1086static PYTORCH_CU128_INDEX_URL: LazyLock<IndexUrl> =
1087 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu128").unwrap());
1088static PYTORCH_CU126_INDEX_URL: LazyLock<IndexUrl> =
1089 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu126").unwrap());
1090static PYTORCH_CU125_INDEX_URL: LazyLock<IndexUrl> =
1091 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu125").unwrap());
1092static PYTORCH_CU124_INDEX_URL: LazyLock<IndexUrl> =
1093 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu124").unwrap());
1094static PYTORCH_CU123_INDEX_URL: LazyLock<IndexUrl> =
1095 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu123").unwrap());
1096static PYTORCH_CU122_INDEX_URL: LazyLock<IndexUrl> =
1097 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu122").unwrap());
1098static PYTORCH_CU121_INDEX_URL: LazyLock<IndexUrl> =
1099 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu121").unwrap());
1100static PYTORCH_CU120_INDEX_URL: LazyLock<IndexUrl> =
1101 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu120").unwrap());
1102static PYTORCH_CU118_INDEX_URL: LazyLock<IndexUrl> =
1103 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu118").unwrap());
1104static PYTORCH_CU117_INDEX_URL: LazyLock<IndexUrl> =
1105 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu117").unwrap());
1106static PYTORCH_CU116_INDEX_URL: LazyLock<IndexUrl> =
1107 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu116").unwrap());
1108static PYTORCH_CU115_INDEX_URL: LazyLock<IndexUrl> =
1109 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu115").unwrap());
1110static PYTORCH_CU114_INDEX_URL: LazyLock<IndexUrl> =
1111 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu114").unwrap());
1112static PYTORCH_CU113_INDEX_URL: LazyLock<IndexUrl> =
1113 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu113").unwrap());
1114static PYTORCH_CU112_INDEX_URL: LazyLock<IndexUrl> =
1115 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu112").unwrap());
1116static PYTORCH_CU111_INDEX_URL: LazyLock<IndexUrl> =
1117 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu111").unwrap());
1118static PYTORCH_CU110_INDEX_URL: LazyLock<IndexUrl> =
1119 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu110").unwrap());
1120static PYTORCH_CU102_INDEX_URL: LazyLock<IndexUrl> =
1121 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu102").unwrap());
1122static PYTORCH_CU101_INDEX_URL: LazyLock<IndexUrl> =
1123 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu101").unwrap());
1124static PYTORCH_CU100_INDEX_URL: LazyLock<IndexUrl> =
1125 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu100").unwrap());
1126static PYTORCH_CU92_INDEX_URL: LazyLock<IndexUrl> =
1127 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu92").unwrap());
1128static PYTORCH_CU91_INDEX_URL: LazyLock<IndexUrl> =
1129 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu91").unwrap());
1130static PYTORCH_CU90_INDEX_URL: LazyLock<IndexUrl> =
1131 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu90").unwrap());
1132static PYTORCH_CU80_INDEX_URL: LazyLock<IndexUrl> =
1133 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/cu80").unwrap());
1134static PYTORCH_ROCM64_INDEX_URL: LazyLock<IndexUrl> =
1135 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm6.4").unwrap());
1136static PYTORCH_ROCM63_INDEX_URL: LazyLock<IndexUrl> =
1137 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm6.3").unwrap());
1138static PYTORCH_ROCM624_INDEX_URL: LazyLock<IndexUrl> =
1139 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm6.2.4").unwrap());
1140static PYTORCH_ROCM62_INDEX_URL: LazyLock<IndexUrl> =
1141 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm6.2").unwrap());
1142static PYTORCH_ROCM61_INDEX_URL: LazyLock<IndexUrl> =
1143 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm6.1").unwrap());
1144static PYTORCH_ROCM60_INDEX_URL: LazyLock<IndexUrl> =
1145 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm6.0").unwrap());
1146static PYTORCH_ROCM57_INDEX_URL: LazyLock<IndexUrl> =
1147 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.7").unwrap());
1148static PYTORCH_ROCM56_INDEX_URL: LazyLock<IndexUrl> =
1149 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.6").unwrap());
1150static PYTORCH_ROCM55_INDEX_URL: LazyLock<IndexUrl> =
1151 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.5").unwrap());
1152static PYTORCH_ROCM542_INDEX_URL: LazyLock<IndexUrl> =
1153 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.4.2").unwrap());
1154static PYTORCH_ROCM54_INDEX_URL: LazyLock<IndexUrl> =
1155 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.4").unwrap());
1156static PYTORCH_ROCM53_INDEX_URL: LazyLock<IndexUrl> =
1157 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.3").unwrap());
1158static PYTORCH_ROCM52_INDEX_URL: LazyLock<IndexUrl> =
1159 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.2").unwrap());
1160static PYTORCH_ROCM511_INDEX_URL: LazyLock<IndexUrl> =
1161 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm5.1.1").unwrap());
1162static PYTORCH_ROCM42_INDEX_URL: LazyLock<IndexUrl> =
1163 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm4.2").unwrap());
1164static PYTORCH_ROCM41_INDEX_URL: LazyLock<IndexUrl> =
1165 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm4.1").unwrap());
1166static PYTORCH_ROCM401_INDEX_URL: LazyLock<IndexUrl> =
1167 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/rocm4.0.1").unwrap());
1168static PYTORCH_XPU_INDEX_URL: LazyLock<IndexUrl> =
1169 LazyLock::new(|| IndexUrl::from_str("https://download.pytorch.org/whl/xpu").unwrap());
1170
1171static PYX_API_BASE_URL: LazyLock<Cow<'static, str>> = LazyLock::new(|| {
1172 std::env::var(EnvVars::PYX_API_URL)
1173 .map(Cow::Owned)
1174 .unwrap_or(Cow::Borrowed("https://api.pyx.dev"))
1175});
1176static PYX_CPU_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1177 let api_base_url = &*PYX_API_BASE_URL;
1178 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cpu")).unwrap()
1179});
1180static PYX_CU130_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1181 let api_base_url = &*PYX_API_BASE_URL;
1182 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu130")).unwrap()
1183});
1184static PYX_CU129_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1185 let api_base_url = &*PYX_API_BASE_URL;
1186 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu129")).unwrap()
1187});
1188static PYX_CU128_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1189 let api_base_url = &*PYX_API_BASE_URL;
1190 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu128")).unwrap()
1191});
1192static PYX_CU126_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1193 let api_base_url = &*PYX_API_BASE_URL;
1194 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu126")).unwrap()
1195});
1196static PYX_CU125_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1197 let api_base_url = &*PYX_API_BASE_URL;
1198 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu125")).unwrap()
1199});
1200static PYX_CU124_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1201 let api_base_url = &*PYX_API_BASE_URL;
1202 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu124")).unwrap()
1203});
1204static PYX_CU123_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1205 let api_base_url = &*PYX_API_BASE_URL;
1206 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu123")).unwrap()
1207});
1208static PYX_CU122_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1209 let api_base_url = &*PYX_API_BASE_URL;
1210 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu122")).unwrap()
1211});
1212static PYX_CU121_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1213 let api_base_url = &*PYX_API_BASE_URL;
1214 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu121")).unwrap()
1215});
1216static PYX_CU120_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1217 let api_base_url = &*PYX_API_BASE_URL;
1218 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu120")).unwrap()
1219});
1220static PYX_CU118_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1221 let api_base_url = &*PYX_API_BASE_URL;
1222 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu118")).unwrap()
1223});
1224static PYX_CU117_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1225 let api_base_url = &*PYX_API_BASE_URL;
1226 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu117")).unwrap()
1227});
1228static PYX_CU116_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1229 let api_base_url = &*PYX_API_BASE_URL;
1230 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu116")).unwrap()
1231});
1232static PYX_CU115_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1233 let api_base_url = &*PYX_API_BASE_URL;
1234 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu115")).unwrap()
1235});
1236static PYX_CU114_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1237 let api_base_url = &*PYX_API_BASE_URL;
1238 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu114")).unwrap()
1239});
1240static PYX_CU113_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1241 let api_base_url = &*PYX_API_BASE_URL;
1242 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu113")).unwrap()
1243});
1244static PYX_CU112_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1245 let api_base_url = &*PYX_API_BASE_URL;
1246 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu112")).unwrap()
1247});
1248static PYX_CU111_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1249 let api_base_url = &*PYX_API_BASE_URL;
1250 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu111")).unwrap()
1251});
1252static PYX_CU110_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1253 let api_base_url = &*PYX_API_BASE_URL;
1254 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu110")).unwrap()
1255});
1256static PYX_CU102_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1257 let api_base_url = &*PYX_API_BASE_URL;
1258 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu102")).unwrap()
1259});
1260static PYX_CU101_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1261 let api_base_url = &*PYX_API_BASE_URL;
1262 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu101")).unwrap()
1263});
1264static PYX_CU100_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1265 let api_base_url = &*PYX_API_BASE_URL;
1266 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu100")).unwrap()
1267});
1268static PYX_CU92_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1269 let api_base_url = &*PYX_API_BASE_URL;
1270 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu92")).unwrap()
1271});
1272static PYX_CU91_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1273 let api_base_url = &*PYX_API_BASE_URL;
1274 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu91")).unwrap()
1275});
1276static PYX_CU90_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1277 let api_base_url = &*PYX_API_BASE_URL;
1278 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu90")).unwrap()
1279});
1280static PYX_CU80_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1281 let api_base_url = &*PYX_API_BASE_URL;
1282 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/cu80")).unwrap()
1283});
1284static PYX_ROCM64_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1285 let api_base_url = &*PYX_API_BASE_URL;
1286 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm6.4")).unwrap()
1287});
1288static PYX_ROCM63_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1289 let api_base_url = &*PYX_API_BASE_URL;
1290 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm6.3")).unwrap()
1291});
1292static PYX_ROCM624_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1293 let api_base_url = &*PYX_API_BASE_URL;
1294 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm6.2.4")).unwrap()
1295});
1296static PYX_ROCM62_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1297 let api_base_url = &*PYX_API_BASE_URL;
1298 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm6.2")).unwrap()
1299});
1300static PYX_ROCM61_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1301 let api_base_url = &*PYX_API_BASE_URL;
1302 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm6.1")).unwrap()
1303});
1304static PYX_ROCM60_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1305 let api_base_url = &*PYX_API_BASE_URL;
1306 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm6.0")).unwrap()
1307});
1308static PYX_ROCM57_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1309 let api_base_url = &*PYX_API_BASE_URL;
1310 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.7")).unwrap()
1311});
1312static PYX_ROCM56_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1313 let api_base_url = &*PYX_API_BASE_URL;
1314 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.6")).unwrap()
1315});
1316static PYX_ROCM55_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1317 let api_base_url = &*PYX_API_BASE_URL;
1318 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.5")).unwrap()
1319});
1320static PYX_ROCM542_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1321 let api_base_url = &*PYX_API_BASE_URL;
1322 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.4.2")).unwrap()
1323});
1324static PYX_ROCM54_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1325 let api_base_url = &*PYX_API_BASE_URL;
1326 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.4")).unwrap()
1327});
1328static PYX_ROCM53_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1329 let api_base_url = &*PYX_API_BASE_URL;
1330 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.3")).unwrap()
1331});
1332static PYX_ROCM52_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1333 let api_base_url = &*PYX_API_BASE_URL;
1334 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.2")).unwrap()
1335});
1336static PYX_ROCM511_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1337 let api_base_url = &*PYX_API_BASE_URL;
1338 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm5.1.1")).unwrap()
1339});
1340static PYX_ROCM42_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1341 let api_base_url = &*PYX_API_BASE_URL;
1342 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm4.2")).unwrap()
1343});
1344static PYX_ROCM41_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1345 let api_base_url = &*PYX_API_BASE_URL;
1346 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm4.1")).unwrap()
1347});
1348static PYX_ROCM401_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1349 let api_base_url = &*PYX_API_BASE_URL;
1350 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/rocm4.0.1")).unwrap()
1351});
1352static PYX_XPU_INDEX_URL: LazyLock<IndexUrl> = LazyLock::new(|| {
1353 let api_base_url = &*PYX_API_BASE_URL;
1354 IndexUrl::from_str(&format!("{api_base_url}/simple/astral-sh/xpu")).unwrap()
1355});