mirror of
https://codeberg.org/guix/guix.git
synced 2026-01-25 03:55:08 -06:00
transformations: Add ‘--amd-gpu’ transformation option.
* guix/transformations.scm (split-on-commas): New procedure, moved from…
(transform-package-toolchain): … here.
(package-amd-gpu-specialization, transform-package-amd-gpu-targets): New
procedures.
(%transformations, %options): Add ‘amd-gpu’.
* tests/transformations.scm ("options->transformations, amd-gpu")
("options->transformations, amd-gpu, not applicable")
("options->transformations, amd-gpu, missing clang-rocm input")
("options->transformations, amd-gpu, wrong GPU"): New tests.
* doc/guix.texi (Package Transformation Options): Document it.
Change-Id: I56bf0dffbf12bc08cf6318fe56952473b395c303
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Merges: #5583
This commit is contained in:
parent
86984d7c62
commit
4562bbb1d2
3 changed files with 173 additions and 6 deletions
|
|
@ -22,7 +22,7 @@
|
|||
@set SUBSTITUTE-URLS https://@value{SUBSTITUTE-SERVER-1} https://@value{SUBSTITUTE-SERVER-2}
|
||||
|
||||
@copying
|
||||
Copyright @copyright{} 2012--2025 Ludovic Courtès@*
|
||||
Copyright @copyright{} 2012--2026 Ludovic Courtès@*
|
||||
Copyright @copyright{} 2013, 2014, 2016, 2024 Andreas Enge@*
|
||||
Copyright @copyright{} 2013 Nikita Karetnikov@*
|
||||
Copyright @copyright{} 2014, 2015, 2016 Alex Kost@*
|
||||
|
|
@ -13664,6 +13664,37 @@ coarse-grain counterpart of @dfn{function multi-versioning} as
|
|||
implemented by the GNU tool chain (@pxref{Function Multiversioning,,,
|
||||
gcc, Using the GNU Compiler Collection (GCC)}).
|
||||
|
||||
@cindex GPUs, AMD compilation targets
|
||||
@cindex AMD GPUs
|
||||
@cindex ROCm/HIP GPU targets
|
||||
@vindex amd-gpu-targets
|
||||
@anchor{amd-gpu-transformation-option}
|
||||
@item --amd-gpu=@var{targets}
|
||||
Build relevant packages for the AMD GPUs specified by @var{targets}.
|
||||
Only packages with an @code{amd-gpu-targets} property are affected.
|
||||
@var{targets} must be a comma-separated list of
|
||||
@uref{https://llvm.org/docs/AMDGPUUsage.html#amdgpu-processor-table, AMD
|
||||
GPU target identifiers}. For example, the command below builds the GPU
|
||||
code of @code{rocm-bandwidth-test} for AMD Instinct MI250
|
||||
(@code{gfx90a}) and for AMD Instinct MI300 (@code{gfx942}):
|
||||
|
||||
@example
|
||||
guix build --amd-gpu=gfx90a,gfx942 rocm-bandwidth-test
|
||||
@end example
|
||||
|
||||
To know the identifier(s) of the GPU(s) available on your machine, run:
|
||||
|
||||
@example
|
||||
guix shell rocminfo -- rocm_agent_enumerator
|
||||
@end example
|
||||
|
||||
Under the hood, these GPU identifiers are
|
||||
passed to Clang's @option{--offload-arch} option.
|
||||
|
||||
When @option{--amd-gpu} is omitted, packages are built for a default set
|
||||
of GPUs, that we hope covers common needs. Building for more GPUs
|
||||
increases build time significantly and leads to bigger package binaries.
|
||||
|
||||
@item --with-source=@var{source}
|
||||
@itemx --with-source=@var{package}=@var{source}
|
||||
@itemx --with-source=@var{package}@@@var{version}=@var{source}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2016-2024 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2016-2024, 2026 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
|
||||
;;; Copyright © 2023 Sarthak Shah <shahsarthakw@gmail.com>
|
||||
;;; Copyright © 2023-2025 Efraim Flashner <efraim@flashner.co.il>
|
||||
|
|
@ -422,15 +422,15 @@ TOOLCHAIN must be an input list."
|
|||
(not (memq p set))))
|
||||
#:deep? #t))))
|
||||
|
||||
(define split-on-commas
|
||||
(cute string-tokenize <> (char-set-complement (char-set #\,))))
|
||||
|
||||
(define (transform-package-toolchain replacement-specs)
|
||||
"Return a procedure that, when passed a package, changes its toolchain or
|
||||
that of its dependencies according to REPLACEMENT-SPECS. REPLACEMENT-SPECS is
|
||||
a list of strings like \"fftw=gcc-toolchain@10\" meaning that the package to
|
||||
the left of the equal sign must be built with the toolchain to the right of
|
||||
the equal sign."
|
||||
(define split-on-commas
|
||||
(cute string-tokenize <> (char-set-complement (char-set #\,))))
|
||||
|
||||
(define (specification->input spec)
|
||||
(let ((package (specification->package spec)))
|
||||
(list (package-name package) package)))
|
||||
|
|
@ -704,6 +704,97 @@ for MICRO-ARCHITECTURE, a string suitable for GCC's '-march'."
|
|||
(rewrite obj)
|
||||
obj))))))
|
||||
|
||||
(define (package-for-amd-gpu-targets p targets)
|
||||
"Return a variant of P compiled for TARGETS, a list of strings denoting AMD
|
||||
GPU targets."
|
||||
(package/inherit p
|
||||
(properties
|
||||
`((amd-gpu-targets . ,targets)
|
||||
,@(alist-delete 'amd-gpu-targets (package-properties p))))))
|
||||
|
||||
(define (assert-valid-amd-gpu-targets package targets)
|
||||
"Raise an error if the AMD GPU identifiers listed in TARGETS are not known
|
||||
to the compiler of PACKAGE."
|
||||
(define (compiler-amd-gpu-targets package)
|
||||
(assoc-ref (package-properties package) 'compiler-amd-gpu-targets))
|
||||
|
||||
(match (any (match-lambda
|
||||
((label (? package? package))
|
||||
(and (compiler-amd-gpu-targets package)
|
||||
package))
|
||||
(_ #f))
|
||||
(package-direct-inputs package))
|
||||
(#f
|
||||
(raise (make-compound-condition
|
||||
(formatted-message
|
||||
(G_ "~a: no ROCm compiler was found among the inputs")
|
||||
(package-full-name package))
|
||||
(condition (&error-location
|
||||
(location (package-location package)))))))
|
||||
(compiler
|
||||
(let ((supported (compiler-amd-gpu-targets compiler)))
|
||||
;; This is quadratic but on small lists.
|
||||
(and=> (find (negate (cut member <> supported)) targets)
|
||||
(lambda (unsupported)
|
||||
(raise
|
||||
(make-compound-condition
|
||||
(formatted-message
|
||||
(G_ "compiler ~a does not support AMD GPU target ~a")
|
||||
(package-full-name compiler) unsupported)
|
||||
(condition (&error-location
|
||||
(location (package-location compiler))))
|
||||
(condition
|
||||
(&fix-hint
|
||||
(hint (format #f (G_ "Compiler ~a supports the following
|
||||
AMD GPU targets:
|
||||
|
||||
@quotation
|
||||
~a
|
||||
@end quotation")
|
||||
(package-full-name compiler "@@")
|
||||
(string-join supported ", ")))))))))))))
|
||||
|
||||
(define package-amd-gpu-specialization
|
||||
(mlambda (targets)
|
||||
"Return a procedure that maps the given package to its counterpart built
|
||||
for the given ROCm TARGETS, a list of GPU architectures."
|
||||
(define rewriting-property
|
||||
(gensym " package-amd-gpu-specialization"))
|
||||
|
||||
(define (mark p)
|
||||
;; Mark P as already processed.
|
||||
(package/inherit p
|
||||
(properties `((,rewriting-property . #t)
|
||||
,@(package-properties p)))))
|
||||
|
||||
(package-mapping (lambda (p)
|
||||
(cond ((assq rewriting-property (package-properties p))
|
||||
p)
|
||||
((assq 'amd-gpu-targets (package-properties p))
|
||||
(assert-valid-amd-gpu-targets p targets)
|
||||
(info (N_ "compiling ~a for AMD GPU~{ ~a~}~%"
|
||||
"compiling ~a for these AMD GPUs:~{ ~a~}~%"
|
||||
(length targets))
|
||||
(package-full-name p) targets)
|
||||
(mark (package-for-amd-gpu-targets p targets)))
|
||||
(else
|
||||
p)))
|
||||
(lambda (p)
|
||||
(assq rewriting-property (package-properties p)))
|
||||
#:deep? #t)))
|
||||
|
||||
(define (transform-package-amd-gpu-targets targets)
|
||||
"Return a procedure that, when applied to a package, returns that package
|
||||
such that the package itself and all its dependencies are specialized for
|
||||
TARGET-LIST, a list of strings denoting AMD GPUs."
|
||||
(match targets
|
||||
((targets _ ...)
|
||||
(let* ((rewrite (package-amd-gpu-specialization targets)))
|
||||
(lambda (obj)
|
||||
(if (package? obj)
|
||||
(rewrite obj)
|
||||
obj))))))
|
||||
|
||||
(define (transform-package-with-debug-info specs)
|
||||
"Return a procedure that, when passed a package, set its 'replacement' field
|
||||
to the same package but with #:strip-binaries? #f in its 'arguments' field."
|
||||
|
|
@ -999,6 +1090,7 @@ are replaced by the specified upstream version."
|
|||
(with-git-url . ,transform-package-source-git-url)
|
||||
(with-c-toolchain . ,transform-package-toolchain)
|
||||
(tune . ,transform-package-tuning)
|
||||
(amd-gpu . ,transform-package-amd-gpu-targets)
|
||||
(with-debug-info . ,transform-package-with-debug-info)
|
||||
(without-tests . ,transform-package-tests)
|
||||
(with-configure-flag . ,transform-package-configure-flag)
|
||||
|
|
@ -1085,6 +1177,11 @@ building for ~a instead of ~a, so tuning cannot be guessed~%")
|
|||
result)
|
||||
(alist-delete 'tune result))
|
||||
rest)))
|
||||
(option '("amd-gpu") #t #f
|
||||
(lambda (opt name arg result . rest)
|
||||
(apply values
|
||||
(alist-cons 'amd-gpu (split-on-commas arg) result)
|
||||
rest)))
|
||||
(option '("with-debug-info") #t #f
|
||||
(parser 'with-debug-info))
|
||||
(option '("without-tests") #t #f
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2016-2017, 2019-2024 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2016-2017, 2019-2024, 2026 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
|
|
@ -638,6 +638,45 @@
|
|||
(package->bag (t p))
|
||||
#f)))
|
||||
|
||||
(test-equal "options->transformations, amd-gpu"
|
||||
'("gfx90a" "gfx942")
|
||||
(let ((p (dummy-package "amd-gpu-code"
|
||||
(native-inputs
|
||||
(list (@ (gnu packages llvm) clang-rocm)))
|
||||
(properties '((amd-gpu-targets . ("whatever"))))))
|
||||
(t (options->transformation '((amd-gpu . ("gfx90a" "gfx942"))))))
|
||||
(assoc-ref (package-properties (t p)) 'amd-gpu-targets)))
|
||||
|
||||
(test-equal "options->transformations, amd-gpu, not applicable"
|
||||
#f
|
||||
(let ((p (dummy-package "not-amd-gpu-code"))
|
||||
(t (options->transformation '((amd-gpu . ("gfx90a" "gfx942"))))))
|
||||
(assoc-ref (package-properties (t p)) 'amd-gpu-targets)))
|
||||
|
||||
(test-assert "options->transformations, amd-gpu, missing clang-rocm input"
|
||||
(let ((p (dummy-package "amd-gpu-code"
|
||||
(properties '((amd-gpu-targets . ("whatever"))))))
|
||||
(t (options->transformation '((amd-gpu . ("generic"))))))
|
||||
;; Since 'clang-rocm' is not among the inputs, an error should be raised.
|
||||
(guard (c ((formatted-message? c)
|
||||
(string-contains (formatted-message-string c)
|
||||
"no ROCm compiler")))
|
||||
(t p)
|
||||
#f)))
|
||||
|
||||
(test-assert "options->transformations, amd-gpu, wrong GPU"
|
||||
(let ((p (dummy-package "amd-gpu-code"
|
||||
(native-inputs
|
||||
(list (@ (gnu packages llvm) clang-rocm)))
|
||||
(properties '((amd-gpu-targets . ("whatever"))))))
|
||||
(t (options->transformation '((amd-gpu . ("does-not-exist"))))))
|
||||
;; Since this AMD GPU target is not known to 'clang-rocm', an error should
|
||||
;; be raised.
|
||||
(guard (c ((formatted-message? c)
|
||||
(member "does-not-exist" (formatted-message-arguments c))))
|
||||
(t p)
|
||||
#f)))
|
||||
|
||||
(test-equal "options->transformation + package->manifest-entry"
|
||||
'((transformations . ((without-tests . "foo"))))
|
||||
(let* ((p (dummy-package "foo"))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue