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

exp operator producing negative values when x is a large negative number. #505

Open
cgyurgyik opened this issue May 8, 2021 · 5 comments
Labels
S: Available Can be worked upon

Comments

@cgyurgyik
Copy link
Collaborator

Program:

python3 calyx-py/calyx/gen_exp.py tests/correctness/exp/degree-4-signed.txt

Data:

{
  "x": {
    "data": [
      -4000.0
    ],
    "format": {
      "numeric_type": "fixed_point",
      "is_signed": true,
      "width": 32,
      "int_width": 16
    }
  },
  "ret": {
    "data": [
      0.0
    ],
   "format": {
      "numeric_type": "fixed_point",
      "is_signed": true,
      "width": 32,
      "int_width": 16
    }
  }
}

Output: "-0.00189208984375"
This should be 0.

@cgyurgyik
Copy link
Collaborator Author

This may be a good starting point to transition to an actual LUT exp rather than my Taylor Series expansion.

@rachitnigam
Copy link
Contributor

While I am able to simulate the component and reproduce the error, I have no clue why it happens. The interpreter says there is an overflow:

WARN - Over/underflow in fixed-point multiplier: 69218.52006149594672024250030517578125 to 3682.520050048828125
WARN - Over/underflow in fixed-point multiplier: 73964.9963769479654729366302490234375 to 8428.996368408203125

So maybe we have a place to root-cause this.

To reproduce, run fud e --to interpreter-out exp.futil -s verilog.data exp.json -vv

@cgyurgyik
Copy link
Collaborator Author

When the type is signed and the value is less than zero, the exp generator will compute e^-4000 as 1 / e^4000:
https://github.com/cucapra/calyx/blob/a14ce9d743d882d3cadd927cbb3be797a3dc42bf/calyx-py/calyx/gen_exp.py#L503-L536

Since this has no decimal places in it, we are computing e^4000 as fp_pow(e, 4000):

https://github.com/cucapra/calyx/blob/a14ce9d743d882d3cadd927cbb3be797a3dc42bf/calyx-py/calyx/gen_exp.py#L632-L643

A simple fix is to add a cut-off if x is a very large negative number, and instead return 0.

@rachitnigam
Copy link
Contributor

Thanks for explaining the problem! One possible option is implementing “saturating” mathematical operators which, instead of overflowing, clamp the outputs to either a maximum or a minimum. So In this case, it’d clamp the value generated by the divider to 0.

@rachitnigam rachitnigam added S: Available Can be worked upon and removed S: Needs Triage Issue needs some thinking labels Nov 27, 2021
@rachitnigam
Copy link
Contributor

For anyone who wants to work on this issue, there are two possible options:

  1. Update the exp generator to have a check for extremely large negative numbers and just return 0 when it meets some threshold.
  2. Implement a "saturating divide" operator in the primitive library and use that instead of the standard divider. This might come down to implementing the threshold check inside the divider instead of the exp.

@calebmkim calebmkim mentioned this issue Oct 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S: Available Can be worked upon
Projects
None yet
Development

No branches or pull requests

2 participants