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.