Purple Sage Computing Solutions, Inc.
Module fthreads Usage
This page is the entry point for the pages describing the module fthreads. This page contains links to the other pages, an introduction to programming using fthreads, a list of the types and constants defined by the module fthreads, and descriptions of the routines making up the fthreads trace facility. A selection of links is below.
A process is run by the operating system. Every process has its associated memory, executes its own instructions, and has a current state. A thread is a separate execution of the instructions, each thread has an associated state. (Examples of state are "executing", "suspended awaiting I/O", "arithmetic exception", and so on.) Each thread is scheduled by the operating system to run independently of other threads. A team is a group of threads, defined by by the programmer via fthreads. A synchronization object is a barrier, an event, a mutex or a semaphore.
When the Win32 system starts a process, it begins executing a thread called the primary thread. The primary thread can then start the running of other threads. Fortran programmers are mainly interested in using these extra threads to accellerate execution of numerically intensive programs. fthreads calls these extra threads worker threads. The idea is for your primary thread (the first thread, started by the operating system) to initialize the fthreads system, initialize any synchronization objects needed, start worker threads to perform the calculation, wait for the worker threads to complete their calculation, gather any statistics the programmer wants about program execution, and then terminate the fthreads system and print any statistics gathered.
fthreads also provides a trace facility to enable the programmer to follow the execution of a program using fthreads. Use of the trace facility is not necessary- to use it, simply declare one or more trace variables of type trace_t, initialize them via trace_init() and pass them to the various fthreads routines the program calls. The programmer can also add messages via trace_msg(). A trace variable is a variable of type trace_t, this type is defined in the fthreads module and so is available whenever fthreads is being used. Most fthreads routines accept a trace variable to trace their activities. The trace variable has a circular buffer of user defined size, set by the call to trace_init(). Each message has the date, time and system clock added to the message. All trace messages from fthreads routines contain the name of the routine making the message.
In order to take full advantage of the modern Fortran interface system, fthreads defines several types which are used to define variables used for different purposes. In addition to the above memtioned trace_t, fthreads also defines thread variables of type thread_t, barrier variables of type barrier_t, event variables of type event_t, mutex variables of type mutex_t and semaphore variables of type semaphore_t. Use of these types enables the compiler to check for correct usage of fthreads routines, so many errors may be caught at compile time, rather than as the cause of an obscure run time exception.
The execution of a process using fthreads will follow this general flow:
The fthreads defines several derived types. These types are listed below. They are available to the programmer whenever the fthreads module is used.
The fthreads constants include status and error codes, and Win32 defined values. These constants are listed below. Other fthreads constants have an fthread defined derived type, as noted below.
The trace routines are listed below, together with their interfaces. Note that many arguments are optional.
The trace_init() routine initializes a trace variable.
interface subroutine trace_init( max_msgs, & lock, trace_v, flag) integer, intent( in) :: max_msgs logical, optional, & intent( in) :: lock type( trace_t), & intent( out) :: trace_v integer, optional, & intent( out) :: flag end subroutine trace_init end interface
The trace variable trace_v is initialized with max_msgs entries for messages, if lock is true, the access to the trace variable is single threaded so the trace variable may be used from different threads. The integer flag should return with a value of fthread_ok.
The trace_msg() adds a message to a trace variable.
interface subroutine trace_msg( msg, code, & trace_v, flag) character( len= *), & intent( in) :: msg integer, optional, & intent( in) :: code type( trace_t), & intent( inout) :: trace_v integer, optional, & intent( out) :: flag end subroutine trace_msg end interface
The message msg is added to the trace variable trace_v with integer code formatted at the end of msg. If the trace variable is single threaded, it is locked. The msg has the date and time added at the beginning. The integer flag should return with a value of fthread_ok, or fthread_buffer_wrapped if the (circular) buffer is full and a message was overwritten.
The trace_print() prints the messages in a trace variable.
interface subroutine trace_print( log_unit, & trace_v, printed, flag) integer, optional, & intent( in) :: log_unit type( trace_t), & intent( inout) :: trace_v integer, optional, & intent( out) :: printed integer, optional, & intent( out) :: flag end subroutine trace_print end interface
The messages in the trace variable trace_v are printed on the unit log_unit. The number printed is returned in the integer printed, this number is at most max_msgs (see trace_init() above). The integer flag returns the status of the operation.
The trace_status() return trace variable statistics.
interface subroutine trace_status( trace_v, & msgs, printed, size, count) type( trace_t), & intent( in) :: trace_v integer, optional, & intent( out) :: msgs integer, optional, & intent( out) :: printed integer, optional, & intent( out) :: size integer, optional, & intent( out) :: count end subroutine trace_status end interface
The routine trace_status() returns the trace variable's statistics. The optional integer msgs returns the total number of messages which have been recorded in the trace variable. The optional integer printed returns the total number of messages printed. The optional integer size returns the number of messages the trace variable is capable of holding (set by the call to trace_init()). The optional integer count returns the number of messages currently in the trace variable, note that this message may be inaccurate in other threads are adding or printing messages.
Please see our Fact Sheet, or E-mail us for more information.