rpc_lesson2b

This example is identical to the rpc_lesson2 example except that 2 copies of the server are run instead of 1 via the copies model parameter.

C Version

Model Code:

 1#include "YggInterface.h"
 2#include <stdio.h>
 3
 4
 5int get_fibonacci(int n) {
 6  int pprev = 0, prev = 1, result = 1, fib_no = 1;
 7  while (fib_no < n) {
 8    result = prev + pprev;
 9    pprev = prev;
10    prev = result;
11    fib_no = fib_no + 1;
12  }
13  return result;
14};
15
16
17int main(int argc, char *argv[]) {
18  
19  int exit_code = 0;
20  char* model_copy = getenv("YGG_MODEL_COPY");
21  printf("Hello from C server%s!\n", model_copy);
22
23  // Create server-side rpc conneciton using model name
24  yggRpc_t rpc = yggRpcServer("server", "%d", "%d");
25
26  // Continue receiving requests until the connection is closed when all
27  // clients have disconnected.
28  int flag, n, result;
29  while (1) {
30    printf("server%s(C): receiving...\n", model_copy);
31    flag = rpcRecv(rpc, &n);
32    if (flag < 0) {
33      printf("server%s(C): end of input\n", model_copy);
34      break;
35    }
36
37    // Compute fibonacci number
38    printf("server%s(C): Received request for Fibonacci number %d\n",
39	   model_copy, n);
40    result = get_fibonacci(n);
41    printf("server%s(C): Sending response for Fibonacci number %d: %d\n",
42	   model_copy, n, result);
43
44    // Send response back
45    flag = rpcSend(rpc, result);
46    if (flag < 0) {
47      printf("server%s(C): ERROR sending\n", model_copy);
48      exit_code = -1;
49      break;
50    }
51  }
52
53  printf("Goodbye from C server%s\n", model_copy);
54  return exit_code;
55};
 1#include "YggInterface.h"
 2#include <stdio.h>
 3
 4
 5int main(int argc, char *argv[]) {
 6   
 7  int iterations = atoi(argv[1]);
 8  int client_index = atoi(argv[2]);
 9  int exit_code = 0;
10  printf("Hello from C client%d: iterations %d\n",
11	 client_index, iterations);
12  
13  // Set up connections matching yaml
14  // RPC client-side connection will be $(server_name)_$(client_name)
15  char rpc_name[100];
16  char log_name[100];
17  sprintf(rpc_name, "server_client%d", client_index);
18  sprintf(log_name, "output_log%d", client_index);
19  yggRpc_t rpc = yggRpcClient(rpc_name, "%d", "%d");
20  yggOutput_t log = yggOutputFmt(log_name, "fib(%-2d) = %-2d\n");
21
22  // Initialize variables
23  int ret = 0;
24  int fib = -1;
25  int i;
26
27  // Iterate over Fibonacci sequence
28  for (i = 1; i <= iterations; i++) {
29    
30    // Call the server and receive response
31    printf("client%d(C): Calling fib(%d)\n", client_index, i);
32    ret = rpcCall(rpc, i, &fib);
33    if (ret < 0) {
34      printf("client%d(C): RPC CALL ERROR\n", client_index);
35      exit_code = -1;
36      break;
37    }
38    printf("client%d(C): Response fib(%d) = %d\n", client_index, i, fib);
39
40    // Log result by sending it to the log connection
41    ret = yggSend(log, i, fib);
42    if (ret < 0) {
43      printf("client%d(C): SEND ERROR\n", client_index);
44      exit_code = -1;
45      break;
46    }
47  }
48
49  printf("Goodbye from C client%d\n", client_index);
50  return exit_code;
51    
52}
53

Model YAML:

1---
2
3model:
4  name: server
5  language: c
6  args: ./src/server.c
7  is_server: True  # Creates a RPC server queue called "server"
8  copies: 2
 1---
 2
 3models:
 4  - name: client1
 5    language: c
 6    args:
 7      - ./src/client.c
 8      - 3  # Pass the number of iterations that should be performed
 9      - 1  # Pass index of the client
10    client_of: server  # Creates an RPC client queue "server_client"
11    outputs: output_log1
12  - name: client2
13    language: c
14    args:
15      - ./src/client.c
16      - 5  # Pass the number of iterations that should be performed
17      - 2  # Pass index of the client
18    client_of: server  # Creates an RPC client queue "server_client"
19    outputs: output_log2
20
21connections:
22  - input: output_log1
23    output: client_output1.txt
24    in_temp: true
25  - input: output_log2
26    output: client_output2.txt
27    in_temp: true

C++ Version

Model Code:

 1#include "YggInterface.hpp"
 2#include <stdio.h>
 3
 4
 5int get_fibonacci(int n) {
 6  int pprev = 0, prev = 1, result = 1, fib_no = 1;
 7  while (fib_no < n) {
 8    result = prev + pprev;
 9    pprev = prev;
10    prev = result;
11    fib_no = fib_no + 1;
12  }
13  return result;
14};
15
16
17int main(int argc, char *argv[]) {
18  
19  int exit_code = 0;
20  char* model_copy = getenv("YGG_MODEL_COPY");
21  printf("Hello from C++ server%s!\n", model_copy);
22
23  // Create server-side rpc conneciton using model name
24  YggRpcServer rpc("server", "%d", "%d");
25
26  // Continue receiving requests until the connection is closed when all
27  // clients have disconnected.
28  int flag, n, result;
29  while (1) {
30    printf("server%s(C++): receiving...\n", model_copy);
31    flag = rpc.recv(1, &n);
32    if (flag < 0) {
33      printf("server%s(C++): end of input\n", model_copy);
34      break;
35    }
36
37    // Compute fibonacci number
38    printf("server%s(C++): Received request for Fibonacci number %d\n",
39	   model_copy, n);
40    result = get_fibonacci(n);
41    printf("server%s(C++): Sending response for Fibonacci number %d: %d\n",
42	   model_copy, n, result);
43
44    // Send response back
45    flag = rpc.send(1, result);
46    if (flag < 0) {
47      printf("server%s(C++): ERROR sending\n", model_copy);
48      exit_code = -1;
49      break;
50    }
51  }
52
53  printf("Goodbye from C++ server%s\n", model_copy);
54  return exit_code;
55};
 1#include "YggInterface.hpp"
 2#include <stdio.h>
 3
 4
 5int main(int argc, char *argv[]) {
 6   
 7  int iterations = atoi(argv[1]);
 8  int client_index = atoi(argv[2]);
 9  int exit_code = 0;
10  printf("Hello from C++ client%d: iterations %d\n",
11	 client_index, iterations);
12  
13  // Set up connections matching yaml
14  // RPC client-side connection will be $(server_name)_$(client_name)
15  char rpc_name[100];
16  char log_name[100];
17  sprintf(rpc_name, "server_client%d", client_index);
18  sprintf(log_name, "output_log%d", client_index);
19  YggRpcClient rpc(rpc_name, "%d", "%d");
20  YggOutput log(log_name, "fib(%-2d) = %-2d\n");
21  
22  // Initialize variables
23  int ret = 0;
24  int fib = -1;
25  char *logmsg = (char*)malloc(YGG_MSG_MAX*sizeof(char));
26  int i;
27
28  // Iterate over Fibonacci sequence
29  for (i = 1; i <= iterations; i++) {
30    
31    // Call the server and receive response
32    printf("client%d(C++): Calling fib(%d)\n", client_index, i);
33    ret = rpc.call(2, i, &fib);
34    if (ret < 0) {
35      printf("client%d(C++): RPC CALL ERROR\n", client_index);
36      exit_code = -1;
37      break;
38    }
39    printf("client%d(C++): Response fib(%d) = %d\n", client_index, i, fib);
40
41    // Log result by sending it to the log connection
42    ret = log.send(2, i, fib);
43    if (ret < 0) {
44      printf("client%d(C++): SEND ERROR\n", client_index);
45      exit_code = -1;
46      break;
47    }
48  }
49
50  free(logmsg);
51  printf("Goodbye from C++ client%d\n", client_index);
52  return exit_code;
53}

Model YAML:

1---
2
3model:
4  name: server
5  language: c++
6  args: ./src/server.cpp
7  is_server: True  # Creates a RPC server queue called "server"
8  copies: 2
 1---
 2
 3models:
 4  - name: client1
 5    language: c++
 6    args:
 7      - ./src/client.cpp
 8      - 3  # Pass the number of iterations that should be performed
 9      - 1  # Pass index of the client
10    client_of: server  # Creates an RPC client queue "server_client"
11    outputs: output_log1
12  - name: client2
13    language: c++
14    args:
15      - ./src/client.cpp
16      - 5  # Pass the number of iterations that should be performed
17      - 2  # Pass index of the client
18    client_of: server  # Creates an RPC client queue "server_client"
19    outputs: output_log2
20
21connections:
22  - input: output_log1
23    output: client_output1.txt
24    in_temp: true
25  - input: output_log2
26    output: client_output2.txt
27    in_temp: true

Fortran Version

Model Code:

 1program main
 2  use fygg
 3
 4  interface
 5     function get_fibonacci(n) result(out)
 6       integer, intent(in) :: n
 7       integer :: out
 8     end function get_fibonacci
 9  end interface
10
11  type(yggcomm) :: rpc
12  logical :: ret
13  integer :: fib, n
14  integer :: exit_code = 0
15  character(len=255) :: model_copy
16
17  call get_environment_variable("YGG_MODEL_COPY", model_copy)
18  write(*, '("Hello from Fortran server",A1,"!")') model_copy
19
20  ! Create server-side rpc conneciton using model name
21  rpc = ygg_rpc_server("server", "%d", "%d")
22
23  ! Initialize variables
24  ret = .true.
25  fib = -1
26
27  ! Continue receiving requests until the connection is closed when all
28  ! clients have disconnected.
29  do while (.TRUE.)
30     write(*, '("server",A1,"(F): receiving...")') model_copy
31     ret = ygg_recv_var(rpc, yggarg(n))
32     if (.not.ret) then
33        write(*, '("server",A1,"(F): end of input")') model_copy
34        exit
35     end if
36
37     ! Compute fibonacci number
38     write(*, '("server",A1,"(F): Received request for Fibonacci number ",i2)') model_copy, n
39     fib = get_fibonacci(n)
40     write(*, '("server",A1,"(F): Sending response for Fibonacci number ",i2,": ",i2)') model_copy, n, fib
41
42     ! Send response back
43     ret = ygg_send_var(rpc, yggarg(fib))
44     if (.not.ret) then
45        write(*, '("server",A1,"(F): ERROR sending")') model_copy
46        exit_code = -1;
47        exit;
48     end if
49  end do
50
51  write(*, '("Goodbye from Fortran server",A1)') model_copy
52  if (exit_code.lt.0) then
53     stop 1
54  end if
55
56end program main
57
58function get_fibonacci(n) result(out)
59  integer, intent(in) :: n
60  integer :: out
61  integer :: pprev, prev, fib_no
62  pprev = 0
63  prev = 1
64  out = 1
65  fib_no = 1
66  do while (fib_no < n)
67     out = prev + pprev
68     pprev = prev
69     prev = out
70     fib_no = fib_no + 1
71  end do
72end function get_fibonacci
 1program main
 2  use fygg
 3
 4  character(len=32) :: arg
 5  integer :: iterations, client_index
 6  type(yggcomm) :: rpc
 7  type(yggcomm) :: log
 8  logical :: ret
 9  integer :: fib, i
