shun_iwasawa a35b8f
#!/usr/bin/env python
shun_iwasawa a35b8f
shun_iwasawa a35b8f
import math
shun_iwasawa a35b8f
import sys
shun_iwasawa a35b8f
import os
shun_iwasawa a35b8f
import random
shun_iwasawa a35b8f
import struct
shun_iwasawa a35b8f
import popen2
shun_iwasawa a35b8f
import getopt
shun_iwasawa a35b8f
import numpy
shun_iwasawa a35b8f
shun_iwasawa a35b8f
pi=math.pi
shun_iwasawa a35b8f
e=math.e
shun_iwasawa a35b8f
j=complex(0,1)
shun_iwasawa a35b8f
shun_iwasawa a35b8f
doreal=0
shun_iwasawa a35b8f
shun_iwasawa a35b8f
datatype = os.environ.get('DATATYPE','float')
shun_iwasawa a35b8f
shun_iwasawa a35b8f
util = '../tools/fft_' + datatype
shun_iwasawa a35b8f
minsnr=90
shun_iwasawa a35b8f
if datatype == 'double':
shun_iwasawa a35b8f
    fmt='d'
shun_iwasawa a35b8f
elif datatype=='int16_t':
shun_iwasawa a35b8f
    fmt='h'
shun_iwasawa a35b8f
    minsnr=10
shun_iwasawa a35b8f
elif datatype=='int32_t':
shun_iwasawa a35b8f
    fmt='i'
shun_iwasawa a35b8f
elif datatype=='simd':
shun_iwasawa a35b8f
    fmt='4f'
shun_iwasawa a35b8f
    sys.stderr.write('testkiss.py does not yet test simd')
shun_iwasawa a35b8f
    sys.exit(0)
shun_iwasawa a35b8f
elif datatype=='float':
shun_iwasawa a35b8f
    fmt='f'
shun_iwasawa a35b8f
else:
shun_iwasawa a35b8f
    sys.stderr.write('unrecognized datatype %s\n' % datatype)
shun_iwasawa a35b8f
    sys.exit(1)
shun_iwasawa a35b8f
 
shun_iwasawa a35b8f
shun_iwasawa a35b8f
def dopack(x,cpx=1):
shun_iwasawa a35b8f
    x = numpy.reshape( x, ( numpy.size(x),) )
shun_iwasawa a35b8f
    
shun_iwasawa a35b8f
    if cpx:
shun_iwasawa a35b8f
        s = ''.join( [ struct.pack(fmt*2,c.real,c.imag) for c in x ] )
shun_iwasawa a35b8f
    else:
shun_iwasawa a35b8f
        s = ''.join( [ struct.pack(fmt,c.real) for c in x ] )
shun_iwasawa a35b8f
    return s
shun_iwasawa a35b8f
shun_iwasawa a35b8f
def dounpack(x,cpx):
shun_iwasawa a35b8f
    uf = fmt * ( len(x) / struct.calcsize(fmt) )
shun_iwasawa a35b8f
    s = struct.unpack(uf,x)
shun_iwasawa a35b8f
    if cpx:
shun_iwasawa a35b8f
        return numpy.array(s[::2]) + numpy.array( s[1::2] )*j
shun_iwasawa a35b8f
    else:
shun_iwasawa a35b8f
        return numpy.array(s )
shun_iwasawa a35b8f
shun_iwasawa a35b8f
def make_random(dims=[1]):
shun_iwasawa a35b8f
    res = []
shun_iwasawa a35b8f
    for i in range(dims[0]):
shun_iwasawa a35b8f
        if len(dims)==1:
shun_iwasawa a35b8f
            r=random.uniform(-1,1)
shun_iwasawa a35b8f
            if doreal:
shun_iwasawa a35b8f
                res.append( r )
shun_iwasawa a35b8f
            else:
shun_iwasawa a35b8f
                i=random.uniform(-1,1)
shun_iwasawa a35b8f
                res.append( complex(r,i) )
shun_iwasawa a35b8f
        else:
shun_iwasawa a35b8f
            res.append( make_random( dims[1:] ) )
shun_iwasawa a35b8f
    return numpy.array(res)
shun_iwasawa a35b8f
shun_iwasawa a35b8f
def flatten(x):
shun_iwasawa a35b8f
    ntotal = numpy.size(x)
shun_iwasawa a35b8f
    return numpy.reshape(x,(ntotal,))
shun_iwasawa a35b8f
shun_iwasawa a35b8f
def randmat( ndims ):
shun_iwasawa a35b8f
    dims=[]
