summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Behrmann2017-01-26 15:25:30 +0100
committerJoerg Behrmann2017-01-26 15:27:08 +0100
commit1d230946066afb3f77a0941e8046c70e1c89fefe (patch)
tree516c8fa23ba05b0a74088738323229944964c112
parent077285d5a32ede4af860e6d1d0bda8cdec41598b (diff)
downloadaur-1d230946066afb3f77a0941e8046c70e1c89fefe.tar.gz
Add note on how to build with MUMPS-support
-rw-r--r--.SRCINFO7
-rw-r--r--PKGBUILD12
-rw-r--r--build.conf3
-rwxr-xr-xsetup.py492
4 files changed, 508 insertions, 6 deletions
diff --git a/.SRCINFO b/.SRCINFO
index d8f304a42cfc..bfb99b03a6f9 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,9 +1,7 @@
-# Generated by mksrcinfo v8
-# Sat Dec 19 16:01:40 UTC 2015
pkgbase = python-kwant
pkgdesc = Python package for numerical calculations on tight-binding models with a strong focus on quantum transport
pkgver = 1.2.2
- pkgrel = 1
+ pkgrel = 2
url = http://kwant-project.org/
arch = any
license = BSD
@@ -14,9 +12,10 @@ pkgbase = python-kwant
depends = blas
depends = python-tinyarray
optdepends = python-matplotlib: needed for plotting support and the tutorial
- optdepends = mumps: a sparse linear algebra library for speed up and memory usage reduction
+ optdepends = mumps: a sparse linear algebra library for speed up and memory usage reduction (use AUR mumps-seq-shared or any other built as shared library)
source = http://downloads.kwant-project.org/kwant/kwant-1.2.2.tar.gz
source = http://downloads.kwant-project.org/kwant/kwant-1.2.2.tar.gz.asc
+ validpgpkeys = 52299057FAD799653C4F088AC3F147F5980F3535
sha1sums = 7a2aa07492c3aee8930fd7de402e62fea84f3eca
sha1sums = SKIP
diff --git a/PKGBUILD b/PKGBUILD
index 91d970a334bc..4d4bb5655cce 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -2,7 +2,7 @@
# Contributor: Max Schlemmer <max.schlemmer@gmail.com>
pkgname=python-kwant
pkgver=1.2.2
-pkgrel=1
+pkgrel=2
pkgdesc="Python package for numerical calculations on tight-binding models with a strong focus on quantum transport"
arch=('any')
url="http://kwant-project.org/"
@@ -10,7 +10,7 @@ license=('BSD')
depends=(python python-scipy lapack blas python-tinyarray)
optdepends=(
'python-matplotlib: needed for plotting support and the tutorial'
- 'mumps: a sparse linear algebra library for speed up and memory usage reduction'
+ 'mumps: a sparse linear algebra library for speed up and memory usage reduction (use AUR mumps-seq-shared or any other built as shared library)'
)
checkdepends=(python-nose)
source=(
@@ -21,6 +21,14 @@ sha1sums=('7a2aa07492c3aee8930fd7de402e62fea84f3eca'
'SKIP')
validpgpkeys=('52299057FAD799653C4F088AC3F147F5980F3535')
+# Comment the prepare function if you want to build _without_ mumps support.
+# This is discouraged because without the incurred performance penalty no
+# serious calculations can be done in a reasonable time.
+prepare() {
+ cp "../build.conf" "$srcdir/kwant-$pkgver/build.conf"
+ cp "../setup.py" "$srcdir/kwant-$pkgver/setup.py"
+}
+
build() {
cd "$srcdir/kwant-$pkgver"
python setup.py build
diff --git a/build.conf b/build.conf
new file mode 100644
index 000000000000..4438d70ff09f
--- /dev/null
+++ b/build.conf
@@ -0,0 +1,3 @@
+[mumps]
+libraries = zmumps mumps_common pord metis mpiseq gfortran
+include_dirs = /usr/include/mumps-seq \ No newline at end of file
diff --git a/setup.py b/setup.py
new file mode 100755
index 000000000000..00e024ac3b32
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,492 @@
+#!/usr/bin/env python3
+
+# Copyright 2011-2015 Kwant authors.
+#
+# This file is part of Kwant. It is subject to the license terms in the file
+# LICENSE.rst found in the top-level directory of this distribution and at
+# http://kwant-project.org/license. A list of Kwant authors can be found in
+# the file AUTHORS.rst at the top-level directory of this distribution and at
+# http://kwant-project.org/authors.
+
+from __future__ import print_function
+
+import sys
+
+v = sys.version_info
+if v[:2] < (3, 4):
+ error = "This version of Kwant requires Python 3.4 or above.\n"
+ if v[0] == 2:
+ error += "Kwant 1.1 is the last version to support Python 2."
+ print(error, file=sys.stderr)
+ sys.exit(1)
+
+import re
+import os
+import glob
+import imp
+import subprocess
+import configparser
+from setuptools import setup, find_packages, Extension, Command
+from sysconfig import get_platform
+from distutils.errors import DistutilsError, DistutilsModuleError, \
+ CCompilerError
+from distutils.command.build import build
+from setuptools.command.sdist import sdist
+from setuptools.command.build_ext import build_ext
+
+try:
+ import numpy
+except ImportError:
+ include_dirs = []
+else:
+ include_dirs = [numpy.get_include()]
+
+CONFIG_FILE = 'build.conf'
+README_FILE = 'README.rst'
+MANIFEST_IN_FILE = 'MANIFEST.in'
+README_END_BEFORE = 'See also in this directory:'
+STATIC_VERSION_PATH = ('kwant', '_kwant_version.py')
+REQUIRED_CYTHON_VERSION = (0, 22)
+CYTHON_OPTION = '--cython'
+TUT_DIR = 'tutorial'
+TUT_GLOB = 'doc/source/tutorial/*.py'
+TUT_HIDDEN_PREFIX = '#HIDDEN'
+CLASSIFIERS = """\
+ Development Status :: 5 - Production/Stable
+ Intended Audience :: Science/Research
+ Intended Audience :: Developers
+ Programming Language :: Python :: 3 :: Only
+ Topic :: Software Development
+ Topic :: Scientific/Engineering
+ Operating System :: POSIX
+ Operating System :: Unix
+ Operating System :: MacOS :: MacOS X
+ Operating System :: Microsoft :: Windows"""
+
+
+# Let Kwant itself determine its own version. We cannot simply import kwant, as
+# it is not built yet.
+_dont_write_bytecode_saved = sys.dont_write_bytecode
+sys.dont_write_bytecode = True
+_common = imp.load_source('_common', 'kwant/_common.py')
+sys.dont_write_bytecode = _dont_write_bytecode_saved
+
+version = _common.version
+version_is_from_git = _common.version_is_from_git
+
+try:
+ sys.argv.remove(CYTHON_OPTION)
+ use_cython = True
+except ValueError:
+ use_cython = version_is_from_git
+
+if use_cython:
+ try:
+ import Cython
+ from Cython.Build import cythonize
+ except ImportError:
+ cython_version = ()
+ else:
+ match = re.match('([0-9.]*)(.*)', Cython.__version__)
+ cython_version = [int(n) for n in match.group(1).split('.')]
+ # Decrease version if the version string contains a suffix.
+ if match.group(2):
+ while cython_version[-1] == 0:
+ cython_version.pop()
+ cython_version[-1] -= 1
+ cython_version = tuple(cython_version)
+
+distr_root = os.path.dirname(os.path.abspath(__file__))
+
+def banner(title=''):
+ starred = title.center(79, '*')
+ return '\n' + starred if title else starred
+
+error_msg = """{header}
+The compilation of Kwant has failed. Please examine the error message
+above and consult the installation instructions in README.rst.
+You might have to customize {{file}}.
+
+Build configuration was:
+
+{{summary}}
+{sep}
+"""
+error_msg = error_msg.format(header=banner(' Error '), sep=banner())
+
+
+class kwant_build_ext(build_ext):
+ def run(self):
+ if not config_file_present:
+ # Create an empty config file if none is present so that the
+ # extensions will not be rebuilt each time. Only depending on the
+ # config file if it is present would make it impossible to detect a
+ # necessary rebuild due to a deleted config file.
+ with open(CONFIG_FILE, 'w') as f:
+ f.write('# Created by setup.py - feel free to modify.\n')
+
+ try:
+ build_ext.run(self)
+ except (DistutilsError, CCompilerError):
+ print(error_msg.format(file=CONFIG_FILE, summary=build_summary),
+ file=sys.stderr)
+ raise
+ print(banner(' Build summary '))
+ print(build_summary)
+ print(banner())
+
+
+class kwant_build_tut(Command):
+ description = "build the tutorial scripts"
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ if not os.path.exists(TUT_DIR):
+ os.mkdir(TUT_DIR)
+ for in_fname in glob.glob(TUT_GLOB):
+ out_fname = os.path.join(TUT_DIR, os.path.basename(in_fname))
+ with open(in_fname) as in_file:
+ with open(out_fname, 'w') as out_file:
+ for line in in_file:
+ if not line.startswith(TUT_HIDDEN_PREFIX):
+ out_file.write(line)
+
+
+# Our version of the "build" command also makes sure the tutorial is made.
+# Even though the tutorial is not necessary for installation, and "build" is
+# supposed to make everything needed to install, this is a robust way to ensure
+# that the tutorial is present.
+class kwant_build(build):
+ sub_commands = [('build_tut', None)] + build.sub_commands
+
+ def run(self):
+ build.run(self)
+ write_version(os.path.join(self.build_lib, *STATIC_VERSION_PATH))
+
+
+def git_lsfiles():
+ if not version_is_from_git:
+ return
+
+ try:
+ p = subprocess.Popen(['git', 'ls-files'], cwd=distr_root,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except OSError:
+ return
+
+ if p.wait() != 0:
+ return
+ return p.communicate()[0].decode().split('\n')[:-1]
+
+
+# Make the command "sdist" depend on "build". This verifies that the
+# distribution in the current state actually builds. It also makes sure that
+# the Cython-made C files and the tutorial will be included in the source
+# distribution and that they will be up-to-date.
+class kwant_sdist(sdist):
+ sub_commands = [('build', None)] + sdist.sub_commands
+
+ def run(self):
+ """
+ Create MANIFEST.in from git if possible, otherwise check that MANIFEST.in
+ is present.
+
+ Right now (2015) generating MANIFEST.in seems to be the only way to
+ include files in the source distribution that setuptools does not think
+ should be there. Setting include_package_data to True makes setuptools
+ include *.pyx and other source files in the binary distribution.
+ """
+ manifest = os.path.join(distr_root, MANIFEST_IN_FILE)
+ names = git_lsfiles()
+ if names is None:
+ if not (os.path.isfile(manifest) and os.access(manifest, os.R_OK)):
+ print("Error:", MANIFEST_IN_FILE,
+ "file is missing and Git is not available"
+ " to regenerate it.", file=sys.stderr)
+ exit(1)
+ else:
+ with open(manifest, 'w') as f:
+ for name in names:
+ a, sep, b = name.rpartition('/')
+ if b == '.gitignore':
+ continue
+ stem, dot, extension = b.rpartition('.')
+ f.write('include {}'.format(name))
+ if extension == 'pyx':
+ f.write(''.join([' ', a, sep, stem, dot, 'c']))
+ f.write('\n')
+
+ sdist.run(self)
+
+ if names is None:
+ print(banner(' Caution '),
+ """Git was not available to generate the list of files to be included in the
+source distribution. The old {} was used.""".format(MANIFEST_IN_FILE),
+ banner(), sep='\n', file=sys.stderr)
+
+ def make_release_tree(self, base_dir, files):
+ sdist.make_release_tree(self, base_dir, files)
+ write_version(os.path.join(base_dir, *STATIC_VERSION_PATH))
+
+
+def write_version(fname):
+ # This could be a hard link, so try to delete it first. Is there any way
+ # to do this atomically together with opening?
+ try:
+ os.remove(fname)
+ except OSError:
+ pass
+ with open(fname, 'w') as f:
+ f.write("# This file has been created by setup.py.\n")
+ f.write("version = '{}'\n".format(version))
+
+
+def long_description():
+ text = []
+ try:
+ with open(README_FILE) as f:
+ for line in f:
+ if line.startswith(README_END_BEFORE):
+ break
+ text.append(line.rstrip())
+ while text[-1] == "":
+ text.pop()
+ except:
+ return ''
+ return '\n'.join(text)
+
+
+def search_mumps():
+ """Return the configuration for MUMPS if it is available in a known way.
+
+ This is known to work with the MUMPS provided by the Debian package
+ libmumps-scotch-dev."""
+
+ libs = ['zmumps_scotch', 'mumps_common_scotch', 'pord', 'mpiseq_scotch',
+ 'gfortran']
+
+ cmd = ['gcc']
+ cmd.extend(['-l' + lib for lib in libs])
+ cmd.extend(['-o/dev/null', '-xc', '-'])
+ try:
+ p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
+ except OSError:
+ pass
+ else:
+ p.communicate(input=b'int main() {}\n')
+ if p.wait() == 0:
+ return {'libraries': libs}
+ return {}
+
+
+def extensions():
+ """Return a list of tuples (args, kwrds) to be passed to Extension."""
+
+ global build_summary, config_file_present
+ build_summary = []
+
+ #### Add components of Kwant without external compile-time dependencies.
+ result = [
+ (['kwant._system', ['kwant/_system.pyx']],
+ {'include_dirs': ['kwant/graph']}),
+ (['kwant.graph.core', ['kwant/graph/core.pyx']],
+ {'depends': ['kwant/graph/core.pxd', 'kwant/graph/defs.h',
+ 'kwant/graph/defs.pxd']}),
+ (['kwant.graph.utils', ['kwant/graph/utils.pyx']],
+ {'depends': ['kwant/graph/defs.h', 'kwant/graph/defs.pxd',
+ 'kwant/graph/core.pxd']}),
+ (['kwant.graph.slicer', ['kwant/graph/slicer.pyx',
+ 'kwant/graph/c_slicer/partitioner.cc',
+ 'kwant/graph/c_slicer/slicer.cc']],
+ {'depends': ['kwant/graph/defs.h', 'kwant/graph/defs.pxd',
+ 'kwant/graph/core.pxd',
+ 'kwant/graph/c_slicer.pxd',
+ 'kwant/graph/c_slicer/bucket_list.h',
+ 'kwant/graph/c_slicer/graphwrap.h',
+ 'kwant/graph/c_slicer/partitioner.h',
+ 'kwant/graph/c_slicer/slicer.h']})]
+
+ #### Add components of Kwant with external compile-time dependencies.
+ config = configparser.ConfigParser()
+ try:
+ with open(CONFIG_FILE) as f:
+ config.read_file(f)
+ except IOError:
+ config_file_present = False
+ else:
+ config_file_present = True
+
+ kwrds_by_section = {}
+ for section in config.sections():
+ kwrds_by_section[section] = kwrds = {}
+ for name, value in config.items(section):
+ kwrds[name] = value.split()
+
+ # Setup LAPACK.
+ lapack = kwrds_by_section.get('lapack')
+ if lapack:
+ build_summary.append('User-configured LAPACK and BLAS')
+ else:
+ lapack = {'libraries': ['lapack', 'blas']}
+ build_summary.append('Default LAPACK and BLAS')
+ kwrds = lapack.copy()
+ kwrds.setdefault('depends', []).extend(
+ ['kwant/linalg/f_lapack.pxd'])
+ result.append((['kwant.linalg.lapack', ['kwant/linalg/lapack.pyx']],
+ kwrds))
+
+ # Setup MUMPS.
+ kwrds = kwrds_by_section.get('mumps')
+ if kwrds:
+ build_summary.append('User-configured MUMPS')
+ else:
+ kwrds = search_mumps()
+ if kwrds:
+ build_summary.append('Auto-configured MUMPS')
+ if kwrds:
+ for name, value in lapack.items():
+ kwrds.setdefault(name, []).extend(value)
+ kwrds.setdefault('depends', []).extend(
+ ['kwant/linalg/cmumps.pxd'])
+ result.append((['kwant.linalg._mumps', ['kwant/linalg/_mumps.pyx']],
+ kwrds))
+ print(kwrds)
+ print(result)
+ else:
+ build_summary.append('No MUMPS support')
+
+ build_summary = '\n'.join(build_summary)
+ return result
+
+
+def complain_cython_unavailable():
+ assert not use_cython or cython_version < REQUIRED_CYTHON_VERSION
+ if use_cython:
+ msg = ("Install Cython {0} or newer so it can be made\n"
+ "or use a source distribution of Kwant.")
+ ver = '.'.join(str(e) for e in REQUIRED_CYTHON_VERSION)
+ print(msg.format(ver), file=sys.stderr)
+ else:
+ print("Run setup.py with the {} option.".format(CYTHON_OPTION),
+ file=sys.stderr)
+
+
+def ext_modules(extensions):
+ """Prepare the ext_modules argument for setuptools.
+
+ If Cython is not to be run, replace .pyx extensions with .c or .cpp, and
+ check timestamps.
+ """
+ if use_cython and cython_version >= REQUIRED_CYTHON_VERSION:
+ return cythonize([Extension(*args, **kwrds)
+ for args, kwrds in extensions], language_level=3)
+
+ # Cython is not going to be run: replace pyx extension by that of
+ # the shipped translated file.
+
+ result = []
+ problematic_files = []
+ for args, kwrds in extensions:
+ name, sources = args
+
+ language = kwrds.get('language')
+ if language is None:
+ ext = '.c'
+ elif language == 'c':
+ ext = '.c'
+ elif language == 'c++':
+ ext = '.cpp'
+ else:
+ print('Unknown language: {}'.format(language), file=sys.stderr)
+ exit(1)
+
+ pyx_files = []
+ cythonized_files = []
+ new_sources = []
+ for f in sources:
+ if f.endswith('.pyx'):
+ pyx_files.append(f)
+ f = f.rstrip('.pyx') + ext
+ cythonized_files.append(f)
+ new_sources.append(f)
+ sources = new_sources
+
+ # Complain if cythonized files are older than Cython source files.
+ try:
+ cythonized_oldest = min(os.stat(f).st_mtime
+ for f in cythonized_files)
+ except OSError:
+ print("error: Cython-generated file {} is missing.".format(f),
+ file=sys.stderr)
+ complain_cython_unavailable()
+ exit(1)
+
+ for f in pyx_files + kwrds.get('depends', []):
+ if f == CONFIG_FILE:
+ # The config file is only a dependency for the compilation
+ # of the cythonized file, not for the cythonization.
+ continue
+ if os.stat(f).st_mtime > cythonized_oldest:
+ problematic_files.append(f)
+
+ result.append(Extension(name, sources, **kwrds))
+
+ if problematic_files:
+ problematic_files = ", ".join(problematic_files)
+ msg = ("Some Cython source files are newer than files that should have\n"
+ "been derived from them, but {}.\n"
+ "\n"
+ "Affected files: {}")
+ if use_cython:
+ if not cython_version:
+ reason = "Cython is not installed"
+ else:
+ reason = "the installed Cython is too old"
+ print(banner(" Error "), msg.format(reason, problematic_files),
+ banner(), sep="\n", file=sys.stderr)
+ print()
+ complain_cython_unavailable()
+ exit(1)
+ else:
+ reason = "the option {} has not been given".format(CYTHON_OPTION)
+ dontworry = ('(Do not worry about this if you are building Kwant\n'
+ 'from unmodified sources, e.g. with "pip install".)\n')
+ print(banner(" Caution "), dontworry,
+ msg.format(reason, problematic_files),
+ banner(), sep='\n', file=sys.stderr)
+
+ return result
+
+
+def main():
+ setup(name='kwant',
+ version=version,
+ author='C. W. Groth (CEA), M. Wimmer, '
+ 'A. R. Akhmerov, X. Waintal (CEA), and others',
+ author_email='authors@kwant-project.org',
+ description="Package for numerical quantum transport calculations.",
+ long_description=long_description(),
+ platforms=["Unix", "Linux", "Mac OS-X", "Windows"],
+ url="http://kwant-project.org/",
+ license="BSD",
+ packages=find_packages('.'),
+ test_suite = 'nose.collector',
+ cmdclass={'build': kwant_build,
+ 'sdist': kwant_sdist,
+ 'build_ext': kwant_build_ext,
+ 'build_tut': kwant_build_tut},
+ ext_modules=ext_modules(extensions()),
+ include_dirs=include_dirs,
+ setup_requires=['numpy > 1.6.1', 'nose >= 1.0'],
+ install_requires=['numpy > 1.6.1', 'scipy >= 0.9', 'tinyarray'],
+ extras_require={'plotting': 'matplotlib >= 1.2'},
+ classifiers=[c.strip() for c in CLASSIFIERS.split('\n')])
+
+if __name__ == '__main__':
+ main()