-1

In the following code, numba.jit produces 7732.96... while python gives -6351.97... (digits omitted for brevity). What can I do to fix this? Is this numba's bug or my coding error? I used Python 3.7 (anaconda) on Spyder 3.

from numba import jit
import numpy as np

@jit(nopython=True)
def test(n):
     sum = 0.0
     arr = np.arange(2, n)
     for x in np.sin(np.cos(arr ** 2)):
           sum += x
     return sum


a = test(100000000)
print(a)
auser
  • 43
  • 5
  • Please see my edit to the original question, where I respond to your (flawed) characterization of this question as off-topic. If you know the answer to my question, please provide it. That would be very helpful; otherwise please remove the hold, so I can benefit from others' responses. Thanks. – auser Aug 08 '19 at 23:06
  • How did you get the result -6351.9? The code you've posted gives 7732.9. We cannot reproduce the first result. – Håken Lid Aug 08 '19 at 23:12
  • The exact value, as printed by the code, is -6351.975726109694. I used python 3.7.0 (64-bit), numpy 1.15.1, numba 0.39.0, Ipython 6.5.0 (Spyder 3 editor) on a Dell Inspiron (x64-based) running on intel core i3 in Win 10. I suspect an overflow problem but nothing in the code looks suspicious. Thanks for any pointers. – auser Aug 08 '19 at 23:52
  • I _tried_ your version, which gave 7732.9. So there's something missing in your question. Either some version info where something was broken (unlikely) or something else in your code or interpreter state that you didn't show (more likely). Close votes were divided between "not reproducible" (because your code works) and the one you see now ("no [mcve]", because you probably can't see your results with your code, so something is missing). Personally, I voted for the latter because you are comparing two values with two methods but your code only contains one method. This is already suspicious. – Andras Deak -- Слава Україні Aug 09 '19 at 10:28
  • And from what I can tell the answerer used your exact code. The `@jit` decorator is syntactical sugar for what the answerer did. They only had to change your code because you didn't add both versions you are comparing. Swapping the decorator for a manual call to `numba.jit` as the answerer did is the simplest way to have access to the decorated and the original function, the two sources for which you claim your values disagree. You are welcome to [edit] your question to add evidence of the source of your problem that only you see, but until then I've removed the complaint from the question. – Andras Deak -- Слава Україні Aug 09 '19 at 10:31
  • Feel free to [@ping me](https://meta.stackexchange.com/questions/43019/how-do-comment-replies-work) if you do edit with new information, otherwise it would probably be missed. – Andras Deak -- Слава Україні Aug 09 '19 at 10:33
  • I think I identified the problem. My version of numpy 1.15.1 uses dtype=int32 by default for integer arrays, without issuing any warning for oversized values, and silently producing wrong results. This seems to be a flaw in the design of numpy 1.15.1. The jitted version of the same code, however, uses 64 bits (an unfortunate case of lack of orthogonality). When I supply int64 or float64 by hand-coding, I do get identical results from python and jit. People who responded to my original post probably ran a version of numpy other than 1.15.1 and therefore failed to reproduce my problem. – auser Aug 10 '19 at 15:51
  • @Andras Deak, MSeifert, Zoe: Please read my other comments from today. Can you please help me a little more by letting me know whether you used numpy 1.15.1 on this program? I found out that my numpy 1.15.1 silently uses 32 bits for integers without any warning for overflows (very sad). Thanks for any help. – auser Aug 10 '19 at 15:57
  • @Andra Deak: Thank you for your response, but my original post did contain the two different versions of the code (python and jitted) and the two different solutions. Just comment out the decorator line @jit(nopython=True) by putting a # before it. To me, commenting out one line was the easiest and most obvious way of producing the second version. I did not explicitly mention it because I thought (and still do) that it was trivial. So I respectfully disagree with you that my “code only contains one method.” – auser Aug 10 '19 at 16:01
  • Having to comment out a line of code is as invasive as the solution in JoshAdel's version: keep the original and decorate another version manually. I'm just saying that the test in the answer was very much relevant. I'll get back to you concerning the int32 issue, I have to look into that a bit which I can only do later. – Andras Deak -- Слава Україні Aug 10 '19 at 16:04
  • @Andras Deak: I appreciate your efforts to help me, but why did you delete my writing(edit)? By deleting my edits, you deprive me of possible help from other readers of my post. In my humble opinion, the whole point of writing posts is to get and give help; this should not be a forum for one-upmanship. I regret to have to say that your conduct is unethical, unprofessional and smacks of arrogance. With due respect, you are free to add anything of your own but you should not delete others’ writing. Please have the courtesy to bring back my edits and also to remove the hold on the post. Thanks. – auser Aug 10 '19 at 16:09
  • Long texts that don't have to do with the technical question at hand don't belong in questions, see e.g. [this meta post](https://meta.stackoverflow.com/questions/260776/should-i-remove-fluff-when-editing-questions) and a dozen others. It might seem weird to you but it's how Stack Overflow works. We concentrate on technical content. I removed your edits because they didn't add anything technical to the question, and the style of your complaints would've made downvotes on your question much more likely. If my interaction with your post is a burden to you I can always do something elsewhere. – Andras Deak -- Слава Україні Aug 10 '19 at 16:51
  • It seems that the issue is not necessarily with numpy versions, but with operating systems. [The docs](https://docs.scipy.org/doc/numpy/user/basics.types.html) says that `np.int_` is "Platform-defined", and there are a lot of hints that on windows the default is 32-bit while on linux it's 64-bit. I only use the latter so I didn't know about the former. I presume numba handles this choice differently. There's [this numba issue](https://github.com/numba/numba/issues/3726) that mentions as an aside that the sum of two int32 numbers will be int64, and you are doing exactly such sums in your loop. – Andras Deak -- Слава Україні Aug 10 '19 at 18:28

1 Answers1

1

I cannot reproduce you error:

from numba import jit
import numpy as np

def test(n):
    sum = 0.0
    arr = np.arange(2, n)
    for x in np.sin(np.cos(arr ** 2)):
        sum += x
    return sum

testnb = jit(nopython=True)(test)

N = 100000000
print(test(N))
print(testnb(N))
# 7732.969676855288
# 7732.969676855337

I am using numba 0.45.1, python 3.7.3 and numpy 1.16.4. My initial guess was that there was some sort of floating point issue where in the non-jitted form, sum is a python value that has infinite precision, whereas in the jitted code, sum is typed as a specific float32 or float64 depending on your system. But for your particular system, I'm not sure what is going on.

JoshAdel
  • 66,734
  • 27
  • 141
  • 140
  • 3
    "sum is a python value that has infinite precision" I think that would only be true if it were an `int` object, `float` objects are essentially wrapping C double's. – juanpa.arrivillaga Aug 08 '19 at 18:41
  • @JoshAdel: Thanks a lot, but can you please run my version of the code (not yours)? I hope you will see the problem then. – auser Aug 08 '19 at 23:02
  • @juanpa.arrivillaga, you are correct. My comment about infinite precision is incorrect. – JoshAdel Aug 09 '19 at 18:08
  • 1
    @auser as pointed out above, your code and mine are functionally identical. I just opted to not use the decorator so that I could easily compare the pure python implementation and a jitted version of it. – JoshAdel Aug 09 '19 at 18:10
  • @JoshAdel: I certainly understand that the two versions are functionally identical. I ran YOUR version (testnb = jit(nopython=True)(test), etc.) on numpy 1.15.1 and I still get the same two (different) results: minus 6351.9 and plus 7732.9. Please see my other comment from today above. Can you please run YOUR code on 1.15.1 and let me know what you get? Thank you very much. – auser Aug 10 '19 at 15:54
  • @auser I tried it with numpy 1.15.1 and I continue to get matching answers. Can you try running the code outside of Spyder, either in the standard python REPL or in ipython or just as a script? – JoshAdel Aug 11 '19 at 20:02
  • Yes, I tried it. Windows 64-bit machines produce the wrong results (uses int32 as the default size), but ubuntu produces correct values (uses int64) on the exact same code. This seems to be a numpy bug. Thanks for your comments. – auser Aug 14 '19 at 13:42
  • @auser I don't think it's a bug, it's just an unpopular feature. [The docs](https://docs.scipy.org/doc/numpy/user/basics.types.html) mention in multiple places that `np.int_` is platform-dependent and `dtype=int` corresponds to `dtype=np.int_`, and [this](https://stackoverflow.com/questions/384502/what-is-the-bit-size-of-long-on-64-bit-windows) and other hints suggest that on windows `long` is not necessarily 64-bit. – Andras Deak -- Слава Україні Aug 14 '19 at 17:18