Skip to content

Conversation

@creavin
Copy link
Collaborator

@creavin creavin commented Sep 14, 2025

This new type enables DaCe users to perform calculations with stochastic rounding in single precision.

This change is validated with unit tests.

@phschaad
Copy link
Collaborator

It appears this PR is still failing tests, will there be any more movement on this?

@phschaad phschaad added the waiting for author Will be closed in 30 days label Oct 30, 2025
Copy link
Contributor

@acalotoiu acalotoiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests would need to be fixed. I am also not sure if we should aim merging to main before trying to work on improving the performance of the SR implementation.

@creavin
Copy link
Collaborator Author

creavin commented Nov 17, 2025

Ack, will (attempt to) fix the tests this week

This new type enables DaCe users to perform calculations with stochastic
rounding in single precision.

This change is validated with unit tests.
@creavin
Copy link
Collaborator Author

creavin commented Nov 23, 2025

Okay, all tests pass except for the FPGA Tests. I fixed the linking error. Now it fails because I use an incompatible abs function and it doesn't support thread-local [1].

I don't have a setup in which I can debug this. I see Lex's comment that the performance of this should be evaluated further before pulling it into main. What I would suggest is that maybe you move this to a feature / experimental branch and when this eval is being done, one tries run this on your FPGA setup and find the compatible alternatives to abs and thread-local.

