Commit 412b5227 authored by Robert Bradshaw's avatar Robert Bradshaw

Fix prange() end condition for (stop - start) % step != 0.

parent dc00a176
...@@ -2,6 +2,16 @@ ...@@ -2,6 +2,16 @@
Cython Changelog Cython Changelog
================ ================
0.23.5 (2015-xx-yy)
===================
Bugs fixed
----------
* Fix prange() to behave identically to range(). The end condition was
miscalculated when the range was not exactly divisible by the step.
0.23.4 (2015-10-10) 0.23.4 (2015-10-10)
=================== ===================
......
...@@ -8541,7 +8541,7 @@ class ParallelRangeNode(ParallelStatNode): ...@@ -8541,7 +8541,7 @@ class ParallelRangeNode(ParallelStatNode):
self.control_flow_var_code_point = code.insertion_point() self.control_flow_var_code_point = code.insertion_point()
# Note: nsteps is private in an outer scope if present # Note: nsteps is private in an outer scope if present
code.putln("%(nsteps)s = (%(stop)s - %(start)s) / %(step)s;" % fmt_dict) code.putln("%(nsteps)s = (%(stop)s - %(start)s + %(step)s - %(step)s/abs(%(step)s)) / %(step)s;" % fmt_dict)
# The target iteration variable might not be initialized, do it only if # The target iteration variable might not be initialized, do it only if
# we are executing at least 1 iteration, otherwise we should leave the # we are executing at least 1 iteration, otherwise we should leave the
......
...@@ -46,6 +46,34 @@ def test_descending_prange(): ...@@ -46,6 +46,34 @@ def test_descending_prange():
return sum return sum
def test_prange_matches_range(int start, int stop, int step):
"""
>>> test_prange_matches_range(0, 8, 3)
>>> test_prange_matches_range(0, 9, 3)
>>> test_prange_matches_range(0, 10, 3)
>>> test_prange_matches_range(0, 10, -3)
>>> test_prange_matches_range(0, -10, -3)
>>> test_prange_matches_range(1, -10, -3)
>>> test_prange_matches_range(2, -10, -3)
>>> test_prange_matches_range(3, -10, -3)
"""
cdef int i, range_last, prange_last
prange_set = set()
for i in prange(start, stop, step, nogil=True, num_threads=3):
prange_last = i
with gil:
prange_set.add(i)
range_set = set(range(start, stop, step))
assert range_set == prange_set, "missing: %s extra %s" % (sorted(range_set-prange_set), sorted(prange_set - range_set))
for ii in range(start, stop, step):
range_last = ii
if range_set:
assert prange_last == i
assert range_last == prange_last
def test_propagation(): def test_propagation():
""" """
>>> test_propagation() >>> test_propagation()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment