Skip to content

UIUC-PPL/ck

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Charm-Kernel

An early-stage attempt to port the TMP-based chare/entry method registration scheme of CharmLite (and, to an extent, VT) to Charm++.

Other links:

Building+Running

Currently NAME is built out-of-tree with Charm++, requiring no modifications to the mainline repository. To build a standalone program, include the include/ directory in this repo, and add the flags to enable C++17 to charmc (i.e., -c++-option -std=c++17). The simplest way to build and run all of NAME's test programs is to run the tests/run.sh script.

Chares

NAME supports all the chare-types through the ck::chare class template. Its first parameter is the user's class (CRTP), and its second is the chare-type, i.e., ck::main_chare, ck::singleton_chare, ck::group, ck::nodegroup, or ck::array<Index>. Note that ck::array is itself a class template whose parameter is the index-type of the chare array. All the built-in indices are supported by default (i.e., CkIndex[1-6]D), with user-defined index-types requiring specializations of the ck::index_view class template (to define their encoding scheme). As with "conventional" Charm++, migratable chare-types must have migration constructors and pup routines.

Entry Methods

Entry methods are specified at the site of a call to ck::send or ck::make_callback. They must be accessible members of chares whose arguments are de/serializable. Most attributes are supported through the CK_[ATTRIBUTE]_ENTRY macro. For example, CK_THREADED_ENTRY(&foo:bar) will define a threaded entry method. Note that these macros must be used at the top-level scope since they define specializations of class templates within the ck namespace. NAME does not include a [reductiontarget] attribute since its marshaled entry methods support multiple message-types by default.

Call-site attribution

One may assign certain attributes at the site of a ck::send method. For example, one may try to execute an entry method inline via:

// a single attribute may be passed directly
ck::send<&foo::bar, ck::Inline>(fooProxy, ...);
// multiple attributes must be wrapped in the `ck::attributes` helper
ck::send<&foo::bar, ck::attributes<ck::Inline, ...>>(fooProxy, ...);

Advanced Attribution

Assigning an attribute to all specializations of a generic entry method is non-trivial, requiring use of SFINAE. Consider the following:

class main : public ck::chare<main, ck::main_chare> {
/* ... */
// an entry method that we want to make [inline]
template <typename A, typename B>
void receive(const A& a, const B& b) {
    /* ... */
}
};
// required to pass instances via template parameters
template <typename A, typename B>
using receive_like_t = void (main::*)(const A&, const B&);
// ONE CAN EITHER MANUALLY WRITE THE SPECIALIZATION
namespace ck {
template <typename A, typename B, receive_like_t<A, B> RL>
struct is_inline<RL, std::enable_if_t<(RL == &main::receive<A, B>)>>
    : public std::true_type {};
}
// OR USE THE CK_ENTRY_ASSIGN_ATTRIBUTE MACRO TO DO IT
CK_ENTRY_ASSIGN_ATTRIBUTE((RL, std::enable_if_t<(RL == &main::receive<A, B>)>),
                        inline, typename A, typename B,
                        receive_like_t<A, B> RL);
// EITHER WAY WILL GET THE JOB DONE
static_assert(ck::is_inline_v<&main::receive<int, int>>);

Pointer-to-offset Optimizations

Instead of copying the data from the message into another buffer, e.g., as with a std::vector, ck::span containers can directly reference and retain (potentially shared) ownership of a message buffer. This process avoids receiver-side copies, and it is referred to as a pointer-to-offset optimization (i.e., it uses an offset within the message buffer as an array/pointer). Note, NAME only applies these optimizations to ck::span containers of bytes-like types received via parameter marshalling.

Proxies

All singleton chares (and main chares, by extension) use ck::chare_proxy proxies. All other chare-types have ck:collection_proxy, ck::element_proxy, and ck::section_proxy proxies. All proxies use the ck::send function, which broadcasts, multicast, or sends a message to the chare(s) they encompass. Calls to ck::send can, optionally, include CkEntryOptions* to specify message priorities, queuing strategies, etc. Non-element proxies use the ck::create function to create new instances. Chare-array element proxies can use the ck::insert function, which behaves similarly (although it takes a proxy as its first argument).

Callbacks

Users can create callbacks to entry methods using the ck::make_callback function template. Its template parameter is an entry method, while its argument is the target proxy.

Reducers

One can register custom reducer functions (i.e., those that combine contributions during reductions) using the ck::reducer function. Generally, valid reducers are of the form T(*)(T,T), although their arguments may be const or r-value references. Note that we consider all reducers over PUPBytes types as "streamable." We provide a helper function for forming contributions, pack_contribution (name pending).

Readonly Variables

NAME supports defining readonly variables via the CK_READONLY macro. One can forward declare readonly variables using the CK_EXTERN_READONLY macro. Note that types of readonly variables containing commas must be enclosed within parenthesis. For example, CK_READONLY((std::map<int, int>), kReadonlyMap) is a valid declaration.

About

Revisiting TMP-based Registration Scheme.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages