The obvious drawback of the function netsolve() is that while the computation is being performed remotely, the user must wait to regain control of the prompt. To address this drawback, we provide a nonblocking function, netsolve_nb(). The user can then do work in parallel and check for the completion of the request later. He can even send multiple requests to NetSolve. Thanks to the load-balancing strategy implemented in the NetSolve agent, all these requests will be solved on different machines if possible, achieving some NetSolve-parallelism. Let us now describe this function with the eig example.
As in the section called Calling netsolve() to perform computation, the user creates a 300 × 300 matrix and calls NetSolve:
>> a = rand(300); >> [r] = netsolve_nb('send','eig',a)
Let us resume our example and see what NetSolve answers to the first call to netsolve_nb():
>> [r] = netsolve_nb('send','eig',a) Sending Input to Server zoot.cs.utk.edu rd->request_id = 0 r = 0 >>
netsolve_nb() returns a request handler: 0. This request handler will be used in the subsequent calls to the function. The request is being processed on cupid, and the result will eventually return. The user can obtain this result in one of two ways. The first one is to call netsolve_nb() with the 'probe' action:
>> [status] = netsolve_nb('probe',r)
netsolve_nb() returns the status of a pending request. The right-hand side contains the action, as is required for netsolve_nb(), and the request handler. This call returns immediately, and prints a message. Here are the two possible scenarios:
>> [status] = netsolve_nb('probe',r) Not ready yet status = -1 ... >> [status] = netsolve_nb('probe',r) Result available status = 1
To obtain the result of the computation one must call netsolve_nb() with the 'wait' action:
>> [x y] = netsolve_nb('wait',r) Downloading Output from Server zoot.cs.utk.edu x = y = 10.1204 0 -0.9801 0.8991 -0.9801 -0.8991 -1.0195 0 -0.6416 0.6511 ... ... ... ...
As with the netsolve() function, one can merge the real part and the imaginary part into a single complex vector. The typical scenario is to call netsolve_nb() with the action 'send', then make repeated calls with the action 'probe' until there is nothing more to do than wait for the result. The user then calls netsolve_nb() with the action 'wait'. It is of course possible to call netsolve_nb() with the action 'wait' before making any call with the action 'probe'. One last action can be passed to netsolve_nb(), as shown here:
>> a=rand(100); b = rand(150); >> [r1] = netsolve_nb('send','eig',a) Sending Input to Server zoot.cs.utk.edu rd->request_id = 0 r1 = 0 >> [r2] = netsolve_nb('send','eig',b) Sending Input to Server zoot.cs.utk.edu rd->request_id = 1 r2 = 1
>> netsolve_nb('status') --- NetSolve: pending requests --- Requests #0: 'eig', submitted to zoot.cs.utk.edu (184.108.40.206) was started 24 seconds ago. netsolveProbeRequest returned: 1, ns_errno = 0 Completed Requests #1: 'eig', submitted to zoot.cs.utk.edu (220.127.116.11) was started 7 seconds ago. netsolveProbeRequest returned: 1, ns_errno = 0 Completed
The user can check what requests he has sent so far and obtain an estimation of the completion times. By using the 'status' action, the user can also determine whether a request is still running or has been completed. By sending multiple non-blocking requests to NetSolve and relying on the agent for load balancing, the user can achieve parallelism.