RPC Engine
This example showcases the RPC Engine capabilities. The code is structured as follows:
source/
contains the different variants of this example corresponding to different backendsmpi.cpp
corresponds to the MPI backend implementation
Topology Discovery
First, we use the topology manager to query the local HiCR instance’s topology
auto topology = topologyManager.queryTopology();
Then, we get the first available compute resource and memory space of the first device:
// Selecting first device
auto d = *topology.getDevices().begin();
// Get first memory space for RPC buffers
auto memSpaces = d->getMemorySpaceList();
auto bufferMemorySpace = *memSpaces.begin();
// Grabbing first compute resource for computing RPCs
auto computeResources = d->getComputeResourceList();
auto executeResource = *computeResources.begin();
RPC Registration
Then, create an RPC Engine define a lambda, and associate it with an RPC:
// Creating RPC engine instance
HiCR::frontend::RPCEngine rpcEngine(...);
// Initialize RPC engine
rpcEngine.initialize();
// Creating execution unit to run as RPC
auto rpcExecutionUnit =
std::make_shared<HiCR::backend::pthreads::ExecutionUnit>([&im](void *closure) {
printf("Instance %lu: running Test RPC\n", im->getCurrentInstance()->getId());
});
// Registering RPC to listen to
rpcEngine.addRPCTarget("Test RPC", rpcExecutionUnit);
SPMD: RPC Invokation and listening
The RPC is invoked by the root instance, the other instances listen to incoming RPCs:
if (currentInstance->isRootInstance())
{
for (auto &instance : im.getInstances())
if (instance != currentInstance) rpcEngine.requestRPC(*instance, "Test RPC");
}
else
rpcEngine.listen();
The result should look like the following:
Instance 1: running Test RPC
Instance 2: running Test RPC
Instance 4: running Test RPC
Instance 3: running Test RPC
Instance 5: running Test RPC