Major cleanup of build code (CMake related). First steps towards C++ and C-compiler safety. Also first steps made to get single precision back to working

This commit is contained in:
Anne de Jong 2021-09-14 20:05:42 +02:00
parent a6906bb620
commit b159f4d144
24 changed files with 430 additions and 340 deletions

1
.gitignore vendored
View File

@ -29,3 +29,4 @@ resources_rc.py
.spyproject
test/test_uldaq
lasp/device/lasp_daq.cxx
lasp/c/lasp_config.h

View File

@ -1,39 +1,45 @@
cmake_minimum_required (VERSION 3.0)
cmake_minimum_required (VERSION 3.1)
# To allow linking to static libs from other directories
cmake_policy(SET CMP0079 NEW)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/lasp/cmake")
include("BuildType")
# This is used for code completion in vim
set(CMAKE_EXPORT_COMPILE_COMMANDS=ON)
project(LASP LANGUAGES C CXX)
# Whether we want to use blas yes or no
set(LASP_USE_BLAS TRUE)
# set(LASP_USE_BLAS FALSE)
set(LASP_FLOAT double)
# set(LASP_FLOAT float)
option(LASP_USE_BLAS "Use external blas library for math" ON)
option(LASP_ARM "Compile subset of code for ARM real time (Bela board)" OFF)
option(LASP_DOUBLE_PRECISION "Compile as double precision floating point" ON)
option(LASP_PARALLEL "Parallel processing" ON)
option(LASP_RTAUDIO "Compile with RtAudio Daq backend" ON)
option(LASP_ULDAQ "Compile with UlDaq backend" ON)
option(LASP_DEBUG "Compile in debug mode" ON)
option(LASP_FFTW_BACKEND "Compile with FFTW fft backend" ON)
option(LASP_FFTPACK_BACKEND "Compile with Fftpack fft backend" OFF)
option(LASP_HAS_RTAUDIO "Compile with RtAudio Daq backend" ON)
option(LASP_HAS_ULDAQ "Compile with UlDaq backend" ON)
set(LASP_MAX_NUM_CHANNELS 16 CACHE STRING "Maximum number of audio channels that is compiled in in code")
set(LASP_MAX_NUM_THREADS 30 CACHE STRING "The maximum number of simultaneous threads in parallel processing")
set(LASP_TRACERNAME "defaulttracer" CACHE STRING "Name of tracer variable containing level")
set(LASP_FFT_BACKEND "FFTW" CACHE STRING "FFT Library backend")
set_property(CACHE LASP_FFT_BACKEND PROPERTY STRINGS "FFTW" "FFTPack" "None")
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(LASP_DEBUG True)
else()
set(LASP_DEBUG False)
endif()
if(LASP_PARALLEL)
add_definitions(-DLASP_MAX_NUM_THREADS=30)
add_definitions(-D_REENTRANT)
add_definitions(-D_REENTRANT)
set(LASP_THREADING_LIBRARIES pthread)
else()
set(LASP_THREADING_LIBRARIES "")
endif()
if(LASP_RTAUDIO)
add_definitions(-DHAS_RTAUDIO_API)
endif()
if(LASP_ULDAQ)
add_definitions(-DHAS_ULDAQ_API)
if(LASP_USE_BLAS)
find_package(BLAS REQUIRED)
endif()
add_definitions(-DLASP_MAX_NUM_CHANNELS=80)
# Reasonable maximum to the nfft size, at 48kHz this is 700s of data...
add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25
@ -42,101 +48,75 @@ add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 11)
# ############### Choose an fft backend here
if(((LASP_FFTW_BACKEND AND LASP_FFTPACK_BACKEND) OR ((NOT (LASP_FFTPACK_BACKEND) AND (NOT LASP_FFTW_BACKEND)))))
message(FATAL_ERROR "Either FFTW or Fftpack backend should be chosen. Please disable one of them")
endif()
if(LASP_FFTW_BACKEND)
if(LASP_FFT_BACKEND STREQUAL "FFTW")
find_library(FFTW_LIBRARY NAMES fftw3 fftw)
set(FFTW_LIBRARIES "${FFTW_LIBRARY}")
set(LASP_FFT_LIBRARY "${FFTW_LIBRARIES}")
add_definitions(-DLASP_FFT_BACKEND_FFTW)
elseif(LASP_FFTPACK_BACKEND)
add_definitions(-DLASP_FFT_BACKEND_FFTPACK)
set(LASP_FFT_LIBRARY "fftpack")
set(FFT_LIBRARIES "${FFTW_LIBRARY}")
elseif(LASP_FFT_BACKEND STREQUAL "FFTPack")
include_directories(fftpack)
set(FFT_LIBRARIES fftpack)
add_subdirectory(fftpack)
endif()
if(LASP_FLOAT STREQUAL "double")
add_definitions(-DLASP_FLOAT=64)
add_definitions(-DLASP_DOUBLE_PRECISION)
else()
# TODO: This has not been tested for a long time.
add_definitions(-DLASP_FLOAT=32)
add_definitions(-DLASP_SINGLE_PRECISION)
endif(LASP_FLOAT STREQUAL "double")
# ##################### END Cmake variables converted to a macro
set(Python_ADDITIONAL_VERSIONS "3.8")
set(python_version_windll "38")
# set(Python_ADDITIONAL_VERSIONS "3.8")
# set(python_version_windll "38")
# #################### Setting definitions and debug-specific compilation flags
# General make flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall -Wextra -Wno-type-limits \
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-type-limits \
-Werror=implicit-function-declaration -Wno-unused-parameter \
-Werror=return-type")
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(win32 true)
set(home $ENV{USERPROFILE})
# set(miniconda_dir ${home}\\Miniconda3)
message("Building for Windows")
include_directories(
..\\rtaudio
C:\\mingw\\mingw64\\include\\OpenBLAS
link_directories(${home}\\miniconda3\\Library\\include)
)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH} $miniconda_dir\\Lib\\cmake")
# include(
add_definitions(-DMS_WIN64)
link_directories(C:\\mingw\\mingw64\\lib)
link_directories(C:\\mingw\\mingw64\\bin)
link_directories(..\\rtaudio)
link_directories(${home}\\Miniconda3)
set(home $ENV{USERPROFILE})
# set(miniconda_dir ${home}\\Miniconda3)
message("Building for Windows")
include_directories(
..\\rtaudio
C:\\mingw\\mingw64\\include\\OpenBLAS
link_directories(${home}\\miniconda3\\Library\\include)
)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH} $miniconda_dir\\Lib\\cmake")
# include(
add_definitions(-DMS_WIN64)
link_directories(C:\\mingw\\mingw64\\lib)
link_directories(C:\\mingw\\mingw64\\bin)
link_directories(..\\rtaudio)
link_directories(${home}\\Miniconda3)
add_definitions(-DHAS_RTAUDIO_WIN_WASAPI_API)
else() # Linux compile
set(win32 false)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Werror=incompatible-pointer-types")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Werror=incompatible-pointer-types")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
include_directories(/usr/local/include/rtaudio)
include_directories(/usr/include/rtaudio)
link_directories(/usr/local/lib)
# This should become optional later on, and be added to the windows list as
# well.
endif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(CYTHON_FLAGS "--fast-fail")
if(LASP_DEBUG)
set(TRACERNAME LASPTracer)
set(LASP_DEBUG_CYTHON=True)
set(CMAKE_BUILD_TYPE Debug)
message("Building debug code")
set(CMAKE_BUILD_TYPE Debug)
add_definitions(-DLASP_DEBUG=1)
add_definitions(-DTRACERNAME=${TRACERNAME})
add_definitions(-DDEBUG)
add_definitions(-DTRACER=1)
# This will produce html files
# set(CYTHON_ANNOTATE ON)
# Add the __FILENAME__ macro
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")
else()
message("Building LASP for release")
set(CMAKE_BUILD_TYPE Release)
set(LASP_DEBUG_CYTHON=False)
set(CYTHON_ANNOTATE OFF)
set(CYTHON_NO_DOCSTRINGS ON)
# Strip unnecessary symbols
# set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--gc-sections")
# set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--gc-sections")
add_definitions(-DTRACER=0 -DNDEBUG)
endif(LASP_DEBUG)
# The last argument here takes care of calling SIGABRT when an integer overflow
@ -155,14 +135,6 @@ set(CMAKE_C_FLAGS_DEBUG "-g" )
set(CMAKE_C_FLAGS_RELEASE "-O2 -mfpmath=sse -march=x86-64 -mtune=native \
-fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions")
# set(CMAKE_C_FLAGS_RELEASE "-O2 -march=native -mtune=native -fomit-frame-pointer")
if(LASP_USE_BLAS)
add_definitions(-DLASP_USE_BLAS=1)
else()
add_definitions(-DLASP_USE_BLAS=0)
endif(LASP_USE_BLAS)
# ############################# End compilation flags
@ -171,10 +143,10 @@ find_package(PythonLibs REQUIRED )
find_package(PythonInterp REQUIRED)
if(LASP_FFTPACK_BACKEND)
add_subdirectory(fftpack)
include_directories(
fftpack
)
add_subdirectory(fftpack)
include_directories(
fftpack
)
endif()
include_directories(

View File

@ -1,4 +1,3 @@
configure_file(config.pxi.in config.pxi)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CYTHON_EXECUTABLE "cython3")
@ -15,7 +14,7 @@ add_subdirectory(device)
set_source_files_properties(wrappers.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} ${CYTHON_EXTRA_C_FLAGS}")
cython_add_module(wrappers wrappers.pyx)
target_link_libraries(wrappers lasp_lib)
target_link_libraries(wrappers lasp_lib ${LASP_THREADING_LIBRARIES})
if(win32)
target_link_libraries(wrappers python${python_version_windll})
endif(win32)

