From c77bb3e71562daa68e9a195a0131b7cc04324784 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 12 Jan 2011 19:20:35 -0800 Subject: Volk: Working on a new QA architecture that doesn't require individual test programs. --- volk/lib/Makefile.am | 2 - volk/lib/qa_32fc_32f_multiply_aligned16.cc | 6 +- volk/lib/qa_8sc_deinterleave_16s_aligned16.cc | 2 +- volk/lib/qa_utils.cc | 223 ++++++++++++++++++++++++++ volk/lib/qa_utils.h | 19 +++ volk/lib/qa_volk.cc | 2 +- 6 files changed, 247 insertions(+), 7 deletions(-) create mode 100644 volk/lib/qa_utils.cc create mode 100644 volk/lib/qa_utils.h diff --git a/volk/lib/Makefile.am b/volk/lib/Makefile.am index 0aeafe4aa..a10b0a362 100644 --- a/volk/lib/Makefile.am +++ b/volk/lib/Makefile.am @@ -156,7 +156,6 @@ endif # ---------------------------------------------------------------- libvolk_qa_la_SOURCES = \ qa_volk.cc \ - qa_utils.cc \ qa_16s_quad_max_star_aligned16.cc \ qa_32fc_dot_prod_aligned16.cc \ qa_32fc_square_dist_aligned16.cc \ @@ -181,7 +180,6 @@ libvolk_qa_la_SOURCES = \ qa_32f_dot_prod_aligned16.cc \ qa_32f_dot_prod_unaligned16.cc \ qa_32f_fm_detect_aligned16.cc \ - qa_32fc_32f_multiply_aligned16.cc \ qa_32fc_multiply_aligned16.cc \ qa_32f_divide_aligned16.cc \ qa_32f_multiply_aligned16.cc \ diff --git a/volk/lib/qa_32fc_32f_multiply_aligned16.cc b/volk/lib/qa_32fc_32f_multiply_aligned16.cc index 7bb8d21c1..b80e0e008 100644 --- a/volk/lib/qa_32fc_32f_multiply_aligned16.cc +++ b/volk/lib/qa_32fc_32f_multiply_aligned16.cc @@ -5,10 +5,11 @@ #include #include #include +#include -#define ERR_DELTA (1e-4) +#define TOLERANCE (1e-4) -void qa_32fc_32f_multiply_aligned16::t1() { +void qa_32fc_32f_multiply_aligned16(void) { const int vlen = 2046; const int ITERS = 100000; @@ -72,4 +73,3 @@ void qa_32fc_32f_multiply_aligned16::t1() { free(results[i]); } } - diff --git a/volk/lib/qa_8sc_deinterleave_16s_aligned16.cc b/volk/lib/qa_8sc_deinterleave_16s_aligned16.cc index 94e63e37d..f753e1107 100644 --- a/volk/lib/qa_8sc_deinterleave_16s_aligned16.cc +++ b/volk/lib/qa_8sc_deinterleave_16s_aligned16.cc @@ -40,7 +40,7 @@ void qa_8sc_deinterleave_16s_aligned16::t1() { start = clock(); for(int count = 0; count < ITERS; ++count) { - volk_8sc_deinterleave_16s_aligned16_manual(output_generic, output_generic1, input0, vlen, "generic"); + volk_8sc_deinterleave_16s_aligned16_manual(output_generic, output_generic1, input0, vlen, "monkeys"); } end = clock(); total = (double)(end-start)/(double)CLOCKS_PER_SEC; diff --git a/volk/lib/qa_utils.cc b/volk/lib/qa_utils.cc new file mode 100644 index 000000000..4d93ca62a --- /dev/null +++ b/volk/lib/qa_utils.cc @@ -0,0 +1,223 @@ +#include "qa_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#include +#include +#include +//#include + +float uniform() { + return 2.0 * ((float) rand() / RAND_MAX - 0.5); // uniformly (-1, 1) +} + +void +random_floats (float *buf, unsigned n) +{ + for (unsigned i = 0; i < n; i++) + buf[i] = uniform (); +} + +template +t *make_aligned_buffer(unsigned int len) { + t *buf; + int ret; + ret = posix_memalign((void**)&buf, 16, len * sizeof(t)); + assert(ret == 0); + return buf; +} + +void make_buffer_for_signature(std::vector &buffs, std::vector inputsig, unsigned int vlen) { + BOOST_FOREACH(std::string sig, inputsig) { + if (sig=="32fc" || sig=="64f") buffs.push_back((void *) make_aligned_buffer(vlen)); + else if(sig=="32f" || sig=="32u" || sig=="32s" || sig=="16sc") buffs.push_back((void *) make_aligned_buffer(vlen)); + else if(sig=="16s" || sig=="16u") buffs.push_back((void *) make_aligned_buffer(vlen)); + else if(sig=="8s" || sig=="8u") buffs.push_back((void *) make_aligned_buffer(vlen)); + else std::cout << "Invalid type!" << std::endl; + } +} + +static std::vector get_arch_list(const int archs[]) { + std::vector archlist; + int num_archs = archs[0]; + + //there has got to be a way to query these arches + for(int i = 0; i < num_archs; i++) { + switch(archs[i+1]) { + case (1< valid_types = boost::assign::list_of("32fc")("32f")("32s")("32u")("16sc")("16s")("16u")("8s")("8u"); + + BOOST_FOREACH(std::string this_type, valid_types) { + if(type == this_type) return true; + } + return false; +} + + +static void get_function_signature(std::vector &inputsig, + std::vector &outputsig, + std::string name) { + boost::char_separator sep("_"); + boost::tokenizer > tok(name, sep); + std::vector toked; + tok.assign(name); + toked.assign(tok.begin(), tok.end()); + + assert(toked[0] == "volk"); + + inputsig.push_back(toked[1]); //mandatory + int pos = 2; + bool valid_type = true; + while(valid_type && pos < toked.size()) { + if(is_valid_type(toked[pos])) inputsig.push_back(toked[pos]); + else valid_type = false; + pos++; + } + while(!valid_type && pos < toked.size()) { + if(is_valid_type(toked[pos])) valid_type = true; + pos++; + } + while(valid_type && pos < toked.size()) { + if(is_valid_type(toked[pos])) outputsig.push_back(toked[pos]); + else valid_type = false; + pos++; + } + + //if there's no explicit output sig then assume the output is the same as the first input + if(outputsig.size() == 0) outputsig.push_back(inputsig[0]); + assert(inputsig.size() != 0); + assert(outputsig.size() != 0); +} + +inline void run_cast_test2(volk_fn_2arg func, void *outbuff, std::vector &inbuffs, unsigned int vlen, unsigned int iter, std::string arch) { + while(iter--) func(outbuff, inbuffs[0], vlen, arch.c_str()); +} + +inline void run_cast_test3(volk_fn_3arg func, void *outbuff, std::vector &inbuffs, unsigned int vlen, unsigned int iter, std::string arch) { + while(iter--) func(outbuff, inbuffs[0], inbuffs[1], vlen, arch.c_str()); +} + +inline void run_cast_test4(volk_fn_4arg func, void *outbuff, std::vector &inbuffs, unsigned int vlen, unsigned int iter, std::string arch) { + while(iter--) func(outbuff, inbuffs[0], inbuffs[1], inbuffs[2], vlen, arch.c_str()); +} + +bool run_volk_tests(const int archs[], void (*manual_func)(), std::string name, float tol, int vlen, int iter) { + std::cout << "RUN_VOLK_TESTS: " << name << std::endl; + + //first let's get a list of available architectures for the test + std::vector arch_list = get_arch_list(archs); + + BOOST_FOREACH(std::string arch, arch_list) { + std::cout << "Found an arch: " << arch << std::endl; + } + + //now we have to get a function signature by parsing the name + std::vector inputsig, outputsig; + get_function_signature(inputsig, outputsig, name); + + for(int i=0; i inbuffs; + make_buffer_for_signature(inbuffs, inputsig, vlen); + + //and set the input buffers to something random + //TODO + + //allocate output buffers -- one for each output for each arch + std::vector outbuffs; + BOOST_FOREACH(std::string arch, arch_list) { + make_buffer_for_signature(outbuffs, outputsig, vlen); + } + + //now run the test + clock_t start, end; + for(int i = 0; i < arch_list.size(); i++) { + start = clock(); + switch(outputsig.size()+inputsig.size()) { + case 2: + run_cast_test2((volk_fn_2arg)(manual_func), outbuffs[i], inbuffs, vlen, iter, arch_list[i]); + break; + case 3: + run_cast_test3((volk_fn_3arg)(manual_func), outbuffs[i], inbuffs, vlen, iter, arch_list[i]); + break; + case 4: + run_cast_test4((volk_fn_4arg)(manual_func), outbuffs[i], inbuffs, vlen, iter, arch_list[i]); + break; + default: + break; + } + end = clock(); + std::cout << arch_list[i] << " completed in " << (double)(end-start)/(double)CLOCKS_PER_SEC << "s" << std::endl; + } + + //and now compare each output to the generic output + //first we have to know which output is the generic one, they aren't in order... + int generic_offset; + for(int i=0; i +#include +#include + +float uniform(void); +void random_floats(float *buf, unsigned n); + +bool run_volk_tests(const int[], void(*)(), std::string, float, int, int); + +#define VOLK_RUN_TESTS(func, tol, len, iter) run_volk_tests(func##_arch_defs, (void (*)())func##_manual, std::string(#func), tol, len, iter) + +typedef void (*volk_fn_2arg)(void *, void *, unsigned int, const char*); +typedef void (*volk_fn_3arg)(void *, void *, void *, unsigned int, const char*); +typedef void (*volk_fn_4arg)(void *, void *, void *, void *, unsigned int, const char*); + +#endif //VOLK_QA_UTILS_H diff --git a/volk/lib/qa_volk.cc b/volk/lib/qa_volk.cc index c3c27b69b..8e7e59768 100644 --- a/volk/lib/qa_volk.cc +++ b/volk/lib/qa_volk.cc @@ -143,7 +143,7 @@ qa_volk::suite() s->addTest(qa_32f_dot_prod_aligned16::suite()); s->addTest(qa_32f_dot_prod_unaligned16::suite()); s->addTest(qa_32f_fm_detect_aligned16::suite()); - s->addTest(qa_32fc_32f_multiply_aligned16::suite()); + //s->addTest(qa_32fc_32f_multiply_aligned16::suite()); s->addTest(qa_32fc_multiply_aligned16::suite()); s->addTest(qa_32f_divide_aligned16::suite()); s->addTest(qa_32f_multiply_aligned16::suite()); -- cgit