Know in advance the maximum of "IGH_DataAccess.Iteration"

Hello, do you know a method or a calculation to know in advance, how many times “SolverInstance” will be called?

thank you. jmv

It is determinable, but grasshopper doesn’t calculate it in advance. It just iterates over the inputs until it runs out.

OK thanks for your answer.

Hello,

In this case, I assume that a call to “SolveInstance” without “IGH_DataAccess.Get …” will go into an infinite loop?

Is there a problem if I run an “empty” SolveInstance with the internal counter of IGH_DataAccess or GH_StructureIterator?

In other words, is it possible to do this:

if (InPreSolve)
     DA.GetData (...);
else if (PreSolveFinish)
     // empty iteration
else
     DA.SetData (...);

thank you. jmv

No. There’s an ‘infinite’ loop inside each component which collects the next set of input values (be they items, lists or trees) from all input parameters. Once it has the next set, it collates them into an IGH_DataAccess object and then invokes the SolveInstance() method. What that method does or does not do is irrelevant to the process. At some point it’ll collect the last set of inputs and that’s the last time SolveInstance is called.

This is slightly different for task capable components, which iterate twice, once to start all processes and once to collect the computed data.

Ok so not possible either.
Thank you!

I don’t know where this comes from. If you want to do something before or after all calls to SolveInstance(), you can override the BeforeSolveInstance() or AfterSolveInstance() methods.

You won’t have access to the IGH_DataAccess object from those methods, but that may not be an issue?

Oh, I thought I was clear.
This comes from the implementation of GH_TaskCapableComponent.
In contrast, PreSolveFinish is a personal switch

public bool InPreSolve {
     get => m_inPreSolve;
     set {
          if (m_inPreSolve && value == false) PreSolveFinish = true;
          m_inPreSolve = value;
     }
}

No, I’ve not need Access to IGH_DataAccess.
GH_TaskCapableComponent does not want to work correctly in my context.
I am therefore looking to replace it. I am able to perform multicore operation with this code:

But it is safer to know in advance the number of operations in order to initialize “CountdownEvent”.

What access do your input parameters have? In some cases it’s very trivial to determine the number of iterations. It only really gets somewhat complicated when there’s a mixture of item and list access.

Well, to caricature, I’m rewriting the Component_CSNET_Script component. So undefined.
And to be honest, I don’t really want to reinterpret your algorithm to know this number :slight_smile:
But I just realized that I wrote a solution right above.

bool m_inPreSolve;
int m_iterationCount;
public bool InPreSolve {
     get => m_inPreSolve;
     set {
         if (m_inPreSolve && value == false)
            // I can place here a code between PreSolve and the rest
            AfterPreSolve ();
         m_inPreSolve = value;
     }
}
protected override void SolveInstance (IGH_DataAccess DA) {
    if (InPreSolve) PreSolve (); else Solve ();
}

protected override void BeforeSolveInstance () {
    m_iterationCount = 0;
}
void PreSolve ()
{
    m_iterationCount++;

    var inst = new MyScriptInstance (...)
    SendData (inst, DA)
    m_instances.Add (inst);
}
void AfterPreSolve ()
{
    var counter = new CountdownEvent (m_iterationCount);
    
    foreach(var inst in m_instances)
        ThreadPool.QueueUserWorkItem (inst.Run, counter);
    counter.Wait ();
}
void Solve ()
{
    ReceiveData (m_instances[DA.Iteration], DA);
}

I will work on it.
Thank you for your help.

1 Like

It works well !!
Fortunately, this forum exists, you saved me a lot of unnecessary testing. :+1: