POV-Ray : Newsgroups : povray.advanced-users : :O I broke it. Server Time
24 Apr 2024 02:31:37 EDT (-0400)
  :O I broke it. (Message 1 to 10 of 10)  
From: Bald Eagle
Subject: :O I broke it.
Date: 12 Aug 2016 20:45:04
Message: <web.57ae6ce5800fc25b5e7df57c0@news.povray.org>
Render Options
  Quality:  9
  Bounding boxes.......On   Bounding threshold: 3
  Antialiasing.........Off
Internal limit exceeded in FixedSimpleVector
Fatal error in renderer: A POV-Ray internal nesting limit was reached.
Render failed


What did I DO???

##########################################################################

#version 3.7;

global_settings {assumed_gamma 1.0}

#include "colors.inc"
#include "textures.inc"

camera {
 location <5, 1, -20>
 look_at  <5, 1, 0>
}


light_source {<20, 50, -100> White shadowless}
light_source {<0, 5, -1> White shadowless}

#declare R = 2;

//###############################################################
#declare r = 0.1;
#declare Step = 0.4 / (2*pi/0.1)*(pi/0.2);
#declare Sphere2 =
union {
#for (Theta, 0, 2*pi, 0.1)
    #for (Phi, 0, pi, 0.2)      // this gets cycles twice, because Theta goes to
2*pi

    #declare X = R * sin (Theta) * cos (Phi);
    #declare Y = R * sin (Theta) * sin (Phi);
    #declare Z = R * cos (Theta);

    sphere {<X, Y, Z>, r pigment {Red*abs(sin(Theta/2))} }
    #declare r = r + Step;
    #end // end for Phi
#end // end for Theta

cylinder {<0, 0, 0>, <R*1.5, 0, 0>, 0.075 pigment {Red}}
cylinder {<0, 0, 0>, <0, R*1.5, 0>, 0.075 pigment {Green}}
cylinder {<0, 0, 0>, <0, 0, R*1.5>, 0.075 pigment {Blue}}

}
//###############################################################

object {Sphere2 translate x*10}


Post a reply to this message

From: Bald Eagle
Subject: Re: :O I broke it.
Date: 12 Aug 2016 20:50:05
Message: <web.57ae6dfbb8fa7f145e7df57c0@news.povray.org>
This fixes it.
Hmmm.

#declare Step = 0.49 / ((2*pi/0.1)*(pi/0.2));

{notice additional brackets}


Post a reply to this message

From: clipka
Subject: Re: :O I broke it.
Date: 12 Aug 2016 22:40:45
Message: <57ae88ad$1@news.povray.org>
Am 13.08.2016 um 02:46 schrieb Bald Eagle:
> This fixes it.
> Hmmm.
> 
> #declare Step = 0.49 / ((2*pi/0.1)*(pi/0.2));
> 
> {notice additional brackets}

I interpret that as "nevermind, please disregard my earlier post".
If that interpretation is incorrect, let me know.


Post a reply to this message

From: Bald Eagle
Subject: Re: :O I broke it.
Date: 13 Aug 2016 13:05:01
Message: <web.57af52ae47ff3d5d79f0f2c20@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
> Am 13.08.2016 um 02:46 schrieb Bald Eagle:
> > This fixes it.
> > Hmmm.
> >
> > #declare Step = 0.49 / ((2*pi/0.1)*(pi/0.2));
> >
> > {notice additional brackets}
>
> I interpret that as "nevermind, please disregard my earlier post".
> If that interpretation is incorrect, let me know.

Wellllll....   it's ok in the short term I guess,
Though it doesn't explain the error - which seems like it may be some sort of
bug.
I don't see any recursion occurring, or limit to be reached.

So, I guess it's up to you to decide   ;)


Post a reply to this message

From: clipka
Subject: Re: :O I broke it.
Date: 13 Aug 2016 17:24:57
Message: <57af9029$1@news.povray.org>
Am 13.08.2016 um 19:02 schrieb Bald Eagle:
> clipka <ano### [at] anonymousorg> wrote:
>> Am 13.08.2016 um 02:46 schrieb Bald Eagle:
>>> This fixes it.
>>> Hmmm.
>>>
>>> #declare Step = 0.49 / ((2*pi/0.1)*(pi/0.2));
>>>
>>> {notice additional brackets}
>>
>> I interpret that as "nevermind, please disregard my earlier post".
>> If that interpretation is incorrect, let me know.
> 
> Wellllll....   it's ok in the short term I guess,
> Though it doesn't explain the error - which seems like it may be some sort of
> bug.
> I don't see any recursion occurring, or limit to be reached.
> 
> So, I guess it's up to you to decide   ;)

My guess would be "camera inside too many spheres at once".

Note that you're increasing the radius of the sphere, `r`, by `Step`
about (pi/0.2) times per inner loop, and do this (2*pi/0.1) times per
outer loop, for a total of about 1000 times.

With your fixed version,

    #declare Step = 0.49 / ((2*pi/0.1)*(pi/0.2));

you get a `Step` value of around 0.00049; Throughout the loops, this
adds about 0.49 to `r`, for a final radius of about 0.59. Since the
position of the sphere is off the center by R=2, the farthest point of
the largest sphere is about 2.59 off the center -- at <5,1,-20> the
camera is way outside that range.

With the bugged version however,

    #declare Step = 0.49 / (2*pi/0.1)*(pi/0.2);

you get a `Step` value of exactly 0.49, which causes `r` to grow to the
distance to the camera (ca. 20.6) in just about 42 steps. So the camera
is inside approximately 950 spheres.

Compiled with the default settings, POV-Ray can cope with a ray being
inside up to 512 overlapping objects, then it raises the white flag.


