larq / compute-engine

Highly optimized inference engine for Binarized Neural Networks
https://docs.larq.dev/compute-engine
Apache License 2.0
243 stars 35 forks source link

DstScalar Type #428

Closed andrewstanfordjason closed 4 years ago

andrewstanfordjason commented 4 years ago

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?

Tombana commented 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.

Tombana commented 4 years ago

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.