[vsipl++] [PATCH] Implement Fir<>, native C++ version
Jules Bergmann
jules at codesourcery.com
Mon Oct 10 14:07:03 UTC 2005
Nathan, Looks good. A couple of comments below. -- Jules
Nathan (Jasper) Myers wrote:
> The following patch has been committed.
>
> It implements vsip::Fir<> using native C++ code, and a comprehensive
> test of all its modes.
>
> Note that a few bits of the test are commented out; it uses
> vsip::Convolution<> to generate the reference output, and that has
> a little bug I haven't got to tracking down yet.
>
> Nathan Myers
> ncm
> + order_(kernel.size() * (1 + (symV != vsip::nonsym)) -
> + (symV == vsip::sym_even_len_odd) - 1),
Clever. This is portable, right? (i.e. do comparisons portably
evaluate to 0 or 1?)
> + decimation_(decimation),
> + skip_(0),
> + state_saved_(0),
> + state_(this->order_, T(0)),
> + kernel_(this->order_ + 1)
> + {
> + assert(input_size > 0);
> + assert(this->order_ + 1 > 1); // counter unsigned wraparound
What's going on here? The comment is a bit hard to decipher at first.
Perhaps "Use modulo arithmetic to counter the effect of unsigned
wraparound", although that doesn't fit on a single line.
Does this catch symV == odd && kernel->size() == 0:
symV kernel->size() order_
nonsym 0 -1
nonsym 1 0
even 0 -1
even 1 1
odd 0 -2 <<<
odd 1 0
How about
assert(kernel->size(0) > 0 && this->order_ >= 1);
> + // Compute rough estimate of flop-count.
> + unsigned cxmul = impl::Is_complex<T>::value ? 4 : 1; // *(4*,2+), +(2+)
A good approx is that each filter tap is a multiply-add. For complex
this is 6 ops, for real this is 2 ops.
> + return (this->timer_.count() * cxmul * 2 * // 1* 1+
> + ((this->order + 1) * this->input_size_ / this->decimation_)) /
> + (1e6 * this->timer_.total());
> + }
> + else if (!strcmp(what, "time"))
> + return this->timer_.total();
> + return 0.f;
> + }
> +
> + assert(vsip::alltrue(result == reference));
Using '==' for floating point values may cause the test to fail. For
example, if FIR and convolution perform the same operations in different
order, they may have different rounding/accumulation errors even though
they produce effectively the same answer. You should try using
'view_equal' (which uses almost_equal() underneath) or perhaps
'error_db' instead.
More information about the vsipl++
mailing list