Skip to content

Commit

Permalink
Add ckDestroy and ckLocalBranch
Browse files Browse the repository at this point in the history
  • Loading branch information
adityapb committed Dec 30, 2021
1 parent 3603cae commit 1c2db20
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 28 deletions.
113 changes: 85 additions & 28 deletions charm4py/chare.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,11 @@ def group_ckNew(cls, args, onPEs):
return proxy
return group_ckNew


def group_proxy_localbranch(proxy):
return charm.groups[proxy.gid]


def group_proxy_contribute(proxy, contributeInfo):
charm.CkContributeToGroup(contributeInfo, proxy.gid, proxy.elemIdx)

Expand Down Expand Up @@ -631,13 +636,16 @@ def __getProxyClass__(C, cls, sectionProxy=False):
M['__eq__'] = group_proxy__eq__
M['__hash__'] = group_proxy__hash__
M['ckNew'] = group_ckNew_gen(cls, entryMethods[0].epIdx)
M['ckLocalBranch'] = group_proxy_localbranch
M['__getsecproxy__'] = group_getsecproxy
if not sectionProxy:
M['ckContribute'] = group_proxy_contribute # function called when target proxy is Group
M['ckContribute'] = group_proxy_contribute
# function called when target proxy is Group
M['__getstate__'] = group_proxy__getstate__
M['__setstate__'] = group_proxy__setstate__
else:
M['ckContribute'] = groupsecproxy_contribute # function called when target proxy is Group
M['ckContribute'] = groupsecproxy_contribute
# function called when target proxy is Group
M['__getstate__'] = groupsecproxy__getstate__
M['__setstate__'] = groupsecproxy__setstate__
proxyCls = type(proxyClassName, (), M) # create and return proxy class
Expand All @@ -655,14 +663,19 @@ def __init__(self):
def array_proxy_ctor(proxy, aid, ndims):
proxy.aid = aid
proxy.ndims = ndims
proxy.elemIdx = () # entry method calls will be to elemIdx array element (broadcast if empty tuple)
# entry method calls will be to elemIdx array element
# (broadcast if empty tuple)
proxy.elemIdx = ()


def array_proxy__getstate__(proxy):
return (proxy.aid, proxy.ndims, proxy.elemIdx)


def array_proxy__setstate__(proxy, state):
proxy.aid, proxy.ndims, proxy.elemIdx = state


def array_proxy__eq__(proxy, other):
if proxy.issec:
if hasattr(other, 'issec'):
Expand All @@ -674,12 +687,14 @@ def array_proxy__eq__(proxy, other):
else:
return False


def array_proxy__hash__(proxy):
if proxy.issec:
return hash(proxy.section)
else:
return hash((proxy.aid, proxy.elemIdx))


def array_getsecproxy(proxy, sinfo):
if proxy.issec:
secproxy = proxy.__class__(proxy.aid, proxy.ndims)
Expand All @@ -688,12 +703,15 @@ def array_getsecproxy(proxy, sinfo):
secproxy.section = sinfo
return secproxy


def arraysecproxy__getstate__(proxy):
return (proxy.aid, proxy.ndims, proxy.elemIdx, proxy.section)


def arraysecproxy__setstate__(proxy, state):
proxy.aid, proxy.ndims, proxy.elemIdx, proxy.section = state


def array_proxy_elem(proxy, idx): # array proxy [] overload method
ndims = proxy.ndims
isslice = True
Expand All @@ -703,17 +721,27 @@ def array_proxy_elem(proxy, idx): # array proxy [] overload method
isslice = False
elif idxtype == slice:
idx = (idx,)
assert len(idx) == ndims, "Dimensions of index " + str(idx) + " don't match array dimensions"
assert len(idx) == ndims, \
"Dimensions of index " + str(idx) + " don't match array dimensions"
if not isslice or not isinstance(idx[0], slice):
proxy_clone = proxy.__class__(proxy.aid, ndims)
proxy_clone.elemIdx = tuple(idx)
return proxy_clone
else:
for _slice in idx:
assert _slice.start is not None and _slice.stop is not None, 'Must specify start and stop indexes for array slicing'
assert _slice.start is not None and _slice.stop is not None, \
'Must specify start and stop indexes for array slicing'
return charm.split(proxy, 1, slicing=idx)[0]

def array_proxy_method_gen(ep, argcount, argnames, defaults): # decorator, generates proxy entry methods

def array_proxy_delete(proxy):
assert proxy.elemIdx != -1, \
"ckDestroy can only be called on an array element"
charm.arrayElemDelete(proxy.aid, proxy.elemIdx)


