Commit 25cb256f authored by Karl Wette's avatar Karl Wette Committed by Adam Mercer
Browse files

Allow LAL code to begin to use C99 complex datatypes

 * A ./configure macro checks that memory layout of C99/C++ complex types
   are identical to the old LAL complex structs. If true, each .c file can
   then chose which complex datatype to use - C99 or LAL - while being
   able to call code defined in another .c file which may have used a
   different complex datatype internally.
 * If LAL_USE_OLD_COMPLEX_STRUCTS macro is not defined (i.e. by default),
   use C99 complex datatypes. Define macros for constructing C99/C++
   complex numbers, and accessing/assigning real and imaginary parts.
   Macros use some GCC extensions where available.
Original: ba26dab7e236328ebe597d8be7320d21c5be67eb
parent f362de89
# lalsuite_build.m4 - top level build macros
#
# serial 31
# serial 32
AC_DEFUN([LALSUITE_USE_LIBTOOL],
[## $0: Generate a libtool script for use in configure tests
......@@ -498,3 +498,118 @@ AC_MSG_RESULT([no])
AC_MSG_RESULT([unknown])
[cuda=false])
])
AC_DEFUN([LALSUITE_CHECK_COMPLEX_NUMBER_MEMORY_LAYOUT],[
AC_MSG_CHECKING([memory layout of complex number type '$3'])
AS_IF([test "$cross_compiling" = yes],[
AC_MSG_WARN([cross compiling: not checking])
],[
# compile a C file containing functions where
# the complex number datatype is a struct
AC_LANG_PUSH([C])
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([
AC_INCLUDES_DEFAULT
typedef struct {
$2 re;
$2 im;
} ComplexStruct;
const size_t zsize = sizeof(ComplexStruct);
const $2 zre = 1.414213562373095048801688724209;
const $2 zim = 3.141592653589793238462643383276;
void Function1(ComplexStruct *pz) {
pz->re = zre;
pz->im = zim;
}
int Function2(ComplexStruct pz) {
return (pz.re == zre && pz.im == zim);
}
ComplexStruct Function3() {
ComplexStruct z = {zre, zim};
return z;
}
])
],[
# if compilation was successful, save the compiled object
mv -f conftest.$ac_objext conftestlink.$ac_objext
_AS_ECHO_LOG([moved conftest.$ac_objext to conftestlink.$ac_objext])
],[
AC_MSG_FAILURE([unexpected compile failure])
])
AC_LANG_POP([C])
# add the object compiled above to the objects
# which will be linked against by the next test
lalsuite_ccnml_LIBS=$LIBS
LIBS="$LIBS conftestlink.$ac_objext"
# push current language so that we can restore
# previous linker settings at end of this test
AC_LANG_PUSH(_AC_LANG)
# compile a _AC_LANG file where the complex number
# datatype is a C99/C++ complex number, and which
# calls functions in the previously-compiled file
# (where the complex number datatype was a struct).
# link it against the previously-compiled object,
# and run the resulting test program.
AC_RUN_IFELSE([
AC_LANG_PROGRAM([
AC_INCLUDES_DEFAULT
#include <$1>
#ifdef __cplusplus
extern "C" {
#endif
extern const size_t zsize;
extern const $2 zre;
extern const $2 zim;
void Function1($3 *pz);
int Function2($3 pz);
$3 Function3();
#ifdef __cplusplus
}
#endif
],[
$3 c;
if (sizeof($3) != zsize) {
return 1;
}
Function1(&c);
if ($4(c) != zre || $5(c) != zim) {
return 2;
}
if (!Function2(c)) {
return 3;
}
c = Function3();
if ($4(c) != zre || $5(c) != zim) {
return 4;
}
return 0 /* ; */
])
],[
# if test program compiled and exited
# normally, test was successful
AC_MSG_RESULT([compatible])
],[
AC_MSG_FAILURE([memory layout of complex number type '$3' is incompatible])
])
# restore previous linker settings and
# delete remaining test object files
LIBS=$lalsuite_ccnml_LIBS
AC_LANG_POP(_AC_LANG)
rm -f conftestlink.$ac_objext
])
])
AC_DEFUN([LALSUITE_CHECK_COMPLEX_NUMBER_TYPES],[
# check C99 complex number datatypes
AC_LANG_PUSH([C])
AC_CHECK_HEADERS([complex.h],[],[AC_MSG_ERROR([could not find 'complex.h'])])
LALSUITE_CHECK_COMPLEX_NUMBER_MEMORY_LAYOUT([complex.h],[float],[float complex],[crealf],[cimagf])
LALSUITE_CHECK_COMPLEX_NUMBER_MEMORY_LAYOUT([complex.h],[double],[double complex],[creal],[cimag])
AC_LANG_POP([C])
# check C++ complex number datatypes
AC_LANG_PUSH([C++])
AC_CHECK_HEADERS([complex],[],[AC_MSG_ERROR([could not find 'complex'])])
LALSUITE_CHECK_COMPLEX_NUMBER_MEMORY_LAYOUT([complex],[float],[std::complex<float>],[real],[imag])
LALSUITE_CHECK_COMPLEX_NUMBER_MEMORY_LAYOUT([complex],[double],[std::complex<double>],[real],[imag])
AC_LANG_POP([C++])
])
......@@ -200,7 +200,7 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if appropriate
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# boinc requires a c++ compiler
# check for c++ compiler
AC_PROG_CXX
# check for programs
......@@ -221,6 +221,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for support tex flags
if test -z "$TEXFLAGS"
then
......
......@@ -19,8 +19,10 @@
/** \file
* \ingroup std
* \author Creighton, J. D. E., and Creighton, T. D.
* \brief The primative LAL datatypes.
* \authors J. D. E. Creighton
* \authors T. D. Creighton
* \authors K. Wette
*
* This header defines the primative LAL datatypes. These datatypes
* are: CHAR, INT2, INT4, INT8 (signed integer types); UCHAR, UINT2
......@@ -209,6 +211,15 @@ typedef unsigned char UCHAR;
typedef unsigned char BOOLEAN;
#include <stdint.h>
#ifndef LAL_USE_OLD_COMPLEX_STRUCTS
#if defined(__cplusplus)
#include <complex>
#else
#include <complex.h>
#endif
#endif /* LAL_USE_OLD_COMPLEX_STRUCTS */
#include <lal/LALConfig.h>
/* If INT8 etc. are already defined, undefine them */
......@@ -242,6 +253,67 @@ typedef uint64_t UINT8;
typedef float REAL4;
typedef double REAL8;
#ifndef SWIG /* exclude from SWIG interface */
#ifndef LAL_USE_OLD_COMPLEX_STRUCTS
/* Complex types */
#if defined(__cplusplus)
typedef std::complex<float> COMPLEX8;
typedef std::complex<double> COMPLEX16;
#else
typedef float complex COMPLEX8;
typedef double complex COMPLEX16;
#endif
/* Complex type constructors */
#if defined(__cplusplus)
#define CX8rect(re, im) std::complex<float>( re, im )
#define CX16rect(re, im) std::complex<float>( re, im )
#define CX8polar(r, th) ( (r) * exp( _Complex_I * (th) ) )
#define CX16polar(r, th) ( (r) * exp( _Complex_I * (th) ) )
#else
#define CX8rect(re, im) ( (re) + _Complex_I * (im) )
#define CX16rect(re, im) ( (re) + _Complex_I * (im) )
#define CX8polar(r, th) ( (r) * cexpf( _Complex_I * (th) ) )
#define CX16polar(r, th) ( (r) * cexp ( _Complex_I * (th) ) )
#endif
/* Real and imaginary part accessors */
#if defined(__cplusplus)
#define CX8re(z) std::real(z)
#define CX16re(z) std::real(z)
#define CX8im(z) std::imag(z)
#define CX16im(z) std::imag(z)
#elif defined(__GNUC__)
#define CX8re(z) __real__(z)
#define CX16re(z) __real__(z)
#define CX8im(z) __imag__(z)
#define CX16im(z) __imag__(z)
#else
#define CX8re(z) crealf(z)
#define CX16re(z) creal (z)
#define CX8im(z) cimagf(z)
#define CX16im(z) cimag (z)
#endif
/* Real and imaginary part assignment */
#if !defined(__cplusplus) && defined(__GNUC__)
#define setCX8re(z, re) __real__(z) = (re)
#define setCX16re(z, re) __real__(z) = (re)
#define setCX8im(z, im) __imag__(z) = (im)
#define setCX16im(z, im) __imag__(z) = (im)
#else
#define setCX8re(z, re) (z) = CX8rect ( re, CX8imag (z) )
#define setCX16re(z, re) (z) = CX16rect( re, CX16imag(z) )
#define setCX8im(z, im) (z) = CX8rect ( CX8re (z), im )
#define setCX16im(z, im) (z) = CX16rect( CX16re(z), im )
#endif
#else /* LAL_USE_OLD_COMPLEX_STRUCTS */
/** \cond DONT_DOXYGEN */
/* <lalLaTeX>
\subsubsection*{Complex datatypes}
......@@ -278,7 +350,6 @@ memory. The fields are:
</lalLaTeX> */
/** Single-precision floating-point complex number (8 bytes total) */
#ifndef SWIG /* exclude from SWIG interface */
typedef struct
tagCOMPLEX8
{
......@@ -286,10 +357,8 @@ tagCOMPLEX8
REAL4 im; /**< The imaginary part. */
}
COMPLEX8;
#endif /* SWIG */
/** Double-precision floating-point complex number (16 bytes total) */
#ifndef SWIG /* exclude from SWIG interface */
typedef struct
tagCOMPLEX16
{
......@@ -297,13 +366,17 @@ tagCOMPLEX16
REAL8 im; /**< The imaginary part. */
}
COMPLEX16;
#endif /* SWIG */
/* <lalLaTeX>
\vfill{\footnotesize\input{LALAtomicDatatypesHV}}
</lalLaTeX> */
/** \endcond */
#endif /* LAL_USE_OLD_COMPLEX_STRUCTS */
#endif /* SWIG */
#ifdef __cplusplus
}
......
......@@ -134,7 +134,7 @@ LALSUITE_MULTILIB_LIBTOOL_HACK
m4_pattern_allow([AC_PROG_CC_C99])
m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# boinc requires a c++ compiler
# check for c++ compiler
AC_PROG_CXX
# check for MPI compiler
......@@ -187,6 +187,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for system libraries
AC_CHECK_LIB([m],[sin])
AC_CHECK_LIB([z],[compress])
......
......@@ -81,6 +81,9 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# check for c++ compiler
AC_PROG_CXX
# checks for programs
AC_PROG_CPP
AC_PROG_INSTALL
......@@ -95,6 +98,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -87,7 +87,7 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# SWIG wrapping requires a c++ compiler
# check for c++ compiler
AC_PROG_CXX
# checks for programs
......@@ -105,6 +105,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -88,6 +88,9 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# check for c++ compiler
AC_PROG_CXX
# checks for programs
AC_PROG_CPP
AC_PROG_INSTALL
......@@ -102,6 +105,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -90,6 +90,9 @@ AC_PROG_CXX
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# check for c++ compiler
AC_PROG_CXX
# checks for programs
AC_PROG_CPP
AC_PROG_INSTALL
......@@ -104,6 +107,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -80,6 +80,9 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# check for c++ compiler
AC_PROG_CXX
# checks for programs
AC_PROG_CPP
AC_PROG_INSTALL
......@@ -94,6 +97,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -87,12 +87,12 @@ LALSUITE_MULTILIB_LIBTOOL_HACK
m4_pattern_allow([AC_PROG_CC_C99])
m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# boinc requires a c++ compiler
AC_PROG_CXX
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# check for c++ compiler
AC_PROG_CXX
# checks for programs
AC_PROG_CPP
AC_PROG_INSTALL
......@@ -107,6 +107,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -84,7 +84,7 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# SWIG wrapping requires a c++ compiler
# check for c++ compiler
AC_PROG_CXX
# checks for programs
......@@ -102,6 +102,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -81,6 +81,9 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# check for c++ compiler
AC_PROG_CXX
# checks for programs
AC_PROG_CPP
AC_PROG_INSTALL
......@@ -95,6 +98,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
......@@ -84,7 +84,7 @@ m4_ifdef([AC_PROG_CC_C99],[AC_PROG_CC_C99],[LALSUITE_AC_PROG_CC_C99])
# use silent build rules if available
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
# SWIG wrapping requires a c++ compiler
# check for c++ compiler
AC_PROG_CXX
# checks for programs
......@@ -101,6 +101,9 @@ LALSUITE_OSX_VERSION_CHECK
# link tests using libtool
LALSUITE_USE_LIBTOOL
# check complex number types
LALSUITE_CHECK_COMPLEX_NUMBER_TYPES
# check for header files
AC_HEADER_STDC
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment