Repository: numba/numba

Issue:
wraparound option not recognized as valid keyword option for jit on CPU target
I'm trying to use the `wraparound` keyword argument for `jit` to disable negative index wrap-around, but this generates a `NameError` for me. I made a toy example below and show the code pasted into IPython, followed by the traceback. I'm using Anaconda 2.7.10, and Numba 0.22.1.

I did some digging in the code and I can't find a reference to `no_wraparound` other than the piece of code that handles these keyword arguments.

In particular, you can see for the target I am working with (a CPU), that the `OPTIONS` `dict` is set to [include the keyword `wraparound`](https://github.com/numba/numba/blob/992a1c1f449075273f18f36dbe6964c9afdc7763/numba/targets/cpu.py#L170), whereas the piece of code that attempts to set the flag [seems to expect this to be `no_wraparound`](https://github.com/numba/numba/blob/a854ae8513baeeaa02b99b3208597841ecea2b68/numba/targets/options.py#L46). 

I think from what code I read that `flags.set` is referring to the [`ConfigOptions.set` method](https://github.com/numba/numba/blob/master/numba/utils.py#L131) defined in `utils.py`. But this is actually hard to reason about because it's not clear why some of the other options map to alternative names, such as `nopython` becoming `enable_pyobject` or `looplift` becoming `enable_looplift` when the flags are set ... these names (`enable_pyobject` and `enable_looplift`) don't appear to be part of the target `OPTIONS` `dict` either, so it's unclear why they do not also raise a `NameError`. I see where [these option names exist in `compiler.py`](https://github.com/numba/numba/blob/master/numba/compiler.py#L22), but it's not clear how one goes from the `OPTIONS` `dict` of the target to the one defined in the `Flags` class. Also, `wraparound` and/or `no_wraparound` seem to have been missing from that `OPTIONS` `dict` in `compiler.py` at least for several versions going back in the commit history. I didn't bisect to see if I could find precisely where it diverges from the documentation, but it might give you some idea of where to start looking. Some clarification about how exactly that bit of code works would be very helpful. Thanks!

``` python
In [77]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:from numba import jit
:
:def py_sum(vals, N):
:    s = 0
:    i = 0
:    while i < N:
:        s += vals[i]
:        i += 1
:    return s
:
:py_sum_jit = jit('int32 (int32[:], int32)', 
:                 nopython=True, 
:                 looplift=True, 
:                 wraparound=False)(py_sum)
:--
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-77-d8e95e59d50e> in <module>()
     12                  nopython=True,
     13                  looplift=True,
---> 14                  wraparound=False)(py_sum)

/home/ely/anaconda/lib/python2.7/site-packages/numba/decorators.pyc in wrapper(func)
    170         if sigs is not None:
    171             for sig in sigs:
--> 172                 disp.compile(sig)
    173             disp.disable_compile()
    174         return disp

/home/ely/anaconda/lib/python2.7/site-packages/numba/dispatcher.pyc in compile(self, sig)
    343 
    344             flags = compiler.Flags()
--> 345             self.targetdescr.options.parse_as_flags(flags, self.targetoptions)
    346 
    347             cres = compiler.compile_extra(self.typingctx, self.targetctx,

/home/ely/anaconda/lib/python2.7/site-packages/numba/targets/options.pyc in parse_as_flags(cls, flags, options)
     25         opt = cls()
     26         opt.from_dict(options)
---> 27         opt.set_flags(flags)
     28         return flags
     29 

/home/ely/anaconda/lib/python2.7/site-packages/numba/targets/options.pyc in set_flags(self, flags)
     45 
     46         if kws.pop('wraparound', True) == False:
---> 47             flags.set("no_wraparound")
     48 
     49         if kws.pop('boundcheck', False):

/home/ely/anaconda/lib/python2.7/site-packages/numba/utils.pyc in set(self, name, value)
    131     def set(self, name, value=True):
    132         if name not in self.OPTIONS:
--> 133             raise NameError("Invalid flag: %s" % name)
    134         self._values[name] = value
    135 

NameError: Invalid flag: no_wraparound
```

You may also want to elaborate in the documentation if the issue is related to the name of the keyword arg, because in the docstring it makes it seem that `wraparound` should be OK:

``` python
targetoptions: 
    For a cpu target, valid options are:
        nopython: bool
            Set to True to disable the use of PyObjects and Python API
            calls. The default behavior is to allow the use of PyObjects
            and Python API. Default value is False.

        forceobj: bool
            Set to True to force the use of PyObjects for every value.
            Default value is False.

        looplift: bool
            Set to True to enable jitting loops in nopython mode while
            leaving surrounding code in object mode. This allows functions
            to allocate NumPy arrays and use Python objects, while the
            tight loops in the function can still be compiled in nopython
            mode. Any arrays that the tight loop uses should be created
            before the loop is entered. Default value is True.

        wraparound: bool
            Set to True to enable array indexing wraparound for negative
            indices, for a small performance penalty. Default value
            is True.
```



Discussion:
We actually removed the `wraparound` flag at some point, but apparently failed to remove it from the docstring as well...


Resolving patch:
diff --git a/numba/decorators.py b/numba/decorators.py
--- a/numba/decorators.py
+++ b/numba/decorators.py
@@ -74,11 +74,6 @@ def jit(signature_or_function=None, locals={}, target='cpu', cache=False, **opti
                 mode. Any arrays that the tight loop uses should be created
                 before the loop is entered. Default value is True.
 
-            wraparound: bool
-                Set to True to enable array indexing wraparound for negative
-                indices, for a small performance penalty. Default value
-                is True.
-
     Returns
     --------
     A callable usable as a compiled function.  Actual compiling will be
diff --git a/numba/targets/cpu.py b/numba/targets/cpu.py
--- a/numba/targets/cpu.py
+++ b/numba/targets/cpu.py
@@ -173,7 +173,6 @@ class CPUTargetOptions(TargetOptions):
         "nogil": bool,
         "forceobj": bool,
         "looplift": bool,
-        "wraparound": bool,
         "boundcheck": bool,
         "_nrt": bool,
         "no_rewrites": bool,
diff --git a/numba/targets/options.py b/numba/targets/options.py
--- a/numba/targets/options.py
+++ b/numba/targets/options.py
@@ -43,9 +43,6 @@ def set_flags(self, flags):
         if kws.pop('looplift', True):
             flags.set("enable_looplift")
 
-        if kws.pop('wraparound', True) == False:
-            flags.set("no_wraparound")
-
         if kws.pop('boundcheck', False):
             flags.set("boundcheck")
 


Test patch: