% /*@@ % @file ThornWriters.tex % @date 27 Jan 1999 % @author Gabrielle Allen, Tom Goodale, Gerd Lanfermann % @desc % Thorn writer's guide part of the Cactus User's Guide % @enddesc % @version $Header$ % @@*/ \begin{cactuspart}{2}{Application thorn writing}{$RCSfile$}{$Revision$} \renewcommand{\thepage}{\Alph{part}\arabic{page}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Overview} This chapter goes into the nitty-gritty of writing a thorn. It introduces key concepts for thorns, then goes on to give a brief outline of how to configure a thorn. There is then some detail about concepts introduced by the configuration step, followed by discussion of code which you must put into your files in order to use Cactus functionality, and details of utility functions you may use to gain extra functionality. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Thorn concepts} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Thorns} A thorn is the basic working module within Cactus. All user-supplied code goes into thorns, which are, by and large, independent of each other. Thorns communicate with each other via calls to the flesh API, plus, more rarely, custom APIs of other thorns. The connection from a thorn to the flesh or to other thorns is specified in configuration files which are parsed at compile time and used to generate glue code which encapsulates the external appearence of a thorn. Thorn names must be (case independently) unique, must start with a letter, and can only contain letters, numbers or underscores. In addition, a thorn cannot have the name {\t doc}, this is reserved for arrangement documentation. Arrangement names which start with a `\#', or finish with `\~{}' or `.bak' will be ignored. \section{Arrangements} Thorns are grouped into {\em arrangements}. This is a logical grouping of thorns which is purely for organisational purposes. For example, you might wish to keep all your initial data thorns in one arrangement, and all your evolution thorns in another arrangement, or you may want to have separate arrangements for your developments, private and shared thorns. The arrangements live in the {\tt arrangements} directory off the main Cactus directory. Arrangement names must be (case independently) unique, must start with a letter, and can only contain letters, numbers or underscores. Arrangement names which start with a `\#', or finish with `\~{}' or `.bak' will be ignored. Inside an arrangement directory there are directories for each thorn belonging to the arrangement. \section{Implementations} \label{sec:im} One of the key concepts for thorns is the concept of the {\bf implementation}. Relationships between thorns are all based upon relationship between the {\bf implementations} they provide. In principle it should be possible to swap one thorn providing an implementation with another thorn providing that implementation, without affecting any other thorn. An {\bf implementation} defines a group of variables and parameters which are used to implement some functionality. For example the thorn {\tt CactusPUGH/PUGH} provides the implementation {\it driver}. This implementation is responsible for providing memory for grid variables and for communication. Another thorn can also implement {\tt driver}, and both thorns can be compiled in {\em at the same time}. At runtime, the user can decide which thorn providing {\tt driver} is used. No other thorn should be affected by this choice. When a thorn decides it needs access to a variable or a parameter provided by another thorn, it defines a relationship between itself and the other thorn's {\bf implementation}, not explicitly with the other {\bf thorn}. This allows the transparent replacement, at compile or runtime, of one thorn with another thorn providing the same functionality as seen by the other thorns. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Anatomy of a thorn} \label{sec:anofath} \section{Thorns} \label{sec:th} A thorn consists of a subdirectory of an arrangement containing three administrative files \begin{Lentry} \item[{\tt interface.ccl}] the cactus interface, which defines the grid functions, variables, etc. See \ref{sec:in}. \item[{\tt param.ccl}] the parameters introduced by this thorn, and the parameters needed from other thorns. See \ref{sec:pa}. \item[{\tt schedule.ccl}] scheduling information for routines called by the flesh. See \ref{sec:sc} \end{Lentry} Thorns can also contain \begin{itemize} \item a subdirectory called {\tt src}, which should hold source files and compilation instructions for the thorn \item a subdirectory {\tt src/include} for include files \item a {\tt README} containing a brief description of the thorn \item a {\tt doc} directory for documentation \item a {\tt par} directory for example parameter files \item a {\tt test} subdirectory may also be added, to hold the thorn's testsuite. See \ref{sec:adatesu} for details. \end{itemize} \section{Creating a thorn} To simplify the creation of a thorn, a make target {\tt gmake newthorn} has been provided. When this is run: \begin{enumerate} \item{} You will be prompted for the name of the new thorn. \item{} You will be prompted for the name of the arrangement you would like to include your thorn in. Either enter a new arrangement name or pick one from the list of available arrangements that are shown. \end{enumerate} \section{Configuring your thorn} The interaction of a thorn with the flesh and other thorns is controlled by various configuration files. These consist of: \begin{Lentry} \item [{\tt interface.ccl}] This defines the {\bf implementation} (Section~\ref{sec:im}) the thorn provides, and the variables the thorn needs, along with their visibility to other implementations. \item [{\tt param.ccl}] This defines the parameters that are used to control the thorn, along with their visibility to other implementations. \item [{\tt schedule.ccl}] This defines which functions from the thorn are called and when they are called. It also handles memory and communication assignment for grid variables. \end{Lentry} \subsection{General syntax of CCL files} CCL {\bf Cactus Configuration Language} files are simple text files used to define configuration information for a thorn. CCL files are case independent, and may contain comments introduced by the `\#' character, which indicates that the rest of the line is a comment. If the last non-blank character of a line in a CCL file is a backslash {\tt $\backslash$}, the following line is treated as a continuation of the current line. \subsection{The {\tt interface.ccl}} The {\tt interface.ccl} file is used to declare \begin{itemize} \item the implementation provided by the thorn, \item the variables provided by the thorn \item the include files provided by the thorn \item the functions provided by the thorn (in development) \end{itemize} The implementation is declared by a single line at the top of the file \begin{verbatim} implements: \end{verbatim} Where {\tt } can be any combination of alphanumeric characters and underscores, and is case independent. There are three different access levels available for variables \begin{Lentry} \item[{\tt Public}] Can be `inherited' by other implementations (see below). \item[{\tt Protected}] Can be shared with other implementations which declare themselves to be friends of this one (see below). \item[{\tt Private}] Can only be seen by this thorn. \end{Lentry} Corresponding to the first two access levels there are two relationship statements that can be used to get variables from other thorns. \begin{Lentry} \item [{\tt Inherits: }] This gets all {\tt Public} variables from implementation {\tt }, and all variables that {\tt } has in turn inherited. An implementation may inherit from any number of other implementations. \item [{\tt Friend: }] This gets all {\tt Protected} variables from implementation {\tt }, but, unlike {\tt inherits} it also pushes its own implementations {\tt Protected} variables onto implementation {\tt }. This keyword is used to define a group of implementations which all end up with the same {\tt Protected} variables. \end{Lentry} So, for example, an {\tt interface.ccl} starting \begin{verbatim} implements: wavetoy inherits: grid friend: wave_extract \end{verbatim} declares that the thorn provides an implementation called `wavetoy', gets all the {\tt public} variables declared by an implementation called `grid', and shares all {\tt protected} variables with {\tt wave\_extract} and its friends. Cactus variables, described in Section~\ref{sec:cava} are placed in groups with homogeneous attributes, where the attributes describe properties such as the data type, group type, dimenension, ghostsize, number of timelevels, type of staggering and distribution. For example, a group, called {\tt realfields} of 5 real grid functions ({\tt phi}, {\tt a}, {\tt b}, {\tt c}, {\tt d}), on a 3D grid, would be defined by \begin{verbatim} CCTK_REAL realfields type=GF TimeLevels=3 Dim=3 { phi a,b,c,d } "Example grid functions"\end{verbatim} or, for a group called {\tt intfields} consisting of just one distributed 2D array of integers, \begin{verbatim} CCTK_INT intfields type=ARRAY size=xsize,ysize ghostsize=gxsize,gysize { anarray } "My 2D arrays" \end{verbatim} where {\tt xsize}, {\tt ysize}, {\tt gxsize}, {\tt gysize} are all parameters defined in the thorns {\tt param.ccl}. By default all groups are {\tt private}, to change this an access specification of the form {\tt public:} or {\tt protected:} (or {\tt private:} to change it back) may be placed on a line by itself. This changes the access level for any group defined in the file from that point on. All variables seen by any one thorn must have distinct names. \subsection{The {\tt param.ccl}} Users control the operation of thorns via parameters given in a file at runtime. The {\tt param.ccl} is used to specify the parameters used to control an individual thorn, and to specify the values these parameters are allowed to take. When the code is run it reads a parameter file and sets the parameters if they fall within the allowed values. If a parameter is not assigned in a parameter file, it is given its default value. There are three access levels available for parameters: \begin{Lentry} \item [{\tt Global}] These parameters are seen by all thorns. \item [{\tt Restricted}] These parameters may be used by other implementations if they so desire. \item [{\tt Private}] These are only seen by this thorn. \end {Lentry} A parameter specification consists of: \begin{itemize} \item the parameter type (each may have an optional {\t CCTK\_} in front) \begin{Lentry} \item [{\tt REAL}] \item [{\tt INT}] \item [{\tt KEYWORD}] A distinct string with only a few known allowed values. \item [{\tt STRING}] An arbitrary string, which must conform to a given regular expression. \item [{\tt BOOLEAN}] A boolean type which can take values 1, `t', `true', `yes' or 0, `f', `false', `no'. \end{Lentry} \item the parameter name \item a {\tt description} of the parameter \item an allowed value block --- This consists of a brace delimited block of lines describing the allowed values of the parameter. Each range may have a description associated with it by placing a :: on the line and putting the description afterwards. \item the default value --- This must be one of the allowed values. \end{itemize} For the numeric types {\tt INT} and {\tt REAL}, a range consists of a string of the forms lower-bound:upper-bound:step where a missing number or a * denotes anything (i.e. infinite bounds or an infinitesimal step). For example \begin{verbatim} REAL Coeff "Important coefficient" { 0:3.14 :: "Range has to be from zero to Pi, default is zero" } 0.0 #No need to define a range for BOOLEAN BOOLEAN nice "Nice weather ?" { }"yes" # A example for a set of keywords and its default (which has to be # defined in the body) KEYWORD confused "Are we getting confused ?" { "yes" :: "absolutely positively" "perhaps" :: "we are not sure" "never" :: "never" } "never" \end{verbatim} defines a REAL parameter, a BOOLEAN parameter, and a KEYWORD. By default all parameters are {\tt private}, to change this an access specification of the form {\tt global:} or {\tt restricted:} (or {\tt private:} to change it back) may be placed on a line by itself. This changes the access level for any parameter defined in the file from that point on. To access {\tt restricted} parameters from another implementation, a line containing {\tt shares: } declares that all parameters mentioned in the file from now until the next access specification originate in implementation {\tt }. Each of these parameters must be qualified by the initial token {\tt USES} or {\tt EXTENDS}, where \begin{Lentry} \item[{\tt USES}] indicates that the parameters range remains unchanged. \item[{\tt EXTENDS}] indicates that the parameters range is going to be extended. \end{Lentry} In contrast to parameter declarations in other access blocks, the default value must be omitted - it is impossible to set the default value of any parameter not originating in this thorn. For example, the following block adds possible values to the keyword {\tt initial\_data} originally defined in the implementation {\tt einstein}, and uses the real parameter {\tt speed}. \begin{verbatim} shares:einstein EXTENDS KEYWORD initial_data { "bl_bh" :: "Brill Lindquist black holes" "misner_bh" :: "Misner black holes" "schwarzschild" :: "One Schwarzschild black hole" } USES CCTK_REAL speed \end{verbatim} Note that you must compile at least one thorn which implements {\tt einstein}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The {\tt schedule.ccl}} \label{subsec:schedule_ccl} By default no routine of a thorn will be run. The {\tt schedule.ccl} file defines those that should be run and when they should be run. The specification of this is via a schedule block which consists of lines of the form \begin{verbatim} schedule at