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

Create mixed precision integer operations #75

Closed
stephenneuendorffer opened this issue Sep 2, 2020 · 13 comments
Closed

Create mixed precision integer operations #75

stephenneuendorffer opened this issue Sep 2, 2020 · 13 comments
Labels
enhancement New feature or request

Comments

@stephenneuendorffer
Copy link
Contributor

HLS often uses arbitrary precision arithmetic. In this model, most operations (e.g. add, multiply) have wider results than their input, in order to represent all the possible result values without overflow. Explicit Truncation operations are necessary in order to limit the growth of values. The rules are roughly:

bitwidth(a + b) = max(bitwidth(a), bitwidth(b)) + 1
bitwidth(a - b) = max(bitwidth(a), bitwidth(b)) + 1
bitwidth(a * b) = bitwidth(a) + bitwidth(b)
bitwidth(a / b) = bitwidth(a)

Most other operations are relatively straightforward. Note that division is often not exact, because only integer results are possible. A bitwidth-inference pass which propagates bitwidths from inputs through such operations, converting standard operations into arbitrary precision operations with explicit truncation would be interesting as well.

@stephenneuendorffer stephenneuendorffer added enhancement New feature or request good first issue Good for newcomers labels Sep 2, 2020
@cgyurgyik
Copy link
Member

Hey Steve. I had a few contextual questions to begin.

  1. Where would be an appropriate place for this, as well as naming schema?
  2. Where can I find how HLS represents arbitrary precision arithmetic for the purposes of this issue, such as getting a number's bitwidth?

@stephenneuendorffer
Copy link
Contributor Author

Hey Steve. I had a few contextual questions to begin.

  1. Where would be an appropriate place for this, as well as naming schema?

I would add an "ap" (for 'Arbitrary Precision') dialect to circt. This should use regular standard MLIR datatypes (e.g. 'i14' or 'i32'), but the input and output types need to be specified. In contrast, the standard operations assume that the input and outputs all have the same types. In a nice custom operation format, this would end up something like:

%1 = ap.add(%a:i14, %b:i12) : i15

  1. Where can I find how HLS represents arbitrary precision arithmetic for the purposes of this issue, such as getting a number's bitwidth?

MLIR (and LLVM) already support arbitrary precision signed and unsigned types (see above). The trick is to add arbitrary precision operations. See https://mlir.llvm.org/docs/LangRef/#integer-type and https://mlir.llvm.org/doxygen/classmlir_1_1IntegerType.html

@cgyurgyik
Copy link
Member

Ok so after doing some poking around,
AddIOp

We want to do something similar to that, with two changes mentioned above:

  1. Input and output types need to be specified.
  2. Apply the necessary bitwidth truncation.

Can you explain what you mean by "the types to be specified"? I understand what you mean at the English level, but having some trouble understanding how this is done within LLVM/MLIR. Maybe an example of it done elsewhere is better fit for this.

@stephenneuendorffer
Copy link
Contributor Author

Sure. Looking here: https://github.com/llvm/llvm-project/blob/master/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td
AddIOp derives (eventually) from ArithmeticOp, which has a SameOperandsAndResultType constraint. ArithmeticOp also implements a custom parser and printer that implements the syntax above, but requires the common type to only be specified once. In the generic IR format, the same type would appear 3 times, once for the result type and again for each argument type. For ap.add, the constraint is not correct (and can be removed) and the custom parser/printer could have a syntax where only the argument types are specified and the result type is implicit. Does this help?

@lattner
Copy link
Collaborator

lattner commented Sep 12, 2020

It's not clear to me that we want the basic operations like + to take mixed width operands. This makes analysis and transformation more difficult, e.g. see the challenges working with the FIRRTL dialect (it follows FIRRTL design closely, which has this property). A bunch of transformations get disabled when types don't match as expected, and we've already had bugs where the check was missed. Here is one random example.

What is the downside to making the extensions explicit in the IR? I understand that you wouldn't want that in a human exposed language, but the constraints on the IR are a bit different.

@lattner lattner changed the title Create arbitrary precision integer operations Create mixed precision integer operations Sep 12, 2020
@stephenneuendorffer
Copy link
Contributor Author

stephenneuendorffer commented Sep 12, 2020 via email

@lattner
Copy link
Collaborator

lattner commented Sep 12, 2020

Sure, I agree that frontend-specific dialects make sense. That's the same reason the FIRRTL dialect follows the definition of FIRRTL pretty closely.

@stephenneuendorffer
Copy link
Contributor Author

Variadic operations are a good example of when it gets nastier: if you have a 4 input add, each input needs at least 2 bits of sign extension to avoid truncation in the add. If inputs to the add get optimized away then a nonlocal bitwidth analysis is needed to determine that the extensions can be reduced in width.

@cgyurgyik
Copy link
Member

Was there ever a consensus made on this? I would like to take a crack at it if so. Otherwise, I'm interested in some small (non-blocking) sub-project to both contribute and continue learning LLVM and MLIR :)

@lattner
Copy link
Collaborator

lattner commented Oct 14, 2020

I would still like to resist this as long as possible. Please don't do this proactively.

@stephenneuendorffer
Copy link
Contributor Author

I'm happy to work with you on it, especially if it helps Chris convince me that it's a bad idea. :)

@cgyurgyik
Copy link
Member

Sounds good. I'm still interested, I just have university and research priorities to commit to first before taking this on; this may need to come after the semester is over.

@lattner lattner removed the good first issue Good for newcomers label Nov 23, 2020
@lattner
Copy link
Collaborator

lattner commented Jun 20, 2021

Closing this as "behaves correctly" for the comb dialect.

@lattner lattner closed this as completed Jun 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants