increasing recursive functions buffer

Started by Hardcoal, February 23, 2020, 00:10:24

Previous topic - Next topic

Hardcoal

hi... i have a recursive function that needs calling itself above blitzmax default memory stack..
is there a way to increase blitzmax memory stack so the recursive function wont crash?

Thanks
Code

Matty

I don't like suggesting this because there may be a valid reason to do it recursively, but if stack limits are a problem can you change the function to be non recursive?  That would solve the problem and likely make it easier to understand the code as recursive functions are annoying to debug if a problem occurs.

JBR

#2
This just stalls my pc, but works perfectly if I edit out the freeEntity <pivot>


[code]Function Line:TEntity(x1#,y1#,z1#,x2#,y2#,z2#)

Local scale# = G_Line_Scale

Local c1:TEntity=CreateSphere()
PositionEntity c1,x1,y1,z1

Local c2:TEntity=CreateSphere()
PositionEntity c2,x2,y2,z2

Local p:TPivot=CreatePivot()
PositionEntity p,x1,y1,z1

Local le#=EntityDistance# (c1,c2) / 2.0
'le#=le#-(le#/2)

Local c3:TEntity=CreateCylinder()
PositionEntity c3,x1,le+y1,z1

ScaleEntity c3,scale,le,scale
EntityColor c3,255,255,255

EntityParent c3,p

PointEntity p,c2
TurnEntity p,90,0,0

FreeEntity c1
FreeEntity c2
FreeEntity p

Return(c3)

End Function
[/code]

Hardcoal

#3
Yes,Im using recursive function because its the right way in this case and it works fine.
Im working alot with recursive functions so Im pretty good controlling them.. so bugs arent my problem :)

My algorithm is working perfectly, Its just get stuck when Im giving it larg Data to decipher.
so if there is no way to enlarge this memory buffer, Ill just try another approach or a trick to overcome this.



Code

Henri

#4
Hi,

stack size is platform dependent, so best option is to avoid recursion on large scale, and use loops instead.

If you really wanted to alter stack size then first place to look is linker options (in Windows it would be Mingw's ld.exe: it has an option --stack <size> ) . You would need to inject this somewhere in the compile toolchain. Note that results may depend on platform.

All in all, see first point :-)


EDIT:

If you want to experiment then one way is to create Windows environment variable called BMK_LD_OPTS. Value could be --stack=8388608 for example. I think you need to restart your IDE for changes to be applied.


Testing stack size:

Code (blitzmax) Select

Global count:Int = 1

test()

Function test:Int()

'This line is only for feedback
If Not (count Mod 1000) Then Print count

count:+ 1

Return test()
EndFunction



-Henri 
- Got 01100011 problems, but the bit ain't 00000001

Hardcoal

#5
Wow. ok.. well im looking for programming my code differently .. before i start messing with stack..
i checked the recursivnes  limit in my case. and it reached to 100,000 lol
Im sure i can find a better way to program my Code..

the algorithm i did is a Fill command.. like you have in photoshop.. when you press on empty space and it fills it with color.
I did that each pixel check his surrounding pixels in the same manor.
Here is the Code.

The Process is That the First Pixel is checking 8 pixels around him.. if those pixels are empty than it runs the same Function And Each Time it marks the Pixel As Either Empty Or Occupied..

anyway it works fine.. until i give it big pictures.. :)

Now Im trying another Method..



Function BuildEmptySpacesField_Req(ImageHandle, CurrentX = 0, CurrentY = 0, Start = False)

   'Start
If Start = True Then
Local Coords:Coords_Class = New Coords_Class
Coords = GetFirstEmptyPoint(ImageHandle)
CurrentX = Coords.X
CurrentY = Coords.Y
Coords = Null
End If

   'Check if Occupied
If PixelIsOccupied(xReadPixel(CurrentX, CurrentY, xImageBuffer(ImageHandle))) Then
Pixel[CurrentX, CurrentY] = OccupiedPix
Return
   'Mark As Empty
Else
Pixel[CurrentX, CurrentY] = EmptyPix
End If

   'Now Check Around Pixel

   'Checks Left Pixel
If CheckLeftPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX - 1, CurrentY] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX - 1, CurrentY)

   'Checks Right Pixel
If CheckRightPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX + 1, CurrentY] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX + 1, CurrentY)

   'ChecksUpPixel
If CheckUpPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX, CurrentY - 1] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX, CurrentY - 1)

   'ChecksDownPixel
If CheckDownPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX, CurrentY + 1] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX, CurrentY + 1)

   'CheckLeftUpPixel
If CheckLeftUpPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX - 1, CurrentY - 1] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX - 1, CurrentY - 1)

   'CheckRightUpPixel
If CheckRightUpPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX + 1, CurrentY - 1] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX + 1, CurrentY - 1)

   'CheckDownLeftPixel
If CheckDownLeftPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX - 1, CurrentY + 1] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX - 1, CurrentY + 1)

   'CheckDownRightPixel
If CheckDownRightPixel(ImageHandle, CurrentX, CurrentY) = False Then If Pixel[CurrentX + 1, CurrentY + 1] = UnChecked Then BuildEmptySpacesField_Req(ImageHandle, CurrentX + 1, CurrentY + 1)

End Function
Code

Hardcoal

40 mins later..

I solved it using another method..

here is the Code


Function BuildEmptySpacesField(ImageHandle, CurrentX = 0, CurrentY = 0, Start = False)
Local X, Y, StartX, StartY

   'Start
If Start = True Then
Local Coords:Coords_Class = New Coords_Class
Coords = GetFirstEmptyPoint(ImageHandle)
StartX = Coords.X
StartY = Coords.Y
Pixel[StartX, StartY] = EmptyPix
Coords = Null
End If

   'Left To Right
For Y = StartY To xImageHeight(ImageHandle) - 1

For X = StartX To xImageWidth(ImageHandle) - 1

   'Is Empty
If PixelIsOccupied(xReadPixel(X, Y, xImageBuffer(ImageHandle))) = False Then
If HasAnEmptyPixelAroundHim(ImageHandle, X, Y) = True Then
Pixel[X, Y] = EmptyPix
End If
End If

Next

Next

   'Right To Left
For Y = xImageHeight(ImageHandle) - 1 To StartY Step - 1

For X = xImageWidth(ImageHandle) - 1 To StartX Step - 1

   'Is Empty
If PixelIsOccupied(xReadPixel(X, Y, xImageBuffer(ImageHandle))) = False Then
If HasAnEmptyPixelAroundHim(ImageHandle, X, Y) = True Then
Pixel[X, Y] = EmptyPix
End If
End If

Next

Next

   'Up To Down
For X = StartX To xImageWidth(ImageHandle) - 1

For Y = StartY To xImageHeight(ImageHandle) - 1

   'Is Empty
If PixelIsOccupied(xReadPixel(X, Y, xImageBuffer(ImageHandle))) = False Then
If HasAnEmptyPixelAroundHim(ImageHandle, X, Y) = True Then
Pixel[X, Y] = EmptyPix
End If
End If

Next

Next

   'Down To Up
For X = StartX To xImageWidth(ImageHandle) - 1

For Y = xImageHeight(ImageHandle) - 1 To StartY Step - 1

   'Is Empty
If PixelIsOccupied(xReadPixel(X, Y, xImageBuffer(ImageHandle))) = False Then
If HasAnEmptyPixelAroundHim(ImageHandle, X, Y) = True Then
Pixel[X, Y] = EmptyPix
End If
End If

Next

Next

End Function
Code

Henri

One alternative way of doing flood fill can be found in https://en.wikipedia.org/wiki/Flood_fill

It uses a queue (TList) to store nodes (pixel objects) that need processing:

1. Check all sides left/right/up and down from starting point. If target color is found then add that node to queue.

2. Repeat until queue is empty.


I noticed that while typing this you posted your solution, but I'll leave this just in case.

-Henri
- Got 01100011 problems, but the bit ain't 00000001

ImJustAnotherCoder

#8
It looks like you've found a better alternative solution but to answer your original question

Quoteis there a way to increase blitzmax memory stack so the recursive function wont crash?
It looks like you can add linker options to your source and module code such as

Import "--stack 32768"

Hardcoal

Code