<div dir="ltr">Hi Shen,<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style="font-size:12.800000190734863px">Let's say we have two modules M1.bc and M2.bc, and in M1 we want to call function foo(defined in M2.bc)with the function type </span><span style="font-size:12.800000190734863px"><br></span></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">int foo(float, char*){...}<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">what basic steps do I need to do to make M1.bc call foo remotely?</blockquote><div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">There's currently no built in support for calling functions with signatures other than void(), int(), or int(int, char*[]).</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">To call a function with a different signature you have a couple of options:</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">(1) Generate a wrapper, encode the args, then decode the return:</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">void wrapper(void *inputs, void *output) {</div><div style="font-size:12.800000190734863px">  // args = decode(inputs)</div><div style="font-size:12.800000190734863px">  int result = foo(args...);</div><div style="font-size:12.800000190734863px">  // output = encode(result)</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">Then on the client end you have to write data to the inputs slab, send it to the server, call wrapper, read the outputs slab back, then decode it.</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">(2) If you know the signature of the function that you want to be able to call ahead of time, you can extend the JIT server's RPC endpoint to handle your function type. (We would just need to make the RPC endpoint in OrcRemoteTargetServer publicly visible for this to work, but that's an easy change):</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">// Declare your function pointer type.</div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">typedef int (*MyFuncType)(float, char*);</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><span style="font-size:12.800000190734863px">// Write a handler to call into a function of your type.</span></font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">int callMyFunc(JITTargetAddress MyFuncAddr, float Arg1, std::string Arg2) {</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">  MyFuncType MyFunc = (MyFuncType)MyFuncAddr;</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">  return MyFunc(Arg1, Arg2.c_str());</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">}</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace"><br></font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">// Write an RPC function definition.</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">class CallMyFunc : public llvm::orc::rpc::Function<CallMyFunc, int(JITTargetAddress, float, std::string)> {</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">public:</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">  static const char *getName() { return "CallMyFunc"; }</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">};</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace"><br></font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">// Register the callMyFunc function as a handler for CallMyFunc (the RPC definition) with the RPC endpoint. </font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">OrcRemoteTargetServer Server(...);</font></div><div style="font-size:12.800000190734863px"><font face="monospace, monospace">Server.getRPCEndpoint().addHandler<CallMyFunc>(callMyFunc);</font></div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">Now on your client you could write:</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">int Result = Client.getRPCEndpoint.callB<CallMyFunc>(3.141, "pi");</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">(3) If you don't know the signature of the function at server build type, you can write the code from part (2) and JIT it into the server after you connect. This would require us extending the OrcRemoteTargetRPC API with a "RegisterRPCExtension" function, but that should also be pretty easy.</div><div style="font-size:12.800000190734863px"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">BTW, does the RPCUtility supports handling pointers now?</blockquote></div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">It does not, and I doubt it ever will - I expect it to remain limited to value types only.</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">The aim of Orc RPC is to be good enough for basic cases, and especially for testing purposes, but we don't want it growing into a fully featured RPC library. That kind of use case would be better supported by writing a new client/server (out of tree) on top of a fully featured RPC library like GRPC or Cap'n Proto.</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">Cheers,</div><div style="font-size:12.800000190734863px">Lang. </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 18, 2017 at 6:04 PM, Shen Liu <span dir="ltr"><<a href="mailto:sxl463@cse.psu.edu" target="_blank">sxl463@cse.psu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi Lang,</div><div><br></div><div>Thanks for your reply! It seems that the code of ORC has been changed a lot these months. Actually what I wanted to see then was quite simple, Let's say we have two modules M1.bc and M2.bc, and in M1 we want to call function foo(defined in M2.bc)with the function type </div><div><br></div><div>int foo(float, char*){...}</div><div><br></div><div>what basic steps do I need to do to make M1.bc call foo remotely?</div><div><br></div><div>BTW, does the RPCUtility supports handling pointers now?</div><span class=""><div><br></div><div>Thanks very much!</div><div><br></div><div>Best regards,</div><div><br></div><div>Shen</div></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 13, 2017 at 9:13 PM, Lang Hames via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Shen,<div><br></div><div>The best place to look for examples is currently the RPCUtilsTest unit test: llvm/unittests/ExecutionEngine<wbr>/Orc/RPCUtilsTest.cpp</div><div><br></div><div>What API do you want to be able to call via RPC? If it's small I can probably write up an example for you.</div><div><br></div><div>Cheers,</div><div>Lang.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="m_-4979994946768006344h5">On Fri, Dec 16, 2016 at 7:37 AM, Shen Liu via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="m_-4979994946768006344h5"><div dir="ltr"><span style="font-family:arial,helvetica,sans-serif"><font style="font-size:12pt" size="3">Hi everyone,</font>

</span><p style="margin-bottom:0in;line-height:100%"><span style="font-family:arial,helvetica,sans-serif"><font style="font-size:12pt" size="3">I </font><font style="font-size:12pt" size="3">want </font><font style="font-size:12pt" size="3">to </font><font style="font-size:12pt" size="3">use an LLVM new feature (llvm::orc::remote::RPCBase) to implement a simple RPC framework </font><font style="font-size:12pt" size="3">between two </font><font style="font-size:12pt" size="3">LLVM modules. </font><font style="font-size:12pt" size="3">It seems by this new class we can do serialization/deserialization on LLVM IR type system directly. But I haven't found any helpful stuff on google showing me how to use these RPC APIs. Can anyone </font><font style="font-size:12pt" size="3">give me </font><font style="font-size:12pt" size="3">some hints or </font><font style="font-size:12pt" size="3">example programs showing me how to use </font><font style="font-size:12pt" size="3">these API correctly</font><font style="font-size:12pt" size="3">? </font><font style="font-size:12pt" size="3">Just a simple serialization/deserialization toy demo is OK, Thanks very much!</font></span></p><span style="font-family:arial,helvetica,sans-serif">

</span><p style="margin-bottom:0in;line-height:100%"><span style="font-family:arial,helvetica,sans-serif"><font style="font-size:12pt" size="3">Best regards,</font></span></p><span style="font-family:arial,helvetica,sans-serif">

</span><p style="margin-bottom:0in;line-height:100%"><span style="font-family:arial,helvetica,sans-serif"><font style="font-size:12pt" size="3">Shen</font></span></p>
<p style="margin-bottom:0in;line-height:100%"><br>
</p>

</div>
<br></div></div>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div>
<br>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div>