This is one of the very few fixed-size data structures still present in
POV-Ray, and it is instantiated at each reflection and refraction, so
although it would be possible to increase the limit, that would mean
increasing memory consumption during each and every render, no matter
whether the limit is ever even remotely approached, and you'd still have
/some/ hard limit anyway.

Also, although it would theoretically be possible to replace the data
structure with a variable-sized one, any attempts at doing so have so
far resulted in severely degraded performance.


Post a reply to this message

From: Bald Eagle
Subject: Re: :O I broke it.
Date: 13 Aug 2016 20:30:06
Message: <web.57afba6a47ff3d5d79f0f2c20@news.povray.org>
And THAT, my fellow POVers, is why we have a shrine to this man.

:)

A deep, detailed, explanation as to why I need to be more careful with my
arithmetic operational hierarchy.

<bows deeply>
Many thanks.


Post a reply to this message

From: Le Forgeron
Subject: Re: :O I broke it.
Date: 14 Aug 2016 03:35:18
Message: <57b01f36$1@news.povray.org>
Le 13/08/2016 à 23:24, clipka a écrit :
> Also, although it would theoretically be possible to replace the data
> structure with a variable-sized one, any attempts at doing so have so
> far resulted in severely degraded performance.

To avoid reallocation at each new element, you can reserve() some containers like
vector<>.
Until the reserved number of element is reached, no more reallocation. But there is no
signaling of the reservation being full, so after that you're back to the
reallocation.

But vector<> has one constraint: the elements are contiguous. Something that is not
always needed.

The less light-hearted programmers might even replace the default allocator for
something totally different.
But gaining over the traditional malloc is hard, very hard.


Post a reply to this message

From: clipka
Subject: Re: :O I broke it.
Date: 14 Aug 2016 13:55:43
Message: <57b0b09f$1@news.povray.org>
Am 14.08.2016 um 09:35 schrieb Le_Forgeron:
> Le 13/08/2016 à 23:24, clipka a écrit :
>> Also, although it would theoretically be possible to replace the data
>> structure with a variable-sized one, any attempts at doing so have so
>> far resulted in severely degraded performance.
> 
> To avoid reallocation at each new element, you can reserve() some containers like
vector<>.
> Until the reserved number of element is reached, no more reallocation.
> But there is no signaling of the reservation being full, so after that you're back
to the reallocation.

The main drawback of vector<> is that there is /any/ allocation at all.
Or, more precisely, that a new instance of vector<> always does at least
one initial allocation.

The lists in question are used as temporary objects in recursive
function calls, and need to be created and discarded multiple times per
ray traced.

POV-Ray's homebrew FixedSimpleVector<> overcomes this problem by using a
static array instead of dynamically allocating memory, allowing it to
reside entirely on the stack.

> The less light-hearted programmers might even replace the default allocator for
something totally different.
> But gaining over the traditional malloc is hard, very hard.

Simply using a vector with a custom allocator isn't going to nail it,
that's for sure.

I have two main variants in mind that I plan on trying someday:

(A) Using a custom vector<>-ish type with a hybrid approach, using a
fixed static array plus dynamically allocated extra storage. This should
provide reasonably good performance for most scenes, while still
allowing pathological scenes to render, albeit at reduced performance.

(B) Allocating the entire vector<> dynamically (as opposed to just
letting vector<> allocate its data space dynamically), but not
discarding it after use, and instead keeping it around in a pool,
without trimming back its capacity. Next time such a vector would be
required, it would not be created anew but fetched from the pool, ready
for use without having to allocate memory for the data. This would still
result in poor performance for the first few rays, but should allow for
high performance throughout the bulk of the render even for pathological
scenes.


Post a reply to this message

From: Le Forgeron
Subject: Re: :O I broke it.
Date: 14 Aug 2016 14:56:43
Message: <57b0beeb$1@news.povray.org>
Le 14/08/2016 à 19:55, clipka a écrit :
> Simply using a vector with a custom allocator isn't going to nail it,
> that's for sure.

And before jumping the wagon, did you check the vector is actually the container that
is needed.
(continuous storage, usually for many direct access to random elements)

It was "like" a vector in C, because that is the more dynamic continuous data storage
with a single allocation block.

Sometime it is good to ask again the basic questions

http://stackoverflow.com/questions/10699265/how-can-i-efficiently-select-a-standard-library-container-in-c11

http://homepages.e3.net.nz/~djm/cppcontainers.html


Post a reply to this message


Attachments:
Download 'stl.png' (9 KB)

Preview of image 'stl.png'
stl.png


 

From: clipka
Subject: Re: :O I broke it.
Date: 14 Aug 2016 15:25:00
Message: <57b0c58c$1@news.povray.org>
Am 14.08.2016 um 20:56 schrieb Le_Forgeron:
> Le 14/08/2016 à 19:55, clipka a écrit :
>> Simply using a vector with a custom allocator isn't going to nail it,
>> that's for sure.
> 
> And before jumping the wagon, did you check the vector is actually the container
that is needed.
> (continuous storage, usually for many direct access to random elements)

The usual criteria for choosing a data structure are moot here: The one
thing that's a complete no-go in this case is dynamic memory allocation
(with the possible exception of pathological scenes).

That categorically rules out virtually every other standard data
structure outright, as they rely even heavier on dynamic memory
allocation than a vector.

> It was "like" a vector in C, because that is the more dynamic continuous data
storage with a single allocation block.

When POV-Ray was still C, I'm pretty sure it was a plain static array.

> Sometime it is good to ask again the basic questions

And sometimes it is necessary to ask entirely different questions.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.