Git Product home page Git Product logo

charm4py's People

Contributors

adityapb avatar juanjgalvez avatar karthiksenthil avatar matthiasdiener avatar mayantaylor avatar nchristensen avatar rbuch avatar smkuls avatar zwfink avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

charm4py's Issues

Charmrun.start can only run Python programs

When invoking charmrun.start on the command line in the following manner:
python3 -m charmrun.start +p2 ./hello.py
it will work as expected, but if one wishes to execute a different program such as perf it will not work:

python3 -m charmrun.start +p2 `which perf` stat `which python3` examples/hello/array_hello.py 
Charmrun> scalable start enabled. 
  File "/usr/bin/perf", line 7
    case "$version" in
         ^
SyntaxError: invalid syntax

It appears that charmrun.start attempts to run the provided executable as a Python script. Running the above command using charmrun directly results in the correct behavior.

Local message optimization breaks correctness

The local message optimization stores a reference to entry method arguments in the destination chare's local msg buffer if the source and destination chares lie on the same PE to avoid copying and serialization. This is an issue because if the sender chare then modifies the data being sent, the receiving chare will now be holding a reference to the modified data.

from time import time
import numpy as np
mainProxy = None

class TestCopy(Chare):
    def __init__(self):
        x = np.array([0, 0])
        mainProxy.send(x)
        x[1] = 10

class Main(Chare):
    def __init__(self, args):
        charm.thisProxy.updateGlobals({'mainProxy': self.thisProxy},
                                      '__main__', awaitable=True).get()
        Chare(TestCopy)

    def send(self, x):
        print(x)
        charm.exit()

charm.start(Main)

For example, the above code prints out [0, 10]

Local Message Optimization Should be Supported

