Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#1990 closed defect (fixed)

[PATCH] OOS due to inconsistent Math.pow

Reported by: scythetwirler Owned by: ben
Priority: Release Blocker Milestone: Alpha 14
Component: Core engine Keywords: patch
Cc: Jonathan Waller Patch:

Description (last modified by scythetwirler)

OOS error between a computer running Ubuntu 12.04.2 and Ubuntu 13.04.

scythetwirler - Ubuntu 12.04.2 (64-bit)

Heiko - Ubuntu 13.04 (32-bit)

Map: Oasis 9

OOS is triggered when female citizen builds next on the same structure as a citizen soldier, adding a bonus.

Attachments (6)

Heiko commands.txt.zip (26.3 KB ) - added by Heiko 11 years ago.
Heiko oos_dump.txt.zip (485.9 KB ) - added by Heiko 11 years ago.
scythetwirler_commands.txt.tar.gz (26.3 KB ) - added by scythetwirler 11 years ago.
scythetwirler_oos_dump.txt.tar.gz (486.1 KB ) - added by scythetwirler 11 years ago.
exp.diff (3.5 KB ) - added by sanderd17 11 years ago.
test_Math.js.patch (5.6 KB ) - added by historic_bruno 11 years ago.

Download all attachments as: .zip

Change History (20)

by Heiko, 11 years ago

Attachment: Heiko commands.txt.zip added

by Heiko, 11 years ago

Attachment: Heiko oos_dump.txt.zip added

by scythetwirler, 11 years ago

by scythetwirler, 11 years ago

comment:1 by scythetwirler, 11 years ago

Description: modified (diff)

comment:2 by scythetwirler, 11 years ago

Description: modified (diff)

comment:3 by historic_bruno, 11 years ago

Summary: OOS during normal gameplay in multiplayerOOS due to inconsistent Math.pow

Same as the last report:

@@ -374225,7 +374225,7 @@ entities:
     1662
   ],
   "numRecentBuilders": 6,
-  "buildMultiplier": 0.5841906810678655,
+  "buildMultiplier": 0.5841906810678654,
   "previewEntity": 1797,
   "finalTemplateName": "structures/rome_house",
   "owner": 1,

both times it was buildMultiplier, which quantumstate pointed out is the result of an expression using Math.pow (known to produce different results on different platforms, see Bugzilla).

comment:4 by scythetwirler, 11 years ago

Description: modified (diff)

comment:5 by sanderd17, 11 years ago

I've implemented a separate Pow function.

It's only around 5 decimal digits precise, but it's numerically stable. I only use the four basic operation (add, substract, multiply and divide). However, I don't know if those are perfectly deterministic across platforms (I certainly hope so).

scythewirler, can I ask you to try it out? Just replace the contents of data/mod/public/globalscripts/Math.js file with this code: http://pastebin.com/EDPeLKQy

You will see a lot of warnings when powers are calculated. Those warnings will also be in the console. So you can already compare from the first calculations if something will be wrong or not. If it works, and you want to get rid of the warnings, just remove line 153.

When it works, we can look into making it more precise, or changing some algorithms by better ones.

comment:6 by scythetwirler, 11 years ago

That fixed it for me so far for Win64-Ubuntu32! I'll test Ubuntu64 with Ubuntu32 later.

comment:7 by sanderd17, 11 years ago

Keywords: patch review added
Summary: OOS due to inconsistent Math.pow[PATCH] OOS due to inconsistent Math.pow

Cleaned up the code a bit, and removed the warnings.

comment:8 by scythetwirler, 11 years ago

It also works with my Ubuntu64 vs Ubuntu32. Thanks, sanderd!

comment:9 by historic_bruno, 11 years ago

Cc: Jonathan Waller added

Thanks for working on this. Our implementations should properly handle the special cases in the spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf (page 160-5)

I don't know if 5 digits is enough precision, how hard is it to improve that?

by sanderd17, 11 years ago

Attachment: exp.diff added

comment:10 by sanderd17, 11 years ago

Thanks for the ECMA spec.

I improved the precision, and now, the overall worst precision (according to my calculations) is around 17 decimal digits for the pow function (similar numbers for other functions).

I also implemented those ECMA script special values (NaN, Infinity ...) and I think they are correct now. But it would be great if someone can confirm my thoughts.

by historic_bruno, 11 years ago

Attachment: test_Math.js.patch added

comment:11 by historic_bruno, 11 years ago

They look good to me. I wrote some tests (see test_Math.js.patch), all the special cases passed and results for a few other tests I added were consistent between an Athlon XP and a Core i7-2600K. Do you have any more tests to suggest?

Some interesting differences with your implementations in extreme cases:

Math.log(1.7e308) // => 709.7268368932282 with SM Math
Math.log(1.7e308) // => 709.0895657128241 with yours

Math.exp(Math.log(1.7e308)) // => 1.6999999999999472e+308 with SM Math
Math.exp(Math.log(1.7e308)) // => 8.988465674311613e+307 with yours

It doesn't really matter other than for comparing precision and possibly not worth worrying about.

comment:12 by sanderd17, 11 years ago

I think that is because of the rounding issues in JS itself. Normally the log should be about 16 decimal digits precise. But if the rounding error accumulates through the loop, I can't help that a lot. I thought by using divisions and multiplications by 2, it wouldn't round, but apparently not.

comment:13 by ben, 11 years ago

Owner: set to ben
Resolution: fixed
Status: newclosed

In 13515:

Adds JS implementations of Math.pow, exp, and log, by sanderd17, refs #1193.
Fixes #1990 (OOS caused by Math.pow).
Adds tests and documentation for Math functions.

comment:14 by historic_bruno, 11 years ago

Keywords: review removed
Note: See TracTickets for help on using tickets.