def array_proxy_method_gen(ep, argcount, argnames, defaults):
# decorator, generates proxy entry methods
def proxy_entry_method(proxy, *args, **kwargs):
num_args = len(args)
if num_args < argcount and len(kwargs) > 0:
Expand All @@ -726,7 +754,8 @@ def proxy_entry_method(proxy, *args, **kwargs):
else:
# if not there, see if there is a default value
def_idx = i - argcount + len(defaults)
assert def_idx >= 0, 'Value not found for parameter \'' + argname + '\' of entry method'
assert def_idx >= 0, 'Value not found for parameter \'' + \
argname + '\' of entry method'
args.append(defaults[def_idx])

header = {}
Expand All @@ -753,16 +782,20 @@ def proxy_entry_method(proxy, *args, **kwargs):
root, sid = proxy.section
header[b'sid'] = sid
if Options.local_msg_optim and root == charm._myPe:
charm.sectionMgr.thisProxy[root].sendToSectionLocal(sid, ep, header, *args)
charm.sectionMgr.thisProxy[root].sendToSectionLocal(
sid, ep, header, *args)
else:
charm.sectionMgr.thisProxy[root].sendToSection(sid, ep, header, *args)
charm.sectionMgr.thisProxy[root].sendToSection(
sid, ep, header, *args)
return blockFuture
proxy_entry_method.ep = ep
return proxy_entry_method


def array_ckNew_gen(C, epIdx):
@classmethod # make ckNew a class (not instance) method of proxy
def array_ckNew(cls, dims=None, ndims=-1, args=[], map=None, useAtSync=False):
def array_ckNew(cls, dims=None, ndims=-1, args=[], map=None,
useAtSync=False):
# if charm.myPe() == 0: print("calling array ckNew for class " + C.__name__ + " cIdx=" + str(C.idx[ARRAY]))
if type(dims) == int: dims = (dims,)

Expand All @@ -789,17 +822,22 @@ def array_ckNew(cls, dims=None, ndims=-1, args=[], map=None, useAtSync=False):
header[b'creation'] = True

msg = charm.packMsg(None, args, header)
aid = charm.lib.CkCreateArray(C.idx[ARRAY], dims, epIdx, msg, map_gid, useAtSync)
aid = charm.lib.CkCreateArray(
C.idx[ARRAY], dims, epIdx, msg, map_gid, useAtSync)
proxy = cls(aid, len(dims))
if creation_future is not None:
proxy.creation_future = creation_future
return proxy
return array_ckNew


def array_ckInsert_gen(epIdx):
def array_ckInsert(proxy, index, args=[], onPE=-1, useAtSync=False, single=False):
if type(index) == int: index = (index,)
assert len(index) == proxy.ndims, 'Invalid index dimensions passed to ckInsert'
def array_ckInsert(proxy, index, args=[], onPE=-1, useAtSync=False,
single=False):
if type(index) == int:
index = (index,)
assert len(index) == proxy.ndims, \
'Invalid index dimensions passed to ckInsert'
header = {}
if single:
header[b'single'] = True
Expand All @@ -812,11 +850,15 @@ def array_ckInsert(proxy, index, args=[], onPE=-1, useAtSync=False, single=False
charm.lib.CkInsert(proxy.aid, index, epIdx, onPE, msg, useAtSync)
return array_ckInsert


def array_proxy_contribute(proxy, contributeInfo):
charm.CkContributeToArray(contributeInfo, proxy.aid, proxy.elemIdx)


def arraysecproxy_contribute(proxy, contributeInfo):
charm.CkContributeToSection(contributeInfo, proxy.section[1], proxy.section[0])
charm.CkContributeToSection(contributeInfo, proxy.section[1],
proxy.section[0])


def array_proxy_doneInserting(proxy):
charm.lib.CkDoneInserting(proxy.aid)
Expand All @@ -826,30 +868,38 @@ class Array(object):

type_id = ARRAY

def __new__(cls, C, dims=None, ndims=-1, args=[], map=None, useAtSync=False):
def __new__(cls, C, dims=None, ndims=-1, args=[], map=None,
useAtSync=False):
if (not hasattr(C, 'mro')) or (Chare not in C.mro()):
raise Charm4PyError('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 Charm4PyError(str(C) + ' not registered for use in Arrays')
return charm.proxyClasses[ARRAY][C].ckNew(dims, ndims, args, map, useAtSync)
return charm.proxyClasses[ARRAY][C].ckNew(dims, ndims, args, map,
useAtSync)

@classmethod
def initMember(cls, obj, aid, index, single=False):
obj.thisIndex = index
if single:
proxy = charm.proxyClasses[ARRAY][obj.__class__](aid, len(obj.thisIndex))
proxy = charm.proxyClasses[ARRAY][obj.__class__](
aid, len(obj.thisIndex))
obj.thisProxy = proxy[index]
else:
obj.thisProxy = charm.proxyClasses[ARRAY][obj.__class__](aid, len(obj.thisIndex))
obj._contributeInfo = charm.lib.initContributeInfo(aid, obj.thisIndex, CONTRIBUTOR_TYPE_ARRAY)
obj.thisProxy = charm.proxyClasses[ARRAY][obj.__class__](
aid, len(obj.thisIndex))
obj._contributeInfo = charm.lib.initContributeInfo(
aid, obj.thisIndex, CONTRIBUTOR_TYPE_ARRAY)
obj.migratable = True

@classmethod
def __baseEntryMethods__(cls):
# 2nd method is used for 2 purposes:
# - to register the migration constructor on Charm++ side (note that this migration constructor does nothing)
# - to register the migration constructor on Charm++ side
# (note that this migration constructor does nothing)
# - Chare.migrated() is called whenever a chare has completed migration.
# The EntryMethod object with this name is used to profile Chare.migrated() calls.
# The EntryMethod object with this name is used to profile
# Chare.migrated() calls.
return ['__init__', 'migrated', 'AtSync']

@classmethod
Expand All @@ -868,9 +918,11 @@ def __getProxyClass__(C, cls, sectionProxy=False):
continue
argcount, argnames, defaults = getEntryMethodInfo(m.C, m.name)
if Options.profiling:
f = profile_send_function(array_proxy_method_gen(m.epIdx, argcount, argnames, defaults))
f = profile_send_function(array_proxy_method_gen(
m.epIdx, argcount, argnames, defaults))
else:
f = array_proxy_method_gen(m.epIdx, argcount, argnames, defaults)
f = array_proxy_method_gen(
m.epIdx, argcount, argnames, defaults)
f.__qualname__ = proxyClassName + '.' + m.name
f.__name__ = m.name
M[m.name] = f
Expand All @@ -882,12 +934,15 @@ def __getProxyClass__(C, cls, sectionProxy=False):
M['__getsecproxy__'] = array_getsecproxy
M['ckInsert'] = array_ckInsert_gen(entryMethods[0].epIdx)
M['ckDoneInserting'] = array_proxy_doneInserting
M['ckDestroy'] = array_proxy_delete
if not sectionProxy:
M['ckContribute'] = array_proxy_contribute # function called when target proxy is Array
M['ckContribute'] = array_proxy_contribute
# function called when target proxy is Array
M['__getstate__'] = array_proxy__getstate__
M['__setstate__'] = array_proxy__setstate__
else:
M['ckContribute'] = arraysecproxy_contribute # function called when target proxy is Array
M['ckContribute'] = arraysecproxy_contribute
# function called when target proxy is Array
M['__getstate__'] = arraysecproxy__getstate__
M['__setstate__'] = arraysecproxy__setstate__
proxyCls = type(proxyClassName, (), M) # create and return proxy class
Expand All @@ -896,6 +951,7 @@ def __getProxyClass__(C, cls, sectionProxy=False):

# ---------------------------------------------------


charm_type_id_to_class = [None] * len(CHARM_TYPES)
for i in CHARM_TYPES:
if i == MAINCHARE:
Expand All @@ -907,7 +963,8 @@ def __getProxyClass__(C, cls, sectionProxy=False):


def charmStarting():
global charm, Options, Reducer, Charm4PyError, CharmRemote, profile_send_function
global charm, Options, Reducer, Charm4PyError, CharmRemote, \
profile_send_function
from .charm import charm, Charm4PyError, CharmRemote, profile_send_function
Options = charm.options
Reducer = charm.reducers
9 changes: 9 additions & 0 deletions charm4py/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,15 @@ def start(self, entry=None, classes=[], modules=[], interactive=False):
self.lb_requested = '+balancer' in sys.argv
self.lib.start()

def arrayElemDelete(self, aid, index):
obj = self.arrays[aid].pop(index)
del obj._contributeInfo
del obj._local
del obj._local_free_head
del obj._active_grp_conds
obj._cond_next = None
obj._cond_last = None

def arrayElemLeave(self, aid, index):
obj = self.arrays[aid].pop(index)
if hasattr(obj, '_scookies'):
Expand Down

0 comments on commit 1c2db20

Please sign in to comment.