Remote Procedures

Ideally, remote procedures should be callable by a syntax similar to:

val=proxy->rp(arg1,arg2);
where proxy is an object on the calling thread that can forward the call to a remote object, call method rp on that remote object with arguments arg1 and arg2, return a value val if necessary.

Unfortunately, C++ syntax requires that the -> operator return an object that has a member rp, which is of little use if the desired object exists in a different address space. This could be addressed using the ->* operator, which is a true binary operator.

However, a more significant problem comes when trying to transport the arguments, and return a value. It is possible to write template functions that know the types of arguments and return values, and can pack these into the message buffer. Clearly, one needs to write a separate template for each argument count, but this is not too difficult a task in practice, and can be made extensible. The problem comes with transmitting the type information to the remote address space. The obvious solution of sending a function pointer to a template handler function simply does not work, as these have different values in different address spaces. The next obvious solution of sending a pointer to a template member of MPIslave also does not work, although the reason seems obscure. Possibly, it is impossible to obtain a pointer to a template member function. The final remaining solution is to create another classdesc action, however it is known that one cannot overload on the number of arguments to a member pointer argument. Classdesc, at present, is not very good at parsing function arguments.

So a more primitive remote procedure calling interface is required, and the one based on the streams model of MPIbuf works well and is reasonably intuitive:

MPIslace << &S::method << arg1 << arg2 << send(p);
This will run S::method on the slave processor, where method must be defined as:
void method(MPIbuf& args)
{
  X arg1; Y arg2; args>>arg1>>arg2;
  ...
  args.reset() << result;
}

The last statement is only needed if the method returns a value. This is sent as a message to the master.