Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion] This package may be highly benefitted from SystemC fixed-point arithmetics #252

Open
danilo-bc opened this issue Jul 29, 2021 · 9 comments
Labels
add-on Making add-ons helps enhancement

Comments

@danilo-bc
Copy link

I've been using SystemC for modelling systems with fixed-point arithmetics for a while. It focuses on describing hardware systems with C++ language and it's been pretty mature, with an IEEE Standard (https://standards.ieee.org/standard/1666-2011.html)

Section 7.10 of the standard approaches fixed-point types and their characteristics. In general, a fixed-point number can be represented and used as:

sc_fixed_fast<8, 1, SC_RND, SC_SAT> x = 0.5; //round and saturate 
sc_fixed_fast<9, 2, SC_TRN, SC_WRAP> y = 0.5; //truncate and wraparound overflow

One of the useful applications of this type system is you can have 'wide' variables to do a series of calculations and store a given value, then create a <8, 1> type to round and saturate the input to your interface. The error from converting a wide type (for example, <32, 8> storing some multiplication) to a smaller type is expected and is part of the whole analysis for the system application.

Apparently, sc_fixed_fast types always store 32/64 bit numbers, but only operate on their given number of bits. They are fast because they don't try to store and odd number of bits (such as 9) in the memory, although they obviously use more memory than necessary.

A bunch of useful operations are defined, such as bitwise AND and OR and bitshift operators (<<, >>, <<<, >>>).

Although this type system from SystemC is pretty useful, I think Julia could offer a much wider world of opportunities.

If all this sounds reasonable, I'd be glad to help. If it's not the scope of the project, it's understandable.

@kimikage
Copy link
Collaborator

I am not familiar with SystemC, but I think it is a good idea to comply with the standards of the technology used in industry.

We might need to consider the following points:

  • Currently, FixedPointNumbers is mainly used to represent colors, so incompatibilities with the downstream packages for visualization and image processing should be minimized.
  • There is no definite design consensus on whether arithmetic and rounding properties should be held by data types or by functions. However, it will be difficult to extend existing types while maintaining compatibility.
  • This package has a long cycle of minor version updates. This is not only a problem of insufficient development resources for this package, but also a problem with the downstream packages.

IMO, if you are considering taking the approach of adding new types, it might be a good idea to create them in an add-on package. Of course, that does not mean that this project is out of the scope of this package.

@danilo-bc
Copy link
Author

I think it's a bit unfortunate that the package is called FixedPointNumbers, but focuses on image processing.

I had a problem a long time ago where I used an entropy function in Matlab in the global scope not knowing it specifically calculated the entropy of an 8-bit greyscale image.

The same problem may happen here if decisions are made for images only. Take FixedPointDecimals.jl which uses the same fixed-point arithmetics basis as this package, but applies to finances.

Maybe a FixedPointBase.jl can be thought out and branched into FixedPointImages and FixedPointFinances?

That said, I'm currently unable to help with these issues, but I'm very interesting by the consequences which would come from them (I'll check with my local and web community if someone also thinks the idea is interesting & would have the time to help).

@kimikage
Copy link
Collaborator

I agree that some parts of the type hierarchy are not ideal, but I don't think it is a fatal problem for practical use.

I believe that basic data types should be identified by the properties that the types themselves should have, not by their applications.

@timholy
Copy link
Member

timholy commented Aug 2, 2021

All of the arithmetic in this package is fixed-point arithmetic. It's just that in addition to the "standard" fixed-point numbers (normalized by 2^n) there are some additional types (normalized by 2^n - 1) that are useful for image-processing, and it so happens that these are far more widely used in practice than the "standard" ones. But there's nothing misleading about calling these fixed-point.

@danilo-bc
Copy link
Author

Thanks for the input! My major problem with using this package (which, don't get me wrong, I find very useful) is that I can't do things like x = Fixed{Int8, 7}(1.3) because I get an ArgumentError, when what I really needed was for the variable to silently either overflow (and become negative) or saturate (to 0.992). This doesn't count for the truncate/round portion that I mention is present on SystemC as well, which could take 0.3 to 0.25, for example.

Am I missing some other type which doesn't throw an error in this situation?

@kimikage
Copy link
Collaborator

kimikage commented Aug 2, 2021

There is no all-around solution, but you can do something like:

julia> 1.3 % Q0f7
-0.703Q0f7

julia> clamp(1.3, Q0f7)
0.992Q0f7

@danilo-bc
Copy link
Author

Thanks for the proposal, this may help me explore my use case a bit more.

When using sc_fixed_fast in SystemC (basically writing C++ code), I'm able to do operations with <8, 1> numbers (Q0f7 if I understand your notation properly), store their results in <18, 4>, then simply do
my_8_1_result = my_18_4_var
and have the <18, 4> result be rounded and saturated the way I configure my my_8_1_result type (possibly with Traits?).

From what I understand this type of automatic type conversion is not supported and I'd always have to do attributions like
my_8_1_result = clamp(my_18_4_var, Q0f7)
as you've just shown me.

In terms of calculation performance, the sc_fixed_fast type stores things as 64-bit variables. I'm pretty sure Julia does the same approach for, say, Int8, Int16, Int32. If so, they both shouldn't have a performance penalty unless some higher-order bit-width is required (like 128-bit fixed-point numbers).

@timholy
Copy link
Member

timholy commented Aug 2, 2021

I'm pretty sure Julia does the same approach for, say, Int8, Int16, Int32.

Julia preserves the precision and uses overflow behavior. You're getting the error on initial creation but then:

julia> x = 0.6Q0f7
0.602Q0f7

julia> x + x
-0.797Q0f7

@danilo-bc
Copy link
Author

Julia preserves the precision and uses overflow behavior.

Thanks, Tim, I understand how this is implemented. My final comment there was in terms of how the variables are stored in the memory (the physical memory). SystemC has sc_fixed_fast and sc_fixed types. The _fast type provides a faster runtime by always allocating 64 bits to store values (even if the required notation uses only 8 bits).

If the suggestion of taking SystemC's fixed-point system methodology doesn't fit this particular project (since it seems widely used in the Image Processing area), I may try to fork the project and try to implement some of the automatic round/truncate, overflow/saturate functionality from SystemC.

@kimikage kimikage added enhancement add-on Making add-ons helps labels Apr 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
add-on Making add-ons helps enhancement
Projects
None yet
Development

No branches or pull requests

3 participants