essentia icon indicating copy to clipboard operation
essentia copied to clipboard

Help needed with single shot composite steps in streaming network mode

Open leonid-s-usov opened this issue 4 years ago • 2 comments

Hi!

I've broken my mind already trying to figure out why my KeyExtractor is not working in real-time streaming mode as I want it, that is emitting predictions regularly over its buffered data.

I conclude that the reason is that there is some problem with how single-shot composite steps are (not)working.

First, this is what it looks like after several seconds of running a simple KeyExtractor network in a RingBufferInput streaming mode (calling runStep() periodically)

[Scheduler ] ------------------------ Buffer states after running the generator and all the nodes ------------------------
[Scheduler ] RingBufferInput          (called 195 times)
[Scheduler ]   - signal                   fill  10%   |   15312 / 144176  |  contiguous: 18022   |  total produced: 133120  
[Scheduler ] 
[Scheduler ] FrameCutter              (called 22 times)
[Scheduler ]   - frame                    fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 21      
[Scheduler ] 
[Scheduler ] Windowing                (called 21 times)
[Scheduler ]   - frame                    fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 21      
[Scheduler ] 
[Scheduler ] Spectrum                 (called 21 times)
[Scheduler ]   - spectrum                 fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 21      
[Scheduler ] 
[Scheduler ] SpectralWhitening        (called 21 times)
[Scheduler ]   - magnitudes               fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 21      
[Scheduler ] 
[Scheduler ] HPCP                     (called 21 times)
[Scheduler ]   - hpcp                     fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 21      
[Scheduler ] 
[Scheduler ] PoolStorage              (called 21 times)
[Scheduler ] 
[Scheduler ] Key                      (called 0 times)
[Scheduler ]   - key                      fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 0       
[Scheduler ]   - scale                    fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 0       
[Scheduler ]   - strength                 fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 0       
[Scheduler ] 
[Scheduler ] DevNull<Real>[0]         (called 0 times)
[Scheduler ] 
[Scheduler ] DevNull<std::string>[1]  (called 0 times)
[Scheduler ] 
[Scheduler ] DevNull<std::string>[0]  (called 0 times)
[Scheduler ] 
[Scheduler ] SpectralPeaks            (called 21 times)
[Scheduler ]   - frequencies              fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 21      
[Scheduler ]   - magnitudes               fill   0%   |       0 / 16      |  contiguous: 0       |  total produced: 21  

One can clearly see that data is being fed to the PoolStorage step of the Key streaming composite, but the recursive Key step is never executed.

Just for reference, this is how Key is defined

  void declareProcessOrder() {
    declareProcessStep(SingleShot(_poolStorage));
    declareProcessStep(SingleShot(this));
  }

The self-referencing magic of such recursive Composite Algo is fully dependent on the following code:

AlgorithmStatus Key::process() {
  if (!shouldStop()) return PASS;

  const vector<vector<Real> >& hpcpKey = _pool.value<vector<vector<Real> > >("internal.hpcp");
  vector<Real> hpcpAverage = meanFrames(hpcpKey);
....

Here, the key concept is around the shouldStop() call, which is used to decide whether to finally process accumulated data in the pool or wait for more.

My biggest issue is: shouldStop() never returns true for a RingBufferInput

More than that, if I would accept the fact and construct a whole network, running it periodically with a pre-aggregated sample vector input, then what's the whole point of making a streaming version of the Key algorithm???

oof...

When I proceed thinking about it, I kind of don't see how "single shot" is otherwise different from a "chain" composite step? Without any special logic to simulate local finished network run it looks like I could add a single shot step as a chain step with just one algo. It would just be executed as other chain members.

If the only reason for a single shot step is to make it possible to recursively reference self, then the whole resulting effect doesn't look any different from an Aggregator algorithm. That one acts the same: silently accumulates inputs during the run and then has the chance to finalize upon generator EOF. For this encapsulation, one could just make pre-defined chains of simple algos without having to invent an internal composition semantics.

Where am I wrong?

Thanks!

leonid-s-usov avatar Jul 25 '19 17:07 leonid-s-usov

Same problem here, right now seems impossible to use Essentia algorithms with realtime data. That "shouldStop" check at the beginning of the "process" function is a show-stopper here.

epaterlini avatar Mar 02 '21 10:03 epaterlini

Any recent movement on this front or workarounds that have been developed? I'm encountering the same issue, which leads to hangs when calling "process" and "runStep" when there isn't enough data accumulated in the buffer.

BlindElephants avatar Apr 14 '23 18:04 BlindElephants