Upped the version to 3.2.0
[gromacs.git] / src / gmxlib / mkinl.h
blobeb5da08b646aaf8b4f9d0c6219ac8ff71f476bce
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.2.0
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
33 * And Hey:
34 * GROningen Mixture of Alchemy and Childrens' Stories
37 #ifndef _mkinl_h
38 #define _mkinl_h
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.
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
50 #include <types/simple.h>
51 #include <metacode.h>
53 #define STRINGSIZE 1024
55 #define WATERATOMS 3
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.
101 /* Electrostatics */
102 typedef enum {
103 COUL_NO,
104 COUL_NORMAL, /* ordinary coulomb, constant epsilon */
105 COUL_RF, /* reaction field */
106 COUL_TAB, /* tabulated interactions */
107 COUL_NR
108 } coul_t;
110 /* Alternatives for nonbonded interactions */
111 typedef enum {
112 VDW_NO,
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 */
117 VDW_NR
118 } vdw_t;
120 typedef enum {
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 */
126 SOL_NR
127 } sol_t;
129 typedef enum {
130 FREE_NO,
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. */
134 } free_t;
137 typedef enum {
138 THREAD_NO,
139 THREAD_MUTEX,
140 THREAD_STRIDE
141 } thread_t;
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
155 #define TYPE_WATER 4
156 #define TYPE_WATERWATER 8
159 /* Global structure determining architectural options */
160 typedef struct {
161 bool gmx_invsqrt; /* Use gmx software invsqrt? */
162 thread_t threads;
163 bool simplewater;
164 bool vectorcpu;
165 bool cray_pragma;
166 } arch_t;
169 /* Global structure determining optimization options */
170 typedef struct {
171 bool inline_invsqrt; /* Inline gmx software invsqrt */
172 looptype_t prefetch;
173 bool decrease_lookup_latency; /* try to hide invsqrt lookup penalty */
174 bool delay_invsqrt;
175 looptype_t vectorize_invsqrt; /* vectorize distance calculation when possible */
176 bool vectorize_recip; /* vector recip is not meaningful on water loops */
177 } opt_t;
180 /* Global structure determining options for the individual
181 * loop currently being written
184 typedef struct {
185 coul_t coul; /* What kind of loop is this? */
186 vdw_t vdw;
187 sol_t sol;
188 free_t free;
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? */
192 bool coul_needs_rsq;
193 bool coul_needs_r;
194 bool vdw_needs_rinv; /* And for the nonbonded? */
195 bool vdw_needs_rinvsq;
196 bool vdw_needs_rsq;
197 bool vdw_needs_r;
198 bool invsqrt; /* tells what we are calculating */
199 bool recip;
200 bool vectorize_invsqrt;
201 bool vectorize_recip;
202 int ni;
203 int nj;
204 } loop_t;
207 extern arch_t arch;
208 extern opt_t opt;
209 extern loop_t loop;
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
228 * to each loop
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);
271 int calc_dist(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);
284 #endif