Hi,
is there any way to set the rounding mode for IEEE floating point operations? Maybe something like > Double roundToMinusInfWhile: [... code goes here ...]Double > roundToZeroWhile: [... more code here ...] If not, is it possible to add this behavior, e.g., via a custom primitive? Best, Steffen |
On Mon, Jan 15, 2018 at 12:27 PM, Steffen Märcker <[hidden email]> wrote: Hi, This might interesting to have something like that for PolyMath, but I'm a little worried of subtle consequences that might appear in UI if you use points for examples. -- Serge Stinckwich UMI UMMISCO 209 (IRD/UPMC/UY1)
|
Yes, I was considering this in the context of some approximation
algorithms. Maybe one of the VM experts here could comment on the possibility to implement that? Am .01.2018, 10:00 Uhr, schrieb Serge Stinckwich <[hidden email]>: > On Mon, Jan 15, 2018 at 12:27 PM, Steffen Märcker <[hidden email]> wrote: > >> Hi, >> >> is there any way to set the rounding mode for IEEE floating point >> operations? Maybe something like >> >> Double roundToMinusInfWhile: [... code goes here ...]Double >>> roundToZeroWhile: [... more code here ...] >>> >> >> If not, is it possible to add this behavior, e.g., via a custom >> primitive? >> >> > This might interesting to have something like that for PolyMath, but > I'm a > little worried of subtle consequences > that might appear in UI if you use points for examples. |
In reply to this post by Steffen Märcker
*bump*
I guess there no way to do this now. But maybe a VM guy can give me how difficult it might be to extend the VM accordingly. Best, Steffen Am .01.2018, 12:27 Uhr, schrieb Steffen Märcker <[hidden email]>: > Hi, > > is there any way to set the rounding mode for IEEE floating point > operations? Maybe something like > >> Double roundToMinusInfWhile: [... code goes here ...]Double >> roundToZeroWhile: [... more code here ...] > > If not, is it possible to add this behavior, e.g., via a custom > primitive? > > Best, Steffen |
On Wed, May 23, 2018 at 11:47 AM Steffen Märcker <[hidden email]> wrote: *bump* Yes you should followup this question to the VM mailing-list. Can you open an issue here: https://github.com/PolyMathOrg/PolyMath/issues so we don't forget about it ? Do you have specific needs behind this ? Serge Stinckwich UMI UMMISCO 209 (SU/IRD/UY1)
|
fesetround()/fegetround() are part of C99, and amazingly, also present in the
Windows CRT, it might be possible to try to do this with FFI only? IIRC the numerical model is supposed to act identical across platforms; whether it would actually affect anything depends on how the VM achieves that; I assume it's done by explicitly setting fp state to be identical (including rounding mode), rather than using some library which avoids x87/sse ops entirely, but I haven't actually looked. For the same reason, I hope you intend roundByMethodXWhile: to be a mandatory API, forgetting to set the mode back when done (or, never getting there due to errors, etc) is an area best left unexplored ;) Cheers, Henry -- Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html |
In reply to this post by SergeStinckwich
I'll cross-post there later. Thanks for the suggestion!
The application I have in mind is approximation algorithms for systems of linear equations or linear programs. Approximation algorithms, such as the power method, typically run until convergence of the solution vector is reached. However, determining convergence is usually done by computing the difference (epsilon) between the last two solutions and comparing it to some threshold. This may work in some cases but not in general, as the intermediate epsilon does not tell the distance to the actual solution. Interval iteration tackles this problem by approaching the solution from above and below. The difference between the upper and lower solution bounds determines the quality of the solution. However, if we use imprecise arithmetic (floats, doubles) it is important to round down/up in computing the lower/upper bounds. Best, Steffen Am .05.2018, 12:50 Uhr, schrieb Serge Stinckwich <[hidden email]>: > On Wed, May 23, 2018 at 11:47 AM Steffen Märcker <[hidden email]> wrote: > >> *bump* >> >> I guess there no way to do this now. But maybe a VM guy can give me how >> difficult it might be to extend the VM accordingly. >> >> > Yes you should followup this question to the VM mailing-list. > Can you open an issue here: > https://github.com/PolyMathOrg/PolyMath/issues > so we don't forget about it ? > > Do you have specific needs behind this ? |
In reply to this post by Henrik Sperre Johansen
Hi Henry,
> [...] it might be possible to try to do this with FFI only? If I understand you correctly, I could use FFI to call an external lib to perform the actual computation according to the rounding mode, right? In this case I'd be worry about the performance impact of many FFI calls. > For the same reason, I hope you intend roundByMethodXWhile: to be a > mandatory API, forgetting to set the mode back when done (or, never > getting > there due to errors, etc) is an area best left unexplored ;) I used roundByMethodXWhile: aBlock just to convey the idea that an API could work "local" and ensures resetting the rounding mode afterwards. =) Best, Steffen |
On Wed, May 23, 2018 at 3:39 PM Steffen Märcker <[hidden email]> wrote: Hi Henry, This quite easy to implement : LibC>>fegetround ^ self ffiCall: #(int fegetround(void)) LibC>> fesetround: round^ self ffiCall: #(void fesetround(int round)) but apparently nothing happens when you do : LibC uniqueInstance fesetround: 1024. LibC uniqueInstance fegetround. always return 0. Serge Stinckwich UMI UMMISCO 209 (SU/IRD/UY1)
|
I actually made progress: It works like a charm! Basically, I implemented
the same code as you. Testing is straightforward (using the constant values from libc): current := LibC fegetround. LibC fesetround: FE_DOWNWARDS. v1 := 1.0/10.0. LibC feesetround: FE_UPWARDS. v2 := 1.0/10.0. LibC feesetround: current. v1 < v2. "true" > but apparently nothing happens when you do : > LibC uniqueInstance fesetround: 1024. > LibC uniqueInstance fegetround. > always return 0. This is expected, since the fesetround function returns 0 only if the set operation was successful. Thanks again for your support! Best, Steffen |
On Thu, May 24, 2018 at 10:31 AM Steffen Märcker <[hidden email]> wrote: I actually made progress: It works like a charm! Basically, I implemented I was talking about fgetround function. Can you check the value returns by your fegetround function ? Constants values are not dependent of the platform ? Can you commit yr code to Pharo 7.0 or if there is no interest for this to PolyMath ? Thank you. Serge Stinckwich UMI UMMISCO 209 (SU/IRD/UY1)
|
What is really strange is when I print the following lines, I obtain 2048: current := LibC uniqueInstance fegetround. LibC uniqueInstance fesetround: 2048. LibC uniqueInstance fegetround. and 0 when I remove the first line : LibC uniqueInstance fesetround: 2048. LibC uniqueInstance fegetround. On Thu, May 24, 2018 at 10:37 AM Serge Stinckwich <[hidden email]> wrote:
-- Serge Stinckwich UMI UMMISCO 209 (SU/IRD/UY1)
|
Hi,
now I've observed the same issue. It might be related to context switching, since introducing a delay has a similar effect. Consider: | FE_TONEAREST FE_DOWNWARD FE_UPWARD FE_TOWARDZERO | FE_TONEAREST := 16r0000. FE_DOWNWARD := 16r0400. FE_UPWARD := 16r0800. FE_TOWARDZERO := 16r0C00. "For some reasons we have to call fegetround once." "c := LibC new fegetround." LibC new fesetround: FE_DOWNWARD. (Delay forSeconds: 1) wait. v1 := 1.0/10.0. LibC new fesetround: FE_UPWARD. v2 := 1.0/10.0. LibC new fesetround: FE_TONEAREST. v1 < v2. If the delay is inserted, the script evaluates to false. Using the same LibC-instance or creating a new one does not seem to change anything here. Interestingly, a similar approach in VisualWorks does not show this issue yet. Actually, I expect the FE_* macros to be platform/implementation dependent, as suggested here: http://www.enseignement.polytechnique.fr/informatique/INF478/docs/Cpp/en/c/numeric/fenv/FE_round.html Best, Steffen Am .05.2018, 11:57 Uhr, schrieb Serge Stinckwich <[hidden email]>: > What is really strange is when I print the following lines, I obtain > 2048: > > current := LibC uniqueInstance fegetround. > LibC uniqueInstance fesetround: 2048. > LibC uniqueInstance fegetround. > > and 0 when I remove the first line : > LibC uniqueInstance fesetround: 2048. > LibC uniqueInstance fegetround. > > > > On Thu, May 24, 2018 at 10:37 AM Serge Stinckwich < > [hidden email]> wrote: > >> >> >> On Thu, May 24, 2018 at 10:31 AM Steffen Märcker <[hidden email]> wrote: >> >>> I actually made progress: It works like a charm! Basically, I >>> implemented >>> the same code as you. Testing is straightforward (using the constant >>> values from libc): >>> >>> current := LibC fegetround. >>> LibC fesetround: FE_DOWNWARDS. >>> v1 := 1.0/10.0. >>> LibC feesetround: FE_UPWARDS. >>> v2 := 1.0/10.0. >>> LibC feesetround: current. >>> v1 < v2. "true" >>> >>> > but apparently nothing happens when you do : >>> > LibC uniqueInstance fesetround: 1024. >>> > LibC uniqueInstance fegetround. >>> > always return 0. >>> >>> This is expected, since the fesetround function returns 0 only if the >>> set >>> operation was successful. >>> >>> >> I was talking about fgetround function. >> Can you check the value returns by your fegetround function ? >> >> Constants values are not dependent of the platform ? >> >> Can you commit yr code to Pharo 7.0 or if there is no interest for this >> to PolyMath ? >> Thank you. >> -- >> Serge Stinckwich >> UMI UMMISCO 209 (SU/IRD/UY1) >> "Programs must be written for people to read, and only incidentally for >> machines to execute."http://www.doesnotunderstand.org/ >> > |
On Thu, May 24, 2018 at 12:27 PM Steffen Märcker <[hidden email]> wrote: Hi, Ok, so maybe we need to use put evaluation in a block and use valueNoContextSwitch ? Maybe use an API like the one you propose before : Double roundToMinusInfWhile: [ ... ] Actually, I expect the FE_* macros to be platform/implementation Ok. Can we try to pack everything in a PR for Pharo 7.0 ? Thank you. Serge Stinckwich UMI UMMISCO 209 (SU/IRD/UY1)
|
Dear Serge,
on the VM mailing list, Levente pointed out, that this could also be related to some lib the VM uses (e.g., Freetype) that might change the rounding mode. I'll dig into it and give your idea a try and come back with the results. I think it would be nice to have in Pharo 7. But before I want to make sure it a) works as expected and b) does not cause some nasty side effects. Bye, Steffen Am .05.2018, 12:26 Uhr, schrieb Serge Stinckwich <[hidden email]>: > On Thu, May 24, 2018 at 12:27 PM Steffen Märcker <[hidden email]> wrote: > >> Hi, >> >> now I've observed the same issue. It might be related to context >> switching, since introducing a delay has a similar effect. Consider: >> >> | FE_TONEAREST FE_DOWNWARD FE_UPWARD FE_TOWARDZERO | >> FE_TONEAREST := 16r0000. >> FE_DOWNWARD := 16r0400. >> FE_UPWARD := 16r0800. >> FE_TOWARDZERO := 16r0C00. >> "For some reasons we have to call fegetround once." >> "c := LibC new fegetround." >> LibC new fesetround: FE_DOWNWARD. >> (Delay forSeconds: 1) wait. >> v1 := 1.0/10.0. >> LibC new fesetround: FE_UPWARD. >> v2 := 1.0/10.0. >> LibC new fesetround: FE_TONEAREST. >> v1 < v2. >> >> If the delay is inserted, the script evaluates to false. Using the same >> LibC-instance or creating a new one does not seem to change anything >> here. >> Interestingly, a similar approach in VisualWorks does not show this >> issue >> yet. >> >> > Ok, so maybe we need to use put evaluation in a block and use > valueNoContextSwitch ? > Maybe use an API like the one you propose before : > Double roundToMinusInfWhile: [ ... ] > > > >> Actually, I expect the FE_* macros to be platform/implementation >> dependent, as suggested here: >> >> http://www.enseignement.polytechnique.fr/informatique/INF478/docs/Cpp/en/c/numeric/fenv/FE_round.html >> >> > Ok. > > Can we try to pack everything in a PR for Pharo 7.0 ? > Thank you. |
On Tue, May 29, 2018 at 4:15 PM Steffen Märcker <[hidden email]> wrote: Dear Serge, I think it would be nice to have in Pharo 7. But before I want to make Yes in order to avoid any side effect, we can use what you propose before. An API like : Double roundToMinusInfWhile: [... code goes here ...] so we don't expose the rest of the system to these modifications. See you. Serge Stinckwich UMI UMMISCO 209 (SU/IRD/UY1)
|
Free forum by Nabble | Edit this page |