From f93318a6c818c969a321bc47d1c8fad06d60429b Mon Sep 17 00:00:00 2001 From: Zaheer Chothia Date: Sun, 22 Apr 2012 21:16:03 +0200 Subject: [PATCH] Refs #95 cblas: compatibility for compilers without C99 complex number support (e.g. Visual Studio) --- Makefile.install | 2 +- cblas.h | 18 +++++++++--------- common.h | 22 ++++++++++++++++++++++ openblas_config_template.h | 31 +++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/Makefile.install b/Makefile.install index 6ecfd91eda..62ceda9869 100644 --- a/Makefile.install +++ b/Makefile.install @@ -23,7 +23,7 @@ install : lib.grd @cat config_last.h >> $(OPENBLAS_INCLUDE_DIR)/openblas_config.h @echo \#define VERSION \" OpenBLAS $(VERSION) \" >> $(OPENBLAS_INCLUDE_DIR)/openblas_config.h @cat openblas_config_template.h >> $(OPENBLAS_INCLUDE_DIR)/openblas_config.h - @echo \#endif >> $(OPENBLAS_INCLUDE_DIR)/openblas_config.h + @echo \#endif \/\* OPENBLAS_CONFIG_H \*\/ >> $(OPENBLAS_INCLUDE_DIR)/openblas_config.h @echo Generating f77blas.h in $(OPENBLAS_INCLUDE_DIR) @echo \#ifndef OPENBLAS_F77BLAS_H > $(OPENBLAS_INCLUDE_DIR)/f77blas.h diff --git a/cblas.h b/cblas.h index 34adc5e997..f3708a9941 100644 --- a/cblas.h +++ b/cblas.h @@ -22,15 +22,15 @@ double cblas_dsdot (blasint n, float *x, blasint incx, float *y, blasint incy); float cblas_sdot(blasint n, float *x, blasint incx, float *y, blasint incy); double cblas_ddot(blasint n, double *x, blasint incx, double *y, blasint incy); -float _Complex cblas_cdotu(blasint n, float *x, blasint incx, float *y, blasint incy); -float _Complex cblas_cdotc(blasint n, float *x, blasint incx, float *y, blasint incy); -double _Complex cblas_zdotu(blasint n, double *x, blasint incx, double *y, blasint incy); -double _Complex cblas_zdotc(blasint n, double *x, blasint incx, double *y, blasint incy); - -void cblas_cdotu_sub(blasint n, float *x, blasint incx, float *y, blasint incy, float _Complex *ret); -void cblas_cdotc_sub(blasint n, float *x, blasint incx, float *y, blasint incy, float _Complex *ret); -void cblas_zdotu_sub(blasint n, double *x, blasint incx, double *y, blasint incy, double _Complex *ret); -void cblas_zdotc_sub(blasint n, double *x, blasint incx, double *y, blasint incy, double _Complex *ret); +openblas_complex_float cblas_cdotu(blasint n, float *x, blasint incx, float *y, blasint incy); +openblas_complex_float cblas_cdotc(blasint n, float *x, blasint incx, float *y, blasint incy); +openblas_complex_double cblas_zdotu(blasint n, double *x, blasint incx, double *y, blasint incy); +openblas_complex_double cblas_zdotc(blasint n, double *x, blasint incx, double *y, blasint incy); + +void cblas_cdotu_sub(blasint n, float *x, blasint incx, float *y, blasint incy, openblas_complex_float *ret); +void cblas_cdotc_sub(blasint n, float *x, blasint incx, float *y, blasint incy, openblas_complex_float *ret); +void cblas_zdotu_sub(blasint n, double *x, blasint incx, double *y, blasint incy, openblas_complex_double *ret); +void cblas_zdotc_sub(blasint n, double *x, blasint incx, double *y, blasint incy, openblas_complex_double *ret); float cblas_sasum (blasint n, float *x, blasint incx); double cblas_dasum (blasint n, double *x, blasint incx); diff --git a/common.h b/common.h index e848f33f30..c6d30ddcf6 100644 --- a/common.h +++ b/common.h @@ -374,6 +374,28 @@ typedef int blasint; #endif #endif +#ifndef ASSEMBLER +#ifndef NOINCLUDE +/* Inclusion of a standard header file is needed for definition of __STDC_* + predefined macros with some compilers (e.g. GCC 4.7 on Linux). This occurs + as a side effect of including either or . */ +#include +#endif // NOINCLUDE + +/* C99 supports complex floating numbers natively, which GCC also offers as an + extension since version 3.0. If neither are available, use a compatible + structure as fallback (see Clause 6.2.5.13 of the C99 standard). */ +#if defined(__STDC_IEC_559_COMPLEX__) || __STDC_VERSION__ >= 199901L || __GNUC__ >= 3 + #define OPENBLAS_COMPLEX_C99 + typedef float _Complex openblas_complex_float; + typedef double _Complex openblas_complex_double; +#else + #define OPENBLAS_COMPLEX_STRUCT + typedef struct { float real, imag; } openblas_complex_float; + typedef struct { double real, imag; } openblas_complex_double; +#endif +#endif // ASSEMBLER + #ifndef IFLUSH #define IFLUSH #endif diff --git a/openblas_config_template.h b/openblas_config_template.h index 8bf9725939..caeccf0265 100644 --- a/openblas_config_template.h +++ b/openblas_config_template.h @@ -39,3 +39,34 @@ typedef int blasint; #define FLOATRET float #endif #endif + +/* Inclusion of a standard header file is needed for definition of __STDC_* + predefined macros with some compilers (e.g. GCC 4.7 on Linux). This occurs + as a side effect of including either or . */ +#include + +/* C99 supports complex floating numbers natively, which GCC also offers as an + extension since version 3.0. If neither are available, use a compatible + structure as fallback (see Clause 6.2.5.13 of the C99 standard). */ +#if defined(__STDC_IEC_559_COMPLEX__) || __STDC_VERSION__ >= 199901L || __GNUC__ >= 3 + #define OPENBLAS_COMPLEX_C99 + #include + typedef float _Complex openblas_complex_float; + typedef double _Complex openblas_complex_double; + #define openblas_make_complex_float(real, imag) ((real) + ((imag) * _Complex_I)) + #define openblas_make_complex_double(real, imag) ((real) + ((imag) * _Complex_I)) + #define openblas_complex_float_real(z) (creal(z)) + #define openblas_complex_float_imag(z) (cimag(z)) + #define openblas_complex_double_real(z) (creal(z)) + #define openblas_complex_double_imag(z) (cimag(z)) +#else + #define OPENBLAS_COMPLEX_STRUCT + typedef struct { float real, imag; } openblas_complex_float; + typedef struct { double real, imag; } openblas_complex_double; + #define openblas_make_complex_float(real, imag) {(real), (imag)} + #define openblas_make_complex_double(real, imag) {(real), (imag)} + #define openblas_complex_float_real(z) ((z).real) + #define openblas_complex_float_imag(z) ((z).imag) + #define openblas_complex_double_real(z) ((z).real) + #define openblas_complex_double_imag(z) ((z).imag) +#endif