[](https://github.com/spcl/dace/actions/runs/19598553709/job/56126669713?pr=2148#step:4:446)WARNING: [HLS 207-5324] using integer absolute value function 'abs' when argument is of floating point type (/home/timos/actions-runner/_work/dace/dace/dace/codegen/../runtime/include/dace/stocastic_rounding.h:58:13)

[](https://github.com/spcl/dace/actions/runs/19598553709/job/56126669713?pr=2148#step:4:447)INFO: [HLS 207-4500] use function 'std::abs' instead (/home/timos/actions-runner/_work/dace/dace/dace/codegen/../runtime/include/dace/stocastic_rounding.h:58:13)

[](https://github.com/spcl/dace/actions/runs/19598553709/job/56126669713?pr=2148#step:4:448)ERROR: [HLS 207-3638] thread-local storage is not supported for the current target (/home/timos/actions-runner/_work/dace/dace/dace/codegen/../runtime/include/dace/stocastic_rounding.h:196:7)

@creavin creavin removed the waiting for author Will be closed in 30 days label Nov 23, 2025
@creavin creavin requested a review from phschaad November 23, 2025 12:52
@tbennun
Copy link
Collaborator

tbennun commented Jan 10, 2026

@creavin Maybe try again after #2252 is merged.

@creavin
Copy link
Collaborator Author

creavin commented Jan 10, 2026 via email

Copy link
Collaborator

@phschaad phschaad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments and minor changes before I can accept, but overall happy with the change, thanks!

restype = np_result_type(dtypes_for_result)
coarse_result_type = None
if result_type in complex_types:
if restype in complex_types:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is/was result_type, why did this change? Was this a bug?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bug introduced by this refactor: c909f8b#diff-b20441227a628465d1c6ca8819915b77cf036f8fc1a8e26fbceb8a930fde9d1dR353

The origional code, formerly in the replacements.py file, looked like

    else:  # Operators with 3 or more arguments
        result_type = _np_result_type(dtypes_for_result)
        coarse_result_type = None
        if result_type in complex_types:
            coarse_result_type = 3  # complex
        elif result_type in float_types:
            coarse_result_type = 2  # float
        elif result_type in signed_types:
            coarse_result_type = 1  # signed integer, bool
        else:
            coarse_result_type = 0  # unsigned integer
        for i, t in enumerate(coarse_types):
            if t != coarse_result_type:
                casting[i] = _cast_str(result_type)

I believe this var was renamed to restype to not conflict when the "result_type" function

raise TypeError(f"Data types of input and output must be equal: {desc_x.dtype}, {desc_res.dtype}")
input_types = (desc_x.dtype.base_type, desc_res.dtype.base_type)
if dace.float32sr in input_types and dace.float32sr in input_types:
pass # ignore mismatch if it is stochastically rounded
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an expert on SR types, so my question here is: can we safely do that, or rather - why can we safely do that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made a typo here -- thank you for catching that. Line 210 should be:
if dace.float32sr in input_types and dace.float32 in input_types:. I will also rename input_types to arg_types and add more comments

What this does and why it's needed: when using stocastic rounding, a legitimate (i.e not a bug) mismatch between the input and output arguments may arise where one argument is a float32sr and the other is a float32 (round-to-nearest). The underlying data type is the same so this should not cause the validation to fail. This is a check for that edge-case

#endif

DACE_HOST_DEVICE static float stochastic_round(double x) {
// uint64_t rbits = lcg64();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these commented out lines still carry significance?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So as part of my thesis, I make a comparison between five different rounding modes. I kept the functions and these commented out invocations partly for posterity and partly to allow future devs to play around with it.

I think there is value in keeping this. I will make this into one compact comment to reduce its footprint. If you disgree, I can remove the comment and the associated functions

@creavin
Copy link
Collaborator Author

creavin commented Jan 13, 2026 via email

Copy link
Collaborator Author

@creavin creavin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed all feedback item. Corrections to follow in next commit

restype = np_result_type(dtypes_for_result)
coarse_result_type = None
if result_type in complex_types:
if restype in complex_types:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bug introduced by this refactor: c909f8b#diff-b20441227a628465d1c6ca8819915b77cf036f8fc1a8e26fbceb8a930fde9d1dR353

The origional code, formerly in the replacements.py file, looked like

    else:  # Operators with 3 or more arguments
        result_type = _np_result_type(dtypes_for_result)
        coarse_result_type = None
        if result_type in complex_types:
            coarse_result_type = 3  # complex
        elif result_type in float_types:
            coarse_result_type = 2  # float
        elif result_type in signed_types:
            coarse_result_type = 1  # signed integer, bool
        else:
            coarse_result_type = 0  # unsigned integer
        for i, t in enumerate(coarse_types):
            if t != coarse_result_type:
                casting[i] = _cast_str(result_type)

I believe this var was renamed to restype to not conflict when the "result_type" function

raise TypeError(f"Data types of input and output must be equal: {desc_x.dtype}, {desc_res.dtype}")
input_types = (desc_x.dtype.base_type, desc_res.dtype.base_type)
if dace.float32sr in input_types and dace.float32sr in input_types:
pass # ignore mismatch if it is stochastically rounded
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made a typo here -- thank you for catching that. Line 210 should be:
if dace.float32sr in input_types and dace.float32 in input_types:. I will also rename input_types to arg_types and add more comments

What this does and why it's needed: when using stocastic rounding, a legitimate (i.e not a bug) mismatch between the input and output arguments may arise where one argument is a float32sr and the other is a float32 (round-to-nearest). The underlying data type is the same so this should not cause the validation to fail. This is a check for that edge-case

#endif

DACE_HOST_DEVICE static float stochastic_round(double x) {
// uint64_t rbits = lcg64();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So as part of my thesis, I make a comparison between five different rounding modes. I kept the functions and these commented out invocations partly for posterity and partly to allow future devs to play around with it.

I think there is value in keeping this. I will make this into one compact comment to reduce its footprint. If you disgree, I can remove the comment and the associated functions

@creavin creavin requested a review from phschaad January 20, 2026 12:40
Copy link
Collaborator

@phschaad phschaad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for addressing the comments

@phschaad phschaad added this pull request to the merge queue Jan 20, 2026
Merged via the queue into main with commit c9576df Jan 20, 2026
12 checks passed
@phschaad phschaad deleted the single-prec-sr branch January 20, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants