Why does grasshopper compute branches that will be thrown out?

I have some large files that have a number of user-selectable options for things like whether to trim the top, bottom, or both from a surface. Some of these are pretty expensive, and what I’ve found is that GH is computing all possible branches, even those that are going to be dropped by a stream gate.

Is there some way to indicate that a component should not be computed if its result is not used by a downstream component? Seems like this would be a huge optimization opportunity:

dead-branch.gh (6.1 KB)

No, but sometimes you can organize your code to execute only the part you have selected. This uses Stream Gate and Combine:


dead-branch_2020Sep15a.gh (7.5 KB)

1 Like

Oh, that’s clever. Thanks!

As for that, it would require that the solver which decides which components to solve in which order would need to be familiar with both what each component does and what its input values happen to be. The former is possible. A lot of work, but possible. And also we’d have to disable that optimisation as soon as any Script or Plugin component is present in the file, because those may rely on data in unpredictable ways.

Hmm. What if we turned this around, and added a context command “enable upstream” to each component? The user could disable every component in the file and then run that for a target. The command would walk upstream and enable all components it hits, honoring stream filter by only enabling upstreams of the selected value. Still has the problem of needing to be aware of what each component does and any branch control input value, which I see gets complicated.

Alternatively, some kind of data provenance mechanism where each component records the ID of any other component used for branch control, as well as the ID of any component used for data, and then a solution knows it only has to recompute components used for data as long as no components used for branch control have changed?

Yeah, I see the problem. @Joseph_Oster’s stream gate solution may be the only decent way.

Thanks!

In GH2 I’ve added a per-component option (in parallel with enable/disable and show/hide) which marks the component as primary/auxiliary. By default all objects are primary, which means they are computed no matter what and they remember the data they compute. When marked as auxiliary the component will forget all its computed data after it has shared it with its downstream recipients. This is supposed to reduce the memory pressure by clearing out data which is only of intermediary importance.

If a string of components terminates with only auxiliary objects it can be skipped altogether, even though that will not fix the issue described here because there is still one component which is connected to the branch you don’t want.

So really the only solid solution here is to design your algorithm in such a way so as to skip calculations you don’t need. We can probably provide better tools for doing that.

1 Like