diff options
author | Josh Blum <josh@joshknows.com> | 2010-06-21 15:51:33 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-06-28 11:12:19 -0700 |
commit | f0005a27c3c0ff3148bab53eefdafcad799f03cc (patch) | |
tree | 6419f1b6f72efeef439d3855689ba41f1c0ba88b /host/lib | |
parent | a34f930a79a0c626706a5f7532d8f692446d3c35 (diff) | |
download | uhd-f0005a27c3c0ff3148bab53eefdafcad799f03cc.tar.gz uhd-f0005a27c3c0ff3148bab53eefdafcad799f03cc.tar.bz2 uhd-f0005a27c3c0ff3148bab53eefdafcad799f03cc.zip |
uhd: replaced single sample converters with vector converters
easy to conditionally compile in SIMD instrinsics etc..
Diffstat (limited to 'host/lib')
-rwxr-xr-x | host/lib/transport/gen_convert_types.py | 143 |
1 files changed, 97 insertions, 46 deletions
diff --git a/host/lib/transport/gen_convert_types.py b/host/lib/transport/gen_convert_types.py index af2bcc7cb..e81bf7330 100755 --- a/host/lib/transport/gen_convert_types.py +++ b/host/lib/transport/gen_convert_types.py @@ -28,53 +28,92 @@ TMPL_TEXT = """ \#include <boost/cstdint.hpp> \#include <boost/detail/endian.hpp> \#include <stdexcept> +\#include <cstring> \#include <complex> -//define the endian macros to convert integers \#ifdef BOOST_BIG_ENDIAN - \#define BE_MACRO(x) x - \#define LE_MACRO(x) uhd::byteswap(x) static const bool is_big_endian = true; \#else - \#define BE_MACRO(x) uhd::byteswap(x) - \#define LE_MACRO(x) x static const bool is_big_endian = false; \#endif using namespace uhd; /*********************************************************************** - * Constants + * Typedefs **********************************************************************/ typedef std::complex<float> fc32_t; typedef std::complex<boost::int16_t> sc16_t; typedef boost::uint32_t item32_t; -static const float shorts_per_float = float(32767); -static const float floats_per_short = float(1.0/shorts_per_float); +/*********************************************************************** + * Convert complex short buffer to items32 + **********************************************************************/ +static UHD_INLINE void sc16_to_item32_nswap( + const sc16_t *input, item32_t *output, size_t nsamps +){ + std::memcpy(output, input, nsamps*sizeof(item32_t)); +} + +static UHD_INLINE void sc16_to_item32_bswap( + const sc16_t *input, item32_t *output, size_t nsamps +){ + const item32_t *item32_input = (const item32_t *)input; + for (size_t i = 0; i < nsamps; i++){ + output[i] = uhd::byteswap(item32_input[i]); + } +} /*********************************************************************** - * Single-sample converters + * Convert items32 buffer to complex short **********************************************************************/ -static UHD_INLINE item32_t sc16_to_item32(sc16_t num){ - boost::uint16_t real = boost::int16_t(num.real()); - boost::uint16_t imag = boost::int16_t(num.imag()); - return (item32_t(real) << 16) | (item32_t(imag) << 0); +static UHD_INLINE void item32_to_sc16_nswap( + const item32_t *input, sc16_t *output, size_t nsamps +){ + std::memcpy(output, input, nsamps*sizeof(item32_t)); } -static UHD_INLINE sc16_t item32_to_sc16(item32_t item){ - return sc16_t( - boost::uint16_t(item >> 16), - boost::uint16_t(item >> 0) - ); +static UHD_INLINE void item32_to_sc16_bswap( + const item32_t *input, sc16_t *output, size_t nsamps +){ + item32_t *item32_output = (item32_t *)output; + for (size_t i = 0; i < nsamps; i++){ + item32_output[i] = uhd::byteswap(input[i]); + } } +/*********************************************************************** + * Convert complex float buffer to items32 + **********************************************************************/ +static const float shorts_per_float = float(32767); + static UHD_INLINE item32_t fc32_to_item32(fc32_t num){ boost::uint16_t real = boost::int16_t(num.real()*shorts_per_float); boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_float); return (item32_t(real) << 16) | (item32_t(imag) << 0); } +static UHD_INLINE void fc32_to_item32_nswap( + const fc32_t *input, item32_t *output, size_t nsamps +){ + for (size_t i = 0; i < nsamps; i++){ + output[i] = fc32_to_item32(input[i]); + } +} + +static UHD_INLINE void fc32_to_item32_bswap( + const fc32_t *input, item32_t *output, size_t nsamps +){ + for (size_t i = 0; i < nsamps; i++){ + output[i] = uhd::byteswap(fc32_to_item32(input[i])); + } +} + +/*********************************************************************** + * Convert items32 buffer to complex float + **********************************************************************/ +static const float floats_per_short = float(1.0/shorts_per_float); + static UHD_INLINE fc32_t item32_to_fc32(item32_t item){ return fc32_t( float(boost::int16_t(item >> 16)*floats_per_short), @@ -82,6 +121,22 @@ static UHD_INLINE fc32_t item32_to_fc32(item32_t item){ ); } +static UHD_INLINE void item32_to_fc32_nswap( + const item32_t *input, fc32_t *output, size_t nsamps +){ + for (size_t i = 0; i < nsamps; i++){ + output[i] = item32_to_fc32(input[i]); + } +} + +static UHD_INLINE void item32_to_fc32_bswap( + const item32_t *input, fc32_t *output, size_t nsamps +){ + for (size_t i = 0; i < nsamps; i++){ + output[i] = item32_to_fc32(uhd::byteswap(input[i])); + } +} + /*********************************************************************** * Sample-buffer converters **********************************************************************/ @@ -92,21 +147,20 @@ UHD_INLINE boost::uint8_t get_pred( boost::uint8_t pred = 0; switch(otw_type.byteorder){ - case otw_type_t::BO_BIG_ENDIAN: pred |= $ph.be_p; break; - case otw_type_t::BO_LITTLE_ENDIAN: pred |= $ph.le_p; break; - ##let the compiler determine the native byte order (we could use python sys.byteorder) - case otw_type_t::BO_NATIVE: pred |= (is_big_endian)? $ph.be_p : $ph.le_p; break; + case otw_type_t::BO_BIG_ENDIAN: pred |= (is_big_endian)? $ph.nswap_p : $ph.bswap_p; break; + case otw_type_t::BO_LITTLE_ENDIAN: pred |= (is_big_endian)? $ph.bswap_p : $ph.nswap_p; break; + case otw_type_t::BO_NATIVE: pred |= $ph.nswap_p; break; default: throw std::runtime_error("unhandled byteorder type"); } - switch(otw_type.width){ - case 16: pred |= $ph.w16_p; break; + switch(otw_type.get_sample_size()){ + case sizeof(boost::uint32_t): pred |= $ph.item32_p; break; default: throw std::runtime_error("unhandled bit width"); } switch(io_type.tid){ - case io_type_t::COMPLEX_INT16: pred |= $ph.sc16_p; break; case io_type_t::COMPLEX_FLOAT32: pred |= $ph.fc32_p; break; + case io_type_t::COMPLEX_INT16: pred |= $ph.sc16_p; break; default: throw std::runtime_error("unhandled io type id"); } @@ -123,11 +177,8 @@ void transport::convert_io_type_to_otw_type( case $pred: #set $out_type = $ph.get_dev_type($pred) #set $in_type = $ph.get_host_type($pred) - #set $converter = $in_type+"_to_"+$out_type - #set $xe_macro = $ph.get_xe_macro($pred) - for (size_t i = 0; i < num_samps; i++){ - (($(out_type)_t *)otw_buff)[i] = $(xe_macro)($(converter)(((const $(in_type)_t *)io_buff)[i])); - } + #set $converter = '_'.join([$in_type, 'to', $out_type, $ph.get_swap_type($pred)]) + $(converter)((const $(in_type)_t *)io_buff, ($(out_type)_t *)otw_buff, num_samps); break; #end for } @@ -143,11 +194,8 @@ void transport::convert_otw_type_to_io_type( case $pred: #set $out_type = $ph.get_host_type($pred) #set $in_type = $ph.get_dev_type($pred) - #set $converter = $in_type+"_to_"+$out_type - #set $xe_macro = $ph.get_xe_macro($pred) - for (size_t i = 0; i < num_samps; i++){ - (($(out_type)_t *)io_buff)[i] = $(converter)($(xe_macro)(((const $(in_type)_t *)otw_buff)[i])); - } + #set $converter = '_'.join([$in_type, 'to', $out_type, $ph.get_swap_type($pred)]) + $(converter)((const $(in_type)_t *)otw_buff, ($(out_type)_t *)io_buff, num_samps); break; #end for } @@ -160,29 +208,32 @@ def parse_tmpl(_tmpl_text, **kwargs): return str(Template(_tmpl_text, kwargs)) class ph: - be_p = 0b00001 - le_p = 0b00000 - w16_p = 0b00000 - sc16_p = 0b00010 - fc32_p = 0b00000 + bswap_p = 0b00001 + nswap_p = 0b00000 + item32_p = 0b00000 + sc16_p = 0b00010 + fc32_p = 0b00000 nbits = 2 #see above @staticmethod - def get_xe_macro(pred): - if (pred & ph.be_p) == ph.be_p: return 'BE_MACRO' - if (pred & ph.le_p) == ph.le_p: return 'LE_MACRO' + def has(pred, flag): return (pred & flag) == flag + + @staticmethod + def get_swap_type(pred): + if ph.has(pred, ph.bswap_p): return 'bswap' + if ph.has(pred, ph.nswap_p): return 'nswap' raise NotImplementedError @staticmethod def get_dev_type(pred): - if (pred & ph.w16_p) == ph.w16_p: return 'item32' + if ph.has(pred, ph.item32_p): return 'item32' raise NotImplementedError @staticmethod def get_host_type(pred): - if (pred & ph.sc16_p) == ph.sc16_p: return 'sc16' - if (pred & ph.fc32_p) == ph.fc32_p: return 'fc32' + if ph.has(pred, ph.sc16_p): return 'sc16' + if ph.has(pred, ph.fc32_p): return 'fc32' raise NotImplementedError if __name__ == '__main__': |