1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
|
//------------------------------------------------------------------------------
// GB_compiler.h: handle compiler variations
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
#ifndef GB_COMPILER_H
#define GB_COMPILER_H
#define GB_COMPILER_NVCC 0
#define GB_COMPILER_ICX 0
#define GB_COMPILER_ICC 0
#define GB_COMPILER_CLANG 0
#define GB_COMPILER_GCC 0
#define GB_COMPILER_MSC 0
#define GB_COMPILER_XLC 0
//------------------------------------------------------------------------------
// determine which compiler is in use
//------------------------------------------------------------------------------
#if defined ( __NVCC__ )
// NVIDIA nvcc compiler
#undef GB_COMPILER_NVCC
#define GB_COMPILER_NVCC 1
#define GB_COMPILER_MAJOR __CUDACC_VER_MAJOR__
#define GB_COMPILER_MINOR __CUDACC_VER_MINOR__
#define GB_COMPILER_SUB __CUDACC_VER_BUILD__
#define GB_COMPILER_NAME "nvcc"
#elif defined ( __INTEL_CLANG_COMPILER )
// Intel icx compiler, 2022.0.0 based on clang/llvm 14.0.0
#undef GB_COMPILER_ICX
#define GB_COMPILER_ICX 1
#define GB_COMPILER_MAJOR __INTEL_CLANG_COMPILER
#define GB_COMPILER_MINOR 0
#define GB_COMPILER_SUB 0
#define GB_COMPILER_NAME __VERSION__
#elif defined ( __INTEL_COMPILER )
// Intel icc compiler: 2021.5.0 uses "gcc 7.5 mode"
#undef GB_COMPILER_ICC
#define GB_COMPILER_ICC 1
#define GB_COMPILER_MAJOR __INTEL_COMPILER
#define GB_COMPILER_MINOR __INTEL_COMPILER_UPDATE
#define GB_COMPILER_SUB 0
#define GB_COMPILER_NAME __VERSION__
#elif defined ( __clang__ )
// clang
#undef GB_COMPILER_CLANG
#define GB_COMPILER_CLANG 1
#define GB_COMPILER_MAJOR __clang_major__
#define GB_COMPILER_MINOR __clang_minor__
#define GB_COMPILER_SUB __clang_patchlevel__
#define GB_COMPILER_NAME "clang " __clang_version__
#elif defined ( __xlC__ )
// xlc
#undef GB_COMPILER_XLC
#define GB_COMPILER_XLC 1
#define GB_COMPILER_MAJOR ( __xlC__ / 256 )
#define GB_COMPILER_MINOR ( __xlC__ - 256 * GB_COMPILER_MAJOR)
#define GB_COMPILER_SUB 0
#define GB_COMPILER_NAME "IBM xlc " GB_XSTR (__xlC__)
#elif defined ( __GNUC__ )
// gcc
#undef GB_COMPILER_GCC
#define GB_COMPILER_GCC 1
#define GB_COMPILER_MAJOR __GNUC__
#define GB_COMPILER_MINOR __GNUC_MINOR__
#define GB_COMPILER_SUB __GNUC_PATCHLEVEL__
#define GB_COMPILER_NAME "GNU gcc " GB_XSTR (__GNUC__) "." \
GB_XSTR (__GNUC_MINOR__) "." GB_XSTR (__GNUC_PATCHLEVEL__)
#elif defined ( _MSC_VER )
// Microsoft Visual Studio (cl compiler)
#undef GB_COMPILER_MSC
#define GB_COMPILER_MSC 1
#define GB_COMPILER_MAJOR ( _MSC_VER / 100 )
#define GB_COMPILER_MINOR ( _MSC_VER - 100 * GB_COMPILER_MAJOR)
#define GB_COMPILER_SUB 0
#define GB_COMPILER_NAME "Microsoft Visual Studio " GB_XSTR (_MSC_VER)
#else
// other compiler
#define GB_COMPILER_MAJOR 0
#define GB_COMPILER_MINOR 0
#define GB_COMPILER_SUB 0
#define GB_COMPILER_NAME "other C compiler"
#endif
//------------------------------------------------------------------------------
// MINGW system, for Windows
//------------------------------------------------------------------------------
#if defined ( __MINGW32__ )
// MinGW (32-bit or 64-bit): using gcc, clang, or other compilers.
#define GB_MINGW 1
#else
#define GB_MINGW 0
#endif
//------------------------------------------------------------------------------
// Workaround for compiler bug in Microsoft Visual Studio 2019
//------------------------------------------------------------------------------
// The GB_COMPILER_MSC_2019 flag disables the FIRST_FC32 and SECOND_FC32 binary
// operators for the MS Visual Studio 2019 compiler (MSC versions 19.20 to
// 19.29). It's possible that the compiler bug appears in 19.30 and later (VS
// 2022), but this hasn't been tested. This macro optimistically assumes the
// bug will be fixed in that version.
#define GB_COMPILER_MSC_2019 ( GB_COMPILER_MSC && (GB_COMPILER_MAJOR == 19) \
&& (GB_COMPILER_MINOR >= 20) && (GB_COMPILER_MINOR <= 29) )
//------------------------------------------------------------------------------
// malloc.h: required include file for Microsoft Visual Studio
//------------------------------------------------------------------------------
#if GB_COMPILER_MSC
#include <malloc.h>
#endif
//------------------------------------------------------------------------------
// OpenMP pragmas and tasks
//------------------------------------------------------------------------------
// GB_PRAGMA(x) becomes "#pragma x", but the way to do this depends on the
// compiler:
#if GB_COMPILER_MSC
// MS Visual Studio is not ANSI C11 compliant, and uses __pragma:
#define GB_PRAGMA(x) __pragma (x)
// no #pragma omp simd is available in MS Visual Studio
#define GB_PRAGMA_SIMD
#define GB_PRAGMA_SIMD_REDUCTION(op,s)
#else
// ANSI C11 compilers use _Pragma:
#define GB_PRAGMA(x) _Pragma (#x)
// create two kinds of SIMD pragmas:
// GB_PRAGMA_SIMD becomes "#pragma omp simd"
// GB_PRAGMA_SIMD_REDUCTION (+,cij) becomes
// "#pragma omp simd reduction(+:cij)"
#define GB_PRAGMA_SIMD GB_PRAGMA (omp simd)
#define GB_PRAGMA_SIMD_REDUCTION(op,s) GB_PRAGMA (omp simd reduction(op:s))
#endif
//------------------------------------------------------------------------------
// variable-length arrays
//------------------------------------------------------------------------------
// If variable-length arrays are not supported, user-defined types are limited
// in size to 128 bytes or less. Many of the type-generic routines allocate
// workspace for a single scalar of variable size, using a statement:
//
// GB_void aij [xsize] ;
//
// To support non-variable-length arrays in ANSI C95 or earlier, this is used:
//
// GB_void aij [GB_VLA(xsize)] ;
//
// GB_VLA(xsize) is either defined as xsize (for ANSI C99 or later), or a fixed
// size of 128, in which case user-defined types
// are limited to a max of 128 bytes.
#if GB_COMPILER_NVCC
// NVIDIA nvcc compiler for host or device code
#define GB_HAS_VLA 1
#elif GB_COMPILER_MSC
// Microsoft Visual Studio does not support variable-length arrays.
#define GB_HAS_VLA 0
#elif defined ( __cplusplus )
#define GB_HAS_VLA 1
#elif (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
// ANSI C99 and later
#define GB_HAS_VLA 1
#else
// ANSI C95 and earlier
#define GB_HAS_VLA 0
#endif
#ifdef PGI_COMPILER_BUG
// If GraphBLAS is compiled with -DPGI_COMPILER_BUG, then a workaround is
// enabled for a bug in the PGI compiler. The compiler does not correctly
// handle automatic arrays of variable size.
#undef GB_HAS_VLA
#define GB_HAS_VLA 0
#endif
#if ( GB_HAS_VLA )
// variable-length arrays are allowed
#define GB_VLA(s) s
#else
// variable-length arrays are not allowed
#define GB_VLA_MAXSIZE 128
#define GB_VLA(s) GB_VLA_MAXSIZE
#endif
//------------------------------------------------------------------------------
// AVX2 and AVX512F support for the x86_64 architecture
//------------------------------------------------------------------------------
// gcc 7.5.0 cannot compile code with __attribute__ ((target ("avx512f"))), or
// avx2 (it triggers a bug in the compiler), but those targets are fine with
// gcc 9.3.0 or later. It might be OK on gcc 8.x but I haven't tested this.
#if GBX86
#if GB_COMPILER_GCC
#if __GNUC__ >= 9
// enable avx512f on gcc 9.x and later
#define GB_COMPILER_SUPPORTS_AVX512F 1
#define GB_COMPILER_SUPPORTS_AVX2 1
#else
// disable avx2 and avx512f on gcc 8.x and earlier
#define GB_COMPILER_SUPPORTS_AVX512F 0
#define GB_COMPILER_SUPPORTS_AVX2 0
#endif
#elif GB_COMPILER_ICX || GB_COMPILER_ICC || GB_COMPILER_CLANG
// all these compilers can handle AVX512F and AVX2 on x86
#define GB_COMPILER_SUPPORTS_AVX512F 1
#define GB_COMPILER_SUPPORTS_AVX2 1
#else
// unsure if xlc can handle AVX, but it is not likely to be used on
// the x86 anyway. cpu_features is disabled for MS Visual Studio.
#define GB_COMPILER_SUPPORTS_AVX512F 0
#define GB_COMPILER_SUPPORTS_AVX2 0
#endif
#else
// non-X86_64 architecture
#define GB_COMPILER_SUPPORTS_AVX512F 0
#define GB_COMPILER_SUPPORTS_AVX2 0
#endif
// prefix for function with target avx512f
#if GB_COMPILER_SUPPORTS_AVX512F
#if (defined (_WIN64) || defined (_WIN32)) && \
(GB_COMPILER_ICC || GB_COMPILER_ICX)
// the Intel compilers on Windows support this feature:
#define GB_TARGET_AVX512F __declspec (target ("avx512f"))
#else
#define GB_TARGET_AVX512F __attribute__ ((target ("avx512f")))
#endif
#else
#define GB_TARGET_AVX512F
#endif
// prefix for function with target avx2
#if GB_COMPILER_SUPPORTS_AVX2
#if (defined (_WIN64) || defined (_WIN32)) && \
(GB_COMPILER_ICC || GB_COMPILER_ICX)
// the Intel compilers on Windows support this feature:
#define GB_TARGET_AVX2 __declspec (target ("avx2"))
#else
#define GB_TARGET_AVX2 __attribute__ ((target ("avx2")))
#endif
#else
#define GB_TARGET_AVX2
#endif
#endif
|