Fixed bug in print_dmat and print_cmat, allow for empty dmats and cmats in some part of the code. Added dmat_foreign_vd. Some minor improvements in code and docs. WARN and DBGWARN now print to stdout instead of stderr, as Spyder taps the stderr. Improved the dFifo to handle memory better. Now dFifo does not have a maximum size anymore. Renamed Fft_alloc to Fft_create.

This commit is contained in:
Anne de Jong 2018-02-19 10:37:08 +01:00 committed by J.A. de Jong - ASCEE
parent 008876dbab
commit aa3935a82b
15 changed files with 174 additions and 160 deletions

View File

@ -16,6 +16,7 @@ add_library(beamforming_lib
mq.c mq.c
worker.c worker.c
dfifo.c dfifo.c
filter.c
) )

View File

@ -5,7 +5,7 @@
// Description: // Description:
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#define TRACERPLUS (-5)
#include "aps.h" #include "aps.h"
#include "ps.h" #include "ps.h"
#include "ascee_alg.h" #include "ascee_alg.h"
@ -170,30 +170,9 @@ cmat* AvPowerSpectra_addTimeData(AvPowerSpectra* aps,
dbgassert(timedata->n_rows > 0,"Invalid time data. " dbgassert(timedata->n_rows > 0,"Invalid time data. "
"Should at least have one row"); "Should at least have one row");
const us nsamples = timedata->n_rows;
/* Split up timedata in blocks of size ~ (FIFO_SIZE_MULT-1)nfft */
const us max_blocksize = (FIFO_SIZE_MULT-1)*nfft;
us pos = 0; /* Current position in timedata buffer */
/* dFifo handle */ /* dFifo handle */
dFifo* fifo = aps->fifo; dFifo* fifo = aps->fifo;
dFifo_push(fifo,timedata);
do {
us nsamples_part = pos+max_blocksize <= nsamples ?
max_blocksize : nsamples-pos;
/* Obtain sub matrix */
dmat timedata_part = dmat_submat(timedata,
pos, /* Startrow */
0, /* Startcol */
nsamples_part, /* n_rows */
nchannels); /* n_cols */
if(dFifo_push(fifo,&timedata_part)!=SUCCESS) {
WARN("Fifo push failed.");
}
/* Temporary storage buffer */ /* Temporary storage buffer */
dmat* buffer = &aps->buffer; dmat* buffer = &aps->buffer;
@ -213,14 +192,6 @@ cmat* AvPowerSpectra_addTimeData(AvPowerSpectra* aps,
} }
dmat_free(&timedata_part);
/* Update position */
pos+=nsamples_part;
} while (pos < nsamples);
dbgassert(pos == nsamples,"BUG");
feTRACE(15); feTRACE(15);
return &aps->ps_storage; return &aps->ps_storage;
} }

View File