View File

@ -1,3 +1,4 @@
configure_file(lasp_config.h.in lasp_config.h)
if(!LASP_DEBUG)
SET_SOURCE_FILES_PROPERTIES(lasp_sosfilterbank.c PROPERTIES COMPILE_FLAGS -O3)
SET_SOURCE_FILES_PROPERTIES(lasp_slm.c PROPERTIES COMPILE_FLAGS -O3)
@ -26,6 +27,4 @@ add_library(lasp_lib
lasp_eq.c
)
target_link_libraries(lasp_lib ${LASP_FFT_LIBRARY} openblas pthread)
target_link_libraries(lasp_lib ${FFT_LIBRARIES} ${BLAS_LIBRARIES})

View File

@ -8,6 +8,7 @@
#pragma once
#ifndef LASP_ALG_H
#define LASP_ALG_H
#include "lasp_config.h"
#include "lasp_mat.h"
/**

View File

@ -5,6 +5,7 @@
// Description:
//
//////////////////////////////////////////////////////////////////////
#include "lasp_config.h"
#include "lasp_assert.h"
#ifdef LASP_DEBUG

53
lasp/c/lasp_config.h.in Normal file
View File

@ -0,0 +1,53 @@
// lasp_config.h
//
// Author: J.A. de Jong - ASCEE
//
// Description: Basic configuration compiler macro definitions, coming from
// cmake configuration. The file is configured using the configure_file()
// cmake macro.
#pragma once
#ifndef LASP_CONFIG_H
#define LASP_CONFIG_H
/* Debug flag */
#cmakedefine01 LASP_DEBUG
#if LASP_DEBUG == 1
#define TRACER 1
#define TRACERNAME @LASP_TRACERNAME@
#else
#define TRACER 0
#endif
/* Type of fft backend */
#define FFTW 1
#define FFTPack 2
#define None 0
#cmakedefine LASP_FFT_BACKEND @LASP_FFT_BACKEND@
#cmakedefine LASP_HAS_RTAUDIO
#cmakedefine LASP_HAS_ULDAQ
#cmakedefine01 LASP_DOUBLE_PRECISION
#cmakedefine01 LASP_USE_BLAS
/* Single / double precision */
#ifdef LASP_DOUBLE_PRECISION
#define LASP_FLOAT 64
#else
#define LASP_FLOAT 32
#endif
/* Serial / parallel computation */
#cmakedefine LASP_PARALLEL
#ifdef LASP_PARALLEL
#cmakedefine LASP_MAX_NUM_THREADS @LASP_MAX_NUM_THREADS@
#endif // LASP_PARALLEL
/* Audio-specific */
#cmakedefine LASP_MAX_NUM_CHANNELS @LASP_MAX_NUM_CHANNELS@
/* Platform-specific */
#ifdef _WIN32
#define MS_WIN64
#endif
#endif // LASP_CONFIG_H

