Skip to content

Commit

Permalink
Add option for Python only install (#72)
Browse files Browse the repository at this point in the history
* Add option for Python only install

* Update changelog
  • Loading branch information
rebeccafair authored Jun 2, 2020
1 parent 2d0a7c0 commit 34ca252
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 60 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

- Improvements:

- Add ``fall_back_on_python`` boolean keyword argument to
- Added ``fall_back_on_python`` boolean keyword argument to
``ForceConstants.calculate_qpoint_phonon_modes`` to control
whether the Python implementation is used as a fallback to the C
extension or not, see
`#35 <https://github.com/pace-neutrons/Euphonic/issues/35>`_
- Added ``--python-only`` option to ``setup.py`` to enable install
without the C extension

- Bug fixes:

Expand Down
33 changes: 22 additions & 11 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,14 @@ If you don't require plotting or reading of Phonopy files, just use:
pip install .
Installing the C extension (optional)
=====================================
Euphonic has an optional C extension, which can lead to increased performance
and enable use of multiple cores when interpolating phonons. By default
Euphonic will attempt to install this extension, but will print a warning and
fall back to the pure Python version if this fails. To determine if the C
extension is installing properly and investigate any problems, it is best to
increase pip's verbosity:
Installing the C extension
==========================

.. code-block:: bash
pip install -vvv euphonic
By default, Euphonic will attempt to build and install the C extension,
which can lead to increased performance and enable use of multiple cores when
interpolating phonons. See below for information on installing the extension
for different platforms. If you are having trouble installing the C extension
and don't require it, see `Installing Euphonic without the C extension`_

**Windows**

Expand All @@ -94,6 +90,21 @@ before running pip install run:
brew install llvm
Installing Euphonic without the C extension
===========================================

If you don't need the extra performance the C extension provides, you can
install the Python parts only with:

.. code-block:: bash
pip install --install-option="--python-only" euphonic
Note that using this option disables the use of wheels which, if they haven't
been installed already, actually makes installing other packages such as Numpy
more difficult. The easiest way around this is running the usual install
command first (which will install all the dependencies), then running again
with the ``--install-option="--python-only"`` option.

.. toctree::
:hidden:
Expand Down
102 changes: 54 additions & 48 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,63 @@
import versioneer
try:
from setuptools import setup, find_packages, Extension
from setuptools.command.install import install
except ImportError:
from distutils.core import setup, find_packages, Extension
from distutils.command.install import install


def run_setup(build_c=True):
class InstallCommand(install):
user_options = install.user_options + [('python-only', None, 'Install only Python')]

def initialize_options(self):
install.initialize_options(self)
self.python_only = 0

def finalize_options(self):
install.finalize_options(self)
if not bool(self.python_only):
self.distribution.ext_modules = [get_c_extension()]

if build_c:
import os
import numpy as np
from sys import platform
import subprocess
include_dirs = [np.get_include(), 'c']
sources = ['c/_euphonic.c', 'c/dyn_mat.c', 'c/util.c', 'c/py_util.c',
'c/load_libs.c']
if platform == 'win32':
# Windows - assume MSVC compiler
compile_args = ['/openmp']
link_args = None
elif platform == 'darwin':
# OSX - assume brew install llvm
brew_prefix_cmd_return = subprocess.run(["brew", "--prefix"],
stdout=subprocess.PIPE)
brew_prefix = brew_prefix_cmd_return.stdout.decode("utf-8").strip()
os.environ['CC'] = '{}/opt/llvm/bin/clang'.format(brew_prefix)
compile_args = ['-fopenmp']
link_args = ['-L{}/opt/llvm/lib'.format(brew_prefix), '-fopenmp']
else:
# Linux - assume gcc
os.environ['CC'] = 'gcc'
compile_args = ['-fopenmp']
link_args = ['-fopenmp']

euphonic_extension = Extension(
'euphonic._euphonic',
extra_compile_args=compile_args,
extra_link_args=link_args,
include_dirs=include_dirs,
sources=sources
)
ext_modules = [euphonic_extension]
def get_c_extension():
import os
import numpy as np
from sys import platform
import subprocess
include_dirs = [np.get_include(), 'c']
sources = ['c/_euphonic.c', 'c/dyn_mat.c', 'c/util.c', 'c/py_util.c',
'c/load_libs.c']
if platform == 'win32':
# Windows - assume MSVC compiler
compile_args = ['/openmp']
link_args = None
elif platform == 'darwin':
# OSX - assume brew install llvm
brew_prefix_cmd_return = subprocess.run(["brew", "--prefix"],
stdout=subprocess.PIPE)
brew_prefix = brew_prefix_cmd_return.stdout.decode("utf-8").strip()
os.environ['CC'] = '{}/opt/llvm/bin/clang'.format(brew_prefix)
compile_args = ['-fopenmp']
link_args = ['-L{}/opt/llvm/lib'.format(brew_prefix), '-fopenmp']
else:
ext_modules = None
# Linux - assume gcc
os.environ['CC'] = 'gcc'
compile_args = ['-fopenmp']
link_args = ['-fopenmp']

euphonic_c_extension = Extension(
'euphonic._euphonic',
extra_compile_args=compile_args,
extra_link_args=link_args,
include_dirs=include_dirs,
sources=sources
)
return euphonic_c_extension


def run_setup(build_c=True):

with open('README.rst', 'r') as f:
long_description = f.read()

Expand All @@ -55,10 +68,13 @@ def run_setup(build_c=True):
'scripts/dos.py',
'scripts/optimise_eta.py']

cmdclass = versioneer.get_cmdclass()
cmdclass['install'] = InstallCommand

setup(
name='euphonic',
version=versioneer.get_version(),
cmdclass=versioneer.get_cmdclass(),
cmdclass=cmdclass,
author='Rebecca Fair',
author_email='[email protected]',
description=(
Expand All @@ -79,17 +95,7 @@ def run_setup(build_c=True):
'matplotlib': ['matplotlib>=1.4.2'],
'phonopy_reader': ['h5py>=2.9.0', 'PyYAML>=5.1.2']
},
scripts=scripts,
ext_modules=ext_modules
scripts=scripts
)


try:
run_setup()
except:
print('*'*79)
print(('Failed to build Euphonic C extension, installing pure '
'Python version instead'))
print('*'*79)
print("Unexpected error: {}".format(sys.exc_info()[0]))
run_setup(build_c=False)
run_setup()

0 comments on commit 34ca252

Please sign in to comment.