From 13c6887d0891431e4b277e2bdb56789791e895b8 Mon Sep 17 00:00:00 2001 From: juanjgalvez Date: Tue, 27 Nov 2018 16:49:18 -0600 Subject: [PATCH] Renamed project to charm4py. Added 0.11 release notes --- .gitignore | 21 +++--- .travis.yml | 4 +- CHANGES.rst | 65 ++++++++++++++----- MANIFEST.in | 6 +- README.rst | 31 +++++---- auto_test.py | 2 +- charm4py/__init__.py | 39 +++++++++++ {charmpy => charm4py}/chare.py | 30 ++++----- {charmpy => charm4py}/charm.py | 44 ++++++------- {charmpy => charm4py}/charmlib/__init__.py | 0 {charmpy => charm4py}/charmlib/ccharm.pxd | 0 .../charmlib/charmlib_cffi.py | 4 +- .../charmlib/charmlib_cffi_build.py | 4 +- .../charmlib/charmlib_ctypes.py | 2 +- .../charmlib/charmlib_cython.pyx | 10 +-- {charmpy => charm4py}/entry_method.py | 0 {charmpy => charm4py}/interactive.py | 2 +- charm4py/libcharm_version | 1 + {charmpy => charm4py}/reduction.py | 8 +-- {charmpy => charm4py}/threads.py | 10 +-- {charmpy => charm4py}/wait.py | 0 charmpy/__init__.py | 38 ----------- charmpy/libcharm_version | 1 - charmrun/start.py | 4 +- docs/Makefile | 8 +-- docs/array-api.rst | 4 +- docs/benchmarks.rst | 16 ++--- docs/chare-api.rst | 6 +- docs/charm-api.rst | 13 ++-- docs/conf.py | 18 ++--- docs/contact.rst | 10 ++- docs/features.rst | 2 +- docs/futures-api.rst | 2 +- docs/group-api.rst | 4 +- docs/index.rst | 18 ++--- docs/install.rst | 24 +++---- docs/make.bat | 4 +- docs/options-api.rst | 6 +- docs/overview.rst | 2 +- docs/performance.rst | 12 ++-- docs/readonlies-api.rst | 6 +- docs/reducer-api.rst | 2 +- docs/running.rst | 22 ++++--- docs/tutorial.rst | 42 +++++++----- examples/hello/array_hello.py | 10 +-- examples/hello/cons_args_hello.py | 10 +-- examples/hello/dynamic_array.py | 10 +-- examples/hello/group_hello.py | 2 +- examples/hello/group_hello2.py | 2 +- examples/multi-module/goodbye.py | 4 +- examples/multi-module/hello.py | 4 +- examples/multi-module/main.py | 4 +- examples/parallel-map/parmap.py | 2 +- examples/particle/particle.py | 4 +- examples/stencil3d/stencil3d.py | 4 +- examples/stencil3d/stencil3d_numba.py | 6 +- examples/tutorial/chares.py | 2 +- examples/tutorial/hello_world.py | 2 +- examples/tutorial/hello_world2.py | 2 +- examples/tutorial/reduction.py | 2 +- examples/tutorial/start.py | 2 +- examples/wave2d/wave2d.py | 7 +- setup.py | 59 ++++++++--------- tests/array_maps/test1.py | 2 +- tests/charm_remote.py | 2 +- tests/collections/test.py | 3 +- tests/dcopy/test_dcopy.py | 10 +-- tests/element_proxy/array_element_proxy.py | 2 +- tests/element_proxy/group_element_proxy.py | 2 +- tests/futures/multi_futures.py | 2 +- tests/futures/test_futures.py | 2 +- tests/migration/chare_migration.py | 2 +- tests/migration/test_migrate.py | 4 +- tests/reductions/array_reduction.py | 27 ++++---- tests/reductions/bench_reductions.py | 12 ++-- tests/reductions/custom_reduction.py | 15 ++--- tests/reductions/future_reduction.py | 2 +- tests/reductions/group_reduction.py | 41 ++++++------ tests/reductions/test_gather.py | 20 +++--- tests/thread_entry_methods/future_bcast.py | 2 +- .../thread_entry_methods/future_reduction.py | 2 +- tests/thread_entry_methods/test1.py | 6 +- tests/thread_entry_methods/test1_when.py | 6 +- tests/thread_entry_methods/test_main.py | 2 +- tests/thread_entry_methods/test_wait.py | 6 +- tests/trees/topo_treeAPI.py | 2 +- tests/when/perf_test.py | 2 +- tests/when/test_when_syntax.py | 4 +- tests/when/when_test.py | 4 +- tests/when/when_test2.py | 6 +- 90 files changed, 462 insertions(+), 413 deletions(-) create mode 100644 charm4py/__init__.py rename {charmpy => charm4py}/chare.py (93%) rename {charmpy => charm4py}/charm.py (94%) rename {charmpy => charm4py}/charmlib/__init__.py (100%) rename {charmpy => charm4py}/charmlib/ccharm.pxd (100%) rename {charmpy => charm4py}/charmlib/charmlib_cffi.py (99%) rename {charmpy => charm4py}/charmlib/charmlib_cffi_build.py (99%) rename {charmpy => charm4py}/charmlib/charmlib_ctypes.py (99%) rename {charmpy => charm4py}/charmlib/charmlib_cython.pyx (99%) rename {charmpy => charm4py}/entry_method.py (100%) rename {charmpy => charm4py}/interactive.py (98%) create mode 100644 charm4py/libcharm_version rename {charmpy => charm4py}/reduction.py (96%) rename {charmpy => charm4py}/threads.py (96%) rename {charmpy => charm4py}/wait.py (100%) delete mode 100644 charmpy/__init__.py delete mode 100644 charmpy/libcharm_version diff --git a/.gitignore b/.gitignore index 64fdd200..0e6d4807 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,22 @@ -#ignore build files +# ignore build files docs/_build/ build/ charm_src/ -charmpy/charmlib/*.o -charmpy/charmlib/*.so -charmpy/charmlib/charmlib_cython.c -charmpy/charmlib/_charmlib_cffi.c -charmpy/charmlib/build/ +charm4py/_version.py +charm4py/charmlib/*.o +charm4py/charmlib/*.so +charm4py/charmlib/charmlib_cython.c +charm4py/charmlib/_charmlib_cffi.c +charm4py/charmlib/build/ __pycache__ -#ignore some common tmp files +# ignore some common tmp files *.swp *.pyc -#ignore binaries -charmpy/.libs/ +# ignore binaries +charm4py/.libs/ charmrun/charmrun -#ignore macOS specific files +# ignore macOS specific files .DS_STORE diff --git a/.travis.yml b/.travis.yml index db754ec6..7a13437e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,9 +17,9 @@ script: - git clone https://github.com/UIUC-PPL/charm charm_src/charm - export CHARM_EXTRA_BUILD_OPTS="--enable-error-checking" - export CHARM_BUILD_PROCESSES=2 - - export CHARMPY_BUILD_CFFI=1 + - export CHARM4PY_BUILD_CFFI=1 - python3 setup.py build_ext --inplace - python2 setup.py build_ext --inplace - export PYTHONPATH=`pwd` - - export CHARMPY_TEST_NUM_PROCESSES=2 + - export CHARM4PY_TEST_NUM_PROCESSES=2 - python3 auto_test.py diff --git a/CHANGES.rst b/CHANGES.rst index 92408767..08bd8c0a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,6 +3,37 @@ This describes the most significant changes. For more detail, see the commit log in the source code repository. +What's new in v0.11 +=================== + +* Changed the name of the project from CharmPy to *charm4py* (more information on why + we changed the name is in the forum). + +* Not directly related to this release, but there is a new forum for charm4py discussions + (see contact details). Feel free to visit the forum for discussions, reports, + provide feedback, request features and to follow development. + +* Support for interactive charm4py shell using multiple processes on one host has been added + as a *beta* feature. Please provide feedback and suggestions in the forum or GitHub. + +* Uses the recent major release of Charm++ (6.9) + +* C-extension module can be built on Windows. Windows binary wheels on PyPI come with + the compiled extension module. + +* API change: method ``Chare.gather()`` has been removed to make the name available + for user-defined remote methods. Use ``self.contribute(data, Reducer.gather, ...)`` + instead. + +* Some methods of ``charm`` are now remotely callable, like ``charm.exit()``. + They can be used as any other remote method including as targets of reductions. + For example: ``self.contribute(None, None, charm.thisProxy[0].exit)`` + +* Can now use Python exit function instead of ``charm.exit()`` + +* Other small fixes and improvements. + + What's new in v0.10.1 ===================== @@ -12,16 +43,16 @@ This is a bugfix and documentation release: * Fixed reduction to Future failing when contributing numeric arrays -* CharmPy now requires Charm++ version >= ``6.8.2-890`` which, among other things, +* Charm4py now requires Charm++ version >= ``6.8.2-890`` which, among other things, includes fixes for the following Windows issues: - Running an application without ``charmrun`` on Windows would crash - - Abort messages were sometimes not displayed on exit. On CharmPy, + - Abort messages were sometimes not displayed on exit. On Charm4py, this had the effect that Python runtime errors were sometimes not shown. - If running with charmrun, any output prior to charm.start() - would not be shown. On CharmPy, this had the effect that Python + would not be shown. On Charm4py, this had the effect that Python syntax errors were not shown. @@ -30,17 +61,17 @@ What's new in v0.10 **Installation and Setup** -* CharmPy can be installed with pip (``pip install charmpy``) on regular +* Charm4py can be installed with pip (``pip install charm4py``) on regular Linux, macOS and Windows systems -* Support setuptools to build, install, and package CharmPy +* Support setuptools to build, install, and package Charm4py * Installation from source is much simpler (see documentation) -* charmpy builds include the charm++ library and are relocatable. ``LD_LIBRARY_PATH`` or +* charm4py builds include the charm++ library and are relocatable. ``LD_LIBRARY_PATH`` or similar schemes are no longer needed. -* charmpy does not need a configuration file anymore (it will automatically +* charm4py does not need a configuration file anymore (it will automatically select the best available interface layer at runtime). @@ -53,7 +84,7 @@ What's new in v0.10 **Performance** * Added Cython-based C-extension module to considerably speed up the interface with - the Charm++ library and critical parts of charmpy (currently only with Python 3+). + the Charm++ library and critical parts of charm4py (currently only with Python 3+). * Several minor performance improvements @@ -92,12 +123,12 @@ What's new in v0.10 * ArrayMap: to customize initial mapping of chares to cores -* Warn if user forgot to call ``charm.start()`` when launching charmpy programs +* Warn if user forgot to call ``charm.start()`` when launching charm4py programs * Exposed ``migrateMe(toPe)`` method of chares to manually migrate a chare to indicated PE -* Exposed `LBTurnInstrumentOn/Off`__ from Charm++ to charmpy applications +* Exposed `LBTurnInstrumentOn/Off`__ from Charm++ to charm4py applications * Interface to construct topology-aware trees of nodes/PEs @@ -137,8 +168,8 @@ What's new in v0.10 * Heavy code refactoring. Code simplification in several places -* Several improvements towards PEP 8 compliance of core charmpy code. - Indentation of code in ``charmpy`` package is PEP 8 compliant. +* Several improvements towards PEP 8 compliance of core charm4py code. + Indentation of code in ``charm4py`` package is PEP 8 compliant. * Improvements to test infrastructure and added Travis CI script @@ -152,9 +183,9 @@ What's new in v0.9 **General** -* CharmPy is compatible with Python 3 (Python 3 is the recommended option) +* Charm4py is compatible with Python 3 (Python 3 is the recommended option) -* Added documentation (http://charmpy.readthedocs.io) +* Added documentation (http://charm4py.readthedocs.io) **API Changes** @@ -206,8 +237,8 @@ What's new in v0.9 * Improved profiling output. Profiling is disabled by default. -* Improved general error handling and output. Errors in charmpy runtime raise - ``CharmPyError`` exception. +* Improved general error handling and output. Errors in charm4py runtime raise + ``Charm4PyError`` exception. * Code Examples: @@ -217,4 +248,4 @@ What's new in v0.9 - Add total iterations as program parameter for wave2d -* Added ``auto_test.py`` script to test charmpy +* Added ``auto_test.py`` script to test charm4py diff --git a/MANIFEST.in b/MANIFEST.in index 305b07b7..7ed0d057 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,11 +1,11 @@ include MANIFEST.in -include README.rst setup.py auto_test.py AUTHORS.md LICENSE CHANGES.rst +include README.rst setup.py auto_test.py test_config.json AUTHORS.md LICENSE CHANGES.rst include charm_src/charm.tar.gz -exclude charmpy/charmlib/charmlib_cython.c +exclude charm4py/charmlib/charmlib_cython.c -recursive-include charmpy libcharm_version *.pxd *.pyx +recursive-include charm4py libcharm_version *.pxd *.pyx recursive-include docs *.py Makefile *.bat *.rst *.svg recursive-include examples *.py recursive-include tests *.py diff --git a/README.rst b/README.rst index 72bb2c3f..9e07604a 100644 --- a/README.rst +++ b/README.rst @@ -1,13 +1,16 @@ -======= -CharmPy -======= +======== +charm4py +======== -CharmPy is a general-purpose parallel and distributed programming framework with a -simple and powerful API, based on migratable Python objects and remote method -invocation; built on top of an adaptive C++ runtime system providing *speed*, -*scalability* and *dynamic load balancing*. +(NOTE: With release v0.11 we have changed the name of the project to charm4py. See +the `forum`_ for more information.) -CharmPy allows development of parallel applications that scale from laptops to +charm4py (Charm++ for Python *-formerly CharmPy-*) is a general-purpose parallel and +distributed programming framework with a simple and powerful API, based on +migratable Python objects and remote method invocation; built on top of an adaptive +C++ runtime system providing *speed*, *scalability* and *dynamic load balancing*. + +charm4py allows development of parallel applications that scale from laptops to supercomputers, using the Python language. It is built on top of `Charm++`_. Please see the Documentation_. @@ -19,7 +22,7 @@ The following computes Pi in parallel, using any number of machines and processo .. code-block:: python - from charmpy import charm, Chare, Group, Reducer + from charm4py import charm, Chare, Group, Reducer from math import pi import time @@ -49,13 +52,13 @@ The following computes Pi in parallel, using any number of machines and processo charm.start(main) -This is a simple example and demonstrates only a few features of CharmPy. Some things to note +This is a simple example and demonstrates only a few features of charm4py. Some things to note from this example: - *Chares* are distributed Python objects. - A *Group* is a type of distributed collection where one instance of the specified chare type is created on each processor. -- Remote method invocation in CharmPy is *asynchronous*. +- Remote method invocation in charm4py is *asynchronous*. In this example, there is only one chare per processor, but multiple chares (of the same or different type) can exist on any given processor, which can bring performance @@ -65,13 +68,13 @@ benefits. Please refer to the documentation_ for more information. Contact ------- -`Mailing list`_ +We want feedback from the community. If you have feature suggestions, support questions or general comments, please visit our `forum`_. Main author at .. _Charm++: https://github.com/UIUC-PPL/charm -.. _Documentation: https://charmpy.readthedocs.io +.. _Documentation: https://charm4py.readthedocs.io -.. _Mailing list: charm@cs.illinois.edu +.. _forum: https://charm.discourse.group/c/charm4py diff --git a/auto_test.py b/auto_test.py index f7efd066..b90d4452 100644 --- a/auto_test.py +++ b/auto_test.py @@ -42,7 +42,7 @@ def searchForPython(python_implementations): CHARM_QUIET_AFTER_NUM_TESTS = 5 commonArgs = ['++local'] -default_num_processes = int(os.environ.get('CHARMPY_TEST_NUM_PROCESSES', 4)) +default_num_processes = int(os.environ.get('CHARM4PY_TEST_NUM_PROCESSES', 4)) try: import numba diff --git a/charm4py/__init__.py b/charm4py/__init__.py new file mode 100644 index 00000000..3640b6a5 --- /dev/null +++ b/charm4py/__init__.py @@ -0,0 +1,39 @@ +import sys +if sys.version_info < (2, 7, 0): + raise RuntimeError("charm4py requires Python 2.7 or higher") +import atexit +import os +import subprocess + + +charm4py_version = "unknown" +try: + from ._version import version as charm4py_version +except: + try: + charm4py_version = subprocess.check_output(['git', 'describe'], + cwd=os.path.dirname(__file__)).rstrip().decode() + except: + pass + +if os.environ.get('CHARM_NOLOAD', '0') == '0': + from .charm import charm, readonlies, Options + Reducer = charm.reducers + + CkMyPe = charm.myPe + CkNumPes = charm.numPes + CkExit = charm.exit + CkAbort = charm.abort + + from .entry_method import when, threaded + + from .chare import Chare, Group, Array, ArrayMap + + + def checkCharmStarted(): + if not charm.started: + print('Program is exiting but charm was not started: charm.start() was not ' + 'called or error happened before start') + + + atexit.register(checkCharmStarted) diff --git a/charmpy/chare.py b/charm4py/chare.py similarity index 93% rename from charmpy/chare.py rename to charm4py/chare.py index 9c719540..d69ae7a0 100644 --- a/charmpy/chare.py +++ b/charm4py/chare.py @@ -7,7 +7,7 @@ # A Chare class defined by a user can be used in 3 ways: (1) as a Mainchare, (2) to form Groups, -# (3) to form Arrays. To achieve this, charmpy can register with the Charm++ library up to 3 +# (3) to form Arrays. To achieve this, charm4py can register with the Charm++ library up to 3 # different types for the given class (a Mainchare, a Group and an Array), and each type will # register its own entry methods, even though the definition (body) of the entry methods in Python is the same. MAINCHARE, GROUP, ARRAY = range(3) @@ -50,7 +50,7 @@ def __init__(self): def __addLocal__(self, msg): if self._local_free_head is None: - raise CharmPyError("Local msg buffer full. Increase LOCAL_MSG_BUF_SIZE") + raise Charm4PyError("Local msg buffer full. Increase LOCAL_MSG_BUF_SIZE") h = self._local_free_head self._local_free_head = self._local[self._local_free_head] self._local[h] = msg @@ -117,7 +117,7 @@ def AtSync(self): charm.CkArraySend(self.thisProxy.aid, self.thisIndex, self.thisProxy.AtSync.ep, (b'', [])) def migrate(self, toPe): - # print("[charmpy] Calling migrate, aid: ", self.thisProxy.aid, "ndims", + # print("[charm4py] Calling migrate, aid: ", self.thisProxy.aid, "ndims", # self.thisProxy.ndims, "index: ", self.thisIndex, "toPe", toPe) charm.lib.CkMigrate(self.thisProxy.aid, self.thisIndex, toPe) @@ -186,7 +186,7 @@ def __getProxyClass__(C, cls): M = dict() # proxy methods for m in charm.classEntryMethods[MAINCHARE][cls]: if m.epIdx == -1: - raise CharmPyError("Unregistered entry method") + raise Charm4PyError("Unregistered entry method") if Options.PROFILING: M[m.name] = profile_send_function(mainchare_proxy_method_gen(m.epIdx)) else: @@ -264,9 +264,9 @@ class Group(object): def __new__(cls, C, args=[]): if (not hasattr(C, 'mro')) or (Chare not in C.mro()): - raise CharmPyError("Only subclasses of Chare can be member of Group") + raise Charm4PyError("Only subclasses of Chare can be member of Group") if C not in charm.proxyClasses[GROUP]: - raise CharmPyError(str(C) + ' not registered for use in Groups') + raise Charm4PyError(str(C) + ' not registered for use in Groups') return charm.proxyClasses[GROUP][C].ckNew(args) @classmethod @@ -286,7 +286,7 @@ def __getProxyClass__(C, cls): entryMethods = charm.classEntryMethods[GROUP][cls] for m in entryMethods: if m.epIdx == -1: - raise CharmPyError("Unregistered entry method") + raise Charm4PyError("Unregistered entry method") if Options.PROFILING: M[m.name] = profile_send_function(group_proxy_method_gen(m.epIdx)) else: @@ -322,7 +322,7 @@ def array_proxy_elem(proxy, idx): # array proxy [] overload method proxy_clone = proxy.__class__(proxy.aid, proxy.ndims) if type(idx) == int: idx = (idx,) if len(idx) != proxy_clone.ndims: - raise CharmPyError("Dimensions of index " + str(idx) + " don't match array dimensions") + raise Charm4PyError("Dimensions of index " + str(idx) + " don't match array dimensions") proxy_clone.elemIdx = tuple(idx) return proxy_clone @@ -353,9 +353,9 @@ def array_ckNew(cls, dims=None, ndims=-1, args=[], map=None): if type(dims) == int: dims = (dims,) if dims is None and ndims == -1: - raise CharmPyError("Bounds and number of dimensions for array cannot be empty in ckNew") + raise Charm4PyError("Bounds and number of dimensions for array cannot be empty in ckNew") elif dims is not None and ndims != -1 and ndims != len(dims): - raise CharmPyError("Number of bounds should match number of dimensions") + raise Charm4PyError("Number of bounds should match number of dimensions") elif dims is None and ndims != -1: # create an empty array dims = (0,) * ndims @@ -397,9 +397,9 @@ class Array(object): def __new__(cls, C, dims=None, ndims=-1, args=[], map=None): if (not hasattr(C, 'mro')) or (Chare not in C.mro()): - raise CharmPyError("Only subclasses of Chare can be member of Array") + raise Charm4PyError("Only subclasses of Chare can be member of Array") if C not in charm.proxyClasses[ARRAY]: - raise CharmPyError(str(C) + ' not registered for use in Arrays') + raise Charm4PyError(str(C) + ' not registered for use in Arrays') return charm.proxyClasses[ARRAY][C].ckNew(dims, ndims, args, map) @classmethod @@ -422,7 +422,7 @@ def __getProxyClass__(C, cls): entryMethods = charm.classEntryMethods[ARRAY][cls] for m in entryMethods: if m.epIdx == -1: - raise CharmPyError("Unregistered entry method") + raise Charm4PyError("Unregistered entry method") if Options.PROFILING: M[m.name] = profile_send_function(array_proxy_method_gen(m.epIdx)) else: @@ -451,9 +451,9 @@ def __getProxyClass__(C, cls): def charmStarting(): - from .charm import charm, Options, CharmPyError, profile_send_function + from .charm import charm, Options, Charm4PyError, profile_send_function globals()['charm'] = charm globals()['Reducer'] = charm.reducers globals()['Options'] = Options - globals()['CharmPyError'] = CharmPyError + globals()['Charm4PyError'] = Charm4PyError globals()['profile_send_function'] = profile_send_function diff --git a/charmpy/charm.py b/charm4py/charm.py similarity index 94% rename from charmpy/charm.py rename to charm4py/charm.py index 5138f8e5..22ac29d8 100644 --- a/charmpy/charm.py +++ b/charm4py/charm.py @@ -40,9 +40,9 @@ class Options: QUIET = False -class CharmPyError(Exception): +class Charm4PyError(Exception): def __init__(self, msg): - super(CharmPyError, self).__init__(msg) + super(Charm4PyError, self).__init__(msg) self.message = msg @@ -143,7 +143,7 @@ def buildMainchare(self, onPe, objPtr, ep, args): roData[attr] = getattr(readonlies, attr) msg = cPickle.dumps(roData, Options.PICKLE_PROTOCOL) # print("Registering readonly data of size " + str(len(msg))) - self.lib.CkRegisterReadonly(b"charmpy_ro", b"charmpy_ro", msg) + self.lib.CkRegisterReadonly(b"charm4py_ro", b"charm4py_ro", msg) def invokeEntryMethod(self, obj, ep, header, args, t0): em = self.entryMethods[ep] @@ -318,9 +318,9 @@ def packMsg(self, destObj, msgArgs, header): def registerInCharmAs(self, C, charm_type, libRegisterFunc): charm_type_id = charm_type.type_id entryMethods = self.classEntryMethods[charm_type_id][C] - # if self.myPe() == 0: print("CharmPy:: Registering class " + C.__name__ + " in Charm with " + str(len(entryMethods)) + " entry methods " + str([e.name for e in entryMethods])) + # if self.myPe() == 0: print("charm4py:: Registering class " + C.__name__ + " in Charm with " + str(len(entryMethods)) + " entry methods " + str([e.name for e in entryMethods])) C.idx[charm_type_id], startEpIdx = libRegisterFunc(C.__name__ + str(charm_type_id), len(entryMethods)) - # if self.myPe() == 0: print("CharmPy:: Chare idx=" + str(C.idx[charm_type_id]) + " ctor Idx=" + str(startEpIdx)) + # if self.myPe() == 0: print("charm4py:: Chare idx=" + str(C.idx[charm_type_id]) + " ctor Idx=" + str(startEpIdx)) for i, em in enumerate(entryMethods): if i == 0: em.isCtor = True @@ -362,8 +362,8 @@ def registerMainModule(self): if (self.myPe() == 0) and (not Options.QUIET): import platform - from . import charmpy_version - out_msg = ("CharmPy> Running CharmPy version " + charmpy_version + + from . import charm4py_version + out_msg = ("charm4py> Running Charm4py version " + charm4py_version + " on Python " + str(platform.python_version()) + " (" + str(platform.python_implementation()) + "). Using '" + self.lib.name + "' interface to access Charm++") @@ -379,7 +379,7 @@ def registerAs(self, C, charm_type_id): assert not self.mainchareRegistered, "More than one entry point has been specified" self.mainchareRegistered = True charm_type = chare.charm_type_id_to_class[charm_type_id] - # print("CharmPy: Registering class " + C.__name__, "as", charm_type.__name__, "type_id=", charm_type_id, charm_type) + # print("charm4py: Registering class " + C.__name__, "as", charm_type.__name__, "type_id=", charm_type_id, charm_type) l = [entry_method.EntryMethod(C, m, profile=Options.PROFILING) for m in charm_type.__baseEntryMethods__()] self.classEntryMethods[charm_type_id][C] = l @@ -387,7 +387,7 @@ def registerAs(self, C, charm_type_id): if not callable(getattr(C, m)): continue if m in chare.method_restrictions['reserved'] and getattr(C, m) != getattr(Chare, m): - raise CharmPyError(str(C) + " redefines reserved method '" + m + "'") + raise Charm4PyError(str(C) + " redefines reserved method '" + m + "'") if m.startswith("__") and m.endswith("__"): continue # filter out non-user methods if m in chare.method_restrictions['non_entry_method']: @@ -397,13 +397,13 @@ def registerAs(self, C, charm_type_id): self.classEntryMethods[charm_type_id][C].append(em) self.registered[C].add(charm_type) - # called by user (from Python) to register their Charm++ classes with the CharmPy runtime + # called by user (from Python) to register their Charm++ classes with the charm4py runtime # by default a class is registered to work with both Groups and Arrays def register(self, C, collections=(GROUP, ARRAY)): if C in self.registered: return if (not hasattr(C, 'mro')) or (Chare not in C.mro()): - raise CharmPyError("Only subclasses of Chare can be registered") + raise Charm4PyError("Only subclasses of Chare can be registered") self.registered[C] = set() for charm_type_id in collections: @@ -418,7 +418,7 @@ def _createInternalChares(self): def start(self, entry=None, classes=[], modules=[], interactive=False): """ - Start Charmpy program. + Start charm4py program. IMPORTANT: classes must be registered in the same order on all processes. In other words, the arguments to this method must have the same ordering on all @@ -441,7 +441,7 @@ def start(self, entry=None, classes=[], modules=[], interactive=False): 'Array': Array, 'Reducer': self.reducers}) if self.started: - raise CharmPyError("charm.start() can only be called once") + raise Charm4PyError("charm.start() can only be called once") self.started = True if Options.PROFILING: @@ -453,12 +453,12 @@ def start(self, entry=None, classes=[], modules=[], interactive=False): if hasattr(entry, 'mro') and Chare in entry.mro(): if entry.__init__.__code__.co_argcount != 2: - raise CharmPyError("Mainchare constructor must have only one parameter") + raise Charm4PyError("Mainchare constructor must have only one parameter") self.register(entry, (MAINCHARE,)) else: assert callable(entry), "Given entry point is not a function or Chare" if entry.__code__.co_argcount != 1: - raise CharmPyError("Main function must have only one parameter") + raise Charm4PyError("Main function must have only one parameter") self.entry_func = entry self.register(chare.DefaultMainchare, (MAINCHARE,)) @@ -468,7 +468,7 @@ def start(self, entry=None, classes=[], modules=[], interactive=False): elif Chare in C.mro(): self.register(C) else: - raise CharmPyError("Class", C, "is not a Chare (can't register)") + raise Charm4PyError("Class", C, "is not a Chare (can't register)") import importlib import inspect @@ -485,7 +485,7 @@ def start(self, entry=None, classes=[], modules=[], interactive=False): elif Chare in C.mro(): self.register(C) elif Group in C.mro() or Array in C.mro() or Mainchare in C.mro(): - raise CharmPyError("Chares must not inherit from Group, Array or" + raise Charm4PyError("Chares must not inherit from Group, Array or" " Mainchare. Refer to new API") for module in (chare, entry_method, threads, wait): @@ -520,8 +520,8 @@ def awaitCreation(self, *proxies): for proxy in proxies: if not hasattr(proxy, 'creation_future'): if not proxy.__class__.__name__.endswith("Proxy"): - raise CharmPyError('Did not pass a proxy to awaitCreation? ' + str(type(proxy))) - raise CharmPyError('awaitCreation can only be used if creation triggered from threaded entry method') + raise Charm4PyError('Did not pass a proxy to awaitCreation? ' + str(type(proxy))) + raise Charm4PyError('awaitCreation can only be used if creation triggered from threaded entry method') proxy.creation_future.get() del proxy.creation_future @@ -542,7 +542,7 @@ def __printTable__(self, table, sep): def printStats(self): if not self.started: - raise CharmPyError('charm was not started') + raise Charm4PyError('charm was not started') if not Options.PROFILING: print('NOTE: called charm.printStats() but profiling is disabled') return @@ -604,7 +604,7 @@ def lib_version_check(self, commit_id_str): if version < req_version: req_str = '.'.join([str(n) for n in req_version]) cur_str = '.'.join([str(n) for n in version]) - raise CharmPyError("Charm++ version >= " + req_str + " required. " + + raise Charm4PyError("Charm++ version >= " + req_str + " required. " + "Existing version is " + cur_str) def getTopoTreeEdges(self, pe, root_pe, pes=None, bfactor=4): @@ -668,7 +668,7 @@ def load_charm_library(charm): elif interface == 'cython': from .charmlib.charmlib_cython import CharmLib else: - raise CharmPyError('Unrecognized interface ' + interface) + raise Charm4PyError('Unrecognized interface ' + interface) else: # pick best available interface import platform diff --git a/charmpy/charmlib/__init__.py b/charm4py/charmlib/__init__.py similarity index 100% rename from charmpy/charmlib/__init__.py rename to charm4py/charmlib/__init__.py diff --git a/charmpy/charmlib/ccharm.pxd b/charm4py/charmlib/ccharm.pxd similarity index 100% rename from charmpy/charmlib/ccharm.pxd rename to charm4py/charmlib/ccharm.pxd diff --git a/charmpy/charmlib/charmlib_cffi.py b/charm4py/charmlib/charmlib_cffi.py similarity index 99% rename from charmpy/charmlib/charmlib_cffi.py rename to charm4py/charmlib/charmlib_cffi.py index b15e7879..dc747e26 100644 --- a/charmpy/charmlib/charmlib_cffi.py +++ b/charm4py/charmlib/charmlib_cffi.py @@ -433,7 +433,7 @@ def createReductionTargetMsg_py2(data, dataSize, reducerType, fid, returnBuffers returnBuffers[0] = ffi.from_buffer(CharmLib.tempData) returnBufferSizes[0] = len(CharmLib.tempData) else: - # do nothing, use message as is (was created by charmpy) + # do nothing, use message as is (was created by charm4py) returnBuffers[0] = data returnBufferSizes[0] = dataSize @@ -489,7 +489,7 @@ def createReductionTargetMsg_py3(data, dataSize, reducerType, fid, returnBuffers returnBuffers[0] = ffi.from_buffer(CharmLib.tempData) returnBufferSizes[0] = len(CharmLib.tempData) else: - # do nothing, use message as is (was created by charmpy) + # do nothing, use message as is (was created by charm4py) returnBuffers[0] = data returnBufferSizes[0] = dataSize diff --git a/charmpy/charmlib/charmlib_cffi_build.py b/charm4py/charmlib/charmlib_cffi_build.py similarity index 99% rename from charmpy/charmlib/charmlib_cffi_build.py rename to charm4py/charmlib/charmlib_cffi_build.py index e8ee51bf..cab12bb9 100644 --- a/charmpy/charmlib/charmlib_cffi_build.py +++ b/charm4py/charmlib/charmlib_cffi_build.py @@ -10,7 +10,7 @@ extra_link_args=["-Wl,-rpath,$ORIGIN/../.libs"] -ffibuilder.set_source("charmpy.charmlib._charmlib_cffi", +ffibuilder.set_source("charm4py.charmlib._charmlib_cffi", r""" // passed to the real C compiler #include "charm.h" #include "spanningTree.h" @@ -96,7 +96,7 @@ """, libraries=['charm'], include_dirs=['charm_src/charm/include'], - library_dirs=['charmpy/.libs'], + library_dirs=['charm4py/.libs'], extra_compile_args=['-g0', '-O3'], extra_link_args=extra_link_args) diff --git a/charmpy/charmlib/charmlib_ctypes.py b/charm4py/charmlib/charmlib_ctypes.py similarity index 99% rename from charmpy/charmlib/charmlib_ctypes.py rename to charm4py/charmlib/charmlib_ctypes.py index 4c20b4d8..be9a674e 100644 --- a/charmpy/charmlib/charmlib_ctypes.py +++ b/charm4py/charmlib/charmlib_ctypes.py @@ -427,7 +427,7 @@ def createReductionTargetMsg(self, data, dataSize, reducerType, fid, returnBuffe returnBuffers[0] = ctypes.cast(c_char_p(pickledData), POINTER(c_char)) returnBufferSizes[0] = len(pickledData) else: - # do nothing, use message as is (was created by charmpy) + # do nothing, use message as is (was created by charm4py) returnBuffers[0] = ctypes.cast(data, c_char_p) returnBufferSizes[0] = dataSize diff --git a/charmpy/charmlib/charmlib_cython.pyx b/charm4py/charmlib/charmlib_cython.pyx similarity index 99% rename from charmpy/charmlib/charmlib_cython.pyx rename to charm4py/charmlib/charmlib_cython.pyx index bde70e4a..eb278570 100644 --- a/charmpy/charmlib/charmlib_cython.pyx +++ b/charm4py/charmlib/charmlib_cython.pyx @@ -8,7 +8,7 @@ from cpython.tuple cimport PyTuple_New, PyTuple_SET_ITEM from cpython.int cimport PyInt_FromSsize_t from cpython.ref cimport Py_INCREF -from ..charm import CharmPyError +from ..charm import Charm4PyError from .. import reduction as red from cpython cimport array import array @@ -159,7 +159,7 @@ cdef class ContributeInfo: cdef int i = 0 cdef int index_len = len(index) if index_len > MAX_INDEX_LEN: - raise CharmPyError("Element index length greater than MAX_INDEX_LEN") + raise Charm4PyError("Element index length greater than MAX_INDEX_LEN") for i in range(index_len): self.index[i] = index[i] self.buf = None self.bufSet = False @@ -296,7 +296,7 @@ cdef object rev_array_type_map cdef object tempData cdef int PROFILING = 0 cdef object PICKLE_PROTOCOL = -1 -cdef object emptyMsg # pickled empty Charmpy msg +cdef object emptyMsg # pickled empty Charm4py msg cdef object times = [0.0] * 3 # track time in [charm reduction callbacks, custom reduction, outgoing object migration] cdef bytes localMsg = b'L:' + (b' ' * sizeof(int)) cdef char* localMsg_ptr = localMsg @@ -628,7 +628,7 @@ class CharmLib(object): a.shape = shape args[arg_pos] = a.copy() else: - raise CharmPyError("unpackMsg: wrong type id received") + raise Charm4PyError("unpackMsg: wrong type id received") msg.advance(buf_size) elif b"custom_reducer" in header: reducer = getattr(charm.reducers, header[b"custom_reducer"]) @@ -838,7 +838,7 @@ cdef void createReductionTargetMsg(void *data, int dataSize, int reducerType, in returnBuffers[0] = tempData returnBufferSizes[0] = len(tempData) else: - # do nothing, use message as is (was created by charmpy) + # do nothing, use message as is (was created by charm4py) returnBuffers[0] = data returnBufferSizes[0] = dataSize diff --git a/charmpy/entry_method.py b/charm4py/entry_method.py similarity index 100% rename from charmpy/entry_method.py rename to charm4py/entry_method.py diff --git a/charmpy/interactive.py b/charm4py/interactive.py similarity index 98% rename from charmpy/interactive.py rename to charm4py/interactive.py index 3ced3f4a..4fe01939 100644 --- a/charmpy/interactive.py +++ b/charm4py/interactive.py @@ -50,7 +50,7 @@ def write(self, data): @threaded def start(self): - self.write('CharmPy interactive shell\n') + self.write('Charm4py interactive shell\n') more = 0 tick = time.time() while 1: diff --git a/charm4py/libcharm_version b/charm4py/libcharm_version new file mode 100644 index 00000000..98fc3254 --- /dev/null +++ b/charm4py/libcharm_version @@ -0,0 +1 @@ +6.9.0.0 diff --git a/charmpy/reduction.py b/charm4py/reduction.py similarity index 96% rename from charmpy/reduction.py rename to charm4py/reduction.py index 044407ae..a7a18476 100644 --- a/charmpy/reduction.py +++ b/charm4py/reduction.py @@ -79,8 +79,8 @@ def __init__(self, charm): def addReducer(self, func, pre=None, post=None): if hasattr(self, func.__name__): - from .charm import CharmPyError - raise CharmPyError("Reducer with name " + func.__name__ + " already registered") + from .charm import Charm4PyError + raise Charm4PyError("Reducer with name " + func.__name__ + " already registered") func.hasPreprocess = False func.hasPostprocess = False if pre is not None: @@ -226,8 +226,8 @@ def prepare(self, data, reducer, contributor): return (charm_reducer_type, data, c_type) else: if not hasattr(pyReducer, 'hasPreprocess'): - from .charm import CharmPyError - raise CharmPyError("Please register reducer '" + reducer.__name__ + "' with addReducer") + from .charm import Charm4PyError + raise Charm4PyError("Please register reducer '" + reducer.__name__ + "' with addReducer") if pyReducer.hasPreprocess: data = pyReducer.preprocess(data, contributor) rednMsg = ({b"custom_reducer": pyReducer.__name__}, [data]) diff --git a/charmpy/threads.py b/charm4py/threads.py similarity index 96% rename from charmpy/threads.py rename to charm4py/threads.py index 389d41a4..d563d7b8 100644 --- a/charmpy/threads.py +++ b/charm4py/threads.py @@ -74,7 +74,7 @@ def __init__(self, obj, entry_method): def __init__(self): self.PROFILING = Options.PROFILING - self.main_thread_id = get_ident() # ID of the charmpy process main thread + self.main_thread_id = get_ident() # ID of the charm4py process main thread # condition variable used by main thread to pause while threaded entry method is running self.entryMethodRunning = threading.Condition() self.threads = {} # thread ID -> ThreadState object @@ -112,7 +112,7 @@ def threadStopped(self, tid): def objMigrating(self, obj): if obj in self.obj_threads: if len(self.obj_threads.pop(obj)) > 0: - raise CharmPyError("Migration of chares with active threads is not yet supported") + raise Charm4PyError("Migration of chares with active threads is not yet supported") def entryMethodRun_thread(self, obj, entry_method, args, header): """ Entry method thread main function """ @@ -143,7 +143,7 @@ def entryMethodRun_thread(self, obj, entry_method, args, header): self.entryMethodRunning.notify() # notify main thread that done def throwNotThreadedError(self): - raise CharmPyError("Entry method '" + charm.mainThreadEntryMethod.C.__name__ + "." + + raise Charm4PyError("Entry method '" + charm.mainThreadEntryMethod.C.__name__ + "." + charm.mainThreadEntryMethod.name + "' must be marked as 'threaded' to block") @@ -215,7 +215,7 @@ def depositFuture(self, fid, result): def charmStarting(): - from .charm import charm, Options, CharmPyError + from .charm import charm, Options, Charm4PyError globals()['charm'] = charm globals()['Options'] = Options - globals()['CharmPyError'] = CharmPyError + globals()['Charm4PyError'] = Charm4PyError diff --git a/charmpy/wait.py b/charm4py/wait.py similarity index 100% rename from charmpy/wait.py rename to charm4py/wait.py diff --git a/charmpy/__init__.py b/charmpy/__init__.py deleted file mode 100644 index d14911bc..00000000 --- a/charmpy/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -import sys -if sys.version_info < (2, 7, 0): - raise RuntimeError("charmpy requires Python 2.7 or higher") -import atexit -import os -import subprocess - - -charmpy_version = "unknown" -try: - from ._version import version as charmpy_version -except: - try: - charmpy_version = subprocess.check_output(['git', 'describe'], - cwd=os.path.dirname(__file__)).rstrip().decode() - except: - pass - -from .charm import charm, readonlies, Options -Reducer = charm.reducers - -CkMyPe = charm.myPe -CkNumPes = charm.numPes -CkExit = charm.exit -CkAbort = charm.abort - -from .entry_method import when, threaded - -from .chare import Chare, Group, Array, ArrayMap - - -def checkCharmStarted(): - if not charm.started: - print('Program is exiting but charm was not started: charm.start() was not ' - 'called or error happened before start') - - -atexit.register(checkCharmStarted) diff --git a/charmpy/libcharm_version b/charmpy/libcharm_version deleted file mode 100644 index 445fcabd..00000000 --- a/charmpy/libcharm_version +++ /dev/null @@ -1 +0,0 @@ -6.8.2.890 diff --git a/charmrun/start.py b/charmrun/start.py index 98ab34f4..392e4308 100644 --- a/charmrun/start.py +++ b/charmrun/start.py @@ -55,9 +55,9 @@ def start(args=[]): args[idx] = '-c' if os.name == 'nt': # workaround for how windows charmrun executable passes argument - args.insert(idx + 1, '\"from charmpy import charm ; charm.start(interactive=True)\"') + args.insert(idx + 1, '\"from charm4py import charm ; charm.start(interactive=True)\"') else: - args.insert(idx + 1, 'from charmpy import charm ; charm.start(interactive=True)') + args.insert(idx + 1, 'from charm4py import charm ; charm.start(interactive=True)') except ValueError: pass diff --git a/docs/Makefile b/docs/Makefile index f9f09060..2a0ae8ef 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -94,9 +94,9 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CharmPy.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Charm4py.qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CharmPy.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Charm4py.qhc" .PHONY: applehelp applehelp: @@ -113,8 +113,8 @@ devhelp: @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/CharmPy" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CharmPy" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Charm4py" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Charm4py" @echo "# devhelp" .PHONY: epub diff --git a/docs/array-api.rst b/docs/array-api.rst index c7015091..eb2f8fa4 100644 --- a/docs/array-api.rst +++ b/docs/array-api.rst @@ -4,7 +4,7 @@ Array ----- -``charmpy.Array`` is a type of distributed collection where chares have +``charm4py.Array`` is a type of distributed collection where chares have n-dimensional indexes (represented by an integer n-tuple), and members can exist anywhere on the system. As such, there can be zero or multiple elements of a chare array on a given PE, and elements can @@ -12,7 +12,7 @@ migrate between PEs. Arrays are created using the following syntax: -``charmpy.Array(chare_type, dims=None, ndims=-1, args=[], map=None)`` where +``charm4py.Array(chare_type, dims=None, ndims=-1, args=[], map=None)`` where ``chare_type`` is the type of chares that will constitute the array. There are two modes to create an array: diff --git a/docs/benchmarks.rst b/docs/benchmarks.rst index 2093cf60..aa2cbecb 100644 --- a/docs/benchmarks.rst +++ b/docs/benchmarks.rst @@ -4,7 +4,7 @@ Benchmarks .. contents:: -This section presents CharmPy benchmark results using: (a) real examples and miniapps; +This section presents Charm4py benchmark results using: (a) real examples and miniapps; (b) synthetic test cases to evaluate specific features. Mini-apps @@ -13,9 +13,9 @@ Mini-apps LeanMD - Molecular Dynamics ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We have ported the LeanMD_ Charm++ mini-app to CharmPy, with all the code written +We have ported the LeanMD_ Charm++ mini-app to Charm4py, with all the code written in Python. The physics functions are JIT compiled by Numba_. The code is currently -available in the ``leanmd-experimental`` branch of CharmPy. +available in the ``leanmd-experimental`` branch of Charm4py. Here we compare the performance between the C++ and Python versions. First we ran a *strong scaling* problem on `Blue Waters`_ with 8 million particles, @@ -26,10 +26,10 @@ obtaining the following results: :width: 60% :align: center -As we can see, the performance and scaling characteristics of CharmPy closely mimic +As we can see, the performance and scaling characteristics of Charm4py closely mimic the behavior of the C++ program. The y axis is logarithmic scale, and we can see that performance scales linearly with the number of cores. The average performance difference -between CharmPy and Charm++ is 19%. +between Charm4py and Charm++ is 19%. We also ran a different problem size (51 million particles) and configuration to evaluate performance with very high core counts (131k cores on Blue Waters), @@ -38,13 +38,13 @@ obtaining the following results: +---------------+----------------------+ | Version | Time per step (ms) | +===============+======================+ -| CharmPy | 438 | +| charm4py | 438 | +---------------+----------------------+ | Charm++ | 458 | +---------------+----------------------+ -Here we can see that CharmPy performs better than C++. At this core count, parallel -overhead becomes significant and CharmPy benefits from a feature that is not yet implemented +Here we can see that Charm4py performs better than C++. At this core count, parallel +overhead becomes significant and Charm4py benefits from a feature that is not yet implemented in the C++ version of Charm. The feature allows aggregation of receives to local objects in the same *section*, thus reducing overhead. diff --git a/docs/chare-api.rst b/docs/chare-api.rst index e090c294..b74baf46 100644 --- a/docs/chare-api.rst +++ b/docs/chare-api.rst @@ -5,7 +5,7 @@ Chare ----- An application specifies new chare types by defining classes that -inherit from ``charmpy.Chare``. These classes can have custom attributes +inherit from ``charm4py.Chare``. These classes can have custom attributes and methods. In addition, every chare instance has the following properties: Attributes @@ -70,7 +70,7 @@ via a proxy. This allows pausing the execution of the method to wait for certain (see ``wait`` construct above, :ref:`futures-api-label` or ``charm.awaitCreation()``). The decorator is placed before the definition of the method, using the syntax: -``@charmpy.threaded`` +``@charm4py.threaded`` .. note:: While a thread is paused, the runtime continues scheduling other work in the same @@ -86,7 +86,7 @@ The semantics of when a remote method can be invoked *at the receiver* can be controlled using the ``when`` decorator. The decorator is placed before the definition of the method, using the syntax: -``@charmpy.when('condition')`` +``@charm4py.when('condition')`` where ``condition`` is a string containing a standard Python conditional statement. The statement can reference any of the chare's attributes (prefixed by ``self``), as well as any of the diff --git a/docs/charm-api.rst b/docs/charm-api.rst index 799eb3da..dea499b0 100644 --- a/docs/charm-api.rst +++ b/docs/charm-api.rst @@ -4,7 +4,7 @@ charm ----- -* **charm.start(entry, classes=[], modules=[])**: +* **charm.start(entry=None, classes=[], modules=[], interactive=False)**: Start the runtime system. This is required in *all* processes, and registers chare types with the runtime. @@ -17,7 +17,10 @@ charm The entry point function (or chare constructor) must have only one parameter, which is used to receive the application's arguments. - On calling ``charm.start()``, CharmPy automatically registers any chare types that + If ``interactive`` is ``True``, an entry point is not needed and instead Charm4py + will transfer control to a Read-Eval-Print Loop (REPL) loop on PE0. + + On calling ``charm.start()``, Charm4py automatically registers any chare types that are defined in the ``__main__`` module. If desired, a list of chare types can also be passed explictly using the ``classes`` optional parameter. These must be references to the classes that are to be registered, and can reference classes in other modules. @@ -25,7 +28,7 @@ charm in the specified list of modules. These are to be given by their names. .. note:: - If ``charmpy`` is imported and the program exits without calling ``charm.start()``, + If ``charm4py`` is imported and the program exits without calling ``charm.start()``, a warning will be printed. This is to remind users in case they forget to start the runtime (otherwise the program might hang or exit without any output). @@ -36,7 +39,7 @@ charm be received by the OS on exit. .. note:: - Calling Python's ``exit()`` function from a chare has the same effect (CharmPy + Calling Python's ``exit()`` function from a chare has the same effect (Charm4py intercepts the SystemExit exception and calls ``charm.exit()``. * **charm.abort(message)**: @@ -87,4 +90,4 @@ charm * **charm.printStats()**: Print profiling metrics and statistics. - ``charmpy.Options.PROFILING`` must have been set to ``True``. + ``charm4py.Options.PROFILING`` must have been set to ``True``. diff --git a/docs/conf.py b/docs/conf.py index aa81f2c6..6a8c9d21 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- # -# CharmPy documentation build configuration file, created by +# charm4py documentation build configuration file, created by # sphinx-quickstart on Fri Jan 26 11:38:51 2018. # # This file is execfile()d with the current directory set to its @@ -48,7 +48,7 @@ master_doc = 'index' # General information about the project. -project = 'CharmPy' +project = 'charm4py' copyright = '2018, University of Illinois' author = 'Juan Galvez' @@ -57,9 +57,9 @@ # built documents. # # The short X.Y version. -version = '0.10' +version = '0.11' # The full version, including alpha/beta/rc tags. -release = '0.10.1' +release = '0.11.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -202,7 +202,7 @@ #html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'Charmpydoc' +htmlhelp_basename = 'Charm4pydoc' # -- Options for LaTeX output --------------------------------------------- @@ -224,7 +224,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'Charmpy.tex', 'Charmpy Documentation', + (master_doc, 'Charm4py.tex', 'charm4py Documentation', 'Juan Galvez', 'manual'), ] @@ -254,7 +254,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'charmpy', 'Charmpy Documentation', + (master_doc, 'charm4py', 'charm4py Documentation', [author], 1) ] @@ -268,8 +268,8 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'Charmpy', 'Charmpy Documentation', - author, 'Charmpy', 'One line description of project.', + (master_doc, 'Charm4py', 'charm4py Documentation', + author, 'Charm4py', 'One line description of project.', 'Miscellaneous'), ] diff --git a/docs/contact.rst b/docs/contact.rst index 4386f120..60910a3e 100644 --- a/docs/contact.rst +++ b/docs/contact.rst @@ -2,11 +2,9 @@ Contact ======= -You can contact us in the `mailing list`_ for discussion of any topics related to -CharmPy or Charm++. +You can contact us in the `forum`_ for discussion of any topics related to +Charm4py or Charm++. -.. _mailing list: charm@cs.illinois.edu +.. _forum: https://charm.discourse.group -Please use the GitHub page to report and track issues (https://github.com/UIUC-PPL/charmpy) - -Also feel free to contact the main author at jjgalvez@illinois.edu. +Please use the GitHub page to report and track issues (https://github.com/UIUC-PPL/charm4py) diff --git a/docs/features.rst b/docs/features.rst index 523b184b..3ef045f8 100644 --- a/docs/features.rst +++ b/docs/features.rst @@ -5,7 +5,7 @@ Features .. .. contents:: - **Speed**: Runtime overhead is very low, particularly compared to Python - libraries with similar features. CharmPy runs on top of `Charm++`_, a C/C++ + libraries with similar features. Charm4py runs on top of `Charm++`_, a C/C++ runtime system designed to run High-performance computing (HPC) applications and to scale to hundreds of thousands of cores - Simple and powerful API diff --git a/docs/futures-api.rst b/docs/futures-api.rst index 2d129335..b1b380d7 100644 --- a/docs/futures-api.rst +++ b/docs/futures-api.rst @@ -5,7 +5,7 @@ Futures ------- Futures are objects that act as placeholders for values which are unknown at the time -they are created. A future is an instance of ``charmpy.threads.Future``. +they are created. A future is an instance of ``charm4py.threads.Future``. Creation ~~~~~~~~ diff --git a/docs/group-api.rst b/docs/group-api.rst index b3d187ab..e0d5a779 100644 --- a/docs/group-api.rst +++ b/docs/group-api.rst @@ -4,14 +4,14 @@ Group ----- -``charmpy.Group`` is a type of collection where there is one chare per PE. +``charm4py.Group`` is a type of collection where there is one chare per PE. These chares are not migratable and are always bound to the PE where they are created. Elements in groups are indexed by integer ID, which for each element coincides with the PE number where it is located. Groups are created using the following syntax: -``charmpy.Group(chare_type, args=[])`` where ``chare_type`` is the type of chares +``charm4py.Group(chare_type, args=[])`` where ``chare_type`` is the type of chares that will constitute the group. ``args`` is the list of arguments to pass to the constructor of each element. diff --git a/docs/index.rst b/docs/index.rst index a49d66fd..81997879 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,20 +1,20 @@ -======= -CharmPy -======= +======== +charm4py +======== -CharmPy is a high-level parallel and distributed programming framework with a simple +charm4py is a high-level parallel and distributed programming framework with a simple and powerful API, based on migratable Python objects and remote method invocation; built on top of an adaptive C/C++ runtime system providing *speed*, *scalability* and *dynamic load balancing*. -CharmPy allows writing parallel and distributed applications in Python based on +charm4py allows writing parallel and distributed applications in Python based on the `Charm++ programming model`_. Charm++ has seen extensive use in the scientific and high performance computing (HPC) communities across a wide variety of computing disciplines, and has been used to produce several large parallel applications that run on the largest supercomputers, like NAMD_. -With CharmPy, all the application code can be written in Python. The core Charm++ -runtime is implemented in a C/C++ shared library which the ``charmpy`` +With charm4py, all the application code can be written in Python. The core Charm++ +runtime is implemented in a C/C++ shared library which the ``charm4py`` module interfaces with. As with any Python program, there are several methods available to support @@ -24,7 +24,7 @@ instructions using Numba_; or accessing C or Fortran code using f2py_. Another option for increased speed is to run the program using a fast Python implementation (e.g. PyPy_). -We have found that using CharmPy + Numba, it is possible to build parallel applications +We have found that using charm4py + Numba, it is possible to build parallel applications entirely in Python that have the same or similar performance as the equivalent C++ application (whether based on Charm++ or MPI), and that scale to hundreds of thousands of cores. @@ -42,7 +42,7 @@ Example applications are in the ``examples`` subdirectory of the source code rep .. _PyPy: http://pypy.org/ -.. _repository: https://github.com/UIUC-PPL/charmpy +.. _repository: https://github.com/UIUC-PPL/charm4py .. toctree:: :maxdepth: 2 diff --git a/docs/install.rst b/docs/install.rst index d07506e3..3ccaba05 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -4,11 +4,11 @@ Install .. .. contents:: -CharmPy runs on Linux, macOS, Windows, and a wide variety of clusters and +charm4py runs on Linux, macOS, Windows, and a wide variety of clusters and supercomputer environments (including many supercomputers in the TOP500). -CharmPy runs on Python 2.7 and 3.3+. Python 3 is *highly* recommended for best -performance. CharmPy has been tested with the following Python implementations: +charm4py runs on Python 2.7 and 3.3+. Python 3 is *highly* recommended for best +performance. charm4py has been tested with the following Python implementations: CPython (most common implementation) and PyPy_. @@ -20,13 +20,13 @@ pip To install on regular Linux, macOS and Windows machines, do:: - $ pip install charmpy + $ pip install charm4py .. note:: - pip >= 8.0 is recommended to simplify the install and avoid building CharmPy or + 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 charmpy. + Note that a 64-bit version of Python is required to install and run charm4py. Install from Source @@ -41,15 +41,15 @@ Prerequisites: To build the latest *stable* release, do:: - $ pip install charmpy --no-binary charmpy + $ pip install charm4py --no-binary charm4py Or download the source distribution from PyPI, uncompress and run ``python setup.py install``. -To build the latest *development* version, download CharmPy and Charm++ source code +To build the latest *development* version, download Charm4py and Charm++ source code and run setup:: - $ git clone https://github.com/UIUC-PPL/charmpy - $ cd charmpy + $ git clone https://github.com/UIUC-PPL/charm4py + $ cd charm4py $ git clone https://github.com/UIUC-PPL/charm charm_src/charm $ python setup.py install @@ -68,7 +68,7 @@ Before running ``python setup.py`` in the steps above, enter the Charm++ source directory (``charm_src/charm``), and manually build the Charm++ library. The build command syntax is:: - $ ./build charmpy -j --with-production + $ ./build charm4py -j --with-production where ```` varies based on the system and communication layer, and ```` is the number of processes to use for compiling. @@ -76,7 +76,7 @@ For help in choosing the correct ````, please refer to the Charm++ manu and the README in Charm++'s root directory. After the library has been built, continue with ``python setup.py install`` in the -charmpy source root directory. +charm4py source root directory. .. _manual: http://charm.cs.illinois.edu/manuals/html/charm++/A.html diff --git a/docs/make.bat b/docs/make.bat index 2ee3d66f..1fd98605 100755 --- a/docs/make.bat +++ b/docs/make.bat @@ -127,9 +127,9 @@ if "%1" == "qthelp" ( echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\CharmPy.qhcp + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Charm4py.qhcp echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\CharmPy.ghc + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Charm4py.ghc goto end ) diff --git a/docs/options-api.rst b/docs/options-api.rst index 6efefe78..871f5863 100644 --- a/docs/options-api.rst +++ b/docs/options-api.rst @@ -2,13 +2,13 @@ Options ------- -``charmpy.Options`` is a global object with the following attributes: +``charm4py.Options`` is a global object with the following attributes: -* **PROFILING** (default=False): if ``True``, charmpy will profile the program and +* **PROFILING** (default=False): if ``True``, charm4py will profile the program and collect timing and message statistics. To print these, the application must call ``charm.printStats()``. Note that this will affect performance of the application. -* **PICKLE_PROTOCOL** (default=-1): determines the pickle protocol used by CharmPy. +* **PICKLE_PROTOCOL** (default=-1): determines the pickle protocol used by Charm4py. A value of ``-1`` tells ``pickle`` to use the highest protocol number (recommended). Note that not every type of argument sent to a remote method is pickled. diff --git a/docs/overview.rst b/docs/overview.rst index de4cdf20..7681ab88 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -21,7 +21,7 @@ increasing resource utilization and minimizing idle times [#]_. .. [#] We also refer to processors as cores. -.. [#] CharmPy supports reference passing for objects in the same process, +.. [#] Charm4py supports reference passing for objects in the same process, Cross Memory Attach for objects in the same host, RDMA for network communications, collectives optimized for network topology, among other performance features. .. Please refer to section TODO for an explanation of these performance features. diff --git a/docs/performance.rst b/docs/performance.rst index b1016b77..af405db6 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -5,13 +5,13 @@ Performance .. contents:: Python 3 with the Cython interface layer is currently the recommended way to run -CharmPy programs to get the best performance (on CPython). This is the option that +Charm4py programs to get the best performance (on CPython). This is the option that is installed when using pip. Performance analysis -------------------- -Set ``charmpy.Options.PROFILING`` to ``True`` to activate profiling. Do this this +Set ``charm4py.Options.PROFILING`` to ``True`` to activate profiling. Do this this before the program starts. ``charm.printStats()``: prints timing results and message statistics @@ -60,21 +60,21 @@ Timings are shown in four colums: :em: Time in user code (outside of runtime) executing an entry method. :send: Time in proxy and contribute calls (in runtime). -:recv: Time between CharmPy layer receiving a message for delivery and the target +:recv: Time between Charm4py layer receiving a message for delivery and the target entry method being invoked (in runtime). :total: Sum of the previous three columns. The last rows show miscellanous overheads pertaining to reductions and migration. .. note:: - While all of the CharmPy code is instrumented, there are parts of the C/C++ + While all of the Charm4py code is instrumented, there are parts of the C/C++ runtime that are not currently reflected in the above timings. The last part of the output shows message statistics for remote method invocations (number of messages sent and received and their sizes). Charm++ has powerful tracing functionality and a performance analysis and visualization -tool called *Projections*. This functionality has not yet been integrated into CharmPy. +tool called *Projections*. This functionality has not yet been integrated into Charm4py. .. _perf-serialization-label: @@ -84,7 +84,7 @@ Serialization In many cases a remote method invocation results in serialization of the arguments into a message that is sent to a remote process. Serialization is also referred to as *pickling*. Pickling can account for much of -the overhead of the CharmPy runtime. Fastest +the overhead of the Charm4py runtime. Fastest serialization is obtained with the C implementation of the ``pickle`` module (only available in CPython). diff --git a/docs/readonlies-api.rst b/docs/readonlies-api.rst index 1a2bcace..e4a1ff8a 100644 --- a/docs/readonlies-api.rst +++ b/docs/readonlies-api.rst @@ -2,7 +2,7 @@ readonlies ---------- -``charmpy.readonlies`` is an object that serves as a container for data that +``charm4py.readonlies`` is an object that serves as a container for data that the application wants to broadcast to every process after the "entry point" has executed. Attributes added to ``readonlies`` during execution of the entry point will become available in the ``readonlies`` instance of every process. @@ -11,8 +11,8 @@ For example: .. code-block:: python - from charmpy import charm, Chare, Group - from charmpy import readonlies as ro + from charm4py import charm, Chare, Group + from charm4py import readonlies as ro class Test(Chare): def __init__(self): diff --git a/docs/reducer-api.rst b/docs/reducer-api.rst index dc009b9a..558c7f9e 100644 --- a/docs/reducer-api.rst +++ b/docs/reducer-api.rst @@ -4,7 +4,7 @@ Reducer ------- -``charmpy.Reducer`` contains the reducer functions that have been registered with +``charm4py.Reducer`` contains the reducer functions that have been registered with the runtime. Reducer functions are used in Reductions, to aggregate data across the members of a chare collection (see :ref:`chare-api-label`). diff --git a/docs/running.rst b/docs/running.rst index 4a5d9175..c2163bb2 100644 --- a/docs/running.rst +++ b/docs/running.rst @@ -4,30 +4,36 @@ Running .. .. contents:: -CharmPy includes a launcher called ``charmrun`` to run parallel applications on +Charm4py includes a launcher called ``charmrun`` to run parallel applications on desktops and small clusters. Supercomputers and some clusters provide their -own application launchers (these can also be used to launch CharmPy applications). +own application launchers (these can also be used to launch Charm4py applications). charmrun -------- -After installing CharmPy as explained in the previous section, you can launch +After installing Charm4py as explained in the previous section, you can launch applications like this:: $ python -m charmrun.start +p4 myprogram.py The option ``+pN`` specifies how many processes to run the application with. -Alternatively, if ``charmrun`` is in your PATH (this depends on where charmpy was +Alternatively, if ``charmrun`` is in your PATH (this depends on where charm4py was installed and your system configuration):: $ charmrun +p4 myprogram.py -CharmPy programs accept the `same command-line parameters`_ as Charm++. +You can launch an *interactive shell* using the ``++interactive`` option, for +example:: + + $ python -m charmrun.start +p4 ++interactive + +Charm4py programs accept the `same command-line parameters`_ as Charm++. .. _same command-line parameters: http://charm.cs.illinois.edu/manuals/html/charm++/C.html + Running on Multiple Hosts ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -59,7 +65,7 @@ files. Using charmrun from a Python program ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can launch a CharmPy application from inside a Python application, +You can launch a Charm4py application from inside a Python application, and wait for it to complete, in this manner: .. code-block:: python @@ -88,7 +94,7 @@ Solution Using system job launchers -------------------------- -CharmPy applications can also be launched using system job launchers +Charm4py applications can also be launched using system job launchers (e.g. aprun, ibrun, SLURM). The exact details of how to do so depend on the system, and typically Charm++ has to be built with a specialized network layer like MPI, GNI or OFI @@ -110,7 +116,7 @@ for SLURM on a Cray-based system: module load craype-hugepages8M module load python/3.6-anaconda-4.4 - export PYTHONPATH=/path/to/charmpy + export PYTHONPATH=/path/to/charm4py PYTHON_EXEC=`which python3` srun -n 512 -c 1 $PYTHON_EXEC myprogram.py app_param1 app_param2 ... diff --git a/docs/tutorial.rst b/docs/tutorial.rst index b38d0e19..5e0eeab3 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -4,7 +4,17 @@ Tutorial .. contents:: -This tutorial assumes that you have installed CharmPy as described in :doc:`install`. +This tutorial assumes that you have installed Charm4py as described in :doc:`install`. +You can run any of these examples in an interactive Python shell (using multiple processes) +by launching Charm4py in the following manner:: + + $ python3 -m charmrun.start +p4 ++interactive + +and inserting code at the prompt. Note that in interactive mode the runtime is already +started when the interactive shell appears, so ``charm.start()`` does *not* need to be called. +For the examples below, you can directly call the main function or, alternatively, just run the body of the main +function in the top-level shell. + Program start and exit ---------------------- @@ -15,17 +25,17 @@ We will begin with a simple example: .. code-block:: python # start.py - from charmpy import charm + from charm4py import charm def main(args): print("Charm program started on processor", charm.myPe()) print("Running on", charm.numPes(), "processors") exit() - charm.start(main) + charm.start(main) # call main([]) in interactive mode -We need to define an entry point to the CharmPy program, which we refer to as the +We need to define an entry point to the Charm4py program, which we refer to as the Charm *main* function. In our example, it is the function called ``main`` . The main function runs on only one processor, typically processor 0, and is in charge @@ -54,7 +64,7 @@ To define a Chare, simply define a class that is a subclass of ``Chare``. .. code-block:: python - from charmpy import Chare + from charm4py import Chare class MyChare(Chare): @@ -72,7 +82,7 @@ For easy management of distributed objects, you can organize chares into distrib .. code-block:: python # chares.py - from charmpy import charm, Chare, Group, Array + from charm4py import charm, Chare, Group, Array class MyChare(Chare): def __init__(self): @@ -96,7 +106,7 @@ For easy management of distributed objects, you can organize chares into distrib charm.awaitCreation(my_group, my_array, my_2d_array) exit() - charm.start(main) + charm.start(main) # call main([]) in interactive mode The above program will create P + 3 + 2\*2 chares and print a message for each created chare, where P is the number of processors used to launch the program. @@ -185,7 +195,7 @@ The above also applies to Chare Arrays. In the case of N-dimensional array index .. tip:: Proxies can be sent to other chares as arguments of methods. -For performance reasons, method invocation is always *asynchronous* in CharmPy, i.e. methods +For performance reasons, method invocation is always *asynchronous* in Charm4py, i.e. methods return immediately without waiting for the actual method to be invoked on the remote object, and therefore without returning any result. Asynchronous method invocation is desirable because it leads to better overlap of computation and communication, and better @@ -254,7 +264,7 @@ any chare or future of your choice. .. code-block:: python # reduction.py - from charmpy import charm, Chare, Group, Reducer + from charm4py import charm, Chare, Group, Reducer class MyChare(Chare): @@ -269,7 +279,7 @@ any chare or future of your choice. my_group = Group(MyChare) my_group.work(3) - charm.start(main) + charm.start(main) # call main([]) in interactive mode In the above code, every element in the group contributes the data received from @@ -293,13 +303,13 @@ to finish. Reductions are useful when data that is distributed among many objects across the system needs to be aggregated in some way, for example to obtain the maximum value in a distributed data set or to concatenate data in some fashion. The aggregation -operations that are applied to the data are called *reducers*, and CharmPy includes +operations that are applied to the data are called *reducers*, and Charm4py includes several built-in reducers (including ``sum``, ``max``, ``min``, ``product``, ``gather``), as well as allowing users to easily define their own custom reducers for use in reductions. Please refer to the manual for more information. Arrays (array.array_) and `NumPy arrays`_ can be passed as contribution to many of -CharmPy's built-in reducers. The reducer will be applied to elements +Charm4py's built-in reducers. The reducer will be applied to elements having the same index in the array. The size of the result will thus be the same as that of each contribution. @@ -332,7 +342,7 @@ Now we will show a full *Hello World* example, that prints a message from all pr .. code-block:: python # hello_world.py - from charmpy import Chare, Group, charm + from charm4py import Chare, Group, charm class Hello(Chare): @@ -346,7 +356,7 @@ Now we will show a full *Hello World* example, that prints a message from all pr hellos.SayHi(ret=True).get() exit() - charm.start(main) + charm.start(main) # call main([]) in interactive mode @@ -370,7 +380,7 @@ explicitly by the user like this: .. code-block:: python # hello_world2.py - from charmpy import Chare, Group, charm + from charm4py import Chare, Group, charm class Hello(Chare): @@ -387,7 +397,7 @@ explicitly by the user like this: f.get() exit() - charm.start(main) + charm.start(main) # call main([]) in interactive mode As we can see, here the user explicitly creates a future and sends it to the group, who then initiate a reduction using the future as reduction target. diff --git a/examples/hello/array_hello.py b/examples/hello/array_hello.py index 6b591699..85490c70 100644 --- a/examples/hello/array_hello.py +++ b/examples/hello/array_hello.py @@ -1,13 +1,13 @@ -from charmpy import charm, Chare, Array, CkMyPe, CkNumPes -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array +from charm4py import readonlies as ro class Hello(Chare): def __init__(self): - print("Hello " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("Hello " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def SayHi(self, hiNo): - print("Hi[" + str(hiNo) + "] from element " + str(self.thisIndex) + " on PE " + str(CkMyPe())) + print("Hi[" + str(hiNo) + "] from element " + str(self.thisIndex) + " on PE " + str(charm.myPe())) if self.thisIndex == ro.lastIdx: print("All done") exit() @@ -33,7 +33,7 @@ def main(args): nElements = 1 for x in ro.ARRAY_SIZE: nElements *= x - print("Running Hello on " + str(CkNumPes()) + " processors for " + str(nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) + print("Running Hello on " + str(charm.numPes()) + " processors for " + str(nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) arrProxy = Array(Hello, ro.ARRAY_SIZE) arrProxy[ro.firstIdx].SayHi(17) diff --git a/examples/hello/cons_args_hello.py b/examples/hello/cons_args_hello.py index 894e732c..eaebd015 100644 --- a/examples/hello/cons_args_hello.py +++ b/examples/hello/cons_args_hello.py @@ -1,15 +1,15 @@ -from charmpy import charm, Chare, Array, Group, CkMyPe, CkNumPes -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array, Group +from charm4py import readonlies as ro import numpy class Hello(Chare): def __init__(self, arg0, arg1, arg2): assert [arg0, arg1, arg2] == [1, "test", [4.2, -9]], "Construtor args for array failed." - print("Hello " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("Hello " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def SayHi(self, hiNo): - print("Hi[" + str(hiNo) + "] from element " + str(self.thisIndex) + " on PE " + str(CkMyPe())) + print("Hi[" + str(hiNo) + "] from element " + str(self.thisIndex) + " on PE " + str(charm.myPe())) if self.thisIndex == ro.lastIdx: print("Array done") ro.grpProxy[0].SayHi(17) @@ -51,7 +51,7 @@ def main(args): nElements = 1 for x in ro.ARRAY_SIZE: nElements *= x - print("Running Hello on " + str(CkNumPes()) + " processors for " + str(nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) + print("Running Hello on " + str(charm.numPes()) + " processors for " + str(nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) arrProxy = Array(Hello, ro.ARRAY_SIZE, args=[1, "test", [4.2, -9]]) ro.grpProxy = Group(HelloGroup, args=[1, "test", [4.2, -9], numpy.full((3,5), 4.2)]) diff --git a/examples/hello/dynamic_array.py b/examples/hello/dynamic_array.py index 98903869..6df2b348 100644 --- a/examples/hello/dynamic_array.py +++ b/examples/hello/dynamic_array.py @@ -1,5 +1,5 @@ -from charmpy import charm, Chare, Array, CkMyPe, CkNumPes, Reducer -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array, Reducer +from charm4py import readonlies as ro import itertools @@ -18,7 +18,7 @@ def __init__(self, args): self.nElements = 1 for x in ro.ARRAY_SIZE: self.nElements *= x - print("Running Hello on " + str(CkNumPes()) + " processors for " + str(self.nElements) + " elements") + print("Running Hello on " + str(charm.numPes()) + " processors for " + str(self.nElements) + " elements") ro.mainProxy = self.thisProxy self.arrProxy = Array(Hello, ndims=ro.nDims) print("Created array proxy") @@ -42,10 +42,10 @@ def doneReduction(self, result): class Hello(Chare): def __init__(self, arg0, arg1): assert [arg0, arg1] == [42, "testing"], "Constructor args for dynamic array insertion failed." - print("Hello " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("Hello " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def SayHi(self, hiNo): - print("Hi[" + str(hiNo) + "] from element " + str(self.thisIndex) + " on PE " + str(CkMyPe())) + print("Hi[" + str(hiNo) + "] from element " + str(self.thisIndex) + " on PE " + str(charm.myPe())) if self.thisIndex == ro.lastIdx: ro.mainProxy.done() else: diff --git a/examples/hello/group_hello.py b/examples/hello/group_hello.py index 1aa857b4..b234dea9 100644 --- a/examples/hello/group_hello.py +++ b/examples/hello/group_hello.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group +from charm4py import charm, Chare, Group class Hello(Chare): diff --git a/examples/hello/group_hello2.py b/examples/hello/group_hello2.py index ce81a43c..50b51107 100644 --- a/examples/hello/group_hello2.py +++ b/examples/hello/group_hello2.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group +from charm4py import charm, Chare, Group class HelloList: diff --git a/examples/multi-module/goodbye.py b/examples/multi-module/goodbye.py index f554b99a..6f60c33b 100644 --- a/examples/multi-module/goodbye.py +++ b/examples/multi-module/goodbye.py @@ -1,5 +1,5 @@ -from charmpy import charm, Chare -from charmpy import readonlies as ro +from charm4py import charm, Chare +from charm4py import readonlies as ro import time class Goodbye(Chare): diff --git a/examples/multi-module/hello.py b/examples/multi-module/hello.py index 3795993a..b6839c5e 100644 --- a/examples/multi-module/hello.py +++ b/examples/multi-module/hello.py @@ -1,5 +1,5 @@ -from charmpy import charm, Chare -from charmpy import readonlies as ro +from charm4py import charm, Chare +from charm4py import readonlies as ro import time class Hello(Chare): diff --git a/examples/multi-module/main.py b/examples/multi-module/main.py index ce93e782..3c3dda44 100644 --- a/examples/multi-module/main.py +++ b/examples/multi-module/main.py @@ -1,5 +1,5 @@ -from charmpy import charm, Chare, Group -from charmpy import readonlies as ro +from charm4py import charm, Chare, Group +from charm4py import readonlies as ro import hello, goodbye class Main(Chare): diff --git a/examples/parallel-map/parmap.py b/examples/parallel-map/parmap.py index 29ebb6cd..ccd87868 100644 --- a/examples/parallel-map/parmap.py +++ b/examples/parallel-map/parmap.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group +from charm4py import charm, Chare, Group # this class is mainly for bookkeeping to store and manage job state class Job: diff --git a/examples/particle/particle.py b/examples/particle/particle.py index f27ba19f..deb0baa8 100644 --- a/examples/particle/particle.py +++ b/examples/particle/particle.py @@ -1,5 +1,5 @@ -from charmpy import charm, Chare, Array, when, Reducer -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array, when, Reducer +from charm4py import readonlies as ro import time import random import math diff --git a/examples/stencil3d/stencil3d.py b/examples/stencil3d/stencil3d.py index 7e7ade0e..fcc65c56 100644 --- a/examples/stencil3d/stencil3d.py +++ b/examples/stencil3d/stencil3d.py @@ -2,8 +2,8 @@ # This version doesn't use NumPy. It runs fairly well on PyPy, but NumPy+Numba version # (stencil3d_numba.py) performs much better -from charmpy import charm, Chare, Array, when -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array, when +from charm4py import readonlies as ro import time import math diff --git a/examples/stencil3d/stencil3d_numba.py b/examples/stencil3d/stencil3d_numba.py index 2aec979e..2a2a3b54 100644 --- a/examples/stencil3d/stencil3d_numba.py +++ b/examples/stencil3d/stencil3d_numba.py @@ -1,8 +1,8 @@ # Port of examples/charm++/load_balancing/stencil3d from Charm++ codebase # This version uses NumPy and Numba -from charmpy import charm, Chare, Group, Array, when -from charmpy import readonlies as ro +from charm4py import charm, Chare, Group, Array, when +from charm4py import readonlies as ro import time import math import numpy as np @@ -11,7 +11,7 @@ import sys sys.argv += ['+LBPeriod', '0.001', '+LBOff', '+LBCommOff'] -from charmpy import Options +from charm4py import Options Options.PROFILING = False diff --git a/examples/tutorial/chares.py b/examples/tutorial/chares.py index 5cbc5fc2..4013bd55 100644 --- a/examples/tutorial/chares.py +++ b/examples/tutorial/chares.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, Array +from charm4py import charm, Chare, Group, Array class MyChare(Chare): def __init__(self): diff --git a/examples/tutorial/hello_world.py b/examples/tutorial/hello_world.py index 4f6e0b3d..3c098541 100644 --- a/examples/tutorial/hello_world.py +++ b/examples/tutorial/hello_world.py @@ -1,5 +1,5 @@ # examples/tutorial/hello_world.py -from charmpy import Chare, Group, charm +from charm4py import Chare, Group, charm class Hello(Chare): diff --git a/examples/tutorial/hello_world2.py b/examples/tutorial/hello_world2.py index b610800a..36dd1c3e 100644 --- a/examples/tutorial/hello_world2.py +++ b/examples/tutorial/hello_world2.py @@ -1,5 +1,5 @@ # examples/tutorial/hello_world2.py -from charmpy import Chare, Group, charm +from charm4py import Chare, Group, charm class Hello(Chare): diff --git a/examples/tutorial/reduction.py b/examples/tutorial/reduction.py index b456da7d..e2d89d2e 100644 --- a/examples/tutorial/reduction.py +++ b/examples/tutorial/reduction.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, Reducer +from charm4py import charm, Chare, Group, Reducer class MyChare(Chare): diff --git a/examples/tutorial/start.py b/examples/tutorial/start.py index 8481b210..ea46a690 100644 --- a/examples/tutorial/start.py +++ b/examples/tutorial/start.py @@ -1,4 +1,4 @@ -from charmpy import charm +from charm4py import charm def main(args): print("Charm program started on processor", charm.myPe()) diff --git a/examples/wave2d/wave2d.py b/examples/wave2d/wave2d.py index 158051f0..b7d0840d 100644 --- a/examples/wave2d/wave2d.py +++ b/examples/wave2d/wave2d.py @@ -4,8 +4,8 @@ # Original author: Isaac Dooley (2008) # Converted to Python from examples/charm++/wave2d in Charm++ codebase -from charmpy import charm, Chare, Array, CkMyPe, CkNumPes -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array +from charm4py import readonlies as ro import time import math import numpy as np @@ -31,7 +31,7 @@ def __init__(self, args): self.programStartTime = self.periodStartTime = time.time() ro.mainProxy = self.thisProxy # store the main proxy - print("Running wave2d on " + str(CkNumPes()) + " processors") + print("Running wave2d on " + str(charm.numPes()) + " processors") # Create new array of worker chares ro.arrayProxy = Array(Wave, (chareArrayWidth, chareArrayHeight)) @@ -154,7 +154,6 @@ def begin_iteration(self, restart): X,Y = chareArrayWidth, chareArrayHeight i = self.thisIndex - # NOTE: sending the arrays as strings is faster than letting charmpy pickle the numpy arrays self.thisProxy[(i[0]-1)%X, i[1]].recvGhosts(RIGHT, left_edge) # Send my left edge self.thisProxy[(i[0]+1)%X, i[1]].recvGhosts(LEFT, right_edge) # Send my right edge self.thisProxy[i[0], (i[1]-1)%Y].recvGhosts(DOWN, top_edge) # Send my top edge diff --git a/setup.py b/setup.py index 2efc9926..ca7fe3a8 100644 --- a/setup.py +++ b/setup.py @@ -27,18 +27,19 @@ try: - charmpy_version = subprocess.check_output(['git', 'describe']).rstrip().decode().split('-')[0] - if charmpy_version.startswith('v'): - charmpy_version = charmpy_version[1:] - with open(os.path.join('charmpy', '_version.py'), 'w') as f: - f.write("version='" + charmpy_version + "'\n") + charm4py_version = subprocess.check_output(['git', 'describe']).rstrip().decode().split('-')[0] + if charm4py_version.startswith('v'): + charm4py_version = charm4py_version[1:] + with open(os.path.join('charm4py', '_version.py'), 'w') as f: + f.write("version='" + charm4py_version + "'\n") except: try: os.environ['PYTHONPATH'] = os.getcwd() - from charmpy import _version - charmpy_version = _version.version + os.environ['CHARM_NOLOAD'] = '1' + from charm4py import _version + charm4py_version = _version.version except: - raise DistutilsSetupError('Could not determine charmpy version') + raise DistutilsSetupError('Could not determine charm4py version') def charm_built(charm_src_dir): @@ -55,7 +56,7 @@ def check_libcharm_version(charm_src_dir): import ctypes library_path = os.path.join(charm_src_dir, 'charm', 'lib', libcharm_filename) lib = ctypes.CDLL(library_path) - with open(os.path.join(os.getcwd(), 'charmpy', 'libcharm_version'), 'r') as f: + with open(os.path.join(os.getcwd(), 'charm4py', 'libcharm_version'), 'r') as f: req_version = tuple(int(n) for n in f.read().split('.')) commit_id_str = ctypes.c_char_p.in_dll(lib, "CmiCommitID").value.decode() version = [int(n) for n in commit_id_str.split('-')[0][1:].split('.')] @@ -75,7 +76,7 @@ def check_cffi(): import cffi version = tuple(int(v) for v in cffi.__version__.split('.')) if version < (1, 7): - raise DistutilsSetupError('charmpy requires cffi >= 1.7. ' + raise DistutilsSetupError('charm4py requires cffi >= 1.7. ' 'Installed version is ' + cffi.__version__) except ImportError: raise DistutilsSetupError('cffi is not installed') @@ -85,8 +86,8 @@ def build_libcharm(charm_src_dir, build_dir): lib_output_dirs = [] charmrun_output_dirs = [] - lib_output_dirs.append(os.path.join(build_dir, 'charmpy', '.libs')) - lib_output_dirs.append(os.path.join(os.getcwd(), 'charmpy', '.libs')) + lib_output_dirs.append(os.path.join(build_dir, 'charm4py', '.libs')) + lib_output_dirs.append(os.path.join(os.getcwd(), 'charm4py', '.libs')) charmrun_output_dirs.append(os.path.join(build_dir, 'charmrun')) charmrun_output_dirs.append(os.path.join(os.getcwd(), 'charmrun')) for output_dir in (lib_output_dirs + charmrun_output_dirs): @@ -99,7 +100,7 @@ def build_libcharm(charm_src_dir, build_dir): if system == 'Windows' or system.lower().startswith('cygwin'): raise DistutilsSetupError('Building charm++ from setup.py not currently supported on Windows.' - ' Please download a charmpy binary wheel (64-bit Python required)') + ' Please download a charm4py binary wheel (64-bit Python required)') if os.path.exists(os.path.join(charm_src_dir, 'charm.tar.gz')): log.info('Uncompressing charm.tar.gz...') @@ -115,9 +116,9 @@ def build_libcharm(charm_src_dir, build_dir): build_num_cores = int(os.environ.get('CHARM_BUILD_PROCESSES', multiprocessing.cpu_count() // 2)) extra_build_opts = os.environ.get('CHARM_EXTRA_BUILD_OPTS', '') if system == 'Darwin': - cmd = './build charmpy netlrts-darwin-x86_64 tcp -j' + str(build_num_cores) + ' --with-production ' + extra_build_opts + cmd = './build charm4py netlrts-darwin-x86_64 tcp -j' + str(build_num_cores) + ' --with-production ' + extra_build_opts else: - cmd = './build charmpy netlrts-linux-x86_64 tcp -j' + str(build_num_cores) + ' --with-production ' + extra_build_opts + cmd = './build charm4py netlrts-linux-x86_64 tcp -j' + str(build_num_cores) + ' --with-production ' + extra_build_opts p = subprocess.Popen(cmd.rstrip().split(' '), cwd=os.path.join(charm_src_dir, 'charm'), shell=False) @@ -136,7 +137,7 @@ def build_libcharm(charm_src_dir, build_dir): raise DistutilsSetupError('install_name_tool error') # verify that the version of charm++ that was built is same or greater than the - # one required by charmpy + # one required by charm4py check_libcharm_version(charm_src_dir) # ---- copy libcharm ---- @@ -162,7 +163,7 @@ class specialized_build_py(build_py, object): def run(self): if not self.dry_run: build_libcharm(os.path.join(os.getcwd(), 'charm_src'), self.build_lib) - shutil.copy(os.path.join(os.getcwd(), 'LICENSE'), os.path.join(self.build_lib, 'charmpy')) + shutil.copy(os.path.join(os.getcwd(), 'LICENSE'), os.path.join(self.build_lib, 'charm4py')) super(specialized_build_py, self).run() @@ -178,7 +179,7 @@ def run(self): py_impl = platform.python_implementation() if py_impl == 'PyPy': - os.environ['CHARMPY_BUILD_CFFI'] = '1' + os.environ['CHARM4PY_BUILD_CFFI'] = '1' elif 'CPY_WHEEL_BUILD_UNIVERSAL' not in os.environ: if sys.version_info[0] >= 3: # compile C-extension module (from cython) @@ -199,10 +200,10 @@ def run(self): else: extra_link_args=["-Wl,-rpath,$ORIGIN/../.libs"] - extensions.extend(cythonize(setuptools.Extension('charmpy.charmlib.charmlib_cython', - sources=['charmpy/charmlib/charmlib_cython.pyx'], + extensions.extend(cythonize(setuptools.Extension('charm4py.charmlib.charmlib_cython', + sources=['charm4py/charmlib/charmlib_cython.pyx'], include_dirs=['charm_src/charm/include'] + my_include_dirs, - library_dirs=[os.path.join(os.getcwd(), 'charmpy', '.libs')], + library_dirs=[os.path.join(os.getcwd(), 'charm4py', '.libs')], libraries=["charm"], extra_compile_args=['-g0', '-O3'], extra_link_args=extra_link_args, @@ -210,15 +211,15 @@ def run(self): else: try: check_cffi() - os.environ['CHARMPY_BUILD_CFFI'] = '1' + os.environ['CHARM4PY_BUILD_CFFI'] = '1' except: pass additional_setup_keywords = {} -if os.environ.get('CHARMPY_BUILD_CFFI') == '1': +if os.environ.get('CHARM4PY_BUILD_CFFI') == '1': check_cffi() - additional_setup_keywords['cffi_modules'] = 'charmpy/charmlib/charmlib_cffi_build.py:ffibuilder' + additional_setup_keywords['cffi_modules'] = 'charm4py/charmlib/charmlib_cffi_build.py:ffibuilder' with open('README.rst', 'r') as f: @@ -226,17 +227,17 @@ def run(self): setuptools.setup( - name='charmpy', - version=charmpy_version, + name='charm4py', + version=charm4py_version, author='Juan Galvez and individual contributors', author_email='jjgalvez@illinois.edu', - description='CharmPy Parallel Programming Framework', + description='charm4py Parallel Programming Framework', long_description=long_description, - url='https://github.com/UIUC-PPL/charmpy', + url='https://github.com/UIUC-PPL/charm4py', keywords='parallel parallel-programming distributed distributed-computing hpc HPC runtime', packages=setuptools.find_packages(), package_data={ - 'charmpy': ['libcharm_version'], + 'charm4py': ['libcharm_version'], }, entry_points={ 'console_scripts': [ diff --git a/tests/array_maps/test1.py b/tests/array_maps/test1.py index 87b9e16a..bed065db 100644 --- a/tests/array_maps/test1.py +++ b/tests/array_maps/test1.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, Array, ArrayMap +from charm4py import charm, Chare, Group, Array, ArrayMap import itertools diff --git a/tests/charm_remote.py b/tests/charm_remote.py index ea7b1396..02bca1e6 100644 --- a/tests/charm_remote.py +++ b/tests/charm_remote.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, threaded +from charm4py import charm, Chare, Group, threaded import random diff --git a/tests/collections/test.py b/tests/collections/test.py index 75ababbb..db480493 100644 --- a/tests/collections/test.py +++ b/tests/collections/test.py @@ -1,5 +1,4 @@ -from charmpy import charm, Chare, Group, Array, Reducer -import charmpy +from charm4py import charm, Chare, Group, Array, Reducer # Test same Chare class (Test) used in multiple collection types (Group, Array) diff --git a/tests/dcopy/test_dcopy.py b/tests/dcopy/test_dcopy.py index 12279c6c..6ba0607b 100644 --- a/tests/dcopy/test_dcopy.py +++ b/tests/dcopy/test_dcopy.py @@ -1,14 +1,14 @@ -import charmpy -from charmpy import charm, Chare, Array, Reducer -from charmpy import readonlies as ro +import charm4py +from charm4py import charm, Chare, Array, Reducer +from charm4py import readonlies as ro import time import array import numpy from numpy.testing import assert_allclose from collections import defaultdict -charmpy.Options.PROFILING = True -charmpy.Options.LOCAL_MSG_OPTIM = False +charm4py.Options.PROFILING = True +charm4py.Options.LOCAL_MSG_OPTIM = False MAX_ITER = 50 DATA_LEN = 15000 # number of doubles diff --git a/tests/element_proxy/array_element_proxy.py b/tests/element_proxy/array_element_proxy.py index 873162c4..a7bf353d 100644 --- a/tests/element_proxy/array_element_proxy.py +++ b/tests/element_proxy/array_element_proxy.py @@ -2,7 +2,7 @@ Tests the index proxy for a particular array element. """ -from charmpy import charm, Chare, Array +from charm4py import charm, Chare, Array class Test(Chare): diff --git a/tests/element_proxy/group_element_proxy.py b/tests/element_proxy/group_element_proxy.py index 8812e828..d47cce9c 100644 --- a/tests/element_proxy/group_element_proxy.py +++ b/tests/element_proxy/group_element_proxy.py @@ -2,7 +2,7 @@ Tests the index proxy for a particular group element. """ -from charmpy import charm, Chare, Group +from charm4py import charm, Chare, Group class Test(Chare): diff --git a/tests/futures/multi_futures.py b/tests/futures/multi_futures.py index a270c711..2169e82f 100644 --- a/tests/futures/multi_futures.py +++ b/tests/futures/multi_futures.py @@ -1,4 +1,4 @@ -from charmpy import charm, Array, Chare, Reducer +from charm4py import charm, Array, Chare, Reducer CHARES_PER_PE = 4 diff --git a/tests/futures/test_futures.py b/tests/futures/test_futures.py index 1bdb6962..1629ff4a 100644 --- a/tests/futures/test_futures.py +++ b/tests/futures/test_futures.py @@ -1,4 +1,4 @@ -from charmpy import charm, Array, Chare, Reducer +from charm4py import charm, Array, Chare, Reducer CHARES_PER_PE = 4 diff --git a/tests/migration/chare_migration.py b/tests/migration/chare_migration.py index 4306f5f7..9f3016eb 100644 --- a/tests/migration/chare_migration.py +++ b/tests/migration/chare_migration.py @@ -3,7 +3,7 @@ A program to test migration of chares. """ -from charmpy import charm, Chare, Array +from charm4py import charm, Chare, Array CHARES_PER_PE = 1 diff --git a/tests/migration/test_migrate.py b/tests/migration/test_migrate.py index 95497127..108f8ecf 100644 --- a/tests/migration/test_migrate.py +++ b/tests/migration/test_migrate.py @@ -1,5 +1,5 @@ -from charmpy import charm, Chare, Group, Array, Reducer -from charmpy import readonlies as ro +from charm4py import charm, Chare, Group, Array, Reducer +from charm4py import readonlies as ro import numpy import math diff --git a/tests/reductions/array_reduction.py b/tests/reductions/array_reduction.py index cf70cfe6..0bf566d3 100644 --- a/tests/reductions/array_reduction.py +++ b/tests/reductions/array_reduction.py @@ -1,6 +1,5 @@ -from charmpy import charm, Chare, Array, Group, CkMyPe, CkNumPes, CkExit -from charmpy import readonlies as ro -from charmpy import Reducer +from charm4py import charm, Chare, Array, Group, Reducer +from charm4py import readonlies as ro import array import numpy @@ -25,7 +24,7 @@ def __init__(self, args): nElements = 1 for x in ro.ARRAY_SIZE: nElements *= x - print("Running reduction example on " + str(CkNumPes()) + " processors for " + str(nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) + print("Running reduction example on " + str(charm.numPes()) + " processors for " + str(nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) ro.mainProxy = self.thisProxy ro.arrProxy = Array(Test, ro.ARRAY_SIZE) ro.groupProxy = Group(TestGroup) @@ -36,51 +35,51 @@ def done_int(self, reduction_result): print("[Main] All sum_int contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_nop(self): print("[Main] All nop contributions received. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_float(self, reduction_result): assert_allclose(reduction_result, [101.0, 134.0, 45.0], 1e-03) print("[Main] All sum_float contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_array_to_array(self): print("[Main] All array-to-array contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_array_to_array_bcast(self): print("[Main] All array-to-array bcast contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_array_to_group(self): print("[Main] All array-to-group contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_array_to_group_bcast(self): print("[Main] All array-to-group bcast contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() class Test(Chare): def __init__(self): - print("Test " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("Test " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def doReduction(self): - print("Test element " + str(self.thisIndex) + " on PE " + str(CkMyPe()) + " is starting its contributions.") + print("Test element " + str(self.thisIndex) + " on PE " + str(charm.myPe()) + " is starting its contributions.") # test contributing single int back to Main self.contribute(42, Reducer.sum, ro.mainProxy.done_int) # test contributing list of floats back to main @@ -108,7 +107,7 @@ def reductionTargetBcast(self, reduction_result): class TestGroup(Chare): def __init__(self): - print("TestGroup " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("TestGroup " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def reduceFromArray(self, reduction_result): assert self.thisIndex == 0 diff --git a/tests/reductions/bench_reductions.py b/tests/reductions/bench_reductions.py index c29460d8..81366186 100644 --- a/tests/reductions/bench_reductions.py +++ b/tests/reductions/bench_reductions.py @@ -1,10 +1,10 @@ -import charmpy -from charmpy import charm, Chare, Array, CkExit, CkNumPes, Reducer -from charmpy import readonlies as ro +import charm4py +from charm4py import charm, Chare, Array, Reducer +from charm4py import readonlies as ro import time import numpy -charmpy.Options.PROFILING = True +charm4py.Options.PROFILING = True CHARES_PER_PE = 8 NUM_ITER = 5000 @@ -18,7 +18,7 @@ class Main(Chare): def __init__(self, args): ro.mainProxy = self.thisProxy - ro.NUM_CHARES = CkNumPes() * CHARES_PER_PE + ro.NUM_CHARES = charm.numPes() * CHARES_PER_PE ro.arrayProxy = Array(Test, ro.NUM_CHARES) ro.arrayProxy.run() self.startTime = time.time() @@ -30,7 +30,7 @@ def collectSum(self, result): def done(self): print("Program done in", time.time() - self.startTime) charm.printStats() - CkExit() + exit() class Test(Chare): def __init__(self): diff --git a/tests/reductions/custom_reduction.py b/tests/reductions/custom_reduction.py index 9a129f41..f18ddd39 100644 --- a/tests/reductions/custom_reduction.py +++ b/tests/reductions/custom_reduction.py @@ -1,6 +1,5 @@ -from charmpy import charm, Chare, Array, Group, CkMyPe, CkNumPes, CkExit, CkAbort -from charmpy import readonlies as ro -from charmpy import Reducer +from charm4py import charm, Chare, Array, Group, Reducer +from charm4py import readonlies as ro def myReducer(contribs): result = [] @@ -23,7 +22,7 @@ def __init__(self, args): self.nElements = 1 for x in ro.ARRAY_SIZE: self.nElements *= x - print("Running reduction example on " + str(CkNumPes()) + " processors for " + str(self.nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) + print("Running reduction example on " + str(charm.numPes()) + " processors for " + str(self.nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) ro.mainProxy = self.thisProxy ro.arrProxy = Array(Test, ro.ARRAY_SIZE) ro.arrProxy.doReduction() @@ -34,7 +33,7 @@ def done_charm_builtin(self, result): print("[Main] All Charm builtin reductions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_python_builtin(self, result): sum_indices = (self.nElements*(self.nElements-1))/2 @@ -43,14 +42,14 @@ def done_python_builtin(self, result): print("[Main] All Python builtin reductions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_python_custom(self, result): assert result == [10, ro.lastIdx[0], 0], "Custom Python myReduce failed" print("[Main] All Python custom reductions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() class MyObject(object): def __init__(self, n): @@ -70,7 +69,7 @@ def __radd__(self, other): class Test(Chare): def __init__(self): - print("Test " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("Test " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def doReduction(self): # test contributing using built-in Charm reducer diff --git a/tests/reductions/future_reduction.py b/tests/reductions/future_reduction.py index 02b90b64..93456788 100644 --- a/tests/reductions/future_reduction.py +++ b/tests/reductions/future_reduction.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, Array, Reducer +from charm4py import charm, Chare, Group, Array, Reducer import numpy as np diff --git a/tests/reductions/group_reduction.py b/tests/reductions/group_reduction.py index 5f0e5d3a..8b5aac02 100644 --- a/tests/reductions/group_reduction.py +++ b/tests/reductions/group_reduction.py @@ -1,6 +1,5 @@ -from charmpy import charm, Chare, Array, Group, CkMyPe, CkNumPes, CkExit, CkAbort -from charmpy import readonlies as ro -from charmpy import Reducer +from charm4py import charm, Chare, Array, Group, Reducer +from charm4py import readonlies as ro # utility methods for assertions def assert_allclose(actual, desired, tol): @@ -23,7 +22,7 @@ def __init__(self, args): nElements = 1 for x in ro.ARRAY_SIZE: nElements *= x - print("Running reduction example on " + str(CkNumPes()) + " processors") + print("Running reduction example on " + str(charm.numPes()) + " processors") ro.mainProxy = self.thisProxy ro.groupProxy = Group(TestGroup) # create an array to test group-to-array reductions @@ -31,58 +30,58 @@ def __init__(self, args): ro.groupProxy.doReduction() def done_int(self, reduction_result): - assert reduction_result == 42*CkNumPes(), "Group-to-singleton sum_int reduction failed" + assert reduction_result == 42*charm.numPes(), "Group-to-singleton sum_int reduction failed" print("[Main] All sum_int contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_nop(self): print("[Main] All nop contributions received. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_float(self, reduction_result): - expected_result = [x*CkNumPes() for x in [10.1, 13.4]] - indices_sum = (CkNumPes() * (CkNumPes() - 1))/2 + expected_result = [x*charm.numPes() for x in [10.1, 13.4]] + indices_sum = (charm.numPes() * (charm.numPes() - 1))/2 expected_result += [float(indices_sum)] assert_allclose(reduction_result, expected_result, 1e-03) print("[Main] All sum_float contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_group_to_array(self): print("[Main] All group-to-array contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_group_to_array_bcast(self): print("[Main] All group-to-array bcast contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_group_to_group(self): print("[Main] All group-to-group contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_group_to_group_bcast(self): print("[Main] All group-to-group bcast contributions done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() class TestGroup(Chare): def __init__(self): - print("TestGroup " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("TestGroup " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def doReduction(self): - print("TestGroup element on PE " + str(CkMyPe()) + " is starting its contributions.") + print("TestGroup element on PE " + str(charm.myPe()) + " is starting its contributions.") # test contributing single int back to Main self.contribute(42, Reducer.sum, ro.mainProxy.done_int) # test contributing list of floats back to Main @@ -101,25 +100,25 @@ def doReduction(self): def reduceGroupToGroup(self, reduction_result): assert self.thisIndex == 0 - assert list(reduction_result) == [CkNumPes()*x for x in [5, 7, -3, 0]], "Group-to-group reduction failed." + assert list(reduction_result) == [charm.numPes()*x for x in [5, 7, -3, 0]], "Group-to-group reduction failed." ro.mainProxy.done_group_to_group() def reduceGroupToGroupBcast(self, reduction_result): - assert_almost_equal(reduction_result, -4.2*CkNumPes(), 1e-03) + assert_almost_equal(reduction_result, -4.2*charm.numPes(), 1e-03) self.contribute(None, None, ro.mainProxy.done_group_to_group_bcast) class TestArray(Chare): def __init__(self): - print("TestArray " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("TestArray " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def reduceGroupToArray(self, reduction_result): assert self.thisIndex[0] == 0 - assert_allclose(reduction_result, [CkNumPes()*x for x in [4.2, 13.1]], 1e-03) + assert_allclose(reduction_result, [charm.numPes()*x for x in [4.2, 13.1]], 1e-03) ro.mainProxy.done_group_to_array() def reduceGroupToArrayBcast(self, reduction_result): - assert reduction_result == -4*CkNumPes(), "Group-to-array bcast reduction failed." + assert reduction_result == -4*charm.numPes(), "Group-to-array bcast reduction failed." self.contribute(None, None, ro.mainProxy.done_group_to_array_bcast) diff --git a/tests/reductions/test_gather.py b/tests/reductions/test_gather.py index 8b0ae91d..d606890a 100644 --- a/tests/reductions/test_gather.py +++ b/tests/reductions/test_gather.py @@ -1,6 +1,6 @@ -from charmpy import charm, Chare, Array, Group, CkMyPe, CkNumPes, CkExit, CkAbort -from charmpy import readonlies as ro -from charmpy import Reducer +from charm4py import charm, Chare, Array, Group, Reducer +from charm4py import readonlies as ro + class Main(Chare): def __init__(self, args): @@ -15,7 +15,7 @@ def __init__(self, args): self.nElements = 1 for x in ro.ARRAY_SIZE: self.nElements *= x - print("Running gather example on " + str(CkNumPes()) + " processors for " + str(self.nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) + print("Running gather example on " + str(charm.numPes()) + " processors for " + str(self.nElements) + " elements, array dims=" + str(ro.ARRAY_SIZE)) ro.mainProxy = self.thisProxy ro.arrProxy = Array(Test, ro.ARRAY_SIZE) ro.grpProxy = Group(TestGroup) @@ -27,25 +27,25 @@ def __init__(self, args): def done_gather_single(self, result): gather_arr_indices = list(range(self.nElements)) - gather_grp_indices = list(range(CkNumPes())) + gather_grp_indices = list(range(charm.numPes())) assert result == gather_arr_indices or result == gather_grp_indices, "Gather single elements failed." print("[Main] Gather collective for single elements done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() def done_gather_array(self, result): gather_arr_indices = [tuple([i]) for i in range(self.nElements)] - gather_grp_indices = [[i, 42] for i in range(CkNumPes())] + gather_grp_indices = [[i, 42] for i in range(charm.numPes())] assert result == gather_arr_indices or result == gather_grp_indices, "Gather arrays failed." print("[Main] Gather collective for arrays done. Test passed") self.recvdReductions += 1 if (self.recvdReductions >= self.expectedReductions): - CkExit() + exit() class Test(Chare): def __init__(self): - print("Test " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("Test " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def doGather(self, red_future=None): if red_future is None: @@ -58,7 +58,7 @@ def doGather(self, red_future=None): class TestGroup(Chare): def __init__(self): - print("TestGroup " + str(self.thisIndex) + " created on PE " + str(CkMyPe())) + print("TestGroup " + str(self.thisIndex) + " created on PE " + str(charm.myPe())) def doGather(self): # gather single elements diff --git a/tests/thread_entry_methods/future_bcast.py b/tests/thread_entry_methods/future_bcast.py index bcd4c3d3..05d673f7 100644 --- a/tests/thread_entry_methods/future_bcast.py +++ b/tests/thread_entry_methods/future_bcast.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, Array +from charm4py import charm, Chare, Group, Array import random import time diff --git a/tests/thread_entry_methods/future_reduction.py b/tests/thread_entry_methods/future_reduction.py index 29b8d21a..601f377a 100644 --- a/tests/thread_entry_methods/future_reduction.py +++ b/tests/thread_entry_methods/future_reduction.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, Reducer +from charm4py import charm, Chare, Group, Reducer def my_sum(contribs): diff --git a/tests/thread_entry_methods/test1.py b/tests/thread_entry_methods/test1.py index 2b1f1f06..61428d56 100644 --- a/tests/thread_entry_methods/test1.py +++ b/tests/thread_entry_methods/test1.py @@ -1,8 +1,8 @@ -from charmpy import charm, Chare, Array, Group, threaded, Reducer -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array, Group, threaded, Reducer +from charm4py import readonlies as ro import time -from charmpy import Options +from charm4py import Options Options.PROFILING = True ITERATIONS = 30 diff --git a/tests/thread_entry_methods/test1_when.py b/tests/thread_entry_methods/test1_when.py index f1a592a4..8c2a389d 100644 --- a/tests/thread_entry_methods/test1_when.py +++ b/tests/thread_entry_methods/test1_when.py @@ -1,8 +1,8 @@ -from charmpy import charm, Chare, Array, Group, threaded, when, Reducer -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array, Group, threaded, when, Reducer +from charm4py import readonlies as ro import time -from charmpy import Options +from charm4py import Options Options.PROFILING = True ITERATIONS = 30 diff --git a/tests/thread_entry_methods/test_main.py b/tests/thread_entry_methods/test_main.py index ce9a2dd2..0e569442 100644 --- a/tests/thread_entry_methods/test_main.py +++ b/tests/thread_entry_methods/test_main.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group +from charm4py import charm, Chare, Group class Test(Chare): diff --git a/tests/thread_entry_methods/test_wait.py b/tests/thread_entry_methods/test_wait.py index 4653d107..8adfb8f8 100644 --- a/tests/thread_entry_methods/test_wait.py +++ b/tests/thread_entry_methods/test_wait.py @@ -1,7 +1,7 @@ -from charmpy import charm, Chare, Array -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array +from charm4py import readonlies as ro -from charmpy import Options +from charm4py import Options Options.PROFILING = True NUM_ITER = 1000 diff --git a/tests/trees/topo_treeAPI.py b/tests/trees/topo_treeAPI.py index 4fd905ef..32a8b5c5 100644 --- a/tests/trees/topo_treeAPI.py +++ b/tests/trees/topo_treeAPI.py @@ -1,4 +1,4 @@ -from charmpy import charm +from charm4py import charm allPes_check = [] evenPes_check = [] diff --git a/tests/when/perf_test.py b/tests/when/perf_test.py index 4394463c..b5b8aa33 100644 --- a/tests/when/perf_test.py +++ b/tests/when/perf_test.py @@ -1,4 +1,4 @@ -from charmpy import charm, Chare, Group, when +from charm4py import charm, Chare, Group, when import random import time diff --git a/tests/when/test_when_syntax.py b/tests/when/test_when_syntax.py index 195be72f..09f53964 100644 --- a/tests/when/test_when_syntax.py +++ b/tests/when/test_when_syntax.py @@ -1,5 +1,5 @@ -from charmpy import charm -from charmpy import wait +from charm4py import charm +from charm4py import wait import re diff --git a/tests/when/when_test.py b/tests/when/when_test.py index eab1d81c..b73a02ff 100644 --- a/tests/when/when_test.py +++ b/tests/when/when_test.py @@ -1,5 +1,5 @@ -from charmpy import charm, Chare, Group, when -from charmpy import readonlies as ro +from charm4py import charm, Chare, Group, when +from charm4py import readonlies as ro GRP_TO_SEND = 20 diff --git a/tests/when/when_test2.py b/tests/when/when_test2.py index 2ecbb30f..065ccaad 100644 --- a/tests/when/when_test2.py +++ b/tests/when/when_test2.py @@ -1,9 +1,9 @@ -from charmpy import charm, Chare, Array, when -from charmpy import readonlies as ro +from charm4py import charm, Chare, Array, when +from charm4py import readonlies as ro import random import time -from charmpy import Options +from charm4py import Options Options.PROFILING = True X, Y, Z = 3, 7, 11