Invalid connections when using ocpi.comp.sdr.dsp.windower_xs.hdl with it's proxy

Has anyone else come across the issue where adding the ocpi.comp.sdr.dsp.windower_xs_proxy causes an error about the windower_xs output port not not being connected on runtime, despite it working without the proxy?

Error mesage:

 Rejected implementation "windower_xs-4/a/windower_xs" in "/run/media/mmcblk0p1/opencpi/artifacts/local.fft_test.test_assm_zed_base.hdl.0.zed.bitz" due to artifact having port "output" connected while application doesn't.

Application snippet:

  <Instance component="ocpi.comp.sdr.dsp.windower_xs">
    <property name="max_window_length" value="2048"/>
  </Instance>
  <Instance component="ocpi.comp.sdr.dsp.windower_proxy" model='rcc' slave="windower_xs">
    <property name="window_length" value="2048"/>
    <property name="window_type" value="hann"/>
  </Instance>
...
<connection> 
    <port instance="chirp" name="out"/>
    <port instance="windower_xs" name="input"/>
  </connection>
  <connection> 
    <port instance="windower_xs" name="output"/>
    <port instance="fast_fourier_transform_xs" name="input"/>
  </connection>

Assembly snippet:

  <Instance worker="ocpi.comp.sdr.dsp.windower_xs">
    <property name="max_window_length" value="2048"/>
  </Instance>
...
<external name='window_input' instance='windower_xs' port='input' />
  <Connection>
    <port instance='windower_xs' name='output'/>
    <port instance='fast_fourier_transform_xs' name='input'/>
  </Connection>

You appear to be using the old proxy syntax for your application.

If you are using a proxy, you don’t need to define its slave as an instance, and you can also remove the slave attribute on the proxy instance.

Then the connections will need to use the proxy name.

I’d originally tried to do it that way but it didn’t work either, instead getting an error that the proxy doesn’t have ports named input or output.
Looking at the spec and resulting object the windower proxy doesn’t seem to have any external ports, and the windower_xs.comp example app still uses the method I’ve used.

I’ll have to have a deeper look at this after work today.

I’ll hopefully have some sort of update by tomorrow.

Thank Dom!

Having added port definitions to the windower_proxy-spec, using the new syntax results in the same error as the old syntax.
Manually connecting the slave component within the windower_xs_proxy lets ocpirun progress past the initial error, but still errors after “Starting proxy workers that are not slaves.” with the following message:

Error Exception: Port "input" of worker "windower_xs_proxy" is not connected

Modified windower_xs_proxy.xml:

<rccworker language="c++"  spec="windower_proxy-spec" controloperations="start"> <!-- slave="windower_xs.hdl" -->
  <specproperty name="window_type" writesync="true"/>
  <slaves>
    <External name='input'/>
    <External name='output'/>
    <Instance worker='windower_xs.hdl'/>

    <Connection>
      <External name='input'/>
      <Port name='input' instance='windower_xs'/>
    </Connection>
    <Connection>
      <Port name='output' instance='windower_xs'/>
      <External name='output'/>
    </Connection>
  </slaves>
</rccworker>

Modified windower_proxy-spec.xml:

<componentspec>
  <property name="window_length" type="ushort" initial="true" writable="false" default="128"
    description="number of coefficients in the window"/>
  <property name="window_type" type="enum" writable="true" enums="hann,blackman_harris,hamming" default="hann"
    description="selects the window type"/>

  <port name="input" producer="false" protocol="complex_short_timed_sample-prot"/>
  <port name="output" producer="true" protocol="complex_short_timed_sample-prot"/>
</componentspec>

As an aside although the component name is windower_xs_proxy, it doesn’t seem to work unless I refer to it as windower_proxy which doesn’t seem right.

Error Exception: No acceptable implementations found in any libraries for "ocpi.comp.sdr.dsp.windower_xs_proxy".

Is there a rule that we’re missing here… like a proxy can only be used with a port that is exposed as a port of an assembly (i.e. not as here where the windower_xs is connected to the fast_fourier_transform_xs inside the assembly)?

The windower and the fft do work with an application connection when both a made external in the assembly.

Right, I got an app to start.

This is what my changes to ocpi.comp.sdr look like (note: I picked the windower_l_proxy, the same should work for the windower_xs_proxy):

diff --git a/components/dsp/specs/windower_proxy-spec.xml b/components/dsp/specs/windower_proxy-spec.xml
index 211e1a6..af39d11 100644
--- a/components/dsp/specs/windower_proxy-spec.xml
+++ b/components/dsp/specs/windower_proxy-spec.xml
@@ -21,4 +21,6 @@
     description="number of coefficients in the window"/>
   <property name="window_type" type="enum" writable="true" enums="hann,blackman_harris,hamming" default="hann"
     description="selects the window type"/>
+  <port name="input"  producer="false"/>
+  <port name="output" producer="true"/>
 </componentspec>
diff --git a/components/dsp/windower_l_proxy.rcc/windower_l_proxy.xml b/components/dsp/windower_l_proxy.rcc/windower_l_proxy.xml
index 5fd5207..a696f9c 100644
--- a/components/dsp/windower_l_proxy.rcc/windower_l_proxy.xml
+++ b/components/dsp/windower_l_proxy.rcc/windower_l_proxy.xml
@@ -16,6 +16,19 @@
 
      You should have received a copy of the GNU Lesser General Public License
      along with this program. If not, see <http://www.gnu.org/licenses/>. -->
-<rccworker language="c++" slave="windower_l.hdl" spec="windower_proxy-spec" controloperations="start">
+<rccworker language="c++" spec="windower_proxy-spec" controloperations="start">
   <specproperty name="window_type" writesync="true"/>
+  <slaves>
+    <external name="input"/>
+    <external name="output"/>
+    <connection>
+      <external name="input"/>
+      <port name="input" instance="windower"/>
+    </connection>
+    <instance worker="windower_l.hdl" name="windower"/>
+    <connection>
+      <port name="output" instance="windower"/>
+      <external name="output"/>
+    </connection>
+  </slaves>
 </rccworker>

This is my assembly:

<hdlassembly componentlibraries="dsp">
    <instance worker="windower_l" externals="true"/>
</hdlassembly>

This is my application:

<application done="file_write">

  <instance component="ocpi.core.file_read" connect="windower">
    <property name="filename" value="input.bin"/>
  </instance>

  <instance
      component="ocpi.comp.sdr.dsp.windower_proxy"
      name="windower"
      connect="file_write"
  >
    <property name="window_length"  value="128"/>
    <property name="window_type"    value="hann"/>
  </instance>

  <instance component="ocpi.core.file_write">
    <property name="filename" value="output.bin"/>
  </instance>

</application>

I did try using worker on the windower_proxy instance to explicitly force use of windower_l_proxy, but that prevented the application from running for some reason that I couldn’t work out.

Edit: The issue that has been struck through above was due to a typo by me. Setting worker on instance to ocpi.comp.sdr.dsp.windower_l_proxy.rcc does work.

Note: In my case, for speed, I added the hdlassembly and application into ocpi.comp.sdr.

Decided to follow up and check exactly how much of that first diff is actually required for the build to work. Turns out, it’s just this:

diff --git a/components/dsp/specs/windower_proxy-spec.xml b/components/dsp/specs/windower_proxy-spec.xml
index 211e1a6..af39d11 100644
--- a/components/dsp/specs/windower_proxy-spec.xml
+++ b/components/dsp/specs/windower_proxy-spec.xml
@@ -21,4 +21,6 @@
     description="number of coefficients in the window"/>
   <property name="window_type" type="enum" writable="true" enums="hann,blackman_harris,hamming" default="hann"
     description="selects the window type"/>
+  <port name="input"  producer="false"/>
+  <port name="output" producer="true"/>
 </componentspec>

The pre v2.1 slave syntax (which is what this worker uses) still works in the rccworker, put the component does need to expose the ports.

So this is a bug. The CI for ocpi.comp.sdr wouldn’t have noticed this because there is currently no way for the unit test framework to test a proxy. So you’d need to write custom tests using applications and hdlassemblys.


One last thing.
The proxy will use the default build of its slaves if they are instantiated as in the pre v2.1 syntax. So in the case of windower_l, it will use the default max_window_length of 128. If you need more than this, you will need to use the newer <slaves> syntax, and set the property.

