Skip to content

Commit dd4acae

Browse files
committed
Allow some methods of charm object to be remotely callable
The charm object is present in every process and represents the Charm4py runtime. This patch effectively turns it into a chare, by creating a Group of CharmRemote objects which act as an interface to the charm object in every process. The new chare can be accessed via the 'thisProxy' attribute of 'charm'.
1 parent f893adc commit dd4acae

File tree

6 files changed

+58
-12
lines changed

6 files changed

+58
-12
lines changed

charmpy/charm.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ def buildMainchare(self, onPe, objPtr, ep, args):
118118
assert cid not in self.chares, "Chare " + str(cid) + " already instantiated"
119119
em = self.entryMethods[ep]
120120
assert em.isCtor, "Specified mainchare entry method is not constructor"
121+
self._createInternalChares()
121122
obj = object.__new__(em.C) # create object but don't call __init__
122123
Mainchare.initMember(obj, cid)
123124
super(em.C, obj).__init__() # call Chare class __init__ first
@@ -403,6 +404,12 @@ def register(self, C, collections=(GROUP, ARRAY)):
403404
self.registerAs(C, charm_type_id)
404405
self.register_order.append(C)
405406

407+
def _registerInternalChares(self):
408+
self.register(CharmRemote, (GROUP,))
409+
410+
def _createInternalChares(self):
411+
Group(CharmRemote)
412+
406413
def start(self, entry, classes=[], modules=[]):
407414
"""
408415
Start Charmpy program.
@@ -429,6 +436,8 @@ def start(self, entry, classes=[], modules=[]):
429436
if "++quiet" in sys.argv:
430437
Options.QUIET = True
431438

439+
self._registerInternalChares()
440+
432441
if hasattr(entry, 'mro') and Chare in entry.mro():
433442
if entry.__init__.__code__.co_argcount != 2:
434443
raise CharmPyError("Mainchare constructor must have only one parameter")
@@ -612,6 +621,18 @@ def LBTurnInstrumentOff(self):
612621
self.lib.LBTurnInstrumentOff()
613622

614623

624+
class CharmRemote(Chare):
625+
626+
def __init__(self):
627+
charm.thisProxy = self.thisProxy
628+
629+
def exit(self, exit_code=0):
630+
charm.exit(exit_code)
631+
632+
def myPe(self):
633+
return charm.myPe()
634+
635+
615636
def load_charm_library(charm):
616637
args = sys.argv
617638
libcharm_path = os.path.join(os.path.dirname(__file__), '.libs')

test_config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
[
2+
{
3+
"force_min_processes": 4,
4+
"path": "tests/charm_remote.py"
5+
},
26
{
37
"force_min_processes": 4,
48
"path": "tests/array_maps/test1.py"

tests/array_maps/test1.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ class MyChare(Chare):
1616

1717
def __init__(self, last):
1818
assert charm.myPe() == index_to_pe(self.thisIndex), "ArrayMap failed"
19-
if last: self.contribute(None, None, self.thisProxy.done)
20-
21-
def done(self):
22-
exit()
19+
if last: self.contribute(None, None, charm.thisProxy[0].exit)
2320

2421

2522
def main(args):

tests/charm_remote.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from charmpy import charm, Chare, Group, threaded
2+
import random
3+
4+
5+
class Controller(Chare):
6+
7+
@threaded
8+
def start(self):
9+
# print('Controller running on PE', charm.myPe())
10+
for i in range(charm.numPes()):
11+
assert i == charm.thisProxy[i].myPe(ret=True).get()
12+
13+
g = Group(Test)
14+
15+
16+
class Test(Chare):
17+
18+
def __init__(self):
19+
self.contribute(None, None, charm.thisProxy[0].exit)
20+
21+
22+
def main(args):
23+
if charm.numPes() > 1:
24+
pes = list(range(1, charm.numPes()))
25+
else:
26+
pes = [0]
27+
Chare(Controller, onPE=random.choice(pes)).start()
28+
29+
30+
charm.start(main)

tests/migration/chare_migration.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ def test(self):
2222
if self.thisIndex == (0,):
2323
print("Test called on PE ", charm.myPe())
2424
assert charm.myPe() == self.toPe
25-
self.contribute(None, None, self.thisProxy[0].done)
26-
27-
def done(self):
28-
exit()
25+
self.contribute(None, None, charm.thisProxy[0].exit)
2926

3027
def start(self):
3128
"""

tests/migration/test_migrate.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ def arrayElemsCreated(self, home_pes):
1818
for i in range(len(home_pes)): arrayElemHomeMap[i] = home_pes[i]
1919
self.contribute(None, None, ro.array.start)
2020

21-
def done(self):
22-
exit()
23-
2421

2522
class Test(Chare):
2623

@@ -40,7 +37,7 @@ def start(self):
4037
for i in range(work): A += 1.33
4138
self.iteration += 1
4239
if self.iteration == MAX_ITER:
43-
self.contribute(None, None, ro.controllers[0].done)
40+
self.contribute(None, None, charm.thisProxy[0].exit)
4441
elif self.iteration % 20 == 0:
4542
self.AtSync()
4643
else:

0 commit comments

Comments
 (0)