CIL icon indicating copy to clipboard operation
CIL copied to clipboard

remove multiple exit from prange

Open paskino opened this issue 1 year ago • 3 comments

Description

  • closes #1900

Changes

  • It uses an accumulator array with each array adding to a location within it depending on the thread_id
  • It returns the sum of the accumulator array
  • It skips the calculation of the KL divergence if any thread evaluates to np.inf using a single int. Numba might be doing some atomic checks for writing to that int, but race conditions may happen very seldom (after discussion with @gfardell )

Testing you performed

Please add any demo scripts to https://github.com/TomographicImaging/CIL-Demos/tree/main/misc

Related issues/links

Checklist

  • [x] I have performed a self-review of my code
  • [ ] I have added docstrings in line with the guidance in the developer guide
  • [ ] I have updated the relevant documentation
  • [x] I have implemented unit tests that cover any new or modified functionality
  • [x] CHANGELOG.md has been updated with any functionality change
  • [x] Request review from all relevant developers
  • [x] Change pull request label to 'Waiting for review'

Contribution Notes

Please read and adhere to the developer guide and local patterns and conventions.

  • [x] The content of this Pull Request (the Contribution) is intentionally submitted for inclusion in CIL (the Work) under the terms and conditions of the Apache-2.0 License
  • [x] I confirm that the contribution does not violate any intellectual property rights of third parties

paskino avatar Aug 22 '24 10:08 paskino

I couldn't find any documentation about breaking a prange, did you?

paskino avatar Aug 22 '24 21:08 paskino

No, which is why I asked...

casperdcl avatar Aug 22 '24 22:08 casperdcl

The following code seems to suggest that break in a prange creates a multiple exit scenario:


import numba as nb
import numpy as np

@nb.njit(parallel=True) 
def break_prange(x, n): 
    accumulator = np.zeros(nb.get_num_threads(), dtype=np.float64) 
    for i in nb.prange(x.size):
        if i > n:
            break
        else:
            accumulator[i] = i
    return accumulator


x = np.arange(nb.get_num_threads() + 10)
x = np.asarray(x, dtype=np.float32)

y = break_prange(x,10) 

print (y)

it returns

/opt/conda/lib/python3.10/site-packages/numba/parfors/parfor.py:2395: NumbaPerformanceWarning: 
prange or pndindex loop will not be executed in parallel due to there being more than one entry to or exit from the loop (e.g., an assertion).

File "../../../../../../tmp/ipykernel_402/3173854079.py", line 7:
<source missing, REPL/exec in use?>

  warnings.warn(
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10.  0.  0.  0.  0.  0.  0.  0.
  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]

Swapping break with pass still works and raises no warning.

paskino avatar Sep 24 '24 13:09 paskino