Jump to content

Recommended Posts

Today I was investigating how really works wrangle nodes type( more in general vex ) trying some printf debug statment.
 
as written in the reference :
 
 "This node runs the snippet on the detail or every point/primitive/vertex (depending on the Class parameter) in the input geometry. The snippet can edit the input geometry by changing attributes. It can access information from other geometry using attributes and VEX functions."
 
so chosing point class parameter and having for example an array/set of points( I don't know how point are actually internally handled by houdini), the code is "applied" to every i-th elements of the array, like a big external "invisible" forEach loop. Correct me if I'm wrong.
 

 
now, my snippet is very simple:

 

for (int i=0; i <5;i++)
{

printf("Point processed is %d \n", @ptnum);
printf("Number of iteration: %d\n", i);
}

 

Share this post


Link to post
Share on other sites

Today I was investigating how really works wrangle nodes type( more in general vex ) trying some printf debug statment.
 
as written in the reference :
 
 "This node runs the snippet on the detail or every point/primitive/vertex (depending on the Class parameter) in the input geometry. The snippet can edit the input geometry by changing attributes. It can access information from other geometry using attributes and VEX functions."
 
sochosing point class parameter and having for example an array/set of points( I don't know how point are actually internally handled by houdini), the code is "applied" to every i-th elements of the array, like a big external "invisible" forEach loop. Correct me if I'm wrong.
 

 
now, my snippet is very simple:

 

for (int i=0; i <5;i++)
{

    printf("Point processed is %d \n", @ptnum);
    printf("Number of iteration: %d\n", i);
}

 

I expect that the output on the consolle is:

 

Point processed is 0 

Number of iteration:0

Point processed is 0

Number of iteration:1

........

Point processed is 0

Number of iteration:n

........

........

........

Point processed is m

Number of iteration:1

........

Point processed is m

Number of iteration:n

 

where m: number of points and n:number of iteration.

 

instead my actual consolle output is:

Point processed is 0 
Point processed is 1 
Point processed is 2 
Point processed is 3 
Number of iteration: 0
Point processed is 0 
Point processed is 1 
Point processed is 2 
Point processed is 3 
Number of iteration: 1
Point processed is 0 
Point processed is 1 
Point processed is 2 
Point processed is 3 
Number of iteration: 2
Point processed is 0 
Point processed is 1 
Point processed is 2 
Point processed is 3 
Number of iteration: 3
Point processed is 0 
Point processed is 1 
Point processed is 2 
Point processed is 3 
Number of iteration: 4

Anyone can explain why this "non-linearity" in the execution flow? thanks in adavance

Edited by PioRaffaeleFina

Share this post


Link to post
Share on other sites

Hi

If the wrangle is set to class Point, Vertices or Primitives, the code in the snippet field over all the "class entities" in the geometry when the node is evaluated. So if the wrangle is set to Points, the code below will run the code once for every point in the geometry. So yes it's like an invisible for loop like you say.

printf("Point processed is %g and it's position is %g \n", @ptnum, @P ); 

On the other hand if the wrangle is set to Detail, the code in the snippet will only once every time the wrangle node is evaluated. So to tun over all the points in some geometry in this mode, you would have to iterate yourself.

vector pos; // Declare a vector to tmp store the point position

for (int i = 0; i < @numpt; i++) // Loop as long as "i" is less than @numpt (number of points)
{
    pos = point( 1, "P", i); //Getting the position for point number "i"
    printf("Point processed is %g and it's position is %g \n", i, @pos  );
}

Hope this helps

 

-b

Edited by bonsak

Share this post


Link to post
Share on other sites

hey bonsak thanks for the clarification, now I'm pretty sure how wrangles nodes works.

 

The real question is in the 2nd part of my post, I don't understand why my code works  but not as I expected, I can't see a reason for the "non-linearity" of execution flow( as you can see in the console's output).

If you have any suggestion let me know :-)

Share this post


Link to post
Share on other sites

Arrest me if i'm wrong but I think this might have to do with the fact that VEX is multithreaded and that printf only runs at a certain intervals during the node execution. Because if you print both @ptnum and "i" in the same statement, the output is correct:

for (int i=0; i <5;i++)
{
    printf("Point %d, Iter: %d \n", @ptnum, i);
}

Ouput:

Point 0, Iter: 0
Point 1, Iter: 0
Point 2, Iter: 0
Point 3, Iter: 0
Point 4, Iter: 0
Point 5, Iter: 0
Point 6, Iter: 0
Point 7, Iter: 0
Point 0, Iter: 1
Point 1, Iter: 1
Point 2, Iter: 1
Point 3, Iter: 1
Point 4, Iter: 1
Point 5, Iter: 1
...

I had a similar problem with setting new attributes and reading those new attributes in the same Wrangle node statement once. Only to realize that the state of the new attributes was not "ready" until the after the Wrangle node was finished executing.

 

-b

  • Like 1

Share this post


Link to post
Share on other sites

First of all, i don't know exactly how internally is processed a wrangle node, but it is executed for each points/primitives "at the same time", when a detail is run only one time.

 

Here two examples which have the same result. One with a run over points, another with a run over detail. Just connect a geometry on the first input, like a line.

printf("---Start Points---\n");

int iterations = 5;

float theta = 6.28318530718; // 360 degrees in radians
float r = 0.1; // radius
float step_angle = theta / iterations;

int my_prim = addprim(0, "poly"); // create new prim
for (int i=1; i<=iterations;i++) {
    vector _P = @P;
    printf("--- Point processed is %d \n", @ptnum);
    _P.x += cos(step_angle * i)*r;
    _P.y += sin(step_angle * i)*r;
    int new_pt = addpoint(0, _P);
    addvertex(0, my_prim, new_pt);
    printf("*** Number of iteration: %d\n", i);
}
printf("--- Start detail ---\n");

int iterations = 5;

float theta = 6.28318530718; // 360 degrees in radians
float r = 0.1; // radius
int npts = npoints(0); // number of points of input 0
float step_angle = theta / iterations;

for (int pt=0; pt<npts; pt++) {
    int my_prim = addprim(0, "poly"); // create new prim
    for (int i=1; i<=iterations;i++) {
        vector _P = point(0, "P", pt); // get position of point pt
        printf("--- Point processed is %d \n", pt);
        _P.x += cos(step_angle * i)*r;
        _P.y += sin(step_angle * i)*r;
        int new_pt = addpoint(0, _P);
        addvertex(0, my_prim, new_pt);
        printf("*** Number of iteration: %d\n", i);
    }
}

See the output in console, the detail wrangle gives us what is expected:

--- Start detail ---
--- Point processed is 0
*** Number of iteration: 1
--- Point processed is 0
*** Number of iteration: 2
--- Point processed is 0
*** Number of iteration: 3
--- Point processed is 0
*** Number of iteration: 4
--- Point processed is 0
*** Number of iteration: 5
--- Point processed is 1
*** Number of iteration: 1
--- Point processed is 1
*** Number of iteration: 2
....

When wrangle points gives us that:

---Start Points---
--- Point processed is 0
--- Point processed is 1
*** Number of iteration: 1
--- Point processed is 0
--- Point processed is 1
*** Number of iteration: 2
--- Point processed is 0
--- Point processed is 1
*** Number of iteration: 3

We expected another *** Number of iteration: 1 at the line 5, why it does not ? I don't know. < Thanks to Bonsak, the answer is here http://forums.odforce.net/topic/25704-wrangle-nodes/?p=149387

 

Edited by fsimerey

Share this post


Link to post
Share on other sites

Arrest me if i'm wrong but I think this might have to do with the fact that VEX is multithreaded and that printf only runs at a certain intervals during the node execution. Because if you print both @ptnum and "i" in the same statement, the output is correct:

for (int i=0; i <5;i++)
{
    printf("Point %d, Iter: %d \n", @ptnum, i);
}

Ouput:

Point 0, Iter: 0
Point 1, Iter: 0
Point 2, Iter: 0
Point 3, Iter: 0
Point 4, Iter: 0
Point 5, Iter: 0
Point 6, Iter: 0
Point 7, Iter: 0
Point 0, Iter: 1
Point 1, Iter: 1
Point 2, Iter: 1
Point 3, Iter: 1
Point 4, Iter: 1
Point 5, Iter: 1
...

I had a similar problem with setting new attributes and reading those new attributes in the same Wrangle node statement once. Only to realize that the state of the new attributes was not "ready" until the after the Wrangle node was finished executing.

 

-b

 

No, you're right and totally agreed with you, I never had experience with parallel and concurrency programming and I totally forgot that vex is multithread!! I must take care of this for the next time, Thanks a lot bonsak  :D

Share this post


Link to post
Share on other sites

to my undersanding it's both, SIMD architecture and type of variable

 - SIMD simply executes commands one by one for all elements, so that's why you will first get first print for all points then next print for all points

- then if your variable is varying (possibly different for each point) like @ptnum or @anyattrib or similar, then you will get unique print for each

but if your variable is constant, like in your case i, you will get just one print for all 

  • Like 3

Share this post


Link to post
Share on other sites

Oh, that totally makes sense now. It evaluates shader for all entities per instruction literally, not the whole shader for each entity in some parallel way.

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×