Maximum recursion depth exceeded while using prange

Hi everyone,

I’m running in to the following error:

numba.core.errors.TypingError: Failed in nopython mode pipeline (step: Handle with contexts)
Failed in nopython mode pipeline (step: nopython frontend)
Internal error at <numba.core.typeinfer.CallConstraint object at 0x1554ec2e2b00>.
Failed in nopython mode pipeline (step: parfor prelowering)
maximum recursion depth exceeded while calling a Python object

I have a jitted function f1 with parallel=True that is calling another jitted function f2 (with parallel=False ) inside the prange loop of f1 .
When I get rid of f2 and paste the code inside f1 everything works as expected. Why is this happening and is there a way to fix this? 1. Is there any way I can debug this further?

I’m working with a pretty big code base and I haven’t found a way to reproduce this simply. Here’s a link to the file and function I’m working with

How to reproduce:

git clone https://github.com/lab-v2/pyreason
cd pyreason
git checkout 80fac257a0981cd758927b8c0232f2c37451976d
pip install .
cd

And then run the following python script:

import pyreason as pr
import networkx as nx

# ================================ CREATE GRAPH====================================
# Create a Directed graph
g = nx.DiGraph()

# Add the nodes
g.add_nodes_from(['John', 'Mary', 'Justin'])
g.add_nodes_from(['Dog', 'Cat'])

# Add the edges and their attributes. When an attribute = x which is <= 1, the annotation
# associated with it will be [x,1]. NOTE: These attributes are immutable
# Friend edges
g.add_edge('Justin', 'Mary', Friends=1)
g.add_edge('John', 'Mary', Friends=1)
g.add_edge('John', 'Justin', Friends=1)

# Pet edges
g.add_edge('Mary', 'Cat', owns=1)
g.add_edge('Justin', 'Cat', owns=1)
g.add_edge('Justin', 'Dog', owns=1)
g.add_edge('John', 'Dog', owns=1)

# ================================= RUN PYREASON ====================================

# Modify pyreason settings to make verbose and to save the rule trace to a file
pr.settings.verbose = False     # Don't Print info to screen
pr.settings.atom_trace = True  # This allows us to view all the atoms that have made a certain rule fire
pr.settings.parallel_computing = True

# Load all rules and the graph into pyreason
pr.load_graph(g)
pr.add_rule('popular(x) <-1 popular(y), Friends(x,y), owns(y,z), owns(x,z)', 'popular_rule')
pr.add_fact(pr.Fact('popular-fact', 'Mary', 'popular', [1, 1], 0, 2))


# Run the program for two timesteps to see the diffusion take place
interpretation = pr.reason(timesteps=2)

# Display the changes in the interpretation for each timestep
dataframes = pr.filter_and_sort_nodes(interpretation, ['popular'])
for t, df in enumerate(dataframes):
    print(f'TIMESTEP - {t}')
    print(df)
    print()

# Save all changes made to the interpretations a file
# pr.save_rule_trace(interpretation)

Thank you for the reproducer. I can reproduce the error and I believe it is a internal error in Numba. I have made issue RecursionError in parfor prelowering · Issue #9182 · numba/numba · GitHub to track this.

@dyu, I noticed a potential race condition when I debugged the problem. This list.append may race: https://github.com/lab-v2/pyreason/blob/80fac257a0981cd758927b8c0232f2c37451976d/pyreason/scripts/interpretation/interpretation_parallel.py#L1164. The unfortunate thing with parallel=True is that only NumPy array reductions are handled. Other containers can still cause race condition if multiple threads are mutating them. I don’t know if the condition at https://github.com/lab-v2/pyreason/blob/80fac257a0981cd758927b8c0232f2c37451976d/pyreason/scripts/interpretation/interpretation_parallel.py#L1136-L1138 will protect the list.append.

@sklam Thanks for your reply. To give you a few more details, this function was working fine with parallel=True in this earlier commit.

The main change that was made was this line was made into a function call (get_edge_rule_node_clause_subset). In the earlier commit, it was not a function call but all the code in get_edge_rule_node_clause_subset was pasted in the line shared above. Basically the moment I copy pasted the code into another function I started getting this error.

Please let me know if you know what might have gone wrong, thanks!