4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROningen Mixture of Alchemy and Childrens' Stories
40 /* This file is NOT threadsafe, but it is only used to create
41 * the innerloops during the build process, so it will never be
42 * executed by multiple threads.
50 #include <types/simple.h>
53 #define STRINGSIZE 1024
57 /* Most options are controlled by these defines.
58 * There are two major reasons for this:
59 * First, it makes the code somewhat less cluttered.
60 * Second, it makes it easier to introduce new interactions and/or
61 * change the code without changing all if statements - just set
62 * the options in mkinl.c and most things should follow automatically.
65 #define DO_FORCE (loop.do_force==TRUE)
66 #define DO_RF (loop.coul==COUL_RF)
67 #define DO_COULTAB (loop.coul==COUL_TAB)
68 #define DO_VDWTAB ((loop.vdw==VDW_TAB) || (loop.vdw==VDW_BHAMTAB))
69 #define DO_TAB (DO_COULTAB || DO_VDWTAB)
70 #define DO_BHAM ((loop.vdw==VDW_BHAM) || (loop.vdw==VDW_BHAMTAB))
71 #define DO_PREFETCH ((loop.sol==SOL_NO && (opt.prefetch & TYPE_NORMAL)) || \
72 (loop.sol==SOL_MNO && (opt.prefetch & TYPE_SOLVENT)) || \
73 (loop.sol==SOL_WATER && (opt.prefetch & TYPE_WATER)) || \
74 (loop.sol==SOL_WATERWATER && (opt.prefetch & TYPE_WATERWATER)))
76 #define DO_SOL (loop.sol==SOL_MNO) /* non-water solvent optimzations */
77 #define DO_WATER (loop.sol==SOL_WATER || loop.sol==SOL_WATERWATER)
78 #define DO_SOFTCORE (loop.free==FREE_SOFTCORE)
80 #define DO_VECTORIZE (loop.vectorize_invsqrt || loop.vectorize_recip)
82 /* For pure LJ-only loops we can save some cycles by just calculating the
83 * reciprocal. In all other cases we need to do the invsqrt
85 #define DO_INLINE_INVSQRT (loop.invsqrt && !loop.vectorize_invsqrt && opt.inline_invsqrt)
86 #define OVERWRITE_RSQ (!arch.vectorcpu && !loop.vdw_needs_r && !loop.vdw_needs_rsq && \
87 !loop.coul_needs_r && !loop.coul_needs_rsq)
88 /* Can we overwrite the vectorization array
89 * holding rsq with the resulting rinv or rinvsq,
90 * or do we need to keep rsq a while?
92 #define N_VDWPARAM (DO_BHAM ? 3 : 2)
94 /* Enumerations for different types of innerloops. These might be similar,
95 * but not identical, to some of the definitions in include/types/enums.h.
96 * Here we also need to take into account whether we use tables or not,
97 * and whether a certain innerloop should calculate free energy or not.
104 COUL_NORMAL
, /* ordinary coulomb, constant epsilon */
105 COUL_RF
, /* reaction field */
106 COUL_TAB
, /* tabulated interactions */
110 /* Alternatives for nonbonded interactions */
113 VDW_LJ
, /* Lennard-Jones 6-12 interactions */
114 VDW_BHAM
, /* Buckingham */
115 VDW_TAB
, /* tabulated interactions */
116 VDW_BHAMTAB
, /* Exponential tab, for buckingham interactions */
121 SOL_NO
, /* no water or solvent optimization */
122 SOL_MNO
, /* interactions with solvent consisting of N
123 * lj+coul atoms and M atoms with coul only */
124 SOL_WATER
, /* interactions with a 3-atom water molecule */
125 SOL_WATERWATER
, /* interactions between two water molecules */
131 FREE_LAMBDA
, /* A separate free energy innerloop (lambda) */
132 FREE_SOFTCORE
, /* is called for alpha=0 or lambda=0 or lambda=1, */
133 FREE_NR
/* to avoid if statements or extra table lookups. */
144 /* This is essentially a boolean telling for which loop types
145 * some features are enabled.
146 * Bit 0 concerns normal loops,
147 * bit 1 solvent loops and
148 * bit 2 water loops and
149 * bit 3 water-water loops.
151 typedef int looptype_t
;
153 #define TYPE_NORMAL 1
154 #define TYPE_SOLVENT 2
156 #define TYPE_WATERWATER 8
159 /* Global structure determining architectural options */
161 bool gmx_invsqrt
; /* Use gmx software invsqrt? */
169 /* Global structure determining optimization options */
171 bool inline_invsqrt
; /* Inline gmx software invsqrt */
173 bool decrease_lookup_latency
; /* try to hide invsqrt lookup penalty */
175 looptype_t vectorize_invsqrt
; /* vectorize distance calculation when possible */
176 bool vectorize_recip
; /* vector recip is not meaningful on water loops */
180 /* Global structure determining options for the individual
181 * loop currently being written
185 coul_t coul
; /* What kind of loop is this? */
189 bool do_force
; /* dont calc force in MC loop versions */
190 bool coul_needs_rinv
; /* Which power of r are needed for the */
191 bool coul_needs_rinvsq
; /* coulombic interactions? */
194 bool vdw_needs_rinv
; /* And for the nonbonded? */
195 bool vdw_needs_rinvsq
;
198 bool invsqrt
; /* tells what we are calculating */
200 bool vectorize_invsqrt
;
201 bool vectorize_recip
;
210 extern bool writeback
;
212 extern char loopname
[STRINGSIZE
];
214 extern int table_element_size
;
216 extern char forcebuf
[255];
217 extern char tabforcebuf
[255];
219 /* Exported routines from each file */
221 /* mkinl_declarations.c */
222 void file_header(void);
223 /* Adds include files for c, and calls fortran functions to be written
224 * at the top of the source file
226 void func_header(char *appendname
);
227 /* Writes the header with some info and assigns the function name
230 void func_args(void);
231 /* Declares function arguments to the variable buffer */
232 void func_localvars(void);
233 /* Declares function variables to the buffer */
234 void func_init_vars(void);
235 /* Initiates some local data before the outermost loop */
238 /* Outer loop routines found in mkinl_outerloop.c
240 void outer_loop(void);
241 /* Called to construct the loop over i particles, and in some
242 * cases also loops over e.g. threads.
246 /* Innerloop routines found in mkinl_innerloop.c
248 void inner_loop(bool calcdist
, bool calcforce
);
249 /* Constructs the loop over j particles in a neighbour list */
251 /* Invsqrt calculation, mkinl_invsqrt.c
253 int calc_invsqrt(void);
254 void invsqrt_vars(void);
255 void fortran_invsqrt(void);
256 int calc_recip(void);
257 void fortran_vecinvsqrt(void);
258 void fortran_vecsqrt(void);
261 /* The interactions, mkinl_interactions.c
264 void start_stripmine_loop(void);
265 void close_stripmine_loop(void);
267 void call_vectorized_routines(void);
269 int calc_interactions(void);
272 int calc_rinv_and_rinvsq(void);
274 int calc_rsquare(char *atom1
, char *atom2
);
276 void prefetch_forces(void);
278 void unpack_inner_data(bool calcdist
, bool calcforce
);
280 void fetch_coord(void);
282 int update_inner_forces(int i
,int j
);