@ -122,6 +122,7 @@ static inline void vc_hadamard(vc* result,const vc* a,const vc* b) {
check_overflow_vx(*b); check_overflow_vx(*b);
feTRACE(15); feTRACE(15);
} }
/** /**
* Compute the element-wise (Hadamard) product of a and b, and store * Compute the element-wise (Hadamard) product of a and b, and store
* in result * in result

View File

@ -16,7 +16,7 @@
#ifdef ASCEE_DEBUG #ifdef ASCEE_DEBUG
void print_dmat(const dmat* m) { void print_dmat(const dmat* m) {
feTRACE(50); fsTRACE(50);
size_t row,col; size_t row,col;
for(row=0;row<m->n_rows;row++){ for(row=0;row<m->n_rows;row++){
indent_trace(); indent_trace();
@ -28,10 +28,10 @@ void print_dmat(const dmat* m) {
printf("\n"); printf("\n");
} }
fsTRACE(50); feTRACE(50);
} }
void print_cmat(const cmat* m) { void print_cmat(const cmat* m) {
feTRACE(50); fsTRACE(50);
size_t row,col; size_t row,col;
for(row=0;row<m->n_rows;row++){ for(row=0;row<m->n_rows;row++){
indent_trace(); indent_trace();

View File

@ -163,10 +163,12 @@ static inline void vc_set(vc* vec,const c value){
*/ */
static inline void dmat_set(dmat* mat,const d value){ static inline void dmat_set(dmat* mat,const d value){
dbgassert(mat,NULLPTRDEREF); dbgassert(mat,NULLPTRDEREF);
if(likely(mat->n_cols && mat->n_rows)) {
for(us col=0;col<mat->n_cols;col++) { for(us col=0;col<mat->n_cols;col++) {
d_set(getdmatval(mat,0,col),value,mat->n_rows); d_set(getdmatval(mat,0,col),value,mat->n_rows);
} }
} }
}
/** /**
@ -177,10 +179,12 @@ static inline void dmat_set(dmat* mat,const d value){
*/ */
static inline void cmat_set(cmat* mat,const c value){ static inline void cmat_set(cmat* mat,const c value){
dbgassert(mat,NULLPTRDEREF); dbgassert(mat,NULLPTRDEREF);
if(likely(mat->n_cols && mat->n_rows)) {
for(us col=0;col<mat->n_cols;col++) { for(us col=0;col<mat->n_cols;col++) {
c_set(getcmatval(mat,0,col),value,mat->n_rows); c_set(getcmatval(mat,0,col),value,mat->n_rows);
} }
} }
}
/** /**
* Allocate data for a float vector. * Allocate data for a float vector.
@ -297,6 +301,24 @@ static inline dmat dmat_foreign(const us n_rows,
dmat result = {n_rows,n_cols,true,n_rows,data}; dmat result = {n_rows,n_cols,true,n_rows,data};
return result; return result;
} }
static inline dmat dmat_foreign_vd(vd* vector) {
dbgassert(vector,NULLPTRDEREF);
dmat result = {vector->size,1,true,vector->size,vector->_data};
return result;
}
/**
* Create vd from foreign data
*
* @param size Size of the vector
* @param data Pointer to data
*
* @return
*/
static inline vd vd_foreign(const us size,d* data) {
dbgassert(data,NULLPTRDEREF);
vd result = {size,true,data};
return result;
}
/** /**
* Creates a cmat from foreign data. Does not copy the data, but only * Creates a cmat from foreign data. Does not copy the data, but only
* initializes the row pointers. Assumes column-major ordering for the * initializes the row pointers. Assumes column-major ordering for the

View File

@ -208,7 +208,7 @@ static inline void cd_copy(c to[],const d from[],const us size) {
* @param to : Vector to write to * @param to : Vector to write to
* @param from : Vector to read from * @param from : Vector to read from
*/ */
static inline void c_copy(c to[],const c from[],us size){ static inline void c_copy(c to[],const c from[],const us size){
#if ASCEE_USE_BLAS == 1 #if ASCEE_USE_BLAS == 1
#if ASCEE_DOUBLE_PRECISION #if ASCEE_DOUBLE_PRECISION
@ -225,12 +225,13 @@ static inline void c_copy(c to[],const c from[],us size){
/** /**
* Multiply y with fac, and add result to x * Multiply y with fac, and add result to x
* *
* @param x Array to add to * @param x[in,out] Array to add to
* @param y Array to add to x * @param y[in] Array to add to x
* @param fac Factor with which to multiply y * @param[in] fac Factor with which to multiply y
* @param size Size of the arrays * @param[in] size Size of the arrays
*/ */
static inline void d_add_to(d x[],const d y[],d fac,us size){ static inline void d_add_to(d x[],const d y[],
const d fac,const us size){
#if ASCEE_USE_BLAS == 1 #if ASCEE_USE_BLAS == 1
#if ASCEE_DOUBLE_PRECISION #if ASCEE_DOUBLE_PRECISION
cblas_daxpy(size,fac,y,1,x,1); cblas_daxpy(size,fac,y,1,x,1);
@ -246,12 +247,13 @@ static inline void d_add_to(d x[],const d y[],d fac,us size){
/** /**
* x = x + fac*y * x = x + fac*y
* *
* @param x Array to add to * @param[in,out] x Array to add to
* @param y Array to add to x * @param[in] y Array to add to x
* @param fac Factor with which to multiply y * @param[in] fac Factor with which to multiply y
* @param size Size of the arrays * @param[in] size Size of the arrays
*/ */
static inline void c_add_to(c x[],const c y[],c fac,us size){ static inline void c_add_to(c x[],const c y[],
const c fac,const us size){
fsTRACE(15); fsTRACE(15);
#if ASCEE_USE_BLAS == 1 #if ASCEE_USE_BLAS == 1
#if ASCEE_DOUBLE_PRECISION #if ASCEE_DOUBLE_PRECISION

View File

@ -52,22 +52,22 @@ void indent_trace();
* Produce a debug warning * Produce a debug warning
*/ */
#define DBGWARN(a) \ #define DBGWARN(a) \
fprintf(stderr,RED);\ printf(RED); \
fprintf(stderr,"%s(%d): ", \ printf("%s(%d): ", \
__FILE__, \ __FILE__, \
__LINE__ \ __LINE__ \
); \ ); \
fprintf(stderr,a); \ printf(a); \
fprintf(stderr,RESET "\n"); printf(RESET "\n");
/** /**
* Produce a runtime warning * Produce a runtime warning
*/ */
#define WARN(a) \ #define WARN(a) \
fprintf(stderr,RED);\ printf(RED); \
fprintf(stderr,"WARNING: "); \ printf("WARNING: "); \
fprintf(stderr,a); \ printf(a); \
fprintf(stderr,RESET "\n"); printf(RESET "\n");
/** /**
* Fatal error, abort execution * Fatal error, abort execution

View File

@ -5,9 +5,8 @@
// Description: // Description:
// Implementation of the dFifo queue // Implementation of the dFifo queue
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#define TRACERPLUS (-5)
#include "dfifo.h" #include "dfifo.h"
#define DFIFO_QUEUE_MAX_BLOCKS (50)
typedef struct dFifo_s { typedef struct dFifo_s {
dmat queue; dmat queue;
@ -19,15 +18,46 @@ us dFifo_size(dFifo* fifo) {
dbgassert(fifo,NULLPTRDEREF); dbgassert(fifo,NULLPTRDEREF);
dbgassert(fifo->start_row <= fifo->end_row,"BUG"); dbgassert(fifo->start_row <= fifo->end_row,"BUG");
feTRACE(15); feTRACE(15);
return fifo->end_row-fifo->start_row; return fifo->end_row-fifo->start_row;
} }
/**
* Change the max size of the dFifo to a new max size specified. Max size
* should be larger than fifo size. Resets start row to 0
*
* @param fifo
* @param new_size
*/
static void dFifo_change_maxsize(dFifo* fifo,const us new_max_size) {
fsTRACE(30);
dmat old_queue = fifo->queue;
dbgassert(new_max_size >= dFifo_size(fifo),"BUG");
const us size = dFifo_size(fifo);
dmat new_queue = dmat_alloc(new_max_size,old_queue.n_cols);
if(size > 0) {
dmat_copy_rows(&new_queue,
&old_queue,
0,
fifo->start_row,
size);
}
dmat_free(&old_queue);
fifo->queue = new_queue;
fifo->end_row -= fifo->start_row;
fifo->start_row = 0;
feTRACE(30);
}
dFifo* dFifo_create(const us nchannels, dFifo* dFifo_create(const us nchannels,
const us max_size) { const us init_size) {
fsTRACE(15); fsTRACE(15);
dFifo* fifo = a_malloc(sizeof(dFifo)); dFifo* fifo = a_malloc(sizeof(dFifo));
fifo->queue = dmat_alloc(max_size,nchannels); fifo->queue = dmat_alloc(init_size,nchannels);
fifo->start_row = 0; fifo->start_row = 0;
fifo->end_row = 0; fifo->end_row = 0;
feTRACE(15); feTRACE(15);
@ -39,54 +69,37 @@ void dFifo_free(dFifo* fifo) {
a_free(fifo); a_free(fifo);
feTRACE(15); feTRACE(15);
} }
int dFifo_push(dFifo* fifo,const dmat* data) { void dFifo_push(dFifo* fifo,const dmat* data) {
fsTRACE(15); fsTRACE(15);
dbgassert(fifo && data, NULLPTRDEREF); dbgassert(fifo && data, NULLPTRDEREF);
dbgassert(data->n_cols == fifo->queue.n_cols, dbgassert(data->n_cols == fifo->queue.n_cols,
"Invalid number of columns in data"); "Invalid number of columns in data");
const us added_size = data->n_rows;
dmat queue = fifo->queue; dmat queue = fifo->queue;
const us max_size = queue.n_rows; const us max_size = queue.n_rows;
const us nchannels = queue.n_cols;
us* start_row = &fifo->start_row;
us* end_row = &fifo->end_row; us* end_row = &fifo->end_row;
const us added_size = data->n_rows;
const us size_before = dFifo_size(fifo);
if(added_size + dFifo_size(fifo) > max_size) { if(added_size + dFifo_size(fifo) > max_size) {
return FIFO_QUEUE_FULL; dFifo_change_maxsize(fifo,2*(max_size+added_size));
}
if(*end_row + added_size > max_size) { /* Now the stack of this function is not valid anymore. Best
if(size_before != 0) { * thing to do is restart the function. */
/* Shift the samples to the front of the queue. TODO: this dFifo_push(fifo,data);
* might not be the most optimal implementation (but it is the feTRACE(15);
* most simple). */ return;
TRACE(15,"Shift samples back in buffer");
uVARTRACE(15,size_before);
dmat tmp = dmat_alloc(size_before,nchannels);
TRACE(15,"SFSG");
dmat_copy_rows(&tmp,
&queue,
0,
*start_row,
size_before);
TRACE(15,"SFSG");
dmat_copy_rows(&queue,
&tmp,
0,0,size_before);
*end_row -= *start_row;
*start_row = 0;
dmat_free(&tmp);
}
else {
*start_row = 0;
*end_row = 0;
} }
else if(*end_row + added_size > max_size) {
dFifo_change_maxsize(fifo,max_size);
/* Now the stack of this function is not valid anymore. Best
* thing to do is restart the function. */
dFifo_push(fifo,data);
feTRACE(15);
return;
} }
/* Now, copy samples */ /* Now, copy samples */
@ -100,7 +113,6 @@ int dFifo_push(dFifo* fifo,const dmat* data) {
*end_row += added_size; *end_row += added_size;
feTRACE(15); feTRACE(15);
return SUCCESS;
} }
int dFifo_pop(dFifo* fifo,dmat* data,const us keep) { int dFifo_pop(dFifo* fifo,dmat* data,const us keep) {
fsTRACE(15); fsTRACE(15);
@ -111,18 +123,13 @@ int dFifo_pop(dFifo* fifo,dmat* data,const us keep) {
" be smaller than requested number of samples"); " be smaller than requested number of samples");
us* start_row = &fifo->start_row; us* start_row = &fifo->start_row;
us* end_row = &fifo->end_row; us cur_size = dFifo_size(fifo);
us cur_contents = dFifo_size(fifo);
us requested = data->n_rows; us requested = data->n_rows;
us obtained = requested > cur_contents ? cur_contents : requested; us obtained = requested > cur_size ? cur_size : requested;
dbgassert(obtained > keep,"Number of samples to keep should be" dbgassert(obtained > keep,"Number of samples to keep should be"
" smaller than requested number of samples"); " smaller than requested number of samples");
uVARTRACE(15,requested);
uVARTRACE(15,obtained);
uVARTRACE(15,*start_row);
uVARTRACE(15,*end_row);
dmat_copy_rows(data, dmat_copy_rows(data,
&fifo->queue, &fifo->queue,

View File

@ -21,11 +21,9 @@ typedef struct dFifo_s dFifo;
* @return Pointer to fifo queue (no null ptr) * @return Pointer to fifo queue (no null ptr)
*/ */
dFifo* dFifo_create(const us nchannels, dFifo* dFifo_create(const us nchannels,
const us max_size); const us init_size);
#define FIFO_QUEUE_FULL (-1)
/** /**
* Pushes samples into the fifo. * Pushes samples into the fifo.
* *
@ -33,10 +31,8 @@ dFifo* dFifo_create(const us nchannels,
* *
* @param data data to push. Number of columns should be equal to * @param data data to push. Number of columns should be equal to
* nchannels. * nchannels.
*
* @return 0 on success, FIFO_QUEUE_FULL when samples do not fit.
*/ */
int dFifo_push(dFifo* fifo,const dmat* data); void dFifo_push(dFifo* fifo,const dmat* data);
/** /**
* Pop samples from the queue * Pop samples from the queue

View File

@ -18,8 +18,12 @@ typedef struct Fft_s {
* result */ * result */
} Fft; } Fft;
Fft* Fft_alloc(const us nfft) { Fft* Fft_create(const us nfft) {
fsTRACE(15); fsTRACE(15);
if(nfft == 0) {
WARN("nfft > 0");
return NULL;
}
Fft* fft = a_malloc(sizeof(Fft)); Fft* fft = a_malloc(sizeof(Fft));
if(fft==NULL) { if(fft==NULL) {

View File

@ -24,7 +24,7 @@ typedef struct Fft_s Fft;
* *
* @return Pointer to Fft handle, NULL on error * @return Pointer to Fft handle, NULL on error
*/ */
Fft* Fft_alloc(const us nfft); Fft* Fft_create(const us nfft);
/** /**
* Returns the nfft for this Fft instance * Returns the nfft for this Fft instance
* *
@ -62,9 +62,9 @@ void Fft_fft(const Fft* fft,const dmat* timedata,cmat* result);
* *
* @param[in] fft Fft handle. * @param[in] fft Fft handle.
* @param[in] freqdata Frequency domain input data, to be iFft'th. * @param[in] freqdata Frequency domain input data, to be iFft'th.
* @param[out] result: iFft't data, should have size (nfft). * @param[out] timedata: iFft't data, should have size (nfft).
*/ */
void Fft_ifft_single(const Fft* fft,const vc* freqdata,vd* result); void Fft_ifft_single(const Fft* fft,const vc* freqdata,vd* timedata);
/** /**
* Perform inverse FFT * Perform inverse FFT

View File

@ -32,7 +32,7 @@ PowerSpectra* PowerSpectra_alloc(const us nfft,
} }
/* ALlocate space */ /* ALlocate space */
Fft* fft = Fft_alloc(nfft); Fft* fft = Fft_create(nfft);
if(fft == NULL) { if(fft == NULL) {
WARN("Fft allocation failed"); WARN("Fft allocation failed");
return NULL; return NULL;

View File

@ -10,27 +10,37 @@ IF ASCEE_FLOAT == "double":
ctypedef double complex c ctypedef double complex c
NUMPY_FLOAT_TYPE = np.float64 NUMPY_FLOAT_TYPE = np.float64
NUMPY_COMPLEX_TYPE = np.complex128 NUMPY_COMPLEX_TYPE = np.complex128
CYTHON_NUMPY_FLOAT_t = np.NPY_FLOAT64
CYTHON_NUMPY_COMPLEX_t = np.NPY_COMPLEX128
ELSE: ELSE:
ctypedef float d ctypedef float d
ctypedef float complex c ctypedef float complex c
NUMPY_FLOAT_TYPE = np.float32 NUMPY_FLOAT_TYPE = np.float32
NUMPY_COMPLEX_TYPE = np.complex128 NUMPY_COMPLEX_TYPE = np.complex64
CYTHON_NUMPY_FLOAT_t = np.NPY_FLOAT32
CYTHON_NUMPY_COMPLEX_t = np.NPY_COMPLEX64
ctypedef size_t us ctypedef size_t us
cdef extern from "ascee_tracer.h": cdef extern from "ascee_tracer.h":
void setTracerLevel(int) void setTracerLevel(int)
void TRACE(int,const char*)
void fsTRACE(int)
void feTRACE(int)
cdef extern from "ascee_math.h": cdef extern from "ascee_math.h":
ctypedef struct dmat: ctypedef struct dmat:
d* data us n_cols
d** col_ptrs us n_rows
us n_cols,n_rows d* _data
bint _foreign_data
ctypedef struct cmat: ctypedef struct cmat:
c* data pass
c** col_ptrs ctypedef struct vd:
us n_cols,n_rows pass
ctypedef struct vc:
pass
dmat dmat_foreign(us n_rows, dmat dmat_foreign(us n_rows,
us n_cols, us n_cols,
d* data) d* data)

View File

@ -17,7 +17,7 @@ def cls():
cdef extern from "fft.h": cdef extern from "fft.h":
ctypedef struct c_Fft "Fft" ctypedef struct c_Fft "Fft"
c_Fft* Fft_alloc(us nfft) c_Fft* Fft_create(us nfft)
void Fft_free(c_Fft*) void Fft_free(c_Fft*)
void Fft_fft(c_Fft*,dmat * timedate,cmat * res) nogil void Fft_fft(c_Fft*,dmat * timedate,cmat * res) nogil
void Fft_ifft(c_Fft*,cmat * freqdata,dmat* timedata) nogil void Fft_ifft(c_Fft*,cmat * freqdata,dmat* timedata) nogil
@ -30,7 +30,7 @@ cdef class Fft:
c_Fft* _fft c_Fft* _fft
def __cinit__(self, us nfft): def __cinit__(self, us nfft):
self._fft = Fft_alloc(nfft) self._fft = Fft_create(nfft)
if self._fft == NULL: if self._fft == NULL:
raise RuntimeError('Fft allocation failed') raise RuntimeError('Fft allocation failed')

View File

@ -16,7 +16,7 @@ int main() {
iVARTRACE(15,getTracerLevel()); iVARTRACE(15,getTracerLevel());
Fft* fft = Fft_alloc(100000); Fft* fft = Fft_create(100000);
/* Fft_fft(fft,NULL,NULL); */ /* Fft_fft(fft,NULL,NULL); */