Currently, the local message optimization (#218) has been turned off because it breaks correctness. We should support in the runtime a way for the user to take advantage of this optimization if they promise to use it in a way that does not break correctness (more details to follow)

Implement threaded entry methods using converse user-level threads

  1. Explore if CharmPy threaded entry methods can be implemented using converse user-level threads. Note that this would imply having multiple python stacks in memory and switching between them (without Python interpreter knowing anything about it?)
  2. If feasible, implement

Currently, CharmPy threaded entry methods are implemented using Python threads, which are implemented on top of OS threads in all major Python implementations. User-level threads are preferable because they are more lightweight.

Allow charmrun to be used from an interactive session

Something like this should work:

from charmrun import start
start.start(['+p4', 'hello_world.py'])

Doing so would launch the application using the specified number of processes, and return control to the interactive session once the application exits.

Passing futures to Arrays on different PE's doesn't work

I'm facing an issue with passing future objects to Arrays.
Let's consider the following example. Two USB cameras, one Stream wrapper, one data processor

  from charm4py import charm, Chare, Array, Reducer, Future, coro
  
  # Camera Class
  class Camera(Chare):
      def read(self, f):
          data = "image"
          self.reduce(f, data, Reducer.gather)
  
  
  # Wrapper for multiple cameras
  class Stream(Chare):
      def __init__(self):
          self.worker = Array(Camera, 2)
  
      @coro
      def get_images(self, f):
          self.worker.read(f)
  
  
  # Do some processing on images
  class Processor(Chare):
      @coro
      def process(self, future):
          images = future.get()
          result = "processing_result"
          return result
  
  
  def main(args):
      stream = Chare(Stream, onPE=-1)
      processor = Chare(Processor, onPE=-1)
  
      while True:
          f1 = Future()
          stream.get_images(f1)
          result = processor.process(f1, awaitable=True).get()
  
  
  charm.start(main)

If stream and processor get initialized as straight Chare's, everything run's fine
But if one of them get's initialized as an Array, like so: processor = Array(Processor, 1, args=[stream])
it stops working. I get following error message:

------------- Processor 0 Exiting: Called CmiAbort ------------ Reason: AttributeError: 'Future' object has no attribute 'gotvalues'

Is this behavior normal/expected?
And for some reason, this code is utilizing all 8 cores at 100%... Am I doing something wrong?

Ubuntu 16.04 Virtual Machine
Python: 3.6.12
Charm4Py: 1.0

printStats does not reflect all timings (mostly timings inside charm++ library)

2018-12-12 8 01 19

I used the charms.printStat() , and this is the provided info. However, I also did a timing, which is right in front the creation of any chares object and right after I get all the results from the future. Nothing is in between Timing result obtained this way shows an extra ten second. doess printStat() hide any part of calculation? Thanks

Blocking barrier and allreduce from threaded entry methods

When inside the context of a threaded entry method, it would be good to support collectives with blocking semantics, for example:

result = charm.allReduce(data, reducer, self)
charm.barrier(self)

There is currently a functioning prototype.

Verify compatibility with python accelerator projects

Various things like PyCUDA and PyOpenCL should work, if they don't we will need to make appropriate adjustments. Need to test these and add examples to illustrate how easy it can be to use many nodes worth of accelerators. Ideally these should do the offload in coro so result can be accessed in a future in a way similar to HAPI. Probably no need to directly support HAPI if the python components are working according to best practices.

Running endless loops in parallel

Hi,
I would like to run two classes with endlessly running loops in parallel.
But only one endless loop is starting....
Am I missing something? I am seeing only the output of one method in the console...

import time
from charm4py import Chare, charm, coro
starttime = time.time()

class Ax(Chare):
    @coro
    def run(self):
        while True:
            print("ox")
            time.sleep(1)

class Ox(Chare):
    @coro
    def run(self):
        while True:
            print("ax")
            time.sleep(1)

def main(args):
    ax_proxy = Chare(Ax)
    ox_proxy = Chare(Ox)
    combined_proxies = charm.combine(ax_proxy, ox_proxy)
    combined_proxies.run()

charm.start(main)

Charm4py and MPI interop

Charm++ can interoperate with MPI applications and libraries, but this is not supported yet with charmpy.

Crash with co-routine suspension within charm.iwait

Currently, charm.iwait assumes that the body of code that executes for each iteratively-received object does not suspend. If suspension does happen and the next object is received while the code executing within the body of the loop is suspended, the program will crash. This is illustrated in the following block of code:

from charm4py import Chare, Channel, charm, Future, Group, coro

class A(Chare):
    def __init__(self):
        self.partnerProxy = self.thisProxy[not self.thisIndex]
        self.channels = [Channel(self, self.partnerProxy),
                         Channel(self, self.partnerProxy)]

    @coro
    def run(self):
        if self.thisIndex == 0:
            my_ch = self.channels[0]
            self.partner_fut = my_ch.recv()
            my_ch.send(4)
            self.channels[1].send(4)
            self.partner_fut(4)
        else:
            my_fut = Future()
            partner_ch = self.channels[0]
            partner_ch.send(my_fut)
            for ch in charm.iwait(self.channels):
                recvd = ch.recv()

                # this greenlet pauses here and resumes here when
                # the second partner channel is ready to receive
                result = my_fut.get()
                print(recvd, result)

def main(args):
    assert charm.numPes() == 2
    chares = Group(A)
    chares.run()

charm.start(main)

This code will crash with the following (truncated) error message:

    result = my_fut.get()
  File "/home/zane/charm4py/charm4py/threads.py", line 51, in get
    return self.values[0]
  Fatal error on PE 1> TypeError: '_Channel' object is not subscriptable

This error happens because the greenlet that suspends when my_fut.get() is called is awakened when the next channel in self.channels is ready to receive and is yielded by charm.iwait.

Allow optional per-message compression

In general, message compression is not desirable, since it adds extra latency due to compression/decompression.

It may be desirable, however, in some specific circumstances, depending on message size, network, etc. Per-message compression would allow using it for specific messages.

Note that per-msg compression would probably require passing a bool in message header so that receiver knows that it has to decompress.

An optional keyword parameter could be used in proxy entry method calls. Proxy could then retrieve it like this: kwargs.get('compress', 0)

Charm.pool.map() and tqdm: obtain a progressbar ?

Hi,

I did not manage to obtain a progressbar with tqdm on charm.pool.map().

Is there a way this could work ? I even tried instanciating a bunch of charm.pool.Task, and .get() them one by one in a loop, but it did not work.

I run on a cluster, the code takes days and I'd love to be able to see the progress in real time. Did I miss an option somewhere ?

If there is not, maybe you could give me an overview / an idea on how hard it would be to add this possiblity to the current implementation of charm.pool.map, and if I feel like I can, I'll do.

Edit: Cross-posted of stackoverflow there : https://stackoverflow.com/questions/63671000/charm-pool-map-tqdm-obtain-a-progressbar

Support Jupyter notebook

The work on interactive mode (see #28) is a step in the right direction, but Jupyter support will probably also require a custom jupyter kernel or extension of IPython kernel.

Help with an error message when processing huge VTU file

Hi,
I have a program written in Python which post-processes an output VTU file from a fluid dynamics framework. The program is massively parallel in the sense that it repeats the exact same calculations at different locations in space, distributed on a grid. I have used Charm4Py to parallelise the workload on a large, university-like cluster, especially the pool functionality as it seemed to be the most appropriate to me. Everything is working properly on "regular" VTU files, and I am obtaining results which compare really well to multiprocessing on a single node and Ray on a multi-node environment. However, I am encountering an issue when I provide a "huge" VTU. What I mean by huge is 3 GB, whereas other files are on the order of a few 100 MB. I am pasting below the output generated by Charm4Py and the traceback for the first PE; the computer I have run this on has 64 GB of RAM. I would be really grateful if anyone could help me with this error and explain to me what it means so that I can attempt to fix it. I am more than happy to provide additional information about the program in itself.

Thank you for any help.

Charmrun> scalable start enabled. 
Charmrun> started all node programs in 1.311 seconds.
Charm++> Running in non-SMP mode: 17 processes (PEs)
Converse/Charm++ Commit ID: v6.10.0-beta1-17-ga5b6b3259
Warning> Randomization of virtual memory (ASLR) is turned on in the kernel, thread migration may not work! Run 'echo 0 > /proc/sys/kernel/randomize_va_space' as root to disable it, or try running with '+isomalloc_sync'.
Charm++> scheduler running in netpoll mode.
CharmLB> Load balancer assumes all CPUs are same.
Charm4py> Running Charm4py version 1.0 on Python 3.8.0 (CPython). Using 'cython' interface to access Charm++
Charm++> Running on 1 hosts (1 sockets x 10 cores x 2 PUs = 20-way SMP)
Charm++> cpu topology info is gathered in 0.001 seconds.
Initializing charm.pool with 16 worker PEs. Warning: charm.pool is experimental (API and performance is subject to change)
----------------- Python Stack Traceback PE 2 -----------------
  File "charm4py/charmlib/charmlib_cython.pyx", line 863, in charm4py.charmlib.charmlib_cython.recvGroupMsg
  File "/home/thomas/.local/lib/python3.8/site-packages/charm4py/charm.py", line 253, in recvGroupMsg
    header, args = self.unpackMsg(msg, dcopy_start, obj)
  File "charm4py/charmlib/charmlib_cython.pyx", line 739, in charm4py.charmlib.charmlib_cython.CharmLib.unpackMsg
------------- Processor 2 Exiting: Called CmiAbort ------------
Reason: UnpicklingError: pickle data was truncated
[2] Stack Traceback:
  [2:0] _Z14CmiAbortHelperPKcS0_S0_ii+0x60  [0x7f78509ea920]
  [2:1] +0x260a51  [0x7f78509eaa51]
  [2:2] +0x18e0e  [0x7f7850d0ae0e]
  [2:3] _PyObject_MakeTpCall+0x28f  [0x5fff6f]
  [2:4]   [0x4ffbbf]
  [2:5] _PyEval_EvalFrameDefault+0x53f0  [0x57dbb0]
  [2:6] _PyFunction_Vectorcall+0x19c  [0x602b2c]
  [2:7] _PyEval_EvalFrameDefault+0x88d  [0x57904d]
  [2:8] +0x11cd0  [0x7f7850d03cd0]
  [2:9] +0x13474  [0x7f7850d05474]
  [2:10] +0x16857  [0x7f7850d08857]
  [2:11] +0x40601  [0x7f7850d32601]
  [2:12] _ZN8GroupExt13__entryMethodEPvS0_+0xb5  [0x7f7850895445]
  [2:13] CkDeliverMessageFree+0x21  [0x7f7850898761]
  [2:14] _Z15_processHandlerPvP11CkCoreState+0x88a  [0x7f78508a18ea]
  [2:15] CsdScheduleForever+0x77  [0x7f78509aa717]
  [2:16] CsdScheduler+0x2d  [0x7f78509aa97d]
  [2:17] ConverseInit+0x64a  [0x7f78509f046a]
  [2:18] StartCharmExt+0x255  [0x7f785089edd5]
  [2:19] +0x3d7be  [0x7f7850d2f7be]
  [2:20] _PyObject_MakeTpCall+0x28f  [0x5fff6f]
  [2:21]   [0x4ffbbf]
  [2:22] _PyEval_EvalFrameDefault+0x53f0  [0x57dbb0]
  [2:23] _PyEval_EvalCodeWithName+0x25c  [0x5765ec]
  [2:24] _PyFunction_Vectorcall+0x442  [0x602dd2]
  [2:25] _PyEval_EvalFrameDefault+0x88d  [0x57904d]
  [2:26] _PyEval_EvalCodeWithName+0x25c  [0x5765ec]
  [2:27]   [0x662c2e]
  [2:28] PyRun_FileExFlags+0x97  [0x662d07]
  [2:29] PyRun_SimpleFileExFlags+0x17f  [0x663a1f]
  [2:30] Py_RunMain+0x20e  [0x687dbe]
  [2:31] Py_BytesMain+0x29  [0x688149]
  [2:32] __libc_start_main+0xe7  [0x7f78efe25bf7]
  [2:33] _start+0x2a  [0x607daa]

Support Charm++ tracing and Projections

Projections is the performance visualization tool used by Charm++, when tracing functionality is enabled. Charm4py applications should also support this functionality.

questions readonlies

is this the same as passing the variable into the constructor manually of the performance cost is smaller? I have a class which contains some method and list, and all of the method are only reading
the data in the class. Those instances are very big. And I distributed them over 6 processors through 6 chares object. I tried readonlies but the performance does not have any improvement.Thanks

Failure to install on macOS Catalina

I am encountering an installation failure on macOS Catalina. I have the most recent version of Apple’s compiler suite, as well as OpenMPI 4.1.1_2 (installed through Homebrew). I have Python 3.9.8 (also installed through Homebrew). I did the pip installation in a newly-created virtual environment, into which I had already install numpy (1.21.4), cython (0.29.24), greenlet (1.1.2) and wheel (0.37.0).

The complaint at the end of the installation (full log is appended to this submission) says “Cannot link C++ programs with mlicxx”. I have verified that mpicxx can, in fact, compile and link a simple MPI program.
charm4py-install.log

Several package dependences are not documented for the build from source path

Can't compile from source without cython.

No charm4py code will run without the greenlet distribution, so we should add that to the install notes. Also, most interesting examples require numba and numpy. So something like:

pip3 install cython greenlet numba numpy

Should be noted as recommended for first time installation from source.

Windows Setup Failure, including wheels

Hello,

I am terribly sorry but I am really struggling to fix the following issue

I have tried installing: MPI and MPI4py, as well as all the

When trying to run the following via pip:

This is the response:

C:\>pip install charm4py
Collecting charm4py
  Using cached charm4py-1.0.tar.gz (3.4 MB)
Requirement already satisfied: numpy>=1.10.0 in c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages (from charm4py) (1.18.5)
Requirement already satisfied: greenlet in c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages (from charm4py) (0.4.16)
Building wheels for collected packages: charm4py
  Building wheel for charm4py (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: 'c:\users\dylan\appdata\local\programs\python\python37-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Dylan\\AppData\\Local\\Temp\\pip-install-vrwss169\\charm4py\\setup.py'"'"'; __file__='"'"'C:\\Users\\Dylan\\AppData\\Local\\Temp\\pip-install-vrwss169\\charm4py\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\Dylan\AppData\Local\Temp\pip-wheel-5sx356ud'
       cwd: C:\Users\Dylan\AppData\Local\Temp\pip-install-vrwss169\charm4py\
  Complete output (10 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib.win32-3.7
  creating build\lib.win32-3.7\charm4py
  creating build\lib.win32-3.7\charm4py\.libs
  creating C:\Users\Dylan\AppData\Local\Temp\pip-install-vrwss169\charm4py\charm4py\.libs
  creating build\lib.win32-3.7\charmrun
  error: Building charm++ from setup.py not currently supported on Windows. Please download a Charm4py binary wheel (64-bit Python required)**
  ----------------------------------------
  ERROR: Failed building wheel for charm4py
  Running setup.py clean for charm4py
Failed to build charm4py
DEPRECATION: Could not build wheels for charm4py which do not use PEP 517. pip will fall back to legacy 'setup.py install' for these. pip 21.0 will remove support for this functionality. A possible replacement is to fix the wheel build issue reported above. You can find discussion regarding this at https://github.com/pypa/pip/issues/8368.
Installing collected packages: charm4py
    Running setup.py install for charm4py ... error
    ERROR: Command errored out with exit status 1:
     command: 'c:\users\dylan\appdata\local\programs\python\python37-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Dylan\\AppData\\Local\\Temp\\pip-install-vrwss169\\charm4py\\setup.py'"'"'; __file__='"'"'C:\\Users\\Dylan\\AppData\\Local\\Temp\\pip-install-vrwss169\\charm4py\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\Dylan\AppData\Local\Temp\pip-record-ild1vqpv\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\dylan\appdata\local\programs\python\python37-32\Include\charm4py'
         cwd: C:\Users\Dylan\AppData\Local\Temp\pip-install-vrwss169\charm4py\
    Complete output (9 lines):
    running install
    running build
    running build_py
    creating build
    creating build\lib.win32-3.7
    creating build\lib.win32-3.7\charm4py
    creating build\lib.win32-3.7\charm4py\.libs
    creating build\lib.win32-3.7\charmrun
    error: Building charm++ from setup.py not currently supported on Windows. Please download a Charm4py binary wheel (64-bit Python required)
    ----------------------------------------
ERROR: Command errored out with exit status 1: 'c:\users\dylan\appdata\local\programs\python\python37-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Dylan\\AppData\\Local\\Temp\\pip-install-vrwss169\\charm4py\\setup.py'"'"'; __file__='"'"'C:\\Users\\Dylan\\AppData\\Local\\Temp\\pip-install-vrwss169\\charm4py\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\Dylan\AppData\Local\Temp\pip-record-ild1vqpv\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\dylan\appdata\local\programs\python\python37-32\Include\charm4py' Check the logs for full command output.

When I run via no Binary option

I get:

C:\>pip3 install [--mpi] charm4py --no-binary charm4py
ERROR: Exception:
Traceback (most recent call last):
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_vendor\packaging\requirements.py", line 98, in __init__
    req = REQUIREMENT.parseString(requirement_string)
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_vendor\pyparsing.py", line 1955, in parseString
    raise exc
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_vendor\pyparsing.py", line 3814, in parseImpl
    raise ParseException(instring, loc, self.errmsg, self)
pip._vendor.pyparsing.ParseException: Expected stringEnd, found '['  (at char 11), (line:1, col:12)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_internal\cli\base_command.py", line 216, in _main
    status = self.run(options, args)
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_internal\cli\req_command.py", line 182, in wrapper
    return func(self, options, args)
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_internal\commands\install.py", line 295, in run
    reqs = self.get_requirements(args, options, finder, session)
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_internal\cli\req_command.py", line 319, in get_requirements
    user_supplied=True,
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_internal\req\constructors.py", line 409, in install_req_from_line
    parts = parse_req_from_line(name, line_source)
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_internal\req\constructors.py", line 349, in parse_req_from_line
    extras = convert_extras(extras_as_string)
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_internal\req\constructors.py", line 75, in convert_extras
    return Requirement("placeholder" + extras.lower()).extras
  File "c:\users\dylan\appdata\local\programs\python\python37-32\lib\site-packages\pip\_vendor\packaging\requirements.py", line 102, in __init__
    requirement_string[e.loc : e.loc + 8], e.msg
pip._vendor.packaging.requirements.InvalidRequirement: Parse error at "'[--mpi]'": Expected stringEnd

I have also tried all the windows wheels and each says that they are not compatible.

Please help

Pip install in new environment fails

Installing charm4py in a new environment fails on my macOS 12.5 machine with Python 3.9.13:

$ python3 -m pip install charm4py
Collecting charm4py
  Using cached charm4py-1.0.tar.gz (3.4 MB)
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error
  
  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [37 lines of output]
      fatal: not a git repository (or any of the parent directories): .git
      Traceback (most recent call last):
        File "/private/var/folders/jb/8vbfr0cn737bzhdszgdjc2rc0000gp/T/pip-install-80ig3b34/charm4py_33d4cf448d404cbcb787ec860eaf1109/setup.py", line 33, in <module>
          charm4py_version = subprocess.check_output(['git', 'describe']).rstrip().decode().split('-')[0]
        File "/usr/local/Cellar/[email protected]/3.9.13_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/subprocess.py", line 424, in check_output
          return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
        File "/usr/local/Cellar/[email protected]/3.9.13_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/subprocess.py", line 528, in run
          raise CalledProcessError(retcode, process.args,
      subprocess.CalledProcessError: Command '['git', 'describe']' returned non-zero exit status 128.
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "/private/var/folders/jb/8vbfr0cn737bzhdszgdjc2rc0000gp/T/pip-install-80ig3b34/charm4py_33d4cf448d404cbcb787ec860eaf1109/charm4py/__init__.py", line 7, in <module>
          import greenlet
      ModuleNotFoundError: No module named 'greenlet'
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "/private/var/folders/jb/8vbfr0cn737bzhdszgdjc2rc0000gp/T/pip-install-80ig3b34/charm4py_33d4cf448d404cbcb787ec860eaf1109/setup.py", line 42, in <module>
          from charm4py import _version
        File "/private/var/folders/jb/8vbfr0cn737bzhdszgdjc2rc0000gp/T/pip-install-80ig3b34/charm4py_33d4cf448d404cbcb787ec860eaf1109/charm4py/__init__.py", line 10, in <module>
          exit(-1)
        File "/usr/local/Cellar/[email protected]/3.9.13_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/_sitebuiltins.py", line 26, in __call__
          raise SystemExit(code)
      SystemExit: -1
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/private/var/folders/jb/8vbfr0cn737bzhdszgdjc2rc0000gp/T/pip-install-80ig3b34/charm4py_33d4cf448d404cbcb787ec860eaf1109/setup.py", line 45, in <module>
          raise DistutilsSetupError('Could not determine Charm4py version')
      distutils.errors.DistutilsSetupError: Could not determine Charm4py version
      Charm4py requires the greenlet package. It can be installed via pip
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

Any ideas?

Make LocalFuture Available to User Code

LocalFutures are lightweight future objects used internally within the runtime system for signaling within a PE. I'm working on an application that uses futures that are guaranteed to send results within the same PE. Because LocalFutures avoid communication, they should be made available to user code, with documentation making it clear that:

  1. They cannot be used across PEs.
  2. Values sent through a local future are passed by reference.

'When' buffer: messages should only be unpickled at time of delivery

Messages stored in _when_buffer should probably not be unpickled before buffering. Instead they should be unpickled after retrieving them from buffer. The reason is that if an object with buffered messages migrates, these messages will have to be pickled and unpickled for each time the object migrates.

Deprecate CTypes Backend

Currently, Charm4Py uses 3 different backends to interface with the Charm++ runtime library: Cython, CFFI, and Ctypes. In the manual, Cython and CFFI are recommended for different Python builds, but Ctypes is not recommended. It also doesn't look like there is a way to build Charm4Py with the Ctypes backend in the installation script.

Given this, I think it would be appropriate to deprecate the Ctypes backend to reduce the amount of work required to make changes to the Charm++/Charm4Py interface.

Section reductions do not always work as expected

Most reduction types do not work when chares in a section contribute to a reduction where each chare contributes a list of values. Some reduction types do not work when the chares are contributing to a section at all.

An example program using Reducer.sum:

from charm4py import *

class A( Chare ):
    def contr( self, future, proxy, doTuple ):
        if doTuple:
            contrib = [1,1]
        else:
            contrib = 1
        if proxy:
            self.contribute( contrib, Reducer.sum, future, proxy )
        else:
            self.reduce( future, contrib, Reducer.sum )

def main( args ):
    arr = Array( A, 10 )

    # Split the odd and even-numbered chares into sections
    sec1 = arr[ 0:10:2 ]
    sec2 = arr[ 1:10:2 ]

    oneFut = Future()
    twoFut = Future()
    redFut = Future()
    blueFut = Future()

    sec1.contr( oneFut, sec1, True )
    sec2.contr( twoFut, sec2, True )
    arr.contr( redFut, None, True )
    arr.contr( blueFut, None, False )

    print( oneFut.get() ) # Expected: [5, 5]
    print( twoFut.get() ) # Expected: [5, 5]
    print( redFut.get() ) # Expected: [10, 10]
    print( blueFut.get() ) # Expected: 10
    exit()

charm.start( main )

When the chares attempt to contribute to their respective sections, the program crashes with the following:

Fatal error on PE 1> TypeError: unsupported operand type(s) for +: 'int' and 'list'

It seems that a function equivalent to Python's built-in sum is called when the chares contribute to a section, while a different function is used when no section is specified. Running sum([list(),list()]) produces the same error.

If the chares contribute single values to the reduction, the program behaves as expected. Changing the contr calls to the following runs as expected:

    sec1.contr( oneFut, sec1, False )
    sec2.contr( twoFut, sec2, False )
    arr.contr( redFut, None, True )
    arr.contr( blueFut, None, False )

Reducer.sum is used as an illustrative example, but many of the default reducer types have similar issues. The built-in reduction types that do not work and the incorrect behavior they exhibit are as follows:

  • Reducer.sum: program crashes as described above.
  • Reducer.product: program crashes with an error similar to that produced by Reducer.sum.
  • Reducer.logical_and, Reducer.logical_or, Reducer.logical_xor: Each of these reduction types returns None rather than producing the expected value. These boolean logic reductions do not work at all with sections, even when each chare contributes exactly one value.

The default reduction types that work as expected are Reducer.min and Reducer.max.

Support "Sections" functionality of Charm++

This refers to the functionality (ckmulticast and cksection) in C++ Charm, which allows obtaining a proxy to a subset of a chare Group or Array, for efficient "multicast" communication.

Not compatible with cython 3.0

As it says above, I get compile errors when installing through pip. Mostly implicit conversion is happening between types.

New release for Charm4Py 1.1

  • Modernize pip infrastructure

  • Build via cibuildwheel

  • Package charm++ with charm4py, if possible (so that charm++ does not need to be built when running pip install charm4py)

  • Test with latest Python version

  • Merge ray implementation

  • Update to Cython 3.0

Later:
Conda-forge (needs new license, see e.g. UIUC-PPL/charm#3793)

Undefined names have the potential to raise NameError at runtime

flake8 testing of https://github.com/UIUC-PPL/charmpy on Python 3.7.0

$ flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics

./examples/stencil3d/stencil3d_numba.py:174:9: F821 undefined name 'compute_kernel_fast'
        compute_kernel_fast(10, T, T)
        ^
./examples/stencil3d/stencil3d_numba.py:175:9: F821 undefined name 'constrainBC_fast'
        constrainBC_fast(T)
        ^
./examples/stencil3d/stencil3d_numba.py:176:9: F821 undefined name 'fillGhostData'
        fillGhostData(T, T, T, T, T, T, T)
        ^
./examples/stencil3d/stencil3d_numba.py:177:9: F821 undefined name 'processGhosts_fast'
        processGhosts_fast(T, LEFT, 1, 1, T)
        ^
./examples/stencil3d/stencil3d_numba.py:192:9: F821 undefined name 'constrainBC_fast'
        constrainBC_fast(self.temperature)
        ^
./examples/stencil3d/stencil3d_numba.py:225:9: F821 undefined name 'fillGhostData'
        fillGhostData(self.temperature, leftGhost, rightGhost, topGhost, bottomGhost, frontGhost, backGhost)
        ^
./examples/stencil3d/stencil3d_numba.py:236:9: F821 undefined name 'processGhosts_fast'
        processGhosts_fast(self.temperature, direction, width, height, gh)
        ^
./examples/stencil3d/stencil3d_numba.py:250:9: F821 undefined name 'constrainBC_fast'
        constrainBC_fast(self.temperature)
        ^
./examples/stencil3d/stencil3d_numba.py:281:9: F821 undefined name 'compute_kernel_fast'
        compute_kernel_fast(int(work), self.new_temperature, self.temperature)
        ^
./charmpy/chare.py:41:44: F821 undefined name 'Options'
        self._local = [i for i in range(1, Options.LOCAL_MSG_BUF_SIZE+1)]
                                           ^
./charmpy/chare.py:53:19: F821 undefined name 'CharmPyError'
            raise CharmPyError("Local msg buffer full. Increase LOCAL_MSG_BUF_SIZE")
                  ^
./charmpy/chare.py:103:28: F821 undefined name 'charm'
        if cond_str not in charm.wait_conditions:
                           ^
./charmpy/chare.py:105:13: F821 undefined name 'charm'
            charm.wait_conditions[cond_str] = cond_template
            ^
./charmpy/chare.py:107:29: F821 undefined name 'charm'
            cond_template = charm.wait_conditions[cond_str]
                            ^
./charmpy/chare.py:110:13: F821 undefined name 'charm'
            charm.threadMgr.pauseThread()
            ^
./charmpy/chare.py:113:9: F821 undefined name 'charm'
        charm.contribute(data, reducer_type, target, self)
        ^
./charmpy/chare.py:116:9: F821 undefined name 'charm'
        charm.contribute(data, Reducer.gather, target, self)
        ^
./charmpy/chare.py:116:32: F821 undefined name 'Reducer'
        charm.contribute(data, Reducer.gather, target, self)
                               ^
./charmpy/chare.py:120:9: F821 undefined name 'charm'
        charm.CkArraySend(self.thisProxy.aid, self.thisIndex, self.thisProxy.AtSync.ep, (b'', []))
        ^
./charmpy/chare.py:125:9: F821 undefined name 'charm'
        charm.lib.CkMigrate(self.thisProxy.aid, self.thisIndex, toPe)
        ^
./charmpy/chare.py:129:9: F821 undefined name 'charm'
        charm.threadMgr.depositFuture(fid, result)
        ^
./charmpy/chare.py:149:46: F821 undefined name 'charm'
            header[b'block'] = blockFuture = charm.createFuture()
                                             ^
./charmpy/chare.py:151:12: F821 undefined name 'Options'
        if Options.LOCAL_MSG_OPTIM and (cid in charm.chares) and (len(args) > 0):
           ^
./charmpy/chare.py:151:48: F821 undefined name 'charm'
        if Options.LOCAL_MSG_OPTIM and (cid in charm.chares) and (len(args) > 0):
                                               ^
./charmpy/chare.py:152:23: F821 undefined name 'charm'
            destObj = charm.chares[cid]
                      ^
./charmpy/chare.py:153:15: F821 undefined name 'charm'
        msg = charm.packMsg(destObj, args, header)
              ^
./charmpy/chare.py:154:9: F821 undefined name 'charm'
        charm.CkChareSend(cid, ep, msg)
        ^
./charmpy/chare.py:160:5: F821 undefined name 'charm'
    charm.CkContributeToChare(contributeInfo, proxy.cid)
    ^
./charmpy/chare.py:169:25: F821 undefined name 'charm'
        obj.thisProxy = charm.proxyClasses[MAINCHARE][obj.__class__](cid)
                        ^
./charmpy/chare.py:179:18: F821 undefined name 'charm'
        for m in charm.classEntryMethods[MAINCHARE][cls]:
                 ^
./charmpy/chare.py:181:23: F821 undefined name 'CharmPyError'
                raise CharmPyError("Unregistered entry method")
                      ^
./charmpy/chare.py:182:16: F821 undefined name 'Options'
            if Options.PROFILING:
               ^
./charmpy/chare.py:183:29: F821 undefined name 'profile_send_function'
                M[m.name] = profile_send_function(mainchare_proxy_method_gen(m.epIdx))
                            ^
./charmpy/chare.py:221:46: F821 undefined name 'charm'
            header[b'block'] = blockFuture = charm.createFuture()
                                             ^
./charmpy/chare.py:225:12: F821 undefined name 'Options'
        if Options.LOCAL_MSG_OPTIM and (elemIdx == charm._myPe) and (len(args) > 0):
           ^
./charmpy/chare.py:225:52: F821 undefined name 'charm'
        if Options.LOCAL_MSG_OPTIM and (elemIdx == charm._myPe) and (len(args) > 0):
                                                   ^
./charmpy/chare.py:226:23: F821 undefined name 'charm'
            destObj = charm.groups[proxy.gid]
                      ^
./charmpy/chare.py:227:15: F821 undefined name 'charm'
        msg = charm.packMsg(destObj, args, header)
              ^
./charmpy/chare.py:228:9: F821 undefined name 'charm'
        charm.CkGroupSend(proxy.gid, elemIdx, ep, msg)
        ^
./charmpy/chare.py:238:27: F821 undefined name 'charm'
        if get_ident() != charm.threadMgr.main_thread_id and ArrayMap not in C.mro():
                          ^
./charmpy/chare.py:239:31: F821 undefined name 'charm'
            creation_future = charm.createFuture()
                              ^
./charmpy/chare.py:241:15: F821 undefined name 'charm'
        msg = charm.packMsg(None, args, header)
              ^
./charmpy/chare.py:242:15: F821 undefined name 'charm'
        gid = charm.lib.CkCreateGroup(C.idx[GROUP], epIdx, msg)
              ^
./charmpy/chare.py:243:17: F821 undefined name 'charm'
        proxy = charm.groups[gid].thisProxy
                ^
./charmpy/chare.py:250:5: F821 undefined name 'charm'
    charm.CkContributeToGroup(contributeInfo, proxy.gid, proxy.elemIdx)
    ^
./charmpy/chare.py:259:19: F821 undefined name 'CharmPyError'
            raise CharmPyError("Only subclasses of Chare can be member of Group")
                  ^
./charmpy/chare.py:260:16: F821 undefined name 'charm'
        return charm.proxyClasses[GROUP][C].ckNew(args)
               ^
./charmpy/chare.py:264:25: F821 undefined name 'charm'
        obj.thisIndex = charm.myPe()
                        ^
./charmpy/chare.py:265:25: F821 undefined name 'charm'
        obj.thisProxy = charm.proxyClasses[GROUP][obj.__class__](gid)
                        ^
./charmpy/chare.py:266:31: F821 undefined name 'charm'
        obj._contributeInfo = charm.lib.initContributeInfo(gid, obj.thisIndex, CONTRIBUTOR_TYPE_GROUP)
                              ^
./charmpy/chare.py:276:24: F821 undefined name 'charm'
        entryMethods = charm.classEntryMethods[GROUP][cls]
                       ^
./charmpy/chare.py:279:23: F821 undefined name 'CharmPyError'
                raise CharmPyError("Unregistered entry method")
                      ^
./charmpy/chare.py:280:16: F821 undefined name 'Options'
            if Options.PROFILING:
               ^
./charmpy/chare.py:281:29: F821 undefined name 'profile_send_function'
                M[m.name] = profile_send_function(group_proxy_method_gen(m.epIdx))
                            ^
./charmpy/chare.py:315:15: F821 undefined name 'CharmPyError'
        raise CharmPyError("Dimensions of index " + str(idx) + " don't match array dimensions")
              ^
./charmpy/chare.py:325:46: F821 undefined name 'charm'
            header[b'block'] = blockFuture = charm.createFuture()
                                             ^
./charmpy/chare.py:329:12: F821 undefined name 'Options'
        if Options.LOCAL_MSG_OPTIM and (len(args) > 0):
           ^
./charmpy/chare.py:330:21: F821 undefined name 'charm'
            array = charm.arrays[proxy.aid]
                    ^
./charmpy/chare.py:333:15: F821 undefined name 'charm'
        msg = charm.packMsg(destObj, args, header)
              ^
./charmpy/chare.py:334:9: F821 undefined name 'charm'
        charm.CkArraySend(proxy.aid, elemIdx, ep, msg)
        ^
./charmpy/chare.py:346:19: F821 undefined name 'CharmPyError'
            raise CharmPyError("Bounds and number of dimensions for array cannot be empty in ckNew")
                  ^
./charmpy/chare.py:348:19: F821 undefined name 'CharmPyError'
            raise CharmPyError("Number of bounds should match number of dimensions")
                  ^
./charmpy/chare.py:357:27: F821 undefined name 'charm'
        if get_ident() != charm.threadMgr.main_thread_id:
                          ^
./charmpy/chare.py:358:31: F821 undefined name 'charm'
            creation_future = charm.createFuture()
                              ^
./charmpy/chare.py:361:15: F821 undefined name 'charm'
        msg = charm.packMsg(None, args, header)
              ^
./charmpy/chare.py:362:15: F821 undefined name 'charm'
        aid = charm.lib.CkCreateArray(C.idx[ARRAY], dims, epIdx, msg, map_gid)
              ^
./charmpy/chare.py:373:15: F821 undefined name 'charm'
        msg = charm.packMsg(None, args, {})
              ^
./charmpy/chare.py:374:9: F821 undefined name 'charm'
        charm.lib.CkInsert(proxy.aid, index, epIdx, onPE, msg)
        ^
./charmpy/chare.py:378:5: F821 undefined name 'charm'
    charm.CkContributeToArray(contributeInfo, proxy.aid, proxy.elemIdx)
    ^
./charmpy/chare.py:381:5: F821 undefined name 'charm'
    charm.lib.CkDoneInserting(proxy.aid)
    ^
./charmpy/chare.py:390:19: F821 undefined name 'CharmPyError'
            raise CharmPyError("Only subclasses of Chare can be member of Array")
                  ^
./charmpy/chare.py:391:16: F821 undefined name 'charm'
        return charm.proxyClasses[ARRAY][C].ckNew(dims, ndims, args, map)
               ^
./charmpy/chare.py:396:25: F821 undefined name 'charm'
        obj.thisProxy = charm.proxyClasses[ARRAY][obj.__class__](aid, len(obj.thisIndex))
                        ^
./charmpy/chare.py:399:31: F821 undefined name 'charm'
        obj._contributeInfo = charm.lib.initContributeInfo(aid, obj.thisIndex, CONTRIBUTOR_TYPE_ARRAY)
                              ^
./charmpy/chare.py:410:24: F821 undefined name 'charm'
        entryMethods = charm.classEntryMethods[ARRAY][cls]
                       ^
./charmpy/chare.py:413:23: F821 undefined name 'CharmPyError'
                raise CharmPyError("Unregistered entry method")
                      ^
./charmpy/chare.py:414:16: F821 undefined name 'Options'
            if Options.PROFILING:
               ^
./charmpy/chare.py:415:29: F821 undefined name 'profile_send_function'
                M[m.name] = profile_send_function(array_proxy_method_gen(m.epIdx))
                            ^
./charmpy/wait.py:143:17: F821 undefined name 'charm'
                charm.threadMgr.resumeThread(tid, None)
                ^
./charmpy/entry_method.py:34:9: F821 undefined name 'charm'
        charm.threadMgr.startThread(obj, self, args, header)
        ^
./charmpy/entry_method.py:47:9: F821 undefined name 'charm'
        charm.runningEntryMethod = self
        ^
./charmpy/entry_method.py:53:9: F821 undefined name 'charm'
        charm.runningEntryMethod = None
        ^
./charmpy/entry_method.py:75:30: F821 undefined name 'charm'
        self.__dict__.update(charm.entryMethods[ep].__dict__)
                             ^
./charmpy/threads.py:29:26: F821 undefined name 'charm'
            self.value = charm.threadMgr.pauseThread()
                         ^
./charmpy/threads.py:40:31: F821 undefined name 'charm'
        proxy_class = getattr(charm, self.proxy_class_name)
                              ^
./charmpy/threads.py:54:17: F821 undefined name 'charm'
                charm.threadMgr.resumeThread(self.tid, self.value)
                ^
./charmpy/threads.py:76:26: F821 undefined name 'Options'
        self.PROFILING = Options.PROFILING
                         ^
./charmpy/threads.py:115:23: F821 undefined name 'CharmPyError'
                raise CharmPyError("Migration of chares with active threads is not yet supported")
                      ^
./charmpy/threads.py:138:15: F821 undefined name 'CharmPyError'
        raise CharmPyError("Entry method '" + charm.mainThreadEntryMethod.C.__name__ + "." +
              ^
./charmpy/threads.py:138:47: F821 undefined name 'charm'
        raise CharmPyError("Entry method '" + charm.mainThreadEntryMethod.C.__name__ + "." +
                                              ^
./charmpy/threads.py:139:28: F821 undefined name 'charm'
                           charm.mainThreadEntryMethod.name +
                           ^
./charmpy/threads.py:171:13: F821 undefined name 'charm'
            charm.mainThreadEntryMethod.stopMeasuringTime()
            ^
./charmpy/threads.py:176:13: F821 undefined name 'charm'
            charm.mainThreadEntryMethod.startMeasuringTime()
            ^
93    F821 undefined name 'Options'
93

Clarify interaction with other parallel tools

The specific issue motivating this is that I'm thinking of spawning a process using either asyncio, subprocess or multiprocessing in the standard library.

  1. All those modules provides ways of waiting until the spawned process is complete. Will those work at all in charm4py? If they are in a method marked @coro, will they yield control, or just block until completion? https://charm4py.readthedocs.io/en/latest/rules.html says

Note that coroutines are non-preemtive [typo] and only yield when they are waiting for something (typically occurs when they are blocked on a future or channel). When a method stops executing, control returns to the scheduler which will start or resume other methods on that process.

The methods are waiting for something, but it is not any kind of a charm thing.

  1. asyncio has an event loop. Is that compatible with charm?

  2. multiprocessing warns against fork from a process with operating system threads. Does charm use such threads?

More generally, will the package interoperate properly with other things in base Python:

  1. Does basic file I/O qualify for the "waiting for something" condition of the documentation?
  2. What if you try to use threads?
  3. The newish native coroutine facility in Python along with await and related keywords?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.