10  integer :: exit_code = 0
11  character(len=100) :: rpc_name
12  character(len=100) :: log_name
13
14  call get_command_argument(1, arg)
15  read(arg, *) iterations
16  call get_command_argument(2, arg)
17  read(arg, *) client_index
18  write(*, '("Hello from Fortran client",i1,": iterations ",i2)') &
19       client_index, iterations
20
21  ! Set up connections matching yaml
22  ! RPC client-side connection will be $(server_name)_$(client_name)
23  write(rpc_name, '("server_client",i1)') client_index
24  write(log_name, '("output_log",i1)') client_index
25  rpc = ygg_rpc_client(trim(rpc_name), "%d", "%d")
26  log = ygg_output_fmt(trim(log_name), "fib(%-2d) = %-2d\n")
27
28  ! Initialize variables
29  ret = .true.
30  fib = -1
31
32  ! Iterate over Fibonacci sequence
33  do i = 1, iterations
34
35     ! Call the server and receive response
36     write(*, '("client",i1,"(F): Calling fib(",i2,")")') &
37          client_index, i
38     ret = ygg_rpc_call(rpc, yggarg(i), yggarg(fib))
39     if (.not.ret) then
40        write(*, '("client",i1,"(F): RPC CALL ERROR")') client_index
41        exit_code = -1;
42        exit
43     end if
44     write(*, '("client",i1,"(F): Response fib(",i2,") = ",i2)') &
45          client_index, i, fib
46
47     ! Log result by sending it to the log connection
48     ret = ygg_send_var(log, [yggarg(i), yggarg(fib)])
49     if (.not.ret) then
50        write(*, '("client",i1,"(F): SEND ERROR")') client_index
51        exit_code = -1
52        exit
53     end if
54
55  end do
56
57  write(*, '("Goodbye from Fortran client",i1)') client_index
58  if (exit_code.lt.0) then
59     stop 1
60  end if
61
62end program main

Model YAML:

1---
2
3model:
4  name: server
5  language: fortran
6  args: ./src/server.f90
7  is_server: True  # Creates a RPC server queue called "server"
8  copies: 2
 1---
 2
 3models:
 4  - name: client1
 5    language: fortran
 6    args:
 7      - ./src/client.f90
 8      - 3  # Pass the number of iterations that should be performed
 9      - 1  # Pass index of the client
10    client_of: server  # Creates an RPC client queue "server_client"
11    outputs: output_log1
12  - name: client2
13    language: fortran
14    args:
15      - ./src/client.f90
16      - 5  # Pass the number of iterations that should be performed
17      - 2  # Pass index of the client
18    client_of: server  # Creates an RPC client queue "server_client"
19    outputs: output_log2
20
21connections:
22  - input: output_log1
23    output: client_output1.txt
24    in_temp: true
25  - input: output_log2
26    output: client_output2.txt
27    in_temp: true

Julia Version

Model Code:

 1using Yggdrasil
 2using Printf
 3
 4
 5function get_fibonacci(n)
 6  global pprev = 0
 7  global prev = 1
 8  global result = 1
 9  global fib_no = 1
10  while (fib_no < n)
11    global result = prev + pprev
12    global pprev = prev
13    global prev = result
14    global fib_no = fib_no + 1
15  end
16  return Int64(result)
17end
18
19
20function main()
21
22  model_copy = ENV["YGG_MODEL_COPY"]
23  @printf("Hello from Julia server%s!\n", model_copy)
24
25  # Create server-side rpc conneciton using model name
26  rpc = Yggdrasil.YggInterface("YggRpcServer", "server", "%d", "%d")
27
28  # Continue receiving requests until the connection is closed when all
29  # clients have disconnected.
30  while (true)
31    @printf("server%s(Julia): receiving...\n", model_copy)
32    retval, rpc_in = rpc.recv()
33    if (!retval)
34      @printf("server%s(Julia): end of input\n", model_copy)
35      break
36    end
37
38    # Compute fibonacci number
39    n = rpc_in[1]
40    @printf("server%s(Julia): Received request for Fibonacci number %d\n", model_copy, n)
41    result = get_fibonacci(n)
42    @printf("server%s(Julia): Sending response for Fibonacci number %d: %d\n", model_copy, n, result)
43
44    # Send response back
45    flag = rpc.send(result)
46    if (!flag)
47      error(sprintf("server%s(Julia): ERROR sending\n", model_copy))
48    end
49  end
50  
51  println("Goodbye from Julia server")
52end
53
54main()
 1using Yggdrasil
 2using Printf
 3
 4
 5function main(iterations, client_index)
 6    
 7  @printf("Hello from Julia client: iterations = %d\n", iterations)
 8
 9  # Set up connections matching yaml
10  # RPC client-side connection will be $(server_name)_$(client_name)
11  rpc = Yggdrasil.YggInterface("YggRpcClient", @sprintf("server_client%d", client_index), "%d", "%d")
12  log = Yggdrasil.YggInterface("YggOutput", @sprintf("output_log%d", client_index), "fib(%-2d) = %-2d\n")
13
14  # Iterate over Fibonacci sequence
15  for i = 1:iterations
16        
17    # Call the server and receive response
18    @printf("client%d(Julia): Calling fib(%d)\n", client_index, i)
19    ret, result = rpc.call(i)
20    if (!ret)
21      error(@sprintf("client%d(Julia): RPC CALL ERROR", client_index))
22    end
23    fib = result[1]
24    @printf("client%d(Julia): Response fib(%d) = %d\n", client_index, i, fib)
25
26    # Log result by sending it to the log connection
27    ret = log.send(i, fib)
28    if (!ret)
29      error(@sprintf("client%d(Julia): SEND ERROR", client_index))
30    end
31  end
32
33  @printf("Goodbye from Julia client%d\n", client_index)
34end
35
36    
37main(parse(Int64, ARGS[1]), parse(Int64, ARGS[2]))

Model YAML:

1---
2
3model:
4  name: server
5  language: julia
6  args: ./src/server.jl
7  is_server: True  # Creates a RPC server queue called "server"
8  copies: 2
 1---
 2
 3models:
 4  - name: client1
 5    language: julia
 6    args:
 7      - ./src/client.jl
 8      - 3  # Pass the number of iterations that should be performed
 9      - 1  # Pass index of the client
10    client_of: server  # Creates an RPC client queue "server_client"
11    outputs: output_log1
12  - name: client2
13    language: julia
14    args:
15      - ./src/client.jl
16      - 5  # Pass the number of iterations that should be performed
17      - 2  # Pass index of the client
18    client_of: server  # Creates an RPC client queue "server_client"
19    outputs: output_log2
20
21connections:
22  - input: output_log1
23    output: client_output1.txt
24    in_temp: true
25  - input: output_log2
26    output: client_output2.txt
27    in_temp: true

Matlab Version

Model Code:

 1function server()
 2
 3  model_copy = getenv('YGG_MODEL_COPY');
 4  fprintf('Hello from Matlab server%s!\n', model_copy);
 5
 6  % Create server-side rpc conneciton using model name
 7  rpc = YggInterface('YggRpcServer', 'server', '%d', '%d');
 8
 9  % Continue receiving requests until the connection is closed when all
10  % clients have disconnected.
11  while true
12    fprintf('server%s(M): receiving...\n', model_copy);
13    [retval, rpc_in] = rpc.recv();
14    if (~retval);
15      fprintf('server%s(M):end of input\n', model_copy);
16      break;
17    end;
18
19    % Compute fibonacci number
20    n = rpc_in{1};
21    fprintf('server%s(M): Received request for Fibonacci number %d\n', model_copy, n);
22    pprev = 0;
23    prev = 1;
24    result = 1;
25    fib_no = 1;
26    while fib_no < n
27      result = prev + pprev;
28      pprev = prev;
29      prev = result;
30      fib_no = fib_no + 1;
31    end;
32    fprintf('server%s(M): Sending response for Fibonacci number %d: %d\n', model_copy, n, result);
33
34    % Send response back
35    flag = rpc.send(int32(result));
36    if (~flag);
37      error(sprintf('server%s(M): ERROR sending', model_copy));
38    end;
39  end;
40
41  fprintf('Goodbye from Matlab server%s\n', model_copy);
42  
43end
 1function client(iterations, client_index)
 2  
 3  iterations = str2num(iterations);
 4  client_index = str2num(client_index);
 5  fprintf('Hello from Matlab client%d: iterations = %d\n', ...
 6          client_index, iterations);
 7
 8  % Set up connections matching yaml
 9  % RPC client-side connection will be $(server_name)_$(client_name)
