02.04.2013 Views

Welcome to Adams/Solver Subroutines - Kxcad.net

Welcome to Adams/Solver Subroutines - Kxcad.net

Welcome to Adams/Solver Subroutines - Kxcad.net

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Welcome</strong> <strong>to</strong> <strong>Adams</strong>/<strong>Solver</strong> <strong>Subroutines</strong><br />

be made about user-written subroutines. Consequently, by default, all user-written subroutines are<br />

executed serially. By default, no user-supplied subroutine will take advantage of the parallel capabilities<br />

of <strong>Adams</strong>/<strong>Solver</strong> (C++).<br />

Because complex models often use user-written subroutines extensively, it can greatly improve<br />

performance <strong>to</strong> execute these in parallel, as well. If this is <strong>to</strong> be done, you must ensure that the userwritten<br />

subroutine and its dependants are threadsafe. If so, the user-written subroutine can indicate this<br />

with a call <strong>to</strong> ADAMS_DECLARE_THREADSAFE. This call should occur during subroutine<br />

initialization (iflag = true). <strong>Adams</strong>/<strong>Solver</strong> (C++) then permits threads <strong>to</strong> make simultaneous calls <strong>to</strong> that<br />

user-written subroutine. For more information, see the PREFERENCES statement.<br />

Writing Threadsafe Code<br />

While a complete guide <strong>to</strong> writing parallel code is left <strong>to</strong> other texts, a few general points are covered<br />

here.<br />

Code can be made thread-safe by eliminating any possibility for data (program variables) <strong>to</strong> be shared<br />

between different threads. For example, if all variables in a user-written subroutine were either passed in<br />

as arguments or are dynamically allocated local variables, then that user-written subroutine would be<br />

threadsafe.<br />

Coding in such a manner, however, is often not practical. There may be a need for a user-written<br />

subroutine <strong>to</strong> access constant tabular data or other parameters, which is most efficiently implemented as<br />

global data and shared by multiple threads. To allow for this, during subroutine initialization, all userwritten<br />

subroutines are run serially. In addition, calls <strong>to</strong> REQSUBs are always performed serially.<br />

General Guidelines<br />

1. The only data that can be modified at any time is:<br />

Dynamically allocated local variables.<br />

Static or global variable that are uniquely indexed so there is no possibility that two threads will<br />

modify them simultaneously. For example, a user-written subroutine with a static array of data<br />

could safely modify the array element that is uniquely mapped <strong>to</strong> the ID of the current modeling<br />

element being evaluated. Because each thread is evaluating a different modeling element, the<br />

threads will not access the same array element at the same time.<br />

2. All data that will be shared by multiple threads must be allocated and set during subroutine<br />

initialization. At other times, this data may be read, but must not be written <strong>to</strong>.<br />

3. No special coding practices need <strong>to</strong> be followed inside a REQSUB.<br />

FORTRAN-Specific Guidelines<br />

1. Some FORTRAN compilers (such as Digital/Compaq Visual FORTRAN) statically allocate<br />

local variables by default. This is avoided by using a compiler option (/au<strong>to</strong>matic) that causes all<br />

local variables <strong>to</strong> be allocated on the stack (unless the SAVE statement is used).<br />

9

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!