Welcome to Adams/Solver Subroutines - Kxcad.net
Welcome to Adams/Solver Subroutines - Kxcad.net
Welcome to Adams/Solver Subroutines - Kxcad.net
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