Initializing Margo
In this tutorial, we will see how to initialize Margo.
Initializing a server
The following code initializes Margo for use as a server, then prints the address at which the server can be contacted.
#include <assert.h>
#include <stdio.h>
#include <margo.h>
int main(int argc, char** argv)
{
margo_instance_id mid = margo_init("tcp", MARGO_SERVER_MODE, 0, -1);
assert(mid);
hg_addr_t my_address;
margo_addr_self(mid, &my_address);
char addr_str[128];
size_t addr_str_size = 128;
margo_addr_to_string(mid, addr_str, &addr_str_size, my_address);
margo_addr_free(mid,my_address);
margo_set_log_level(mid, MARGO_LOG_INFO);
margo_info(mid, "Server running at address %s", addr_str);
margo_wait_for_finalize(mid);
return 0;
}
margo_init
creates a margo_instance_id
object. It takes four arguments.
The first one is protocol (here TCP). It is also possible to provide the address and port number to use.
The second argument specifies that Margo is initialized as a server.
The third argument indicates whether an Argobots execution stream (ES) should be created to run the
Mercury progress loop. If this argument is set to 0, the progress loop is going to run in the
context of the main ES (this should be the standard scenario, unless you have a good reason for not
using the main ES, such as the main ES using MPI primitives that could block the progress loop). A value
of 1 will make Margo create an ES to run the Mercury progress loop.
The fourth argument is the number of ES to create and use for executing RPC handlers. A value of 0 will
make Margo execute RPCs in the ES that called margo_init
. A value of -1 will make Margo execute the
RPCs in the ES running the progress loop. A positive value will make Margo create new ESs to run the RPCs.
margo_addr_self
is then used to get the address of the server, which is then converted into a string
using margo_addr_to_string
. The address returned by margo_addr_self
should be freed using
margo_addr_free
.
margo_wait_for_finalize
blocks the server in the Mercury progress loop until another ES calls
margo_finalize
. In this example, nothing calls margo_finalize
, so you will need to kill the server
manually if you run it.
Note
We use margo_info
to display information. This function is part of Margo’s logging feature,
which includes six logging levels: margo_trace
, margo_debug
, margo_info
,
margo_warning
, margo_error
, and margo_critical
. These functions take a margo
instance as first argument, a string format as second argument, and optional parameters.
Note that these functions will automatically add a n
at the end of the
provided string. The logging level can be set using margo_set_log_level
(see margo-logging.h).
Initializing a client
The following code initializes Margo for use as a client.
client.c (show/hide)
#include <assert.h>
#include <stdio.h>
#include <margo.h>
int main(int argc, char** argv)
{
margo_instance_id mid = margo_init("tcp",MARGO_CLIENT_MODE, 0, 0);
assert(mid);
margo_finalize(mid);
return 0;
}
We call margo_init
with MARGO_CLIENT_MODE
to indicate that this is a client.
Just like servers, clients have to run a Mercury progress loop. This progress loop can be
executed in the context of the main ES (by providing 0 as a third argument) or in a separate
ES (by providing 1). In general, a value of 0 is sufficient. Putting the Mercury progress
loop of a client in a separate ES is useful if the client uses non-blocking RPCs,
or if the client is multithreaded.
margo_finalize
is used to finalize the margo_instance_id
object.
Important
A margo instance initialized as a server (i.e. expected to receive RPCs) can also be used as a client (i.e. expected to send RPCs). There is no need to initialize multiple margo instances in the same process, and it is often a bad idea to do so as their respective progress loops will compete for network resources in an unpredictable manner.
Extended initialization
A margo_init_ext
function is provided that enables passing
configuration parameters as well as externally-initialized Argobots pools
and Mercury class/context. This function is explained in detail in
a latter section.