shun_iwasawa a35b8f
    for i in range( ndims ):
shun_iwasawa a35b8f
        curdim = int( random.uniform(2,5) )
shun_iwasawa a35b8f
        if doreal and i==(ndims-1):
shun_iwasawa a35b8f
            curdim = int(curdim/2)*2 # force even last dimension if real
shun_iwasawa a35b8f
        dims.append( curdim )
shun_iwasawa a35b8f
    return make_random(dims )
shun_iwasawa a35b8f
shun_iwasawa a35b8f
def test_fft(ndims):
shun_iwasawa a35b8f
    x=randmat( ndims )
shun_iwasawa a35b8f
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    if doreal:
shun_iwasawa a35b8f
        xver = numpy.fft.rfftn(x)
shun_iwasawa a35b8f
    else:
shun_iwasawa a35b8f
        xver = numpy.fft.fftn(x)
shun_iwasawa a35b8f
    
shun_iwasawa a35b8f
    open('/tmp/fftexp.dat','w').write(dopack( flatten(xver) , True ) )
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    x2=dofft(x,doreal)
shun_iwasawa a35b8f
    err = xver - x2
shun_iwasawa a35b8f
    errf = flatten(err)
shun_iwasawa a35b8f
    xverf = flatten(xver)
shun_iwasawa a35b8f
    errpow = numpy.vdot(errf,errf)+1e-10
shun_iwasawa a35b8f
    sigpow = numpy.vdot(xverf,xverf)+1e-10
shun_iwasawa a35b8f
    snr = 10*math.log10(abs(sigpow/errpow) )
shun_iwasawa a35b8f
    print 'SNR (compared to NumPy) : %.1fdB' % float(snr)
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    if snr
shun_iwasawa a35b8f
        print 'xver=',xver
shun_iwasawa a35b8f
        print 'x2=',x2
shun_iwasawa a35b8f
        print 'err',err
shun_iwasawa a35b8f
        sys.exit(1)
shun_iwasawa a35b8f
 
shun_iwasawa a35b8f
def dofft(x,isreal):
shun_iwasawa a35b8f
    dims=list( numpy.shape(x) )
shun_iwasawa a35b8f
    x = flatten(x)
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    scale=1
shun_iwasawa a35b8f
    if datatype=='int16_t':
shun_iwasawa a35b8f
        x = 32767 * x
shun_iwasawa a35b8f
        scale = len(x) / 32767.0
shun_iwasawa a35b8f
    elif datatype=='int32_t':
shun_iwasawa a35b8f
        x = 2147483647.0 * x
shun_iwasawa a35b8f
        scale = len(x) / 2147483647.0
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    cmd='%s -n ' % util
shun_iwasawa a35b8f
    cmd += ','.join([str(d) for d in dims])
shun_iwasawa a35b8f
    if doreal:
shun_iwasawa a35b8f
        cmd += ' -R '
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    print cmd
shun_iwasawa a35b8f
    p = popen2.Popen3(cmd )
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    open('/tmp/fftin.dat','w').write(dopack( x , isreal==False ) )
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    p.tochild.write( dopack( x , isreal==False ) )
shun_iwasawa a35b8f
    p.tochild.close()
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    res = dounpack( p.fromchild.read() , 1 )
shun_iwasawa a35b8f
    open('/tmp/fftout.dat','w').write(dopack( flatten(res) , True ) )
shun_iwasawa a35b8f
    if doreal:
shun_iwasawa a35b8f
        dims[-1] = int( dims[-1]/2 ) + 1
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    res = scale * res
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    p.wait()
shun_iwasawa a35b8f
    return numpy.reshape(res,dims)
shun_iwasawa a35b8f
shun_iwasawa a35b8f
def main():
shun_iwasawa a35b8f
    opts,args = getopt.getopt(sys.argv[1:],'r')
shun_iwasawa a35b8f
    opts=dict(opts)
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    global doreal
shun_iwasawa a35b8f
    doreal = opts.has_key('-r')
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    if doreal:
shun_iwasawa a35b8f
        print 'Testing multi-dimensional real FFTs'
shun_iwasawa a35b8f
    else:
shun_iwasawa a35b8f
        print 'Testing multi-dimensional FFTs'
shun_iwasawa a35b8f
shun_iwasawa a35b8f
    for dim in range(1,4):
shun_iwasawa a35b8f
        test_fft( dim )
shun_iwasawa a35b8f
shun_iwasawa a35b8f
if __name__ == "__main__":
shun_iwasawa a35b8f
    main()
shun_iwasawa a35b8f