igraph Reference Manual

For using the igraph C library

Search the manual:

Chapter 32. Advanced igraph programming

1. Using igraph in multi-threaded programs

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.

1.1. IGRAPH_THREAD_SAFE — Specifies whether igraph was built in thread-safe mode.

#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.

1.2. Thread-safe ARPACK library

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.

1.3. Thread-safety of random number generators

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.

2. Progress handlers

2.1.  About progress handlers

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().

2.2. Setting up progress handlers

2.2.1. igraph_progress_handler_t — Type of progress handler functions

typedef int 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: 

message:

A string describing the function or algorithm that is reporting the progress. Current igraph functions always use the name message argument if reporting from the same function.

percent:

Numeric, the percentage that was completed by the algorithm or function.

data:

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_SUCCESS, then igraph_progress() returns the error code IGRAPH_INTERRUPTED. The IGRAPH_PROGRESS() macro frees all memory and finishes the igraph function with error code IGRAPH_INTERRUPTED in this case.

2.2.2. igraph_set_progress_handler — Install a progress handler, or remove the current handler.

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: 

new_handler:

Pointer to a function of type igraph_progress_handler_t, the progress handler function to install. To uninstall the current progress handler, this argument can be a null pointer.

Returns: 

Pointer to the previously installed progress handler function.

Time complexity: O(1).

2.2.3. igraph_progress_handler_stderr — A simple predefined progress handler.

int 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: 

message:

A string describing the function or algorithm that is reporting the progress. Current igraph functions always use the same message argument if reporting from the same function.

percent:

Numeric, the percentage that was completed by the algorithm or function.

data:

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 IGRAPH_SUCCESS.

Time complexity: O(1).

2.3. Invoking the progress handler

2.3.1. IGRAPH_PROGRESS — Report progress.

#define IGRAPH_PROGRESS(message, percent, data)

The standard way to report progress from an igraph function

Arguments: 

message:

A string, a textual message that references the calculation under progress.

percent:

Numeric scalar, the percentage that is complete.

data:

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_INTERRUPTED, then this macro frees up the igraph allocated memory for temporary data and returns to the caller with IGRAPH_INTERRUPTED.

2.3.2. igraph_progress — Report progress

int 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: 

message:

A string describing the function or algorithm that is reporting the progress. Current igraph functions always use the name message argument if reporting from the same function.

percent:

Numeric, the percentage that was completed by the algorithm or function.

data:

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 IGRAPH_SUCCESS, then IGRAPH_INTERRUPTED is returned.

Time complexity: O(1).

2.3.3. igraph_progressf — Report progress, printf-like version

int 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: 

message:

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 libc printf function.

percent:

Numeric, the percentage that was completed by the algorithm or function.

data:

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 message argument.

Returns: 

If there is a progress handler installed and it does not return IGRAPH_SUCCESS, then IGRAPH_INTERRUPTED is returned. \return

2.4.  Writing progress handlers

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.

2.5.  Writing igraph functions with progress reporting

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.

2.6.  Multi-threaded programs

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.

3. Status handlers

3.1.  Status reporting

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 install 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.

3.2. Setting up status handlers

3.2.1. igraph_status_handler_t — The type of the igraph status handler functions

typedef int igraph_status_handler_t(const char *message, void *data);

Arguments: 

message:

The status message.

data:

Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here.

3.2.2. igraph_set_status_handler — Install of uninstall a status handler function.

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: 

new_handler:

The status handler function to install.

Returns: 

The previously installed status handler function.

Time complexity: O(1).

3.2.3. igraph_status_handler_stderr — A simple predefined status handler function.

int igraph_status_handler_stderr(const char *message, void *data);

A simple status handler function, that writes the status message to the standard errror.

Arguments: 

message:

The status message.

data:

Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here.

Returns: 

Error code.

Time complexity: O(1).

3.3. Invoking the status handler

3.3.1. IGRAPH_STATUS — Report the status of an igraph function.

#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: 

message:

The status message.

data:

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 IGRAPH_SUCCESS, then the function that called this macro returns as well, with error code IGRAPH_INTERRUPTED.

3.3.2. IGRAPH_STATUSF — Report the status from an igraph function

#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: 

args:

The arguments to pass to igraph_statusf().

Returns: 

If the status handler returns with a value other than IGRAPH_SUCCESS, then the function that called this macro returns as well, with error code IGRAPH_INTERRUPTED.

3.3.3. igraph_status — Report status from an igraph function.

int 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: 

message:

The status message.

data:

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 IGRAPH_SUCCESS, then IGRAPH_INTERRUPTED is returned by igraph_status().

Time complexity: O(1).

3.3.4. igraph_statusf — Report status, more flexible printf-like version.

int 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: 

message:

Status message template string, the syntax is the same as for the printf function.

data:

Additional context, with user-defined semantics. Existing igraph functions pass a null pointer here.

...:

The additional arguments to fill the template given in the message argument.

Returns: 

Error code. If a status handler function was called and it did not return with IGRAPH_SUCCESS, then IGRAPH_INTERRUPTED is returned by igraph_status().