For using the igraph C library
The igraph library is considered thread-safe if it has been compiled
with thread-local storage enabled, i.e. the IGRAPH_ENABLE_TLS
setting was toggled to ON
and the current platform
supports this feature. To check whether an igraph build is thread-safe, use the
IGRAPH_THREAD_SAFE
macro. When linking to external versions of igraph's dependencies, it is
the responsibility of the user to check that these dependencies were also
compiled to be thread-safe.
#define IGRAPH_THREAD_SAFE
This macro is defined to 1 if the current build of the igraph library is built in thread-safe mode, and 0 if it is not. A thread-safe igraph library attempts to use thread-local data structures instead of global ones, but note that this is not (and can not) be guaranteed for third-party libraries that igraph links to.
Note that igraph is only thread-safe if it was built with the internal ARPACK library, i.e. the one that comes with igraph. The standard ARPACK library is not thread-safe.
The default random number generator that igraph uses is not guaranteed to be thread-safe. You need to set a different random number generator instance for every thread that you want to use igraph from. This is especially important if you set the seed of the random number generator to ensure reproducibility; sharing a random number generator between threads would break reproducibility as the order in which the various threads are scheduled is random, and therefore they would still receive random numbers in an unpredictable order from the shared random number generator.
It is often useful to report the progress of some long calculation, to allow the user to follow the computation and guess the total running time. A couple of igraph functions support this at the time of writing, hopefully more will support it in the future.
To see the progress of a computation, the user has to install a
progress handler, as there is none installed by default.
If an igraph function supports progress reporting, then it
calls the installed progress handler periodically, and passes a
percentage value to it, the percentage of computation already
performed. To install a progress handler, you need to call
igraph_set_progress_handler()
. Currently there is a single
pre-defined progress handler, called igraph_progress_handler_stderr()
.
typedef igraph_error_t igraph_progress_handler_t(const char *message, igraph_real_t percent, void *data);
This is the type of the igraph progress handler functions.
There is currently one such predefined function,
igraph_progress_handler_stderr()
, but the user can
write and set up more sophisticated ones.
Arguments:
|
A string describing the function or algorithm
that is reporting the progress. Current igraph functions
always use the name |
|
Numeric, the percentage that was completed by the algorithm or function. |
|
User-defined data. Current igraph functions that report progress pass a null pointer here. Users can write their own progress handlers and functions with progress reporting, and then pass some meaningfull context here. |
Returns:
If the return value of the progress handler is not
|
igraph_progress_handler_t * igraph_set_progress_handler(igraph_progress_handler_t new_handler);
There is a single simple predefined progress handler:
igraph_progress_handler_stderr()
.
Arguments:
|
Pointer to a function of type
|
Returns:
Pointer to the previously installed progress handler function. |
Time complexity: O(1).
igraph_error_t igraph_progress_handler_stderr(const char *message, igraph_real_t percent, void* data);
This simple progress handler first prints message
, and then
the percentage complete value in a short message to standard error.
Arguments:
|
A string describing the function or algorithm
that is reporting the progress. Current igraph functions
always use the same |
|
Numeric, the percentage that was completed by the algorithm or function. |
|
User-defined data. Current igraph functions that report progress pass a null pointer here. Users can write their own progress handlers and functions with progress reporting, and then pass some meaningfull context here. |
Returns:
This function always returns with |
Time complexity: O(1).
#define IGRAPH_PROGRESS(message, percent, data)
The standard way to report progress from an igraph function
Arguments:
|
A string, a textual message that references the calculation under progress. |
|
Numeric scalar, the percentage that is complete. |
|
User-defined data, this can be used in user-defined progress handler functions, from user-written igraph functions. |
Returns:
If the progress handler returns with |
igraph_error_t igraph_progress(const char *message, igraph_real_t percent, void *data);
Note that the usual way to report progress is the IGRAPH_PROGRESS
macro, as that takes care of the return value of the progress
handler.
Arguments:
|
A string describing the function or algorithm
that is reporting the progress. Current igraph functions
always use the name |
|
Numeric, the percentage that was completed by the algorithm or function. |
|
User-defined data. Current igraph functions that report progress pass a null pointer here. Users can write their own progress handlers and functions with progress reporting, and then pass some meaningfull context here. |
Returns:
If there is a progress handler installed and
it does not return |
Time complexity: O(1).
igraph_error_t igraph_progressf(const char *message, igraph_real_t percent, void *data, ...);
This is a more flexible version of igraph_progress()
, with
a printf-like template string. First the template string
is filled with the additional arguments and then igraph_progress()
is called.
Note that there is an upper limit for the length of
the message
string, currently 1000 characters.
Arguments:
|
A string describing the function or algorithm
that is reporting the progress. For this function this is a
template string, using the same syntax as the standard
|
|
Numeric, the percentage that was completed by the algorithm or function. |
|
User-defined data. Current igraph functions that report progress pass a null pointer here. Users can write their own progress handlers and functions with progress reporting, and then pass some meaningfull context here. |
|
Additional argument that were specified in the
|
Returns:
If there is a progress handler installed and
it does not return |
To write a new progress handler, one needs to create a function of
type igraph_progress_handler_t
. The new progress handler
can then be installed with the igraph_set_progress_handler()
function.
One can assume that the first progress handler call from a
calculation will be call with zero as the percentage
argument,
and the last call from a function will have 100 as the percentage
argument. Note, however, that if an error happens in the
middle of a computation, then the 100 percent call might be
omitted.
If you want to write a function that uses igraph and supports
progress reporting, you need to include igraph_progress()
calls in your function, usually via the IGRAPH_PROGRESS()
macro.
It is good practice to always include a call to igraph_progress()
with a zero percentage
argument, before the
computation; and another call with 100 percentage
value
after the computation is completed.
It is also good practice not to call igraph_progress()
too
often, as this would slow down the computation. It might not be
worth to support progress reporting in functions with linear or
log-linear time complexity, as these are fast, even with a large
amount of data. For functions with quadratic or higher time
complexity make sure that the time complexity of the progress
reporting is constant or at least linear. In practice this means
having at most O(n) progress checks and at most 100
igraph_progress()
calls.
In multi-threaded programs, each thread has its own progress
handler, if thread-local storage is supported and igraph is
thread-safe. See the IGRAPH_THREAD_SAFE
macro for checking
whether an igraph build is thread-safe.
In addition to the possibility of reporting the progress of an
igraph computation via igraph_progress()
, it is also possible
to report simple status messages from within igraph functions,
without having to judge how much of the computation was performed
already. For this one needs to install a status handler function.
Status handler functions must be of type igraph_status_handler_t
and they can be installed by a call to igraph_set_status_handler()
.
Currently there is a simple predefined status handler function,
called igraph_status_handler_stderr()
, but the user can define
new ones.
igraph functions report their status via a call to the
IGRAPH_STATUS()
or the IGRAPH_STATUSF()
macro.
typedef igraph_error_t igraph_status_handler_t(const char *message, void *data);
Arguments:
|
The status message. |
|
Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here. |
Returns:
Error code. The current calculation will abort if you return anything
else than |
igraph_status_handler_t * igraph_set_status_handler(igraph_status_handler_t new_handler);
To uninstall the currently installed status handler, call this function with a null pointer.
Arguments:
|
The status handler function to install. |
Returns:
The previously installed status handler function. |
Time complexity: O(1).
igraph_error_t igraph_status_handler_stderr(const char *message, void *data);
A simple status handler function that writes the status message to the standard error.
Arguments:
|
The status message. |
|
Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here. |
Returns:
Error code. |
Time complexity: O(1).
#define IGRAPH_STATUS(message, data)
Typically this function is called only a handful of times from an igraph function. E.g. if an algorithm has three major steps, then it is logical to call it three times, to signal the three major steps.
Arguments:
|
The status message. |
|
Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here. |
Returns:
If the status handler returns with a value other than
|
#define IGRAPH_STATUSF(args)
This is the more flexible version of IGRAPH_STATUS()
,
having a printf-like syntax. As this macro takes variable
number of arguments, they must be all supplied as a single
argument, enclosed in parentheses. Then igraph_statusf()
is called with the given arguments.
Arguments:
|
The arguments to pass to |
Returns:
If the status handler returns with a value other than
|
igraph_error_t igraph_status(const char *message, void *data);
It calls the installed status handler function, if there is
one. Otherwise it does nothing. Note that the standard way to
report the status from an igraph function is the
IGRAPH_STATUS
or IGRAPH_STATUSF
macro, as these
take care of the termination of the calling function if the
status handler returns with IGRAPH_INTERRUPTED
.
Arguments:
|
The status message. |
|
Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here. |
Returns:
Error code. If a status handler function was called
and it did not return with |
Time complexity: O(1).
igraph_error_t igraph_statusf(const char *message, void *data, ...);
This is the more flexible version of igraph_status()
,
that has a syntax similar to the printf
standard C library function.
It substitutes the values of the additional arguments into the
message
template string and calls igraph_status()
.
Arguments:
|
Status message template string, the syntax is the same
as for the |
|
Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here. |
|
The additional arguments to fill the template given in the
|
Returns:
Error code. If a status handler function was called
and it did not return with |
← Chapter 30. Bipartite, i.e. two-mode graphs | Chapter 32. Non-graph related functions → |