all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* RFC: building numpy against OpenBLAS.
@ 2015-05-23  7:20 Federico Beffa
  2015-05-27 15:50 ` Ricardo Wurmus
  0 siblings, 1 reply; 13+ messages in thread
From: Federico Beffa @ 2015-05-23  7:20 UTC (permalink / raw)
  To: ricardo.wurmus; +Cc: Guix-devel

Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> writes:

> Hi Guix,
>
> python-numpy currently depends on Atlas, which means that it cannot be
> substituted with a binary built elsewhere.  OpenBLAS is an alternative
> to Atlas and the binary can be used on all supported CPUs at runtime.
> This makes it possible for us to make numpy substitutable.

Out of curiosity, could you outline how OpenBLAS is optimized for a
specific CPU architecture while being compiled on a different CPU (and
hence allowing to be substituted)?

Thanks,
Fede

^ permalink raw reply	[flat|nested] 13+ messages in thread
* RFC: building numpy against OpenBLAS.
@ 2015-05-22 15:00 Ricardo Wurmus
  2015-05-22 15:16 ` Eric Bavier
  2015-06-01 13:11 ` Ricardo Wurmus
  0 siblings, 2 replies; 13+ messages in thread
From: Ricardo Wurmus @ 2015-05-22 15:00 UTC (permalink / raw)
  To: guix

[-- Attachment #1: Type: text/plain, Size: 1923 bytes --]

Hi Guix,

python-numpy currently depends on Atlas, which means that it cannot be
substituted with a binary built elsewhere.  OpenBLAS is an alternative
to Atlas and the binary can be used on all supported CPUs at runtime.
This makes it possible for us to make numpy substitutable.

We currently do not have a working OpenBLAS on MIPS, so the attached
patch selects OpenBLAS as an input only when not on MIPS.  Some
additional configuration happens only unless "atlas" is among the
inputs.

I have successfully compiled numpy and python-scikit-image for both
versions of Python on x86_64 with these changes.  I should say, however,
that there's a note in the numpy sources that warns about a bug under
certain conditions:

    # **Warning**: OpenBLAS, by default, is built in multithreaded mode. Due to the
    # way Python's multiprocessing is implemented, a multithreaded OpenBLAS can
    # cause programs using both to hang as soon as a worker process is forked on
    # POSIX systems (Linux, Mac).
    # This is fixed in Openblas 0.2.9 for the pthread build, the OpenMP build using
    # GNU openmp is as of gcc-4.9 not fixed yet.
    # Python 3.4 will introduce a new feature in multiprocessing, called the
    # "forkserver", which solves this problem. For older versions, make sure
    # OpenBLAS is built using pthreads or use Python threads instead of
    # multiprocessing.
    # (This problem does not exist with multithreaded ATLAS.)

I do not know if this is still a problem and I haven't yet tried to
reproduce this.  Our OpenBLAS is not built with openmp, so I think this
problem does not affect us.

Anyway, I just wanted to post this here to ask for opinions.  Maybe this
is a bad idea.  (In my case it makes sense not to use Atlas, because the
compile-time tuning is useless when a shared store is used and clients
use Atlas on machines other than the build host.)

Comments are very welcome!

~~ Ricardo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gnu-python-numpy-Build-against-OpenBLAS.patch --]
[-- Type: text/x-patch, Size: 3268 bytes --]

From 4b56608674a9c7977cad88ce3f03a9fcb72c93bc Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Fri, 22 May 2015 16:48:05 +0200
Subject: [PATCH] gnu: python-numpy: Build against OpenBLAS.

* gnu/packages/python.scm (python-numpy)[inputs]: Use "openblas" instead of
  "atlas" when not on MIPS.
* gnu/packages/python.scm (python-numpy)[arguments]: Configure build against
  OpenBLAS unless "atlas" is among the inputs.
---
 gnu/packages/python.scm | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 0916a75..c96296f 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -2283,7 +2283,9 @@ writing C extensions for Python as easy as Python itself.")
     (build-system python-build-system)
     (inputs
      `(("python-nose" ,python-nose)
-       ("atlas" ,atlas)))
+       ,(if (string-prefix? "mips" (%current-system))
+            `("atlas" ,atlas)
+            `("openblas" ,openblas))))
     (native-inputs
      `(("gfortran" ,gfortran-4.8)))
     (arguments
@@ -2291,16 +2293,32 @@ writing C extensions for Python as easy as Python itself.")
        (alist-cons-before
         'build 'set-environment-variables
         (lambda* (#:key inputs #:allow-other-keys)
-          (let* ((atlas-threaded
-                  (string-append (assoc-ref inputs "atlas")
-                                 "/lib/libtatlas.so"))
-                 ;; On single core CPUs only the serial library is created.
-                 (atlas-lib
-                  (if (file-exists? atlas-threaded)
-                      atlas-threaded
+          (if (assoc-ref inputs "atlas")
+              ;; Link against Atlas
+              (let* ((atlas-threaded
                       (string-append (assoc-ref inputs "atlas")
-                                     "/lib/libsatlas.so"))))
-            (setenv "ATLAS" atlas-lib)))
+                                     "/lib/libtatlas.so"))
+                     ;; On single core CPUs only the serial library is created.
+                     (atlas-lib
+                      (if (file-exists? atlas-threaded)
+                          atlas-threaded
+                          (string-append (assoc-ref inputs "atlas")
+                                         "/lib/libsatlas.so"))))
+                (setenv "ATLAS" atlas-lib))
+              ;; Link against OpenBLAS
+              (begin
+                (call-with-output-file "site.cfg"
+                  (lambda (port)
+                    (format port "[openblas]
+libraries = openblas
+library_dirs = ~a/lib
+include_dirs = ~a/include
+" (assoc-ref inputs "openblas") (assoc-ref inputs "openblas"))))
+                ;; Use "gcc" executable, not "cc".
+                (substitute* "numpy/distutils/system_info.py"
+                  (("c = distutils\\.ccompiler\\.new_compiler\\(\\)")
+                   "c = distutils.ccompiler.new_compiler(); c.set_executables(compiler='gcc',compiler_so='gcc',linker_exe='gcc',linker_so='gcc -shared')"))))
+          #t)
         ;; Tests can only be run after the library has been installed and not
         ;; within the source directory.
         (alist-cons-after
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-06-07 21:32 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-23  7:20 RFC: building numpy against OpenBLAS Federico Beffa
2015-05-27 15:50 ` Ricardo Wurmus
2015-05-28  6:38   ` Federico Beffa
  -- strict thread matches above, loose matches on Subject: below --
2015-05-22 15:00 Ricardo Wurmus
2015-05-22 15:16 ` Eric Bavier
2015-06-01 13:11 ` Ricardo Wurmus
2015-06-05 13:52   ` Mark H Weaver
2015-06-05 13:54   ` Mark H Weaver
2015-06-05 15:36     ` Mark H Weaver
2015-06-05 16:01     ` Ricardo Wurmus
2015-06-05 17:33       ` Mark H Weaver
2015-06-07 19:46         ` Ludovic Courtès
2015-06-07 21:32           ` Mark H Weaver

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.