Skip to content

fixing build issues on mac #254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions charm4py/charmlib/charmlib_ctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import sys
import os
import time
import platform
if sys.version_info < (3, 0, 0):
import cPickle
else:
Expand Down Expand Up @@ -108,6 +109,7 @@ def __init__(self, charm, opts, libcharm_path):
self.chareNames = []
self.charm = charm
self.opts = opts
self.system = platform.system().lower()
self.init(libcharm_path)
self.ReducerType = ReducerTypes.in_dll(self.lib, "charm_reducers")
self.times = [0.0] * 3 # track time in [charm reduction callbacks, custom reduction, outgoing object migration]
Expand Down Expand Up @@ -609,9 +611,15 @@ def init(self, libcharm_path):
p = os.environ.get('LIBCHARM_PATH')
if p is not None: libcharm_path = p
if libcharm_path is not None:
self.lib = ctypes.CDLL(os.path.join(libcharm_path, 'libcharm.so'))
if self.system == 'darwin':
self.lib = ctypes.CDLL(os.path.join(libcharm_path, 'libcharm.dylib'))
else:
self.lib = ctypes.CDLL(os.path.join(libcharm_path, 'libcharm.so'))
else:
self.lib = ctypes.CDLL('libcharm.so')
if self.system == 'darwin':
self.lib = ctypes.CDLL('libcharm.dylib')
else:
self.lib = ctypes.CDLL('libcharm.so')
else:
self.lib = ctypes.CDLL(os.path.join(libcharm_path, 'charm.dll'))

Expand Down
97 changes: 51 additions & 46 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,56 @@ CPython (most common implementation) and PyPy_.
.. _PyPy: http://pypy.org


pip
---

To install on regular Linux, macOS and Windows machines, do::
Manually building the Charm++ shared library
--------------------------------------------

$ pip3 install charm4py
Use this to build Charm4py binaries manually, instead of downloading prebuilt libraries from pip.
This is needed when building Charm++ for specialized machine/network layers
other than TCP and MPI (e.g. Cray XC/XE).

.. note::
Before installing, you need the following prerequisites:
- CPython: numpy, greenlet and cython (``pip3 install 'numpy>=1.10.0' cython greenlet``)
- PyPy: none

This option uses Charm++'s TCP layer as the communication layer.
If you want a faster communication layer (e.g. MPI), see "Install from
source" below.
The first step is to clone the Charm4py repository from Git::

pip >= 8.0 is recommended to simplify the install and avoid building Charm4py or
any dependencies from sources.
$ git clone https://github.com/UIUC-PPL/charm4py
$ cd charm4py

Note that a 64-bit version of Python is required to install and run Charm4py.
Next, create a folder called charm_src in the charm4py repo, and then clone the Charm++ repo
into that folder::

$ mkdir charm_src && cd charm_src
$ git clone https://github.com/UIUC-PPL/charm

Install from source
-------------------
Once this is done, there are two ways to build Charm4py. The first way is to change back up
into the Charm4Py directory and run the install script::

$ cd ..
$ python3 setup.py install [--mpi]

.. note::
This is not required if installing from a binary wheel with pip.
The optional flag ``--mpi``, when enabled, will build the
Charm++ library with the MPI communication layer (MPI headers and libraries
need to be installed on the system). After this, Charm4Py will be built.

Prerequisites:
- CPython: numpy, greenlet and cython (``pip3 install 'numpy>=1.10.0' cython greenlet``)
- PyPy: none
The other option is to manually build Charm++ before building Charm4py. To do this, change to
the charm directory and run the following build command::

$ cd charm
$ ./build charm4py <version> -j<N> --with-production

To build the latest *stable* release, do::
Then, return to the charm4py directory and run setup.py::

$ pip3 install [--install-option="--mpi"] charm4py --no-binary charm4py
$ cd ../..
$ python3 setup.py install [--mpi]

Or download the source distribution from PyPI, uncompress and run
``python3 setup.py install [--mpi]``.

The optional flag ``--mpi``, when enabled, will build the
Charm++ library with the MPI communication layer (MPI headers and libraries
need to be installed on the system).
After building, you can run Charm4py examples. One example you can try is
array_hello.py, which can be run as follows::

To build the latest *development* version, download Charm4py and Charm++ source code
and run setup::
$ cd examples/hello
$ python -m charmrun.start +p2 array_hello.py

$ git clone https://github.com/UIUC-PPL/charm4py
$ cd charm4py
$ git clone https://github.com/UIUC-PPL/charm charm_src/charm
$ python3 setup.py install [--mpi]

.. note::

Expand All @@ -72,25 +75,27 @@ and run setup::
to manually build the Charm++ library (see below).


Manually building the Charm++ shared library
--------------------------------------------
pip
---

This is needed when building Charm++ for specialized machine/network layers
other than TCP and MPI (e.g. Cray XC/XE).
This option installs prebuilt Charm4Py binaries from pip. The prebuilt pip libraries
were built with Python 3.7.

Before running ``python3 setup.py`` in the steps above, enter the Charm++ source code
directory (``charm_src/charm``), and manually build the Charm++ library. The build
command syntax is::
To install on regular Linux, macOS and Windows machines, do::

$ ./build charm4py <version> -j<N> --with-production
$ pip3 install charm4py

where ``<version>`` varies based on the system and communication layer, and ``<N>``
is the number of processes to use for compiling.
For help in choosing the correct ``<version>``, please refer to the Charm++ manual_
and the README in Charm++'s root directory.
.. note::

This option uses Charm++'s TCP layer as the communication layer.
If you want a faster communication layer (e.g. MPI), see "Install from
source" below.

pip >= 8.0 is recommended to simplify the install and avoid building Charm4py or
any dependencies from sources.

Note that a 64-bit version of Python is required to install and run Charm4py.

After the library has been built, continue with ``python3 setup.py install`` in the
Charm4py source root directory.


.. _manual: https://charm.readthedocs.io/en/latest/charm++/manual.html#installing-charm
42 changes: 40 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys
import os
import re
import shutil
import platform
import subprocess
Expand All @@ -8,6 +9,7 @@
from setuptools.command.build_py import build_py
from setuptools.command.install import install
from distutils.errors import DistutilsSetupError
from distutils.command.install_lib import install_lib as _install_lib
from distutils import log
import distutils

Expand All @@ -17,10 +19,11 @@
build_mpi = False



def get_build_machine():
machine = platform.machine()
if machine == 'arm64' or machine == 'aarch64':
return 'arm8'
return 'arm64'
return machine


Expand Down Expand Up @@ -53,6 +56,10 @@ def get_build_triple(build_mpi):
os.environ['ARCHFLAGS'] = f'-arch {machine}'
libcharm_filename = 'libcharm.dylib'
charmrun_filename = 'charmrun'
if 'CPPFLAGS' in os.environ:
os.environ['CPPFLAGS'] += ' -Wno-error=implicit-function-declaration' # needed because some functions used by charm4py are not exported by charm.
else:
os.environ['CPPFLAGS'] = '-Wno-error=implicit-function-declaration '
else: # Linux
libcharm_filename = 'libcharm.so'
charmrun_filename = 'charmrun'
Expand Down Expand Up @@ -185,6 +192,7 @@ def build_libcharm(charm_src_dir, build_dir):
for output_dir in lib_output_dirs:
log.info('copying ' + os.path.relpath(lib_src_path) + ' to ' + os.path.relpath(output_dir))
shutil.copy(lib_src_path, output_dir)


# ---- copy charmrun ----
charmrun_src_path = os.path.join(charm_src_dir, 'charm', 'bin', charmrun_filename)
Expand Down Expand Up @@ -257,6 +265,35 @@ def run(self):
build_libcharm(os.path.join(os.getcwd(), 'charm_src'), self.build_lib)
super(custom_build_ext, self).run()

class _renameInstalled(_install_lib):
def __init__(self, *args, **kwargs):
_install_lib.__init__(self, *args, **kwargs)

def install(self):
log.info("Renaming libraries")
outfiles = _install_lib.install(self)
for file in outfiles:
if "c_object_store" in file and system == "darwin":
direc = os.path.dirname(file)
install_name_command = "install_name_tool -change lib/libcharm.dylib "
install_name_command += direc
install_name_command += "/.libs/libcharm.dylib "
install_name_command += direc
install_name_command += "/c_object_store.*.so"
log.info(install_name_command)
os.system(install_name_command)
elif "charmlib_cython" in file and system == "darwin":
direc = os.path.dirname(file)
install_name_command = "install_name_tool -change lib/libcharm.dylib "
install_name_command += direc
install_name_command += "/.libs/libcharm.dylib "
install_name_command += direc
install_name_command += "/charmlib_cython.*.so"
log.info(install_name_command)
os.system(install_name_command)
return outfiles



extensions = []
py_impl = platform.python_implementation()
Expand Down Expand Up @@ -369,6 +406,7 @@ def run(self):
ext_modules=extensions,
cmdclass = {'build_py': custom_build_py,
'build_ext': custom_build_ext,
'install': custom_install},
'install': custom_install,
'install_lib': _renameInstalled,},
**additional_setup_keywords
)
Loading