Is it possible to cache a value while looping over points in an AttributeWrangle?

   3614   6   0
User Avatar
Member
65 posts
Joined: 2月 2017
Offline
First, do attribute wrangles process all points simultaneously like a vertex shader on the GPU? If so, each point is independent.

I'm looking to loop over each point in a linear manner (detail once?) and with each point update a variable that is shared across all points. Is this possible?
Edited by aoakenfoArchiact - 2017年3月16日 17:02:11
User Avatar
Member
2559 posts
Joined: 6月 2008
Online
Points are processed in parallel based upon the number of CPU cores you have. So on an eight core system you get 8 points processed simultaneously then the next 8 and so on.

You can use detail based attributes as globals while running over points.
I just posted an example of this yesterday at this link.
https://www.sidefx.com/forum/topic/48767/#post-220216 [sidefx.com]
Using Houdini Indie 20.0
Windows 11 64GB Ryzen 16 core.
nVidia 3050RTX 8BG RAM.
User Avatar
Member
2042 posts
Joined: 9月 2015
Offline
Yeah…Detail once.

I typically get the number of points with npoints and use that value as my for loop counter.

You could initially create a local variable just before the loop, and in the loop do what you want for each point using your loop ‘counter’ as your index to indicate which point you want to work on along with that local variable.
User Avatar
スタッフ
6245 posts
Joined: 7月 2005
Offline
aoakenfoArchiact
First, do attribute wrangles process all points simultaneously like a vertex shader on the GPU? If so, each point is independent.

From the viewpoint of the VEX user, it should be as if the points were executed in a single thread, one at a time.

However, we intentionally limit the operations you can do on the points so that we can still process them out of order and in parallel.

But if you do something like

addpoint(…)

the order in which the addpoints create points will always be the same and be in increasing point order.

One important trick we do to ensure this is to have the input be a separate copy from the output. So when you write to a point with setpointattrib() you will not get that value back by reading with pointattrib(). The pointattrib and point functions will always read the unchanging input geometry, and there is no explicit way to read the partially constructed output geometry (as we'd have to synchronize, and you'd lose all your speed advantages)

This is also why writing directly to a bound variable:
@P = …
is faster than invoking setpointattrib() on it. The setpointattrib() has to ensure all the invocations are done in the right order, but the bound variable can write through immediately since it is only one processor per point.
User Avatar
Member
65 posts
Joined: 2月 2017
Offline
So with Enivob's solution above, he creates a detail attr if it doesn't exist and then sets a value on it. Is there thread sync when setting detail attr likes this? Are these “global” vars atomic?
User Avatar
Member
2042 posts
Joined: 9月 2015
Offline
You don't have to think about thread syncing.

The only thing you have to think about is what is happens when you use run over points and it's relationship to your code.

For a users endpoint with runover points, all you have to keep in mind conceptually is that it acts like a ‘for’ loop.

For each point, sequentially in order, your code will be executed on that point and/or on your ‘global’ attrib/var.

Keep in mind too, ‘global’ attrib/vars once seen for the first time, ie. your code is showing it's initial creation.

That even though like I said before your code gets executed for every point, the second time it sees it( the attribute you created), will not re-create it. So in this aspect it differs from the ‘for’ loop analogy I mentioned.

It's as if, and I don't mean this to be a correct technical explanation, it's like it does a pre-compile and takes out your declaration of the ‘global’ attrib/var.

It doesn't do this with localy created variablees, which would be ‘re-declared’ for each point run over and definitely give you unexpected results if you were hoping for a ‘persistant’ variable.
Edited by BabaJ - 2017年3月20日 15:19:05
User Avatar
スタッフ
640 posts
Joined: 8月 2013
Offline
aoakenfoArchiact
So with Enivob's solution above, he creates a detail attr if it doesn't exist and then sets a value on it. Is there thread sync when setting detail attr likes this? Are these “global” vars atomic?

When you run over points or similar, writes to detail attributes are sequential, but purely for determinism I think. It's not atomic in the sense that you're hoping for. As jlait explained, you can't read back the written attribute values at all.

You probably do want “Detail (once)” for what you're trying to achieve. With this mode you can loop over all the points yourself and store any required data in a variable. Storing to attributes is only useful for storing the final results. They can only be accessed by subsequent operators.
Kai Stavginski
Senior Technical Director
SideFX
  • Quick Links