mirror of
https://github.com/mborgerding/kissfft.git
synced 2025-05-25 20:20:26 -04:00
alignment fixing for USE_SIMD - all memory allocations are rounded
up to 16-byte boundaries. This fixes crashes where the sub-buffers for complex FFTs end up unaligned violating compiler expectations
This commit is contained in:
parent
33d9ad3bad
commit
58cf0c0fc1
@ -332,9 +332,11 @@ void kf_factor(int n,int * facbuf)
|
|||||||
* */
|
* */
|
||||||
kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
|
kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
|
||||||
{
|
{
|
||||||
|
KISS_FFT_ALIGN_CHECK(mem)
|
||||||
|
|
||||||
kiss_fft_cfg st=NULL;
|
kiss_fft_cfg st=NULL;
|
||||||
size_t memneeded = sizeof(struct kiss_fft_state)
|
size_t memneeded = KISS_FFT_ALIGN_SIZE_UP(sizeof(struct kiss_fft_state)
|
||||||
+ sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
|
+ sizeof(kiss_fft_cpx)*(nfft-1)); /* twiddle factors*/
|
||||||
|
|
||||||
if ( lenmem==NULL ) {
|
if ( lenmem==NULL ) {
|
||||||
st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
|
st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
|
||||||
|
@ -37,11 +37,15 @@ extern "C" {
|
|||||||
# define kiss_fft_scalar __m128
|
# define kiss_fft_scalar __m128
|
||||||
# ifndef KISS_FFT_MALLOC
|
# ifndef KISS_FFT_MALLOC
|
||||||
# define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
|
# define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
|
||||||
|
# define KISS_FFT_ALIGN_CHECK(ptr) assert((((uintptr_t) ptr) & 0xF) == 0);
|
||||||
|
# define KISS_FFT_ALIGN_SIZE_UP(size) ((size + 15UL) & ~0xFUL)
|
||||||
# endif
|
# endif
|
||||||
# ifndef KISS_FFT_FREE
|
# ifndef KISS_FFT_FREE
|
||||||
# define KISS_FFT_FREE _mm_free
|
# define KISS_FFT_FREE _mm_free
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
|
# define KISS_FFT_ALIGN_CHECK(ptr)
|
||||||
|
# define KISS_FFT_ALIGN_SIZE_UP(size) (size)
|
||||||
# ifndef KISS_FFT_MALLOC
|
# ifndef KISS_FFT_MALLOC
|
||||||
# define KISS_FFT_MALLOC malloc
|
# define KISS_FFT_MALLOC malloc
|
||||||
# endif
|
# endif
|
||||||
|
@ -19,11 +19,13 @@ struct kiss_fftnd_state{
|
|||||||
|
|
||||||
kiss_fftnd_cfg kiss_fftnd_alloc(const int *dims,int ndims,int inverse_fft,void*mem,size_t*lenmem)
|
kiss_fftnd_cfg kiss_fftnd_alloc(const int *dims,int ndims,int inverse_fft,void*mem,size_t*lenmem)
|
||||||
{
|
{
|
||||||
|
KISS_FFT_ALIGN_CHECK(mem)
|
||||||
|
|
||||||
kiss_fftnd_cfg st = NULL;
|
kiss_fftnd_cfg st = NULL;
|
||||||
int i;
|
int i;
|
||||||
int dimprod=1;
|
int dimprod=1;
|
||||||
size_t memneeded = sizeof(struct kiss_fftnd_state);
|
size_t memneeded = KISS_FFT_ALIGN_SIZE_UP(sizeof(struct kiss_fftnd_state));
|
||||||
char * ptr;
|
char * ptr = NULL;
|
||||||
|
|
||||||
for (i=0;i<ndims;++i) {
|
for (i=0;i<ndims;++i) {
|
||||||
size_t sublen=0;
|
size_t sublen=0;
|
||||||
@ -31,32 +33,33 @@ kiss_fftnd_cfg kiss_fftnd_alloc(const int *dims,int ndims,int inverse_fft,void*m
|
|||||||
memneeded += sublen; /* st->states[i] */
|
memneeded += sublen; /* st->states[i] */
|
||||||
dimprod *= dims[i];
|
dimprod *= dims[i];
|
||||||
}
|
}
|
||||||
memneeded += sizeof(int) * ndims;/* st->dims */
|
memneeded += KISS_FFT_ALIGN_SIZE_UP(sizeof(int) * ndims);/* st->dims */
|
||||||
memneeded += sizeof(void*) * ndims;/* st->states */
|
memneeded += KISS_FFT_ALIGN_SIZE_UP(sizeof(void*) * ndims);/* st->states */
|
||||||
memneeded += sizeof(kiss_fft_cpx) * dimprod; /* st->tmpbuf */
|
memneeded += KISS_FFT_ALIGN_SIZE_UP(sizeof(kiss_fft_cpx) * dimprod); /* st->tmpbuf */
|
||||||
|
|
||||||
if (lenmem == NULL) {/* allocate for the caller*/
|
if (lenmem == NULL) {/* allocate for the caller*/
|
||||||
st = (kiss_fftnd_cfg) malloc (memneeded);
|
ptr = (char *) malloc (memneeded);
|
||||||
} else { /* initialize supplied buffer if big enough */
|
} else { /* initialize supplied buffer if big enough */
|
||||||
if (*lenmem >= memneeded)
|
if (*lenmem >= memneeded)
|
||||||
st = (kiss_fftnd_cfg) mem;
|
ptr = (char *) mem;
|
||||||
*lenmem = memneeded; /*tell caller how big struct is (or would be) */
|
*lenmem = memneeded; /*tell caller how big struct is (or would be) */
|
||||||
}
|
}
|
||||||
if (!st)
|
if (!ptr)
|
||||||
return NULL; /*malloc failed or buffer too small */
|
return NULL; /*malloc failed or buffer too small */
|
||||||
|
|
||||||
|
st = (kiss_fftnd_cfg) ptr;
|
||||||
st->dimprod = dimprod;
|
st->dimprod = dimprod;
|
||||||
st->ndims = ndims;
|
st->ndims = ndims;
|
||||||
ptr=(char*)(st+1);
|
ptr += KISS_FFT_ALIGN_SIZE_UP(sizeof(struct kiss_fftnd_state));
|
||||||
|
|
||||||
st->states = (kiss_fft_cfg *)ptr;
|
st->states = (kiss_fft_cfg *)ptr;
|
||||||
ptr += sizeof(void*) * ndims;
|
ptr += KISS_FFT_ALIGN_SIZE_UP(sizeof(void*) * ndims);
|
||||||
|
|
||||||
st->dims = (int*)ptr;
|
st->dims = (int*)ptr;
|
||||||
ptr += sizeof(int) * ndims;
|
ptr += KISS_FFT_ALIGN_SIZE_UP(sizeof(int) * ndims);
|
||||||
|
|
||||||
st->tmpbuf = (kiss_fft_cpx*)ptr;
|
st->tmpbuf = (kiss_fft_cpx*)ptr;
|
||||||
ptr += sizeof(kiss_fft_cpx) * dimprod;
|
ptr += KISS_FFT_ALIGN_SIZE_UP(sizeof(kiss_fft_cpx) * dimprod);
|
||||||
|
|
||||||
for (i=0;i<ndims;++i) {
|
for (i=0;i<ndims;++i) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -29,36 +29,44 @@ static int prod(const int *dims, int ndims)
|
|||||||
|
|
||||||
kiss_fftndr_cfg kiss_fftndr_alloc(const int *dims,int ndims,int inverse_fft,void*mem,size_t*lenmem)
|
kiss_fftndr_cfg kiss_fftndr_alloc(const int *dims,int ndims,int inverse_fft,void*mem,size_t*lenmem)
|
||||||
{
|
{
|
||||||
|
KISS_FFT_ALIGN_CHECK(mem)
|
||||||
|
|
||||||
kiss_fftndr_cfg st = NULL;
|
kiss_fftndr_cfg st = NULL;
|
||||||
size_t nr=0 , nd=0,ntmp=0;
|
size_t nr=0 , nd=0,ntmp=0;
|
||||||
int dimReal = dims[ndims-1];
|
int dimReal = dims[ndims-1];
|
||||||
int dimOther = prod(dims,ndims-1);
|
int dimOther = prod(dims,ndims-1);
|
||||||
size_t memneeded;
|
size_t memneeded;
|
||||||
|
char * ptr = NULL;
|
||||||
|
|
||||||
(void)kiss_fftr_alloc(dimReal,inverse_fft,NULL,&nr);
|
(void)kiss_fftr_alloc(dimReal,inverse_fft,NULL,&nr);
|
||||||
(void)kiss_fftnd_alloc(dims,ndims-1,inverse_fft,NULL,&nd);
|
(void)kiss_fftnd_alloc(dims,ndims-1,inverse_fft,NULL,&nd);
|
||||||
ntmp =
|
ntmp =
|
||||||
MAX( 2*dimOther , dimReal+2) * sizeof(kiss_fft_scalar) // freq buffer for one pass
|
MAX( 2*dimOther , dimReal+2) * sizeof(kiss_fft_scalar) // freq buffer for one pass
|
||||||
+ dimOther*(dimReal+2) * sizeof(kiss_fft_scalar); // large enough to hold entire input in case of in-place
|
+ dimOther*(dimReal+2) * sizeof(kiss_fft_scalar); // large enough to hold entire input in case of in-place
|
||||||
|
|
||||||
memneeded = sizeof( struct kiss_fftndr_state ) + nr + nd + ntmp;
|
memneeded = KISS_FFT_ALIGN_SIZE_UP(sizeof( struct kiss_fftndr_state )) + KISS_FFT_ALIGN_SIZE_UP(nr) + KISS_FFT_ALIGN_SIZE_UP(nd) + KISS_FFT_ALIGN_SIZE_UP(ntmp);
|
||||||
|
|
||||||
if (lenmem==NULL) {
|
if (lenmem==NULL) {
|
||||||
st = (kiss_fftndr_cfg) malloc(memneeded);
|
ptr = (char*) malloc(memneeded);
|
||||||
}else{
|
}else{
|
||||||
if (*lenmem >= memneeded)
|
if (*lenmem >= memneeded)
|
||||||
st = (kiss_fftndr_cfg)mem;
|
ptr = (char *)mem;
|
||||||
*lenmem = memneeded;
|
*lenmem = memneeded;
|
||||||
}
|
}
|
||||||
if (st==NULL)
|
if (ptr==NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
st = (kiss_fftndr_cfg) ptr;
|
||||||
memset( st , 0 , memneeded);
|
memset( st , 0 , memneeded);
|
||||||
|
ptr += KISS_FFT_ALIGN_SIZE_UP(sizeof(struct kiss_fftndr_state));
|
||||||
|
|
||||||
st->dimReal = dimReal;
|
st->dimReal = dimReal;
|
||||||
st->dimOther = dimOther;
|
st->dimOther = dimOther;
|
||||||
st->cfg_r = kiss_fftr_alloc( dimReal,inverse_fft,st+1,&nr);
|
st->cfg_r = kiss_fftr_alloc( dimReal,inverse_fft,ptr,&nr);
|
||||||
st->cfg_nd = kiss_fftnd_alloc(dims,ndims-1,inverse_fft, ((char*) st->cfg_r)+nr,&nd);
|
ptr += KISS_FFT_ALIGN_SIZE_UP(nr);
|
||||||
st->tmpbuf = (char*)st->cfg_nd + nd;
|
st->cfg_nd = kiss_fftnd_alloc(dims,ndims-1,inverse_fft, ptr,&nd);
|
||||||
|
ptr += KISS_FFT_ALIGN_SIZE_UP(nd);
|
||||||
|
st->tmpbuf = ptr;
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ struct kiss_fftr_state{
|
|||||||
|
|
||||||
kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
|
kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
|
||||||
{
|
{
|
||||||
|
KISS_FFT_ALIGN_CHECK(mem)
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
kiss_fftr_cfg st = NULL;
|
kiss_fftr_cfg st = NULL;
|
||||||
size_t subsize = 0, memneeded;
|
size_t subsize = 0, memneeded;
|
||||||
|
Loading…
Reference in New Issue
Block a user