Skip to main content

prefx (c38b2)

CHARMM Preprocessing

There is a CHARMM preprocessor, PREFX (formerly PREFLX), which
reads source files as input and produces fortran files for subsequent
compilation. The main purpose of this preprocessor is to allow a single
version of the source code to work with all platforms and compile options.
A summary of preflx capabilities:
1. Allows selective compile of machine specific code
2. Allows selected features to be not compiled (to reduce memory needs)
3. Supports a size directive to allow larger (and smaller) versions.
4. Handles the inclusion of .fcm files in a general manner
5. Allows alternate include file directory to be specified
6. Allows code expansion for alternate compiles
(can move IFs from a DO loop).
7. Allows comments on source lines following a "!"
8. Handles the conversion to single precision (CRAY, DEC alpha,...)
9. Identifies unwanted tabs in the source code
10. Checks for line lengths exceeding 72 for non-comments
11. Allows processing multiple files from a list (Macintosh version).
12. Allows the removal of "IMPLICIT NONE" from source files.

The source files have the extension ".src".
These files are processed by the preprocessor (PREFX)

* Conditional | Conditional compilation directives
* Listing | Keyword listing directives
* Expansion | Code expansion directives
* Reserved | Preprocessor reserved words
* Keywords | Some important keywords


Conditional compilation is controlled by simple directives. The directives
all start with "##" in the first column. Global keywords should be in upper
case and have multiple letters (local keywords use single character or lower
case). ##IF constructs can be nested (up to 40 levels).

##IF keyword(s) (match-token) ! process code if any keyword is active.
##ELIF keyword(s) (match-token) ! after and IF or IFN,
alternate processing.
##ELSE (match-token) ! after and IF, ELIF, or IFN,
process the rest.
##ERROR 'message' ! indicates an error within a
##IF construct
(usually after a ##ELSE condition).
Note: single quotes are required.
##ENDIF (match-token) ! terminates IF, IFN, ELSE,
or ELIF constructs.
##IFN keyword(s) (match-token) ! process code if no keyword is active.

keywords:: A set of one or more keyword that may be specified in pref.dat
or in an ##EXPAND construct (see below).

match-token :: unique text string in parentheses; must be the
same for each use in an ##IF ... ##ENDIF block

Example (from fcm/dimens.fcm):

##IFN VECTOR PARVECT (maxvec_spec)
integer(chm_int),PARAMETER :: MAXVEC = 10
##ELIF LARGE XLARGE (maxvec_spec)
integer(chm_int),PARAMETER :: MAXVEC = 4000
##ELIF MEDIUM (maxvec_spec)
integer(chm_int),PARAMETER :: MAXVEC = 2000
##ELIF SMALL (maxvec_spec)
integer(chm_int),PARAMETER :: MAXVEC = 2000
##ELIF XSMALL (maxvec_spec)
integer(chm_int),PARAMETER :: MAXVEC = 1000
##ELSE (maxvec_spec)
##ERROR 'Unrecognized size directive in DIMENS.FCM.'
##ENDIF (maxvec_spec)

When multiple keywords are specified, an "OR" condition is implied.
IF an "AND" condition is required, use a nested ##IF construct.
In the example above, MAXVEC will not be 10 if either VECTOR or
PARVECT is specified.

The text ".not." may be added before a keyname to test for its inverse.
For example, the following constructs are equivalent:


but these are not equivalent:

This is because the the first will select when both are false but the second
will select when either is false.

Selective compilation may also be done using on a single line using
a "!##" construct. The syntax is:
standard-fortran-line !## keyword(s) ! comments

A space is not required between the "!##" and the keyword list.
For example the following constructs are equivalent:

Standard format:

Compact format (with comments):
QLONGL=.TRUE. !##LONGLINE ! specify the QLONGL flag
QLONGL=.FALSE. !##.not.LONGLINE ! based on compilation options

Both "and" and "or" conditions can be used for one line processing:
!##PERT !##PARALLEL - An "AND" conditional compile
!##PERT PARALLEL - An "OR" conditional compile

NOTE: To assist the automatic ##IF checking utilities, please do not place
## characters in the source code (other than on comment lines) unless
absolutely necessary.

Keyword listing directives;

Inserts a fortran write lines of all current keywords to the selected
write unit. "unit" may be a variable name or a number but it is limited
to 8 characters maximum.
##KEYWORDS FILL count array
Fills an integer count variable with the number of current keys and
also fill a character*12 array in the program with the current keys.
Count and array variable names are limited to 8 characters maximum.


For computational intensive routines which are not too large, code expansion
may be used to increase efficiency. This is achieved by moving constant IF
conditions to the outside of major loops. Code expansion is optional and (if
done properly) the code should function in both expanded and unexpanded forms.
This means that the code should be written and tested in an unexpanded
form and then retested with expansion enabled.

##EXPAND local-flag(s) .when. conditional-flag(s) (identifier)

Expand subcommands control section (immediately following the ##EXPAND):
##PASS1 flag1 flag2 ...
##PASS2 flag1 flag2 ...
##PASS3 ... - code sections and conditions for each pass
##PASS[n] ...
##EXFIN - code section for the termination of the expand section
##EXEND - end of expansion specification
##ENDEX (identifier)
(the identifier is required and must match the corresponding ##EXPAND).
For each pass, the specified flags are temporarily set (or .not. set)
as requested. If all of the conditions for the code expansion (flags
specified after the .when. construct) are not set, then all flags from
the ##EXPAND line (before the .when.) are temporarily set and no code
expansion is processed.

Example (from nbonds/enbfs8.src):
!--- Do block expansion of code
##EXPAND B forces .when. BLOCK EXPAND (expand_block)
##PASS1 .not.forces
##PASS2 forces
##PASS3 .not.BLOCK forces

mainloop: DO I=1,NATOMX ! Begin of main loop
frcloop: IF (.NOT. NOFORC) THEN !##B
##IF forces
ENDIF frcloop !##B
ENDDO mainloop ! End of main loop

##ENDEX (expand_block)
END subroutine enbfs8

This example will do a multi pass compilation when BOTH the
"EXPAND" and the "BLOCK" keywords are set. If they are not both
set, then the local flags "B" and "forces" will be set until
the corresponding ##ENDEX is reached. If the "EXPAND" and "BLOCK"
conditions are met, then the body of the expanded section will be
compiled three times.
PASS1 - additional active flag: disabled flag: forces
PASS2 - additional active flag: forces disabled flag:
PASS3 - additional active flag: forces disabled flag: BLOCK


The following keywords are reserved:
END - The end of keywords in pref.dat (END is not a keyword)
SINGLE - Conversion to single precision (SINGLE is a keyword)
PUTFCM - Include files are to be copied into fortran files
VMS - Use VMS directory names (from DEC's DCL)
REMIMPNON - Remove any "IMPLICIT NONE" lines found in the source
FCMDIR - Specification of include file directory
UPPERCASE - Convert all non-text code to uppercase Fortran
LONGLINE - Allows a longer line output format (>80 characters).
SAVEFCM - Include all SAVE statements
EXPAND - Do semi-automatic code expansion
single-letter - reserved for unexpanded compile conditionals
lower-case - reserved for local compile flags (within a routine)
IF IFN ELIF ELSE ENDIF - prefx logic
KEYWORDS LIST FILL - prefx macro.
ERROR - stop preprocessing and exit with error code

Other Keyword Rules
- Keyword may not exceed 12 characters in length.
- Global keywords must be all uppercase
- Local keywords must be all lowercase
- Keywords should otherwise follow fortran standards for naming
- Recommendation: Avoid one and two letter keywords (harder to find)

preflx.dat or pref.dat are the preprocessor instruction data files.
Create a file preflx.dat or pref.dat (with UNIX) that contains
one or more of the keywords specified below. On UNIX platforms,
generates the default pref.dat file in build/{machine_type} directory.
"END" keyword stops parsing keywords.

The use of a (Match-Token) can help to identify the components of ##IF
blocks in source files that make heavy use of ## directives; it should
follow any keywords, and must be appended to all components of a given
##IF block. It should always be used with the exception of very short
non-embedded ##IF blocks. See the code for more examples.


A complete list of all compile flags and options WITH SUITABLE DESCRIPTIONS
will be found in the documentation file *note » preflx_list ::
It can change much between released CHARMM versions.

The information list here highlights reserved keywords and other basic
information that is unlikely to change between versions.

[1] Include File Directory
FCMDIR=directory_name ! point to a particular directory
FCMDIR=CURRENT ! use what is specified in the include line.
FCMDIR=LOCAL ! use the local directory.

[2] Machine Type (choose exactly one)
ALPHA = DEC alpha workstation
APOLLO = HP-Apollo, both AEGIS and UNIX
CONVEX = Convex Computer
CRAY = Cray Research Inc.
HPUX = Hewlett-Packard series 700.
IBM = IBM-3090 running AIX
IRIS = Silicon Graphics
SUN = Sun Microsystems

Other machine descriptors
GNU = using GNU Fortran compiler
GRAPE = Use MD-GRAPE-II board to speedup nonbond calculations
LOBOS = LoBoS cluster specific code

Parallel machine types
ALPHAMP = DEC Alpha Multi Processor machines
SGIMP = machine type = SGI Power Challenge
T3D = Cray massively parallel (DEC Alpha chip)
T3E = Cray massively parallel (DEC Alpha chip)
TERRA = multiprocessor DEC Alpha chip system

[3] Operating system (choose at most one)
OS2 = IBM pre-emptive multitasking

[4] Size directive (must choose exactly one)
XXLARGE =360720 atom limit
XLARGE =240480 atom limit
LARGE = 60120 atom limit
MEDIUM = 25140 atom limit
REDUCE = 15000 atom limit
SMALL = 6120 atom limit
XSMALL = 2040 atom limit

[5] Machine Architecture (may choose several)
SCALAR = machine characteristics = default for scalar machines
VECTOR = feature directive * = Vectorized routines
PARVECT = Parallel vector code (multi processor vector machines)
CRAYVEC = Fast vector code (standard vector code)
SINGLE = specifies single precision version (primarily used for CRAY)
SGIF90 = Used to compile CHARMM using F90 compiler on SGI machines
T3ETRAJ = Used to read t3e trajectories on IEEE machines
w/ 32 bit integers

[6] Parallel CHARMM descriptors
(all require the PARALLEL keyword)
» preflx_list Parallel::

[7] Feature directives
» preflx_list Feature::

[8] Graphics keywords; choose only one (except on Apollo)
GLDISPLAY = use the GL display code for the graphics window (*)
NODISPLAY = no graphics window; PostScript, other files produced
NOGRAPHICS = graphics code not compiled
XDISPLAY = use the X11 display code for the graphics window

(*) the GL code is relatively untested, and may have problems

[9] Keywords Not for Normal Use
» preflx_list Unnorm::

[10] Major Blocks that can be Removed, but normally are not.
» preflx_list NOINC::

[11] Other Control Directives
EXPAND = Do semi-automatic code expansion
LONGLINE = Allows a longer line output format (>80 characters).
SAVEFCM = Include all SAVE statements in .fcm files
SINGLE = Conversion to single precision (SINGLE is a keyword)
PUTFCM = Include files are to be copied into fortran files
VMS = Use VMS directory names (from DEC's DCL)
REMIMPNON = Remove any "IMPLICIT NONE" lines found in the source
UPPERCASE = Convert all non-text code to uppercase Fortran

By employing appropriate preprocessor keys, one can generate a
variant of CHARMM for a specific machine with specific features.