View File

@ -6,17 +6,18 @@
//
//////////////////////////////////////////////////////////////////////
#define TRACERPLUS (-5)
#include "lasp_types.h"
#include "lasp_config.h"
#include "lasp_tracer.h"
#include "lasp_fft.h"
#include "lasp_types.h"
#ifdef LASP_FFT_BACKEND_FFTPACK
#if LASP_FFT_BACKEND == FFTPack
#include "fftpack.h"
typedef struct Fft_s {
us nfft;
vd fft_work; // Storage memory for fftpack
} Fft_s;
#elif defined LASP_FFT_BACKEND_FFTW
#elif LASP_FFT_BACKEND == FFTW
#include <fftw3.h>
typedef struct Fft_s {
@ -26,12 +27,13 @@ typedef struct Fft_s {
c* complex_storage;
d* real_storage;
} Fft_s;
#else
#error "Cannot compile lasp_ffc.c, no FFT backend specified"
#endif
void load_fft_wisdom(const char* wisdom) {
#ifdef LASP_FFT_BACKEND_FFTPACK
#elif defined LASP_FFT_BACKEND_FFTW
#if LASP_FFT_BACKEND == FFTPack
#elif LASP_FFT_BACKEND == FFTW
if(wisdom) {
int rv= fftw_import_wisdom_from_string(wisdom);
if(rv != 1) {
@ -42,9 +44,9 @@ void load_fft_wisdom(const char* wisdom) {
}
char* store_fft_wisdom() {
#ifdef LASP_FFT_BACKEND_FFTPACK
#if LASP_FFT_BACKEND == FFTPack
return NULL;
#elif defined LASP_FFT_BACKEND_FFTW
#elif LASP_FFT_BACKEND == FFTW
return fftw_export_wisdom_to_string();
#endif
}
@ -60,12 +62,12 @@ Fft* Fft_create(const us nfft) {
fft->nfft = nfft;
#ifdef LASP_FFT_BACKEND_FFTPACK
#if LASP_FFT_BACKEND == FFTPack
/* Initialize foreign fft lib */
fft->fft_work = vd_alloc(2*nfft+15);
npy_rffti(nfft,getvdval(&fft->fft_work,0));
check_overflow_vx(fft->fft_work);
#elif defined LASP_FFT_BACKEND_FFTW
#elif LASP_FFT_BACKEND == FFTW
fft->complex_storage = fftw_malloc(sizeof(c) * (nfft/2 + 1));
fft->real_storage = fftw_malloc(sizeof(d) * nfft);
@ -88,9 +90,9 @@ Fft* Fft_create(const us nfft) {
void Fft_free(Fft* fft) {
fsTRACE(15);
dbgassert(fft,NULLPTRDEREF);
#ifdef LASP_FFT_BACKEND_FFTPACK
#if LASP_FFT_BACKEND == FFTPack
vd_free(&fft->fft_work);
#elif defined LASP_FFT_BACKEND_FFTW
#elif LASP_FFT_BACKEND == FFTW
fftw_free(fft->complex_storage);
fftw_free(fft->real_storage);
fftw_destroy_plan(fft->forward_plan);
@ -116,7 +118,7 @@ void Fft_ifft_single(const Fft* fft,const vc* freqdata,vd* result) {
d* result_ptr = getvdval(result,0);
#ifdef LASP_FFT_BACKEND_FFTPACK
#if LASP_FFT_BACKEND == FFTPack
d* freqdata_ptr = (d*) getvcval(freqdata,0);
/* Copy freqdata, to fft_result. */
d_copy(&result_ptr[1],&freqdata_ptr[2],nfft-1,1,1);
@ -187,7 +189,7 @@ void Fft_fft_single(const Fft* fft,const vd* timedata,vc* result) {
" result array");
#ifdef LASP_FFT_BACKEND_FFTPACK
#if LASP_FFT_BACKEND == FFTPack
d* result_ptr = (d*) getvcval(result,0);
/* Fftpack stores the data a bit strange, the resulting array

View File

@ -7,10 +7,16 @@
//////////////////////////////////////////////////////////////////////
#define TRACERPLUS (-5)
#include "lasp_math_raw.h"
#if LASP_USE_BLAS
#if LASP_USE_BLAS == 1
#include <cblas.h>
#endif
#ifdef __MKL_CBLAS_H__
/* Symbol not present in MKL blas */
#define blasint CBLAS_INDEX
#else
#endif
void d_elem_prod_d(d res[],
const d arr1[],
const d arr2[],
@ -101,7 +107,7 @@ void c_hadamard(c res[],
#endif /* LASP_DEBUG */
#if LASP_DOUBLE_PRECISION
#if LASP_DOUBLE_PRECISION == 1
#define elem_prod_fun cblas_zgbmv
#else
#define elem_prod_fun cblas_cgbmv

View File

@ -8,6 +8,7 @@
#pragma once
#ifndef LASP_MATH_RAW_H
#define LASP_MATH_RAW_H
#include "lasp_config.h"
#include "lasp_assert.h"
#include "lasp_tracer.h"
#include "lasp_types.h"
@ -16,12 +17,13 @@
#if LASP_USE_BLAS == 1
#include <cblas.h>
#elif LASP_USE_BLAS == 0
#else
#error "LASP_USE_BLAS should be set to either 0 or 1"
#endif
#ifdef LASP_DOUBLE_PRECISION
#if LASP_DOUBLE_PRECISION == 1
#define c_real creal
#define c_imag cimag
#define d_abs fabs
@ -73,9 +75,9 @@ static const d number_pi = 3.141592653589793238462643383279502884197169399375105
* @param size
*/
static inline void d_set(d to[],d val,us size) {
for(us i=0;i<size;i++) {
to[i]=val;
}
for(us i=0;i<size;i++) {
to[i]=val;
}
}
/**
* Set all elements in an array equal to val
@ -85,9 +87,9 @@ static inline void d_set(d to[],d val,us size) {
* @param size
*/
static inline void c_set(c to[],c val,us size) {
for(us i=0;i<size;i++) {
to[i]=val;
}
for(us i=0;i<size;i++) {
to[i]=val;
}
}
/**
@ -99,7 +101,7 @@ static inline void c_set(c to[],c val,us size) {
* @returns the maximum of value 1 and 2
*/
static inline d d_max(const d a,const d b) {
return a>b?a:b;
return a>b?a:b;
}
@ -114,12 +116,12 @@ static inline d d_max(const d a,const d b) {
* @return the dot product
*/
static inline c cd_dot(const c a[],const d b[],us size){
c result = 0;
us i;
for(i=0;i<size;i++){
result+=a[i]*b[i];
}
return result;
c result = 0;
us i;
for(i=0;i<size;i++){
result+=a[i]*b[i];
}
return result;
}
/**
* Return the dot product of two complex-valued arrays. Wraps BLAS
@ -132,22 +134,35 @@ static inline c cd_dot(const c a[],const d b[],us size){
* @return the dot product
*/
static inline c cc_dot(const c a[],const c b[],us size){
#if LASP_USE_BLAS == 1
WARN("CBlas zdotu not yet tested");
#if LASP_DOUBLE_PRECISION
// assert(0);
return cblas_zdotu(size,(d*) a,1,(d*) b,1);
#else
return cblas_cdotu(size,(d*) a,1,(d*) b,1);
#endif
#else
c result = 0;
us i;
for(i=0;i<size;i++){
result+=a[i]*b[i];
}
return result;
#endif
#if LASP_USE_BLAS == 1
WARN("CBlas zdotu not yet tested");
#if LASP_DOUBLE_PRECISION == 1
// Openblas and MKL blas provide some subroutines with a different name, we
// correct for this fact here
#ifdef __MKL_CBLAS_H__
d res;
cblas_zdotu_sub(size,(d*) a,1,(d*) b,1, &res);
return res;
#else
return cblas_zdotu(size,(d*) a,1,(d*) b,1);
#endif
#else
#ifdef __MKL_CBLAS_H__
d res;
cblas_cdotu_sub(size,(d*) a,1,(d*) b,1, &res);
return res;
#endif
return cblas_cdotu(size,(d*) a,1,(d*) b,1);
#endif // LASP_DOUBLE_PRECISION
#else
c result = 0;
us i;
for(i=0;i<size;i++){
result+=a[i]*b[i];
}
return result;
#endif
}
/**
@ -159,20 +174,20 @@ static inline c cc_dot(const c a[],const c b[],us size){
* @return The result.
*/
static inline d d_dot(const d a[],const d b[],const us size){
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION
return cblas_ddot(size,a,1,b,1);
#else // Single precision function
return cblas_sdot(size,a,1,b,1);
#endif
#else // No BLAS, do it manually
d result = 0;
us i;
for(i=0;i<size;i++){
result+=a[i]*b[i];
}
return result;
#endif
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION
return cblas_ddot(size,a,1,b,1);
#else // Single precision function
return cblas_sdot(size,a,1,b,1);
#endif
#else // No BLAS, do it manually
d result = 0;
us i;
for(i=0;i<size;i++){
result+=a[i]*b[i];
}
return result;
#endif
}
@ -186,17 +201,17 @@ static inline d d_dot(const d a[],const d b[],const us size){
* @param from_inc : Mostly equal to 1, the stride of the array to copy from
*/
static inline void d_copy(d to[],
const d from[],
const us size,
const us to_inc,
const us from_inc){
#if LASP_USE_BLAS == 1
cblas_dcopy(size,from,from_inc,to,to_inc);
#else
us i;
for(i=0;i<size;i++)
to[i*to_inc] = from[i*from_inc];
#endif
const d from[],
const us size,
const us to_inc,
const us from_inc){
#if LASP_USE_BLAS == 1
cblas_dcopy(size,from,from_inc,to,to_inc);
#else
us i;
for(i=0;i<size;i++)
to[i*to_inc] = from[i*from_inc];
#endif
}
@ -209,11 +224,11 @@ static inline void d_copy(d to[],
* @param size : Size of arrays
*/
static inline void cd_copy(c to[],const d from[],const us size) {
us i;
for(i=0;i<size;i++) {
to[i] = (c) (from[i]);
dbgassert(cimag(to[i]) == 0,"Imaginary part not equal to zero");
}
us i;
for(i=0;i<size;i++) {
to[i] = (c) (from[i]);
dbgassert(cimag(to[i]) == 0,"Imaginary part not equal to zero");
}
}
/**
@ -224,18 +239,18 @@ static inline void cd_copy(c to[],const d from[],const us size) {
* @param from : Vector to read from
*/
static inline void c_copy(c to[],const c from[],const us size){
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION
cblas_zcopy(size,(d*) from,1,(d*) to,1);
#else
cblas_ccopy(size,(d*) from,1,(d*) to,1);
#endif
#else
us i;
for(i=0;i<size;i++)
to[i] = from[i];
#endif
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION == 1
cblas_zcopy(size,(d*) from,1,(d*) to,1);
#else
cblas_ccopy(size,(d*) from,1,(d*) to,1);
#endif
#else
us i;
for(i=0;i<size;i++)
to[i] = from[i];
#endif
}
/**
* Multiply y with fac, and add result to x
@ -246,18 +261,18 @@ static inline void c_copy(c to[],const c from[],const us size){
* @param[in] size Size of the arrays
*/
static inline void d_add_to(d x[],const d y[],
const d fac,const us size){
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION
cblas_daxpy(size,fac,y,1,x,1);
#else
cblas_saxpy(size,fac,y,1,x,1);
#endif
#else
us i;
for(i=0;i<size;i++)
x[i]+=fac*y[i];
#endif
const d fac,const us size){
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION == 1
cblas_daxpy(size,fac,y,1,x,1);
#else
cblas_saxpy(size,fac,y,1,x,1);
#endif
#else
us i;
for(i=0;i<size;i++)
x[i]+=fac*y[i];
#endif
}
/**
* x = x + fac*y
@ -268,20 +283,20 @@ static inline void d_add_to(d x[],const d y[],
* @param[in] size Size of the arrays
*/
static inline void c_add_to(c x[],const c y[],
const c fac,const us size){
fsTRACE(15);
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION
cblas_zaxpy(size,(d*) &fac,(d*) y,1,(d*) x,1);
#else
cblas_caxpy(size,(d*) &fac,(d*) y,1,(d*) x,1);
#endif
#else
us i;
for(i=0;i<size;i++)
x[i]+=fac*y[i];
#endif
feTRACE(15);
const c fac,const us size){
fsTRACE(15);
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION == 1
cblas_zaxpy(size,(d*) &fac,(d*) y,1,(d*) x,1);
#else
cblas_caxpy(size,(d*) &fac,(d*) y,1,(d*) x,1);
#endif
#else
us i;
for(i=0;i<size;i++)
x[i]+=fac*y[i];
#endif
feTRACE(15);
}
/**
@ -292,17 +307,17 @@ static inline void c_add_to(c x[],const c y[],
* @param size size of the array
*/
static inline void d_scale(d a[],const d scale_fac,us size){
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION
cblas_dscal(size,scale_fac,a,1);
#else
cblas_sscal(size,scale_fac,a,1);
#endif
#else
us i;
for(i=0;i<size;i++)
a[i]*=scale_fac;
#endif
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION == 1
cblas_dscal(size,scale_fac,a,1);
#else
cblas_sscal(size,scale_fac,a,1);
#endif
#else
us i;
for(i=0;i<size;i++)
a[i]*=scale_fac;
#endif
}
@ -314,23 +329,23 @@ static inline void d_scale(d a[],const d scale_fac,us size){
* @param size size of the array
*/
static inline void c_scale(c a[],const c scale_fac,us size){
#if LASP_USE_BLAS == 1
// Complex argument should be given in as array of two double
// values. The first the real part, the second the imaginary
// part. Fortunately the (c) type stores the two values in this
// order. To be portable and absolutely sure anything goes well,
// we convert it explicitly here.
#if LASP_USE_BLAS == 1
// Complex argument should be given in as array of two double
// values. The first the real part, the second the imaginary
// part. Fortunately the (c) type stores the two values in this
// order. To be portable and absolutely sure anything goes well,
// we convert it explicitly here.
#if LASP_DOUBLE_PRECISION
cblas_zscal(size,(d*) &scale_fac,(d*) a,1);
#else
cblas_cscal(size,(d*) &scale_fac,(d*) a,1);
#endif
#else
us i;
for(i=0;i<size;i++)
a[i]*=scale_fac;
#endif
#if LASP_DOUBLE_PRECISION == 1
cblas_zscal(size,(d*) &scale_fac,(d*) a,1);
#else
cblas_cscal(size,(d*) &scale_fac,(d*) a,1);
#endif
#else
us i;
for(i=0;i<size;i++)
a[i]*=scale_fac;
#endif
}
@ -342,12 +357,12 @@ static inline void c_scale(c a[],const c scale_fac,us size){
* @return maximum
*/
static inline d darray_max(const d a[],us size){
us i;
d max = a[0];
for(i=1;i<size;i++){
if(a[i] > max) max=a[i];
}
return max;
us i;
d max = a[0];
for(i=1;i<size;i++){
if(a[i] > max) max=a[i];
}
return max;
}
/**
* Compute the minimum of an array
@ -357,12 +372,12 @@ static inline d darray_max(const d a[],us size){
* @return minimum
*/
static inline d d_min(const d a[],us size){
us i;
d min = a[0];
for(i=1;i<size;i++){
if(a[i] > min) min=a[i];
}
return min;
us i;
d min = a[0];
for(i=1;i<size;i++){
if(a[i] > min) min=a[i];
}
return min;
}
/**
@ -372,18 +387,18 @@ static inline d d_min(const d a[],us size){
* @param size Size of array
*/
static inline d d_norm(const d a[],us size){
#if LASP_USE_BLAS == 1
return cblas_dnrm2(size,a,1);
#else
d norm = 0;
us i;
for(i=0;i<size;i++){
norm+=a[i]*a[i];
}
norm = d_sqrt(norm);
return norm;
#endif
#if LASP_USE_BLAS == 1
return cblas_dnrm2(size,a,1);
#else
d norm = 0;
us i;
for(i=0;i<size;i++){
norm+=a[i]*a[i];
}
norm = d_sqrt(norm);
return norm;
#endif
}
/**
@ -393,19 +408,19 @@ static inline d d_norm(const d a[],us size){
* @param size Size of array
*/
static inline d c_norm(const c a[],us size){
#if LASP_USE_BLAS == 1
return cblas_dznrm2(size,(d*) a,1);
#else
d norm = 0;
us i;
for(i=0;i<size;i++){
d absa = c_abs(a[i]);
norm+=absa*absa;
}
norm = d_sqrt(norm);
return norm;
#endif
#if LASP_USE_BLAS == 1
return cblas_dznrm2(size,(d*) a,1);
#else
d norm = 0;
us i;
for(i=0;i<size;i++){
d absa = c_abs(a[i]);
norm+=absa*absa;
}
norm = d_sqrt(norm);
return norm;
#endif
}
@ -419,9 +434,9 @@ static inline d c_norm(const c a[],us size){
* @param size: Size of the arrays
*/
void d_elem_prod_d(d res[],
const d arr1[],
const d arr2[],
const us size);
const d arr1[],
const d arr2[],
const us size);
/**
* Computes the element-wise vector product, or Hadamard product of
@ -433,9 +448,9 @@ void d_elem_prod_d(d res[],
* @param size: Size of the arrays
*/
void c_hadamard(c res[],
const c arr1[],
const c arr2[],
const us size);
const c arr1[],
const c arr2[],
const us size);
/**
* Compute the complex conjugate of a complex vector and store the
@ -446,25 +461,25 @@ void c_hadamard(c res[],
* @param size Size of the vector
*/
static inline void carray_conj(c res[],const c in[],const us size) {
// First set the result vector to zero
fsTRACE(15);
c_set(res,0,size);
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION
// Cast as a float, scale all odd elements with minus one to find
// the complex conjugate.
cblas_daxpy(size ,1.0,(d*) in,2,(d*) res,2);
cblas_daxpy(size,-1.0,&((d*) in)[1],2,&((d*) res)[1],2);
#else
cblas_faxpy(size ,1,(d*) in,2,(d*) res,2);
cblas_faxpy(size,-1,&((d*) in)[1],2,&((d*) res)[1],2);
#endif // LASP_DOUBLE_PRECISION
#else
for(us i=0;i<size;i++) {
res[i] = c_conj(in[i]);
}
#endif // LASP_USE_BLAS
feTRACE(15);
// First set the result vector to zero
fsTRACE(15);
c_set(res,0,size);
#if LASP_USE_BLAS == 1
#if LASP_DOUBLE_PRECISION == 1
// Cast as a float, scale all odd elements with minus one to find
// the complex conjugate.
cblas_daxpy(size ,1.0,(d*) in,2,(d*) res,2);
cblas_daxpy(size,-1.0,&((d*) in)[1],2,&((d*) res)[1],2);
#else
cblas_faxpy(size ,1,(d*) in,2,(d*) res,2);
cblas_faxpy(size,-1,&((d*) in)[1],2,&((d*) res)[1],2);
#endif // LASP_DOUBLE_PRECISION
#else
for(us i=0;i<size;i++) {
res[i] = c_conj(in[i]);
}
#endif // LASP_USE_BLAS
feTRACE(15);
}
/**
* In place complex conjugation
@ -473,19 +488,19 @@ static inline void carray_conj(c res[],const c in[],const us size) {
* @param size Size of the vector
*/
static inline void c_conj_inplace(c res[],us size) {
#if LASP_USE_BLAS
#if LASP_DOUBLE_PRECISION
// Cast as a float, scale all odd elements with minus one to find
// the complex conjugate.
cblas_dscal(size,-1,&((d*) res)[1],2);
#else
cblas_sscal(size,-1,&((d*) res)[1],2);
#endif // LASP_DOUBLE_PRECISION
#else
for(us i=0;i<size;i++) {
res[i] = c_conj(res[i]);
}
#endif // LASP_USE_BLAS
#if LASP_USE_BLAS
#if LASP_DOUBLE_PRECISION == 1
// Cast as a float, scale all odd elements with minus one to find
// the complex conjugate.
cblas_dscal(size,-1,&((d*) res)[1],2);
#else
cblas_sscal(size,-1,&((d*) res)[1],2);
#endif // LASP_DOUBLE_PRECISION
#else
for(us i=0;i<size;i++) {
res[i] = c_conj(res[i]);
}
#endif // LASP_USE_BLAS
}
#endif // LASP_MATH_RAW_H

View File

@ -236,7 +236,7 @@ int JobQueue_push(JobQueue* jq,void* job_ptr) {
UNLOCK_MUTEX;
return SUCCESS;
return LASP_SUCCESS;
}
void* JobQueue_assign(JobQueue* jq) {

View File

@ -10,7 +10,8 @@
#ifndef LASP_PYARRAY_H
#define LASP_PYARRAY_H
#include <numpy/ndarrayobject.h>
#ifdef LASP_DOUBLE_PRECISION
#include "lasp_types.h"
#if LASP_DOUBLE_PRECISION == 1
#define LASP_NUMPY_FLOAT_TYPE NPY_FLOAT64
#define LASP_NUMPY_COMPLEX_TYPE NPY_COMPLEX128
#else
@ -31,7 +32,16 @@ static inline void capsule_cleanup(PyObject *capsule) {
#endif
static inline PyObject *data_to_ndarray(void *data, int n_rows, int n_cols,
/**
* Create a numpy array from a raw data pointer.
*
* @param data pointer to data, assumes d* for data
* @param transfer_ownership If set to true, Numpy array will be responsible
* for freeing the data.
*
* @return Numpy array
*/
static inline PyObject *data_to_ndarray(d *data, int n_rows, int n_cols,
int typenum, bool transfer_ownership,
bool F_contiguous) {

View File

@ -8,6 +8,7 @@
#pragma once
#ifndef LASP_FILTERBANK_H
#define LASP_FILTERBANK_H
#include "lasp_config.h"
#include "lasp_types.h"
#include "lasp_mat.h"

View File

@ -3,8 +3,9 @@
// last-edit-by: J.A. de Jong
//
// Description:
//
// Debug tracing code implementation
//////////////////////////////////////////////////////////////////////
#include "lasp_config.h"
#if TRACER == 1
#include <stdio.h>
#include "lasp_tracer.h"

View File

@ -6,8 +6,9 @@
// Basic tracing code for debugging.
//////////////////////////////////////////////////////////////////////
#pragma once
#ifndef ASCEE_TRACER_H
#define ASCEE_TRACER_H
#ifndef LASP_TRACER_H
#define LASP_TRACER_H
#include "lasp_config.h"
#include "lasp_types.h"
#include <string.h>
#include <stdio.h>
@ -226,5 +227,5 @@ void uvartrace_impl(const char* pos,int line,const char* varname,size_t var);
#endif // ######################################## TRACER ==1
#endif // ASCEE_TRACER_H
#endif // LASP_TRACER_H
//////////////////////////////////////////////////////////////////////

View File

@ -9,7 +9,9 @@
#pragma once
#ifndef LASP_TYPES_H
#define LASP_TYPES_H
#include "lasp_config.h"
#include <stddef.h>
// // Branch prediction performance improvement
#if !defined(islikely) && defined(__GNUC__) && !defined(LASP_DEBUG)
#define islikely(x) __builtin_expect(!!(x), 1)
@ -20,30 +22,41 @@
#endif // !defined(likely)
/// We often use boolean values
#ifndef __cplusplus
#include <stdbool.h> // true, false
#include <stddef.h>
#include <complex.h>
#endif
typedef size_t us; /* Size type I always use */
// To change the whole code to 32-bit floating points, change this to
// float.
#if LASP_FLOAT == 32
typedef float d; /* Shortcut for double */
typedef float complex c;
#elif LASP_FLOAT == 64
typedef double d; /* Shortcut for double */
typedef double complex c;
#else
#error LASP_FLOAT should be either 32 or 64
#endif
#include <complex.h>
#ifdef __cplusplus
typedef std::complex<d> c;
#else
#if LASP_FLOAT == 32
typedef float complex c;
#else
typedef double complex c;
#endif
#endif
/// I need these numbers so often, that they can be in the global
/// namespace.
#define SUCCESS 0
#define INTERRUPTED (-3)
#define MALLOC_FAILED (-1)
#define FAILURE -2
#define LASP_SUCCESS 0
#define LASP_INTERRUPTED (-3)
#define LASP_MALLOC_FAILED (-1)
#define LASP_FAILURE (-2)
#endif // LASP_TYPES_H

View File

@ -104,7 +104,7 @@ int window_create(const WindowType wintype,vd* result,d* win_pow) {
*win_pow = signal_power(result);
feTRACE(15);
return SUCCESS;
return LASP_SUCCESS;
}

View File

@ -0,0 +1,13 @@
# Set a default build type if none was specified
set(default_build_type "Release")
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(default_build_type "Debug")
endif()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
endif()

View File

@ -1,12 +1,13 @@
set(cpp_daq_files lasp_cppdaq.cpp)
set(cpp_daq_linklibs pthread)
set(cpp_daq_linklibs ${LASP_THREADING_LIBRARIES})
include_directories(../c)
if(LASP_RTAUDIO)
if(LASP_HAS_RTAUDIO)
include_directories(/usr/include/rtaudio)
list(APPEND cpp_daq_files lasp_cpprtaudio.cpp)
list(PREPEND cpp_daq_linklibs rtaudio)
endif()
if(LASP_ULDAQ)
if(LASP_HAS_ULDAQ)
list(APPEND cpp_daq_files lasp_cppuldaq.cpp)
list(PREPEND cpp_daq_linklibs uldaq)
endif()

View File

@ -37,7 +37,7 @@ cdef extern from "lasp_pyarray.h":
bool transfer_ownership,
bool F_contiguous)
ctypedef unsigned us
ctypedef size_t us
ctypedef vector[bool] boolvec
ctypedef vector[double] dvec
ctypedef vector[us] usvec

View File

@ -1,11 +1,13 @@
#ifndef LASP_CPPDAQ_H
#define LASP_CPPDAQ_H
#include "lasp_config.h"
#include "lasp_types.h"
#ifdef HAS_RTAUDIO_API
#ifdef LASP_HAS_RTAUDIO
#include <RtAudio.h>
#endif
#ifdef HAS_ULDAQ_API
#ifdef LASP_HAS_ULDAQ
#include <uldaq.h>
#endif
@ -25,8 +27,6 @@ using std::string;
using std::vector;
using std::to_string;
typedef unsigned int us;
typedef vector<bool> boolvec;
typedef vector<double> dvec;
typedef vector<us> usvec;
@ -76,10 +76,10 @@ class DaqApi {
static vector<DaqApi> getAvailableApis();
};
#ifdef HAS_ULDAQ_API
#ifdef LASP_HAS_ULDAQ
const DaqApi uldaqapi("UlDaq", 0);
#endif
#ifdef HAS_RTAUDIO_API
#ifdef LASP_HAS_RTAUDIO
const DaqApi rtaudioAlsaApi("RtAudio Linux ALSA", 1, RtAudio::Api::LINUX_ALSA);
const DaqApi rtaudioPulseaudioApi("RtAudio Linux Pulseaudio", 2,
RtAudio::Api::LINUX_PULSE);

View File

@ -4,6 +4,7 @@
#include <thread>
#include <cstring>
#include <cassert>
#if MS_WIN64
typedef uint8_t u_int8_t;
#endif
@ -181,7 +182,7 @@ class AudioDaq: public Daq {
instreamparams,
format,
(us) samplerate(),
&nFramesPerBlock,
(unsigned*) &nFramesPerBlock,
&mycallback,
(void*) this,
&streamoptions,

View File

@ -70,7 +70,7 @@ public:
UlError err;
us numdevs = MAX_DEV_COUNT_PER_API;
err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, &numdevs);
err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, (unsigned*) &numdevs);
if (err != ERR_NO_ERROR) {
throw runtime_error("Device inventarization failed");
}
@ -531,7 +531,7 @@ void fillUlDaqDeviceInfo(vector<DeviceInfo> &devinfolist) {
DaqDeviceDescriptor descriptor;
DaqDeviceInterface interfaceType = ANY_IFC;
err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, &numdevs);
err = ulGetDaqDeviceInventory(interfaceType, devdescriptors,static_cast<unsigned*>(&numdevs));
if (err != ERR_NO_ERROR)
throw std::runtime_error("UlDaq device inventarization failed");

View File

@ -6,10 +6,10 @@ add_executable(test_workers test_workers.c)
add_executable(test_fft test_fft.c)
add_executable(test_math test_math.c)
target_link_libraries(test_bf lasp_lib)
target_link_libraries(test_fft lasp_lib)
target_link_libraries(test_workers lasp_lib)
target_link_libraries(test_math lasp_lib)
target_link_libraries(test_bf lasp_lib ${LASP_THREADING_LIBRARIES})
target_link_libraries(test_fft lasp_lib ${LASP_THREADING_LIBRARIES})
target_link_libraries(test_workers lasp_lib ${LASP_THREADING_LIBRARIES})
target_link_libraries(test_math lasp_lib ${LASP_THREADING_LIBRARIES})
if(LASP_ULDAQ)
add_executable(test_uldaq test_uldaq.cpp)