From: "Ludovic Courtès" <ludo@gnu.org>
To: 52283@debbugs.gnu.org
Cc: "Ludovic Courtès" <ludovic.courtes@inria.fr>
Subject: [bug#52283] [PATCH 02/10] transformations: Add '--tune'.
Date: Sat, 4 Dec 2021 21:49:16 +0100 [thread overview]
Message-ID: <20211204204924.15581-2-ludo@gnu.org> (raw)
In-Reply-To: <20211204204924.15581-1-ludo@gnu.org>
From: Ludovic Courtès <ludovic.courtes@inria.fr>
* guix/transformations.scm (tuning-compiler)
(tuned-package, tunable-package?, package-tuning)
(transform-package-tuning): New procedures.
(%transformations): Add 'tune'.
(%transformation-options): Add "--tune".
* tests/transformations.scm ("options->transformation, tune"): New
test.
* doc/guix.texi (Package Transformation Options): Document '--tune'.
---
doc/guix.texi | 54 +++++++++++++++
guix/transformations.scm | 134 ++++++++++++++++++++++++++++++++++++++
tests/transformations.scm | 20 ++++++
3 files changed, 208 insertions(+)
diff --git a/doc/guix.texi b/doc/guix.texi
index a675631b79..e3aca8fd3b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -10906,6 +10906,60 @@ available options and a synopsis (these options are not shown in the
@table @code
+@cindex performance, tuning code
+@cindex optimization, of package code
+@cindex tuning, of package code
+@cindex SIMD support
+@cindex tunable packages
+@cindex package multi-versioning
+@item --tune[=@var{cpu}]
+Use versions of the packages marked as ``tunable'' optimized for
+@var{cpu}. When @var{cpu} is @code{native}, or when it is omitted, tune
+for the CPU on which the @command{guix} command is running.
+
+Valid @var{cpu} names are those recognized by GCC, the GNU Compiler
+Collection. On x86_64 processors, this includes CPU names such as
+@code{nehalem}, @code{haswell}, and @code{skylake} (@pxref{x86 Options,
+@code{-march},, gcc, Using the GNU Compiler Collection (GCC)}).
+
+As new generations of CPUs come out, they augment the standard
+instruction set architecture (ISA) with additional instructions, in
+particular instructions for single-instruction/multiple-data (SIMD)
+parallel processing. For example, while Core2 and Skylake CPUs both
+implement the x86_64 ISA, only the latter supports AVX2 SIMD
+instructions.
+
+The primary gain one can expect from @option{--tune} is for programs
+that can make use of those SIMD capabilities @emph{and} that do not
+already have a mechanism to select the right optimized code at run time.
+Packages that have the @code{tunable?} property set are considered
+@dfn{tunable packages} by the @option{--tune} option; a package
+definition with the property set looks like this:
+
+@lisp
+(package
+ (name "hello-simd")
+ ;; ...
+
+ ;; This package may benefit from SIMD extensions so
+ ;; mark it as "tunable".
+ (properties '((tunable? . #t))))
+@end lisp
+
+Other packages are not considered tunable. This allows Guix to use
+generic binaries in the cases where tuning for a specific CPU is
+unlikely to provide any gain.
+
+Tuned packages are @emph{grafted} onto packages that depend on them
+(@pxref{Security Updates, grafts}). Thus, using @option{--no-grafts}
+annihilates the effect of @option{--tune}.
+
+We call this technique @dfn{package multi-versioning}: several variants
+of tunable packages may be built, one for each CPU variant. It is the
+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)}).
+
@item --with-source=@var{source}
@itemx --with-source=@var{package}=@var{source}
@itemx --with-source=@var{package}@@@var{version}=@var{source}
diff --git a/guix/transformations.scm b/guix/transformations.scm
index 5ae1977cb2..3be02179ef 100644
--- a/guix/transformations.scm
+++ b/guix/transformations.scm
@@ -29,6 +29,7 @@ (define-module (guix transformations)
#:autoload (guix upstream) (package-latest-release
upstream-source-version
upstream-source-signature-urls)
+ #:autoload (guix cpu) (current-cpu cpu->gcc-architecture)
#:use-module (guix utils)
#:use-module (guix memoization)
#:use-module (guix gexp)
@@ -49,6 +50,9 @@ (define-module (guix transformations)
#:export (options->transformation
manifest-entry-with-transformations
+ tunable-package?
+ tuned-package
+
show-transformation-options-help
%transformation-options))
@@ -419,6 +423,120 @@ (define replacements
obj)
obj)))
+(define tuning-compiler
+ (mlambda (micro-architecture)
+ "Return a compiler wrapper that passes '-march=MICRO-ARCHITECTURE' to the
+actual compiler."
+ (define wrapper
+ #~(begin
+ (use-modules (ice-9 match))
+
+ (define* (search-next command
+ #:optional
+ (path (string-split (getenv "PATH")
+ #\:)))
+ ;; Search the next COMMAND on PATH, a list of
+ ;; directories representing the executable search path.
+ (define this
+ (stat (car (command-line))))
+
+ (let loop ((path path))
+ (match path
+ (()
+ (match command
+ ("cc" (search-next "gcc"))
+ (_ #f)))
+ ((directory rest ...)
+ (let* ((file (string-append
+ directory "/" command))
+ (st (stat file #f)))
+ (if (and st (not (equal? this st)))
+ file
+ (loop rest)))))))
+
+ (match (command-line)
+ ((command arguments ...)
+ (match (search-next (basename command))
+ (#f (exit 127))
+ (next
+ (apply execl next
+ (append (cons next arguments)
+ (list (string-append "-march="
+ #$micro-architecture))))))))))
+
+ (define program
+ (program-file (string-append "tuning-compiler-wrapper-" micro-architecture)
+ wrapper))
+
+ (computed-file (string-append "tuning-compiler-" micro-architecture)
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+
+ (define bin (string-append #$output "/bin"))
+ (mkdir-p bin)
+
+ (for-each (lambda (program)
+ (symlink #$program
+ (string-append bin "/" program)))
+ '("cc" "gcc" "clang" "g++" "c++" "clang++")))))))
+
+(define (tuned-package p micro-architecture)
+ "Return package P tuned for MICRO-ARCHITECTURE."
+ (define compiler
+ (tuning-compiler micro-architecture))
+
+ (package
+ (inherit p)
+ (native-inputs
+ ;; Arrange so that COMPILER comes first in $PATH.
+ `(("tuning-compiler" ,compiler)
+ ,@(package-native-inputs p)))
+ (arguments
+ (substitute-keyword-arguments (package-arguments p)
+ ((#:tests? _ #f) #f)))
+ (properties
+ `((cpu-tuning . ,micro-architecture)
+ ,@(package-properties p)))))
+
+(define (tunable-package? package)
+ "Return true if package PACKAGE is \"tunable\"--i.e., if tuning it for the
+host CPU is worthwhile."
+ (assq 'tunable? (package-properties package)))
+
+(define package-tuning
+ (mlambda (micro-architecture)
+ "Return a procedure that maps the given package to its counterpart tuned
+for MICRO-ARCHITECTURE, a string suitable for GCC's '-march'."
+ (define rewriting-property
+ (gensym " package-tuning"))
+
+ (package-mapping (lambda (p)
+ (cond ((assq rewriting-property (package-properties p))
+ p)
+ ((assq 'tunable? (package-properties p))
+ (package/inherit p
+ (replacement (tuned-package p micro-architecture))
+ (properties `((,rewriting-property . #t)
+ ,@(package-properties p)))))
+ (else
+ p)))
+ (lambda (p)
+ (assq rewriting-property (package-properties p)))
+ #:deep? #t)))
+
+(define (transform-package-tuning micro-architectures)
+ "Return a procedure that, when "
+ (match micro-architectures
+ ((micro-architecture _ ...)
+ (info (G_ "tuning for CPU micro-architecture ~a~%")
+ micro-architecture)
+ (let ((rewrite (package-tuning micro-architecture)))
+ (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."
@@ -601,6 +719,7 @@ (define %transformations
(with-commit . ,transform-package-source-commit)
(with-git-url . ,transform-package-source-git-url)
(with-c-toolchain . ,transform-package-toolchain)
+ (tune . ,transform-package-tuning)
(with-debug-info . ,transform-package-with-debug-info)
(without-tests . ,transform-package-tests)
(with-patch . ,transform-package-patches)
@@ -640,6 +759,21 @@ (define %transformation-options
(parser 'with-git-url))
(option '("with-c-toolchain") #t #f
(parser 'with-c-toolchain))
+ (option '("tune") #f #t
+ (lambda (opt name arg result . rest)
+ (define micro-architecture
+ (match arg
+ ((or #f "native")
+ (cpu->gcc-architecture (current-cpu)))
+ ("generic" #f)
+ (_ arg)))
+
+ (apply values
+ (if micro-architecture
+ (alist-cons 'tune micro-architecture
+ result)
+ (alist-delete 'tune result))
+ rest)))
(option '("with-debug-info") #t #f
(parser 'with-debug-info))
(option '("without-tests") #t #f
diff --git a/tests/transformations.scm b/tests/transformations.scm
index 09839dc1c5..760b523e6e 100644
--- a/tests/transformations.scm
+++ b/tests/transformations.scm
@@ -465,6 +465,26 @@ (define (package-name* obj)
`((with-latest . "foo")))))
(package-version (t p)))))
+(test-equal "options->transformation, tune"
+ '(cpu-tuning . "superfast")
+ (let* ((p0 (dummy-package "p0"))
+ (p1 (dummy-package "p1"
+ (inputs `(("p0" ,p0)))
+ (properties '((tunable? . #t)))))
+ (p2 (dummy-package "p2"
+ (inputs `(("p1" ,p1)))))
+ (t (options->transformation '((tune . "superfast"))))
+ (p3 (t p2)))
+ (and (not (package-replacement p3))
+ (match (package-inputs p3)
+ ((("p1" tuned))
+ (match (package-inputs tuned)
+ ((("p0" p0))
+ (and (not (package-replacement p0))
+ (assq 'cpu-tuning
+ (package-properties
+ (package-replacement tuned)))))))))))
+
(test-equal "options->transformation + package->manifest-entry"
'((transformations . ((without-tests . "foo"))))
(let* ((p (dummy-package "foo"))
--
2.33.0
next prev parent reply other threads:[~2021-12-04 20:50 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-04 20:34 [bug#52283] [PATCH 00/10] Tuning packages for CPU micro-architectures Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 01/10] Add (guix cpu) Ludovic Courtès
2021-12-04 20:49 ` Ludovic Courtès [this message]
2021-12-06 23:18 ` [bug#52283] [PATCH 02/10] transformations: Add '--tune' Thiago Jung Bauermann via Guix-patches via
2021-12-07 8:04 ` Ludovic Courtès
2021-12-07 10:32 ` zimoun
2021-12-07 14:52 ` Ludovic Courtès
2021-12-07 15:52 ` zimoun
2021-12-09 9:19 ` Ludovic Courtès
2021-12-09 10:35 ` zimoun
2021-12-10 8:49 ` Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 03/10] ci: Add extra jobs for tunable packages Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 04/10] gnu: Add eigen-benchmarks Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 05/10] gnu: Add xsimd-benchmark Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 06/10] gnu: Add xtensor-benchmark Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 07/10] gnu: ceres-solver: Mark as tunable Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 08/10] gnu: Add ceres-solver-benchmarks Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 09/10] gnu: libfive: Mark as tunable Ludovic Courtès
2021-12-04 20:49 ` [bug#52283] [PATCH 10/10] gnu: prusa-slicer: " Ludovic Courtès
2021-12-05 8:37 ` [bug#52283] [PATCH 00/10] Tuning packages for CPU micro-architectures Mathieu Othacehe
2021-12-06 10:38 ` Ludovic Courtès
2021-12-06 12:47 ` zimoun
2021-12-07 8:39 ` Mathieu Othacehe
2021-12-07 9:02 ` Ludovic Courtès
2021-12-06 16:48 ` Ludovic Courtès
2021-12-04 21:11 ` Ludovic Courtès
2021-12-07 9:13 ` Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 00/12] " Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 01/12] Add (guix cpu) Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 02/12] gnu: gcc: Add 'compiler-cpu-architectures' property Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 03/12] gnu: clang: " Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 04/12] transformations: Add '--tune' Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 05/12] ci: Add extra jobs for tunable packages Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 06/12] gnu: Add eigen-benchmarks Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 07/12] gnu: Add xsimd-benchmark Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 08/12] gnu: Add xtensor-benchmark Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 09/12] gnu: ceres-solver: Mark as tunable Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 10/12] gnu: Add ceres-solver-benchmarks Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 11/12] gnu: libfive: Mark as tunable Ludovic Courtès
2021-12-16 17:58 ` [bug#52283] [PATCH v2 12/12] gnu: prusa-slicer: " Ludovic Courtès
2022-01-01 14:59 ` bug#52283: [PATCH 00/10] Tuning packages for CPU micro-architectures Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211204204924.15581-2-ludo@gnu.org \
--to=ludo@gnu.org \
--cc=52283@debbugs.gnu.org \
--cc=ludovic.courtes@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.