Opened 9 years ago

Last modified 3 years ago

#3905 new defect

findZeroCrossings scales as O(N^2)

Reported by: Francesco Casella Owned by: Martin Sjölund
Priority: critical Milestone:
Component: Backend Version:
Keywords: Cc:

Description

As demonstrated by the BreakerCircuit models of the ScalableTestSuite, the findZeroCrossing function scales as O(N2). It is currently the biggest bottleneck in our large network models, when including line breakers and current protections, which generate up to 40000 zero-crossing functions.

@hkiel reports that

findZeroCrossings uses lots of listAppend() in wrong order (mostly appending a single element). Either someone can switch the code to build the lists in reverse order (does order matter annyhow?) or use the DoubleEndedList. I'm currently too busy to do such a huge task.

In fact the order doesn't matter at all, so I guess DoubleEndedList would do the job.

Change History (17)

comment:1 by Martin Sjölund, 9 years ago

I also guessed the order doesn't matter, but it breaks the testsuite if I change the ordering :(

comment:2 by Francesco Casella, 9 years ago

Probably it breaks the testsuite because there is some place where an ordered list of crossing functions is compared with a reference one, and as the two don't match, an error is generated.

I can't really see any reason why there should be a preferred ordering for these functions and what could be the ordering criterion.

comment:3 by Martin Sjölund, 8 years ago

It broke the testsuite because the relations have indexes in them pointing to the correct zero-crossing. So if you generate them in the wrong order, the references become invalid and you get the wrong result.

comment:4 by Francesco Casella, 8 years ago

I have added some structurally very simple test cases to the ScalableTestSuite. Please check the performance of the ScalableTestSuite.Elementary.WhenEvents.ScaledExperiments.ManyEvents_N_XXX models:

    model ManyEvents "Model with many events in when clauses"
      parameter Integer N = 5;
      Real x[N](each start = 0, each fixed = true);
      Boolean e[N](each start = false, each fixed = true);
    equation
      for i in 1:N loop
        der(x[i]) = 1/i;
        when x[i] > 1 then
          e[i] = true;
        end when;
      end for;
    end ManyEvents;

On my PC, I get the following times for running findZeroCrossings

NTime[s]
10000.25
20001.25
40008.08

corresponding to O(N2.5). Maybe this very essential test case helps sorting out the issue...

comment:5 by Francesco Casella, 8 years ago

One way to make this manageable for large N could be allowing to optionally turn off some optimizations. For example, if we know a priori there are no duplicate conditions in the model, we could avoid looking for them in the backend.

comment:6 by Martin Sjölund, 8 years ago

Milestone: 1.10.01.11.0

Ticket retargeted after milestone closed

in reply to:  4 comment:7 by Francesco Casella, 8 years ago

Status update, using results obtained today with master run on libraries.openmodelica.org

NTime[s]Memory [GB]
1000 0.7 0.18
2000 3.9 0.68
4000 15.4 2.68
8000 63.3 10.61


Time grows as O(N2) for N >= 2000. No idea why it should be significantly faster than that for N = 1000.

Memory allocation also grows quadratically.

comment:8 by Martin Sjölund, 8 years ago

Milestone: 1.11.01.12.0

comment:9 by Francesco Casella, 7 years ago

The situation is still unchanged. Any chance to fix this?

comment:10 by Francesco Casella, 7 years ago

Milestone: 1.12.01.13.0

Milestone moved to 1.13.0 due to 1.12.0 already being released.

comment:11 by Francesco Casella, 7 years ago

@sjoelund.se could you have another look at this? This is the last remaining major scaling issue with large models that cannot be circumvented by using --daeMode

BTW, the compilation of the generated code corresponding to the event detection is also very expensive, although it scales linearly with model size. Looking at the Hudson report, it takes between 15 and 25 ms per single event to compile the C code, which is a lot of time and basically makes it impossible to go above 10000 event generating functions. We need a lot more than that to manage realistic transmission grid models. Any suggestion how to make this substantially faster would be welcome.

Thanks!

comment:12 by Willi Braun, 7 years ago

I think for an efficient findZeroCrossing module we will need to redesign the Expressions that are used for zero-crossings. Basically, by introducing an separated Expression for ZeroCrossing would make things much easier, as far as I see, therefore I started PR2061.

comment:13 by Francesco Casella, 6 years ago

Milestone: 1.13.01.14.0

Rescheduled to 1.14.0 after 1.13.0 releasee

comment:14 by Francesco Casella, 5 years ago

Milestone: 1.14.01.16.0

Releasing 1.14.0 which is stable and has many improvements w.r.t. 1.13.2. This issue is rescheduled to 1.16.0

comment:15 by Francesco Casella, 4 years ago

Milestone: 1.16.01.17.0

Retargeted to 1.17.0 after 1.16.0 release

comment:16 by Francesco Casella, 4 years ago

Milestone: 1.17.01.18.0

Retargeted to 1.18.0 because of 1.17.0 timed release.

comment:17 by Francesco Casella, 3 years ago

Milestone: 1.18.0

Ticket retargeted after milestone closed

Note: See TracTickets for help on using tickets.