10  rpc_name = sprintf('server_client%d', client_index);
11  log_name = sprintf('output_log%d', client_index);
12  rpc = YggInterface('YggRpcClient', rpc_name, '%d', '%d');
13  log = YggInterface('YggOutput', log_name, 'fib(%-2d) = %-2d\n');
14
15  % Iterate over Fibonacci sequence
16  for i = 1:iterations
17    
18    % Call the server and receive response
19    fprintf('client%d(Matlab): Calling fib(%d)\n', client_index, i);
20    [ret, result] = rpc.call(int32(i));
21    if (~ret);
22      error(sprintf('client%d(Matlab): RPC CALL ERROR\n', client_index));
23    end;
24    fib = result{1};
25    fprintf('client%d(Matlab): Response fib(%d) = %d\n', client_index, ...
26            i, fib);
27
28    % Log result by sending it to the log connection
29    ret = log.send(int32(i), fib);
30    if (~ret);
31      error(sprintf('client%d(Matlab): SEND ERROR\n', client_index));
32    end;
33  end;
34
35  fprintf('Goodbye from Matlab client%d\n', client_index);
36  
37end

Model YAML:

1---
2
3model:
4  name: server
5  language: matlab
6  args: ./src/server.m
7  is_server: True  # Creates a RPC server queue called "server"
8  copies: 2
 1---
 2
 3models:
 4  - name: client1
 5    language: matlab
 6    args:
 7      - ./src/client.m
 8      - 3  # Pass the number of iterations that should be performed
 9      - 1  # Pass index of the client
10    client_of: server  # Creates an RPC client queue "server_client"
11    outputs: output_log1
12  - name: client2
13    language: matlab
14    args:
15      - ./src/client.m
16      - 5  # Pass the number of iterations that should be performed
17      - 2  # Pass index of the client
18    client_of: server  # Creates an RPC client queue "server_client"
19    outputs: output_log2
20
21connections:
22  - input: output_log1
23    output: client_output1.txt
24    in_temp: true
25  - input: output_log2
26    output: client_output2.txt
27    in_temp: true

Python Version

Model Code:

 1import os
 2import numpy as np
 3from yggdrasil.interface.YggInterface import YggInput, YggRpcServer
 4
 5
 6def get_fibonacci(n):
 7    r"""Compute the nth number of the Fibonacci sequence.
 8
 9    Args:
10        n (int): Index of the Fibonacci number in the Fibonacci sequence that
11            should be returned.
12
13    Returns:
14        int: The nth Fibonacci number.
15
16    """
17    pprev = 0
18    prev = 1
19    result = 1
20    fib_no = 1
21    while fib_no < n:
22        result = prev + pprev
23        pprev = prev
24        prev = result
25        fib_no = fib_no + 1
26    return result
27
28
29def main():
30    r"""Function to execute server communication and computation in a loop."""
31
32    print('Hello from Python server%s!' % os.environ['YGG_MODEL_COPY'])
33
34    # Get parameters
35    inp = YggInput("params")
36    retval, params = inp.recv()
37    if not retval:
38        raise RuntimeError('server%s: ERROR receiving parameters'
39                           % os.environ['YGG_MODEL_COPY'])
40    print('server%s: Parameters = %s'
41          % (os.environ['YGG_MODEL_COPY'], params))
42
43    # Create server-side rpc conneciton using model name
44    rpc = YggRpcServer("server", "%d", "%d")
45
46    # Continue receiving requests until the connection is closed when all
47    # clients have disconnected.
48    while True:
49        print('server%s: receiving...' % os.environ['YGG_MODEL_COPY'])
50        retval, rpc_in = rpc.recv()
51        if not retval:
52            print('server: end of input')
53            break
54
55        # Compute fibonacci number
56        n = rpc_in[0]
57        print('server%s: Received request for Fibonacci number %d'
58              % (os.environ['YGG_MODEL_COPY'], n))
59        result = get_fibonacci(n)
60        print('server%s: Sending response for Fibonacci number %d: %d'
61              % (os.environ['YGG_MODEL_COPY'], n, result))
62
63        # Send response back
64        flag = rpc.send(np.int32(result))
65        if not flag:
66            raise RuntimeError('server%s: ERROR sending'
67                               % os.environ['YGG_MODEL_COPY'])
68
69    print('Goodbye from Python server%s' % os.environ['YGG_MODEL_COPY'])
70
71    
72if __name__ == '__main__':
73    main()
 1import sys
 2import numpy as np
 3from yggdrasil.interface.YggInterface import (
 4    YggRpcClient, YggOutput)
 5
 6
 7def main(iterations, client_index):
 8    r"""Function to execute client communication with server that computes
 9    numbers in the Fibonacci sequence.
10
11    Args:
12        iterations (int): The number of Fibonacci numbers to log.
13        client_index (int): Index of the client in total list of clients.
14
15    """
16
17    print('Hello from Python client%d: iterations = %d ' % (client_index,
18                                                            iterations))
19
20    # Set up connections matching yaml
21    # RPC client-side connection will be $(server_name)_$(client_name)
22    rpc = YggRpcClient("server_client%d" % client_index, "%d", "%d")
23    log = YggOutput("output_log%d" % client_index, 'fib(%-2d) = %-2d\n')
24
25    # Iterate over Fibonacci sequence
26    for i in range(1, iterations + 1):
27        
28        # Call the server and receive response
29        print('client%d(Python): Calling fib(%d)' % (client_index, i))
30        ret, result = rpc.call(np.int32(i))
31        if not ret:
32            raise RuntimeError('client%d(Python): RPC CALL ERROR' % client_index)
33        fib = result[0]
34        print('client%d(Python): Response fib(%d) = %d' % (client_index, i, fib))
35
36        # Log result by sending it to the log connection
37        ret = log.send(np.int32(i), fib)
38        if not ret:
39            raise RuntimeError('client%d(Python): SEND ERROR' % client_index)
40
41    print('Goodbye from Python client%d' % client_index)
42
43    
44if __name__ == '__main__':
45    # Take number of iterations from the first argument and the
46    # client index from the second
47    main(int(sys.argv[1]), int(sys.argv[2]))

Model YAML:

 1---
 2
 3model:
 4  name: server
 5  language: python
 6  args: ./src/server.py
 7  is_server: True  # Creates a RPC server queue called "server"
 8  copies: 2
 9  inputs:
10    name: params
11    default_file:
12      name: ./Input/server_params.txt
13      filetype: ascii
 1---
 2
 3models:
 4  - name: client1
 5    language: python
 6    args:
 7      - ./src/client.py
 8      - 3  # Pass the number of iterations that should be performed
 9      - 1  # Pass index of the client
10    client_of: server  # Creates an RPC client queue "server_client"
11    outputs: output_log1
12  - name: client2
13    language: python
14    args:
15      - ./src/client.py
16      - 5  # Pass the number of iterations that should be performed
17      - 2  # Pass index of the client
18    client_of: server  # Creates an RPC client queue "server_client"
19    outputs: output_log2
20
21connections:
22  - input: output_log1
23    output: client_output1.txt
24    in_temp: true
25  - input: output_log2
26    output: client_output2.txt
27    in_temp: true

R Version

Model Code:

 1library(yggdrasil)
 2
 3
 4get_fibonacci <- function(n) {
 5  pprev = 0
 6  prev = 1
 7  result = 1
 8  fib_no = 1
 9  while (fib_no < n) {
10    result = prev + pprev
11    pprev = prev
12    prev = result
13    fib_no = fib_no + 1
14  }
15  return(as.integer(result))
16}
17
18
19main <- function() {
20
21  model_copy = Sys.getenv('YGG_MODEL_COPY')
22  fprintf('Hello from R server%s!', model_copy)
23
24  # Create server-side rpc conneciton using model name
25  rpc <- YggInterface('YggRpcServer', "server", "%d", "%d")
26
27  # Continue receiving requests until the connection is closed when all
28  # clients have disconnected.
29  while (1) {
30    fprintf('server%s(R): receiving...', model_copy)
31    c(retval, rpc_in) %<-% rpc$recv()
32    if (!retval) {
33      fprintf('server%s(R): end of input', model_copy)
34      break
35    }
36
37    # Compute fibonacci number
38    n = rpc_in[[1]]
39    fprintf('server%s(R): Received request for Fibonacci number %d', model_copy, n)
40    result = get_fibonacci(n)
41    fprintf('server%s(R): Sending response for Fibonacci number %d: %d', model_copy, n, result)
42
43    # Send response back
44    flag <- rpc$send(result)
45    if (!flag) {
46      stop(sprintf('server%s(R): ERROR sending', model_copy))
47    }
48    
49  }
50
51  fprintf('Goodbye from R server%s', model_copy)
52}
53
54main()
 1library(yggdrasil)
 2
 3
 4main <- function(iterations, client_index) {
 5
 6  fprintf('Hello from Python client: iterations = %d ', iterations)
 7
 8  # Set up connections matching yaml
 9  # RPC client-side connection will be $(server_name)_$(client_name)
10  rpc <- YggInterface('YggRpcClient',
11                      sprintf("server_client%d", client_index), "%d", "%d")
12  log <- YggInterface('YggOutput',
13                      sprintf("output_log%d", client_index), 'fib(%-2d) = %-2d\n')
14
15  # Iterate over Fibonacci sequence
16  for (i in 1:iterations) {
17        
18    # Call the server and receive response
19    fprintf('client%d(R): Calling fib(%d)', client_index, i)
20    c(ret, result) %<-% rpc$call(i)
21    if (!ret) {
22      stop(sprintf('client%d(R): RPC CALL ERROR', client_index))
23    }
24    fib <- result[[1]]
25    fprintf('client%d(R): Response fib(%d) = %d', client_index, i, fib)
26
27    # Log result by sending it to the log connection
28    ret <- log$send(i, fib)
29    if (!ret) {
30      stop(sprintf('client%d(R): SEND ERROR', client_index))
31    }
32  }
33
34  fprintf('Goodbye from R client%d', client_index)
35}
36
37
38args = commandArgs(trailingOnly=TRUE)
39main(strtoi(args[[1]]), strtoi(args[[2]]))

Model YAML:

1---
2
3model:
4  name: server
5  language: R
6  args: ./src/server.R
7  is_server: True  # Creates a RPC server queue called "server"
8  copies: 2
 1---
 2
 3models:
 4  - name: client1
 5    language: R
 6    args:
 7      - ./src/client.R
 8      - 3  # Pass the number of iterations that should be performed
 9      - 1  # Pass index of the client
10    client_of: server  # Creates an RPC client queue "server_client"
11    outputs: output_log1
12  - name: client2
13    language: R
14    args:
15      - ./src/client.R
16      - 5  # Pass the number of iterations that should be performed
17      - 2  # Pass index of the client
18    client_of: server  # Creates an RPC client queue "server_client"
19    outputs: output_log2
20
21connections:
22  - input: output_log1
23    output: client_output1.txt
24    in_temp: true
25  - input: output_log2
26    output: client_output2.txt
27    in_temp: true