Merge release-4-5-patches into release-4-6
[alexxy/gromacs.git] / include / gmx_detectcpu.h
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2  *
3  * 
4  * This file is part of GROMACS.
5  * Copyright (c) 2012-  
6  *
7  * Written by the Gromacs development team under coordination of
8  * David van der Spoel, Berk Hess, and Erik Lindahl.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * To help us fund GROMACS development, we humbly ask that you cite
16  * the research papers on the package. Check out http://www.gromacs.org
17  * 
18  * And Hey:
19  * Gnomes, ROck Monsters And Chili Sauce
20  */
21 #ifndef _GMX_detectcpu_H_
22 #define _GMX_detectcpu_H_
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 #if 0
28 } /* fixes auto-indentation problems */
29 #endif
30
31
32 /* Currently identifiable CPU Vendors */
33 typedef enum
34 {
35     GMX_DETECTCPU_VENDOR_UNKNOWN = 0,
36     GMX_DETECTCPU_VENDOR_INTEL,
37     GMX_DETECTCPU_VENDOR_AMD,
38     GMX_DETECTCPU_NVENDORS
39 }
40 gmx_detectcpu_vendorid_t;
41
42 /* Text strings corresponding to CPU vendors */
43 extern const char *
44 gmx_detectcpu_vendorid_string[GMX_DETECTCPU_NVENDORS];
45
46
47
48
49 /* CPU feature/property list, to be used as indices into the feature array of the
50  * gmxDetectCpu_t data structure.
51  *
52  * Always add entries to the end of this list, just before the last NFEATURES line.
53  * To keep the length of this list reasonable, we only add flags referring to
54  * features that we actually might have to check/use in Gromacs - feel free to add more.
55  *
56  * AMD and Intel are unfortunately gradually diverging, so while we can use the
57  * same type of intrinsic instruction functions in the source, the resulting binary
58  * is frequently not compatible starting from AVX.
59  */
60 typedef enum
61 {
62     GMX_DETECTCPU_FEATURE_CANNOTDETECT = 0,  /* Flag set if we could not detect on this CPU  */
63     GMX_DETECTCPU_FEATURE_X86_HTT,           /* Hyperthreading technology                    */
64     GMX_DETECTCPU_FEATURE_X86_SSE2,          /* SSE 2                                        */
65     GMX_DETECTCPU_FEATURE_X86_SSE4_1,        /* SSE 4.1                                      */
66     GMX_DETECTCPU_FEATURE_X86_RDRAND,        /* RDRAND high-quality hardware random numbers  */
67     GMX_DETECTCPU_FEATURE_X86_AES,           /* x86 advanced encryption standard accel.      */
68     GMX_DETECTCPU_FEATURE_X86_AVX,           /* Advanced vector extensions                   */
69     GMX_DETECTCPU_FEATURE_X86_FMA,           /* Fused-multiply add support (mainly for AVX)  */
70     GMX_DETECTCPU_FEATURE_X86_FMA4,          /* 4-operand FMA, only on AMD for now           */
71     GMX_DETECTCPU_FEATURE_X86_XOP,           /* AMD extended instructions, only AMD for now  */
72     GMX_DETECTCPU_FEATURE_X86_AVX2,          /* AVX2 including gather support (not used yet) */
73     GMX_DETECTCPU_FEATURE_X86_RDTSCP,        /* Serializing rdtscp instruction available     */
74     GMX_DETECTCPU_NFEATURES
75 }
76 gmx_detectcpu_feature_t;
77
78 /* Text strings for CPU feature indices */
79 extern const char *
80 gmx_detectcpu_feature_string[GMX_DETECTCPU_NFEATURES];
81
82
83 /* Currently supported acceleration instruction sets, intrinsics or other similar combinations
84  * in Gromacs. There is not always a 1-to-1 correspondence with feature flags; on some AMD
85  * hardware we prefer to use 128bit AVX instructions (although 256-bit ones could be executed),
86  * and we still havent written the AVX2 kernels.
87  */
88 typedef enum
89 {
90     GMX_DETECTCPU_ACCELERATION_NONE = 0,
91     GMX_DETECTCPU_ACCELERATION_X86_SSE2,
92     GMX_DETECTCPU_ACCELERATION_X86_SSE4_1,
93     GMX_DETECTCPU_ACCELERATION_X86_AVX_128_FMA,
94     GMX_DETECTCPU_ACCELERATION_X86_AVX_256,
95     GMX_DETECTCPU_NACCELERATIONS
96 }
97 gmx_detectcpu_acceleration_t;
98
99 /* Text strings for Gromacs acceleration/instruction sets */
100 extern const char *
101 gmx_detectcpu_acceleration_string[GMX_DETECTCPU_NACCELERATIONS];
102
103
104
105 #define GMX_DETECTCPU_STRLEN  64
106
107 /* Data structure with CPU detection information. Set by gmxDetectCpu().
108  * This is listed in the header for now, since we might want to access it in
109  * performance-sensitive part of the code where we don't want function calls.
110  */
111 typedef struct
112 {
113     gmx_detectcpu_vendorid_t  vendorid;
114     char                       brand[GMX_DETECTCPU_STRLEN];
115     int                        family;
116     int                        model;
117     int                        stepping;
118
119     char                       feature[GMX_DETECTCPU_NFEATURES];
120 }
121 gmx_detectcpu_t;
122
123
124
125 /* Fill the data structure by using CPU detection instructions.
126  * Return 0 on success, 1 if something bad happened.
127  */
128 int
129 gmx_detectcpu                   (gmx_detectcpu_t *              data);
130
131
132 /* Formats a text string (up to n characters) from the data structure.
133  * The output will have max 80 chars between newline characters.
134  */
135 int
136 gmx_detectcpu_formatstring       (gmx_detectcpu_t                data,
137                                   char *                         s,
138                                   int                            n);
139
140
141 /* Suggests a suitable gromacs acceleration based on the support in the
142  * hardware.
143  */
144 int
145 gmx_detectcpu_suggest_acceleration  (gmx_detectcpu_t                 data,
146                                      gmx_detectcpu_acceleration_t *  acc);
147
148 /* Check if this binary was compiled with the same acceleration as we
149  * would suggest for the current hardware. Always print stats to the log file
150  * if it is non-NULL, and print a warning in stdout if we don't have a match.
151  */
152 int
153 gmx_detectcpu_check_acceleration    (gmx_detectcpu_t                data,
154                                      FILE *                         log);
155
156
157 #ifdef __cplusplus
158 }
159 #endif
160
161
162 #endif /* _GMX_DETECTCPU_H_ */