I’ve replicated your changes and dropped the protocol from the windower_proxy-spec but it still doesn’t seem to run for me, getting to the same stage as my changes and then ending with a disconnected port.

Proxy:

<rccworker language="c++"  spec="windower_proxy-spec" controloperations="start"> <!-- slave="windower_xs.hdl" -->
  <specproperty name="window_type" writesync="true"/>
  <slaves>
    <external name='input'/>
    <external name='output'/>
    <instance worker='windower_xs.hdl'>
      <!-- <property name="max_window_length" value="2048"/> -->
   </instance>

    <connection>
      <external name='input'/>
      <port name='input' instance='windower_xs'/>
    </connection>
    <connection>
      <port name='output' instance='windower_xs'/>
      <external name='output'/>
    </connection>
  </slaves>
</rccworker>

Proxy Spec:

<componentspec>
  <property name="window_length" type="ushort" initial="true" writable="false" default="128"
    description="number of coefficients in the window"/>
  <property name="window_type" type="enum" writable="true" enums="hann,blackman_harris,hamming" default="hann"
    description="selects the window type"/>

  <port name="input" producer="false"/>
  <port name="output" producer="true"/>
</componentspec>

App:

<Application>
  <instance component='local.av_test_proj.fmcw_chirp'/>
  <Instance component="ocpi.comp.sdr.dsp.windower_proxy"/>
  <Instance Component="local.zed_test.endcap"/>

  <connection> 
    <port instance="fmcw_chirp" name="out"/>
    <port instance="windower_proxy" name="input"/>
  </connection>
  <connection> 
    <port instance="windower_proxy" name="output"/>
    <port instance="endcap" name="in"/>
  </connection>
</Application>

Assembly:

<HdlAssembly componentlibraries="dsp">
   <Instance worker="windower_xs">
      <!-- <property name="max_window_length" value="2048"/> -->
   </Instance>

   <connection>
      <external name='input'/>
      <port name='input' instance='windower_xs'/>
   </connection>
   <connection>
      <port name='output' instance='windower_xs'/>
      <external name='output'/>
   </connection>
</HdlAssembly>

What OpenCPI version are you using? I was using current develop, which is basically pre release v2.4.7.

Edit: I just copied precisely your hdlassembly and rccworker and my application still runs. I think you’ve found a deployment issue that has been fixed since whichever version you are on.

I’m on v2.4.7 but had previously tried on v2.4.6 with similar results

Okay, now I’m wondering if the deployment algorithm is selecting a different assembly or windower_#_proxy.

Can you make symlinks to all the necessary artifacts in your application directory, and then set OCPI_LIBRARY_PATH to just the application directory? That’ll avoid the whole deployment algorithm, by supplying exactly the required artifacts.

Given that I couldn’t recreate this, it’s either some other file that’s affecting the environment, or a version mismatch / improper rebuild.

I’ll put my example in a project by itself, and try build it from completely clean on v2.4.6.

Here’s my project:

Built against a completely clean copy of release-2.4.6.

Edit: Okay, whilst I thought this worked, it didn’t.

Right, I think my initial run where I thought it worked, it didn’t actually work.

I’ve replicated this issue in v2.4.7, and updated the project linked above.

As I was going through this, I started to feel like this was a familiar problem.

Turns out, it is:

The current workaround is that ports on proxies that are delegated to a slave, have to be optional on the proxy.

So this patch should work:

diff --git a/components/dsp/specs/windower_proxy-spec.xml b/components/dsp/specs/windower_proxy-spec.xml
index 211e1a6..af39d11 100644
--- a/components/dsp/specs/windower_proxy-spec.xml
+++ b/components/dsp/specs/windower_proxy-spec.xml
@@ -21,4 +21,6 @@
     description="number of coefficients in the window"/>
   <property name="window_type" type="enum" writable="true" enums="hann,blackman_harris,hamming" default="hann"
     description="selects the window type"/>
+  <port name="input"  producer="false" optional="true"/>
+  <port name="output" producer="true"  optional="true"/>
 </componentspec>

Thanks Dom that’s worked!