Closed andrewstanfordjason closed 4 years ago
That is a good question.
We try to use unsigned types everywhere for all our bitpacked datatypes (uint8
, uint32
, uint64
depending on the bitpacking blocksize). However, Tensorflow Lite does not support setting tensor types to unsigned (with the exception of uint8
), so when the bconv has to output 32-bit bitpacked data, we can only request a signed int32
tensor from Tensorflow Lite. This is why sometimes the type is signed.
Other than that, there is no difference. Since the data is bitpacked we are not interpreting it as a number so whether it is signed or unsigned does not have much meaning here.
There is something to watch out for: we sometimes use std::numeric_limits< T >::digits
to get the number of bits in a type. This will return 31 for int32
which is not what we want, and it will return 32 for uint32
, which is what we want. That is one reason why we tried to use the unsigned type whenever possible.
Another thing to watch out for, is that if you do bit-operations, such as shifting, then a right shift >>
(arithmetic right shift) has a different effect on a signed integer. For bitpacked data, we generally want the unsigned version of >>
(logical right shift).
I hope that answers your question.
We have now standardized on 32-bit bitpacking since https://github.com/larq/compute-engine/pull/461, so we have a single TBitpacked
type, which is std::int32_t
. I'm closing this issue, but feel free to ask more questions.
I'm looking at https://github.com/larq/compute-engine/blob/master/larq_compute_engine/core/bconv2d_impl_ref.h and notice how the packed inputs and filters are std::uint32_t but when packed output are used they are std::int32_t. Is there a reason for this?