I'm using python 2.7.2 on mac os 10.7.3
I'm doing a recursive algorithm in python with more than 50 000 recursion levels.
I tried to increase the maximum recursion level to 1 000 000 but my python shell still exit after 18 000 recursion levels.
I tried to increase the resources available :
import resource
resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(10**6)
and I get this error :
Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
resource.setrlimit(resource.RLIMIT_STACK,(2**29,-1))
ValueError: not allowed to raise maximum limit
I don't know why I cannot raise the maximum limit ?
thanks for your suggestions .
From the python documentation:
Raises ValueError if an invalid resource is specified, if the new soft
limit exceeds the hard limit, or if a process tries to raise its hard
limit (unless the process has an effective UID of super-user). Can
also raise error if the underlying system call fails.
From this I guess that your attempt new soft limit is too large. You probably need to rewrite you algorithm to be iterative. Python's not really designed to handle massive recursion like this.
While it is probably a better idea to write a more effecient algo, you can raise the hard limit by running python as root (as is mentioned in the docs).
If you execute as root, you can actually set the stack size to unlimited with the following line :
import resource
resource.setrlimit(resource.RLIMIT_STACK, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
Related
Can python have a stack overflow error?
Recently I was just letting my mind wander when I came across the question: "can python get the stack overflow error? Does anyone have any answers?
I searched for the answer but only found java answers. I have used java but its just not my question:
What is a StackOverflowError?
https://rollbar.com/blog/how-to-fix-java-lang-stackoverflowerror-in-java/
My Reasoning
I initially thought no because python just... works most of the time (like passing an int for a string). It also doesn't have stacks (to my knowledge). But I wasn't sure. Here I am.
Sure it can
the following code will cause a seg fault:
import sys
sys.setrecursionlimit(10_000_000)
def foo():
foo()
On Mac OS, this throws:
Segmentation fault: 11
Which is caused by a stack overflow.
You can, if your recursion limit is too high:
def foo():
return foo()
>>> foo()
Result:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
.......
File "<stdin>", line 2, in foo
RuntimeError: maximum recursion depth exceeded
>>>
The default recursion limit is 10**3 (verifiable via sys.getrecursionlimit), but you can change it using sys.setrecursionlimit:
import sys
sys.setrecursionlimit(10**8)
def foo():
foo()
but doing so could be dangerous -- the standard limit is a little conservative, but Python stackframes can be quite big.
By default, Python's recursion limit is 10**3, theoretically if you were to pass this then you would be given a RecursionError.
You can even reduce the recursion limit using setrecursionlimit() to make this happen more quickly.
Due to this, I need to use python memoryview.cast('I') to access a FPGA avoiding double read/write strobe. No panic, you wont need an FPGA to answer the question below...
So here comes a python sample which fails ('testfile' can be any file here -just longer than 20 bytes-, but for me, eventually it will be a IO mapped FPGA HW):
#!/usr/bin/python
import struct
import mmap
with open('testfile', "r+b") as f:
mm=memoryview(mmap.mmap(f.fileno(), 20)).cast('I')
# now try to assign the 2 first U32 of the file new values 1 and 2
# mm[0]=1; mm[1]=2 would work, but the following fails:
mm[0:1]=memoryview(struct.pack('II',1,2)).cast('I') #assignement error
The error is:
./test.py
Traceback (most recent call last):
File "./test.py", line 8, in <module>
mm[0:1]=memoryview(struct.pack('II',1,2)).cast('I')
ValueError: memoryview assignment: lvalue and rvalue have different structures
I don't undestand the error... what "different structures" are we talking about??
How can I rewrite the right hand-side of the assignment expression so it works??
Changing the left-hand-side will fail for the FPGA... as it seems anything else generates wrong signal towards the hardware...
More generally, how should I rework my array of 32 bit integers to fit the left-hand-side of the assignment...?
Yes #Monica is right: The error was simpler than I though. The slice on the left hand side is wrong indeed.
I was intending to use recursion instead of for loop to print out some numbers (for no reason except playing around) so I came to this code and when I implement it, it works perfectly for all values of i's up to 980 where it implements the code correctly but after the end of the implementation it gives
Traceback
(lots of stuff)
File "C:\Python34\lib\idlelib\PyShell.py", line 1342, in write
return self.shell.write(s, self.tags)
RuntimeError: maximum recursion depth exceeded while calling a Python object
Additionally, for values of i greater than 980, it does not print all of the values, It just prints the first 980 loops and then crashes giving the same message.
I suspect that this is related to space and time required to do the implementation and has to do with the structure of how python works rather than an error of the code but I'm no expert in neither python nor programming so I'd like to understand why this happens?
def cout(i):
if i==0:
print(0)
else:
print(i)
i-=1
cout(i)
This is not a stack overflow as #Some_programmer_dude mentions but a security to avoid stack overflow. You can change the recursion limit with sys.setrecursionlimit, but doing so is dangerous -- the standard limit is a little conservative, but Python stackframes can be quite big.
You should rewrite your algorithm without recursion. As you may know, every recursive algorithm can be transformed into an equivalent iterative one.
I'm attempting to write a program that waits for readline input, but only for a limited span of time for non-blocking input. From another question on stackoverflow, I was alerted to the Select module. It seemed to fit the bill for me. However, when I attempt to implement it, as follows:
i,o,e = select([sys.stdin],[],[],5)
as described in docs.python.org, (I'm only interested in input, and in this example, a timeout of 5 seconds) I get an error message reading:
TypeError: select() takes at most 3 arguments (4 given)
If I instead call it as:
i,o,e = select([sys.stdin],[],[])
Then I get:
ValueError: list of cases must be same length as list of conditions
with a calling module of /usr/lib/pymodules/python2.7/numpy/lib/function_base.py line 718.
I'm running ubuntu 11.10, with Python 2.7.2+.
Can anyone shed some light on this for me? I really need the timeout functionality.
Sounds like you're calling the numpy.select function , but you want the select.select function. Import them accordingly.
I am getting the error:
Warning: invalid value encountered in log
From Python and I believe the error is thrown by numpy (using version 1.5.0). However, since I am calling the "log" function in several places, I'm not sure where the error is coming from. Is there a way to get numpy to print the line number that generated this error?
I assume the warning is caused by taking the log of a number that is small enough to be rounded to 0 or smaller (negative). Is that right? What is the usual origin of these warnings?
Putting np.seterr(invalid='raise') in your code (before the errant log call)
will cause numpy to raise an exception instead of issuing a warning.
That will give you a traceback error message and tell you the line Python was executing when the error occurred.
If you have access to the numpy source, you should be able to find the line that prints that warning (using grep, etc) and edit the corresponding file to force an error (using an assertion, for example) when an invalid value is passed. That will give you a stack trace pointing to the place in your code that called log with the improper value.
I had a brief look in my numpy source, and couldn't find anything that matches the warning you described though (my version of numpy is older than yours, though).
>>> import numpy
>>> numpy.log(0)
-inf
>>> numpy.__version__
'1.3.0'
Is it possible that you're calling some other log function that isn't in numpy? For example, here is one that actually throws an exception when given invalid input.
>>> import math
>>> math.log(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error