error: interface `xxx' can only connect tasks on the same tile

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
ozel
Active Member
Posts: 45
Joined: Wed Sep 08, 2010 10:16 am

error: interface `xxx' can only connect tasks on the same tile

Post by ozel »

What are the pre-conditions for interfaces to connect tasks across tiles?
Could it be missing resources?
In this project for a XE216 chip are 6 other interfaces and 2 streaming channels defined.


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

What are the pre-conditions for interfaces to connect tasks across tiles?
Not 100% sure what you mean but be aware that the switch in between the tiles has 4 ports on it. So you can only simultaneously have 4 connections. Interfaces and normal channels (no streaming) open the circuit and close afterwards.
Could it be missing resources?
Can you show the code that has caused this? Perhaps you are trying to share memory which is not possible across tiles.
In this project for a XE216 chip are 6 other interfaces and 2 streaming channels defined.
You can have as many interfaces/channels as channel ends available on the same tile but please see the above restriction. However I would not expect a compile time error - switch (between tiles) blocking would be a runtime lock-up. The compiler is not clever enough to understand the temporal behaviour of channels and interfaces.
ozel
Active Member
Posts: 45
Joined: Wed Sep 08, 2010 10:16 am

Post by ozel »

Hi, thank's a lot for your hint! It was a compile time error and it appeared due to a memory sharing attempt as you suggested because I accidentally declared an interface function with a pointer as argument like so:

Code: Select all

typedef interface TPX3_ctrl_if {
    void reset_chip(void);
    void init_chip(void);
    void write_cmd_16b(unsigned char header, unsigned short conf);
    void write_cmd_array(unsigned char header, unsigned char * array, unsigned char length); //throws compiler error because pointers can't be passed across tiles like that
} TPX3_ctrl_if;
I had only declared write_cmd_array() and wrote only an empty implementation so far. Changing the pointer to a reference (which is what I intended to have in the first place) quickly fixed everything.
If a reference is passed across tiles, is one of those magic memcpy()s inserted by the compiler?

Regarding the 4 switch links per tile: Does it make a difference if a streaming channel is only used in one direction - e.g. assuming a bi-directional usage would consume 2 of those links?
It seems my application is running pretty close to the throughput limits of the chip: I'm deserialising a 40 Mbits serial bitstream (the goal is several streams and if possible at 80 Mbits) including 8b10b decoding. A streaming channel seems to be the only way to offload the recovered bytes to another task fast enough. Interestingly, if this streaming channel points to the same tile where the deserialiser sits (a tile with 3 tasks in total, but one idling during port input) it's too slow while if the streaming channel points to the other tile (with 8 tasks in total!) it's fast enough to keep up with the input rate on the pins. Some old post mentions that the switch may increase buffering depth but there seems to be no information in the official xs2 documents on this.
I'd be very glad about explanations of my observation.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

If a reference is passed across tiles, is one of those magic memcpy()s inserted by the compiler?
From memory, I think remote references are handled by sending copies across the link and writing them back. If you want the array to play with outside of the case, you need to do an explicit memcpy to your own copy.
Regarding the 4 switch links per tile: Does it make a difference if a streaming channel is only used in one direction - e.g. assuming a bi-directional usage would consume 2 of those links?
No - a bidirectional channel will only consume one link.
Interestingly, if this streaming channel points to the same tile where the deserialiser sits (a tile with 3 tasks in total, but one idling during port input) it's too slow while if the streaming channel points to the other tile (with 8 tasks in total!) it's fast enough to keep up with the input rate on the pins.
That will be due channel buffering, which you can make use of if you choose a streaming channel. You can buffer 2 x 32b words on the same tile but when you go through the switch you get a lot more buffering. What it means is that your consuming task is probably not ready to consume when the producer task is outputting so you are relying on the buffering to prevent the producer from blocking.
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

ozel wrote:If a reference is passed across tiles, is one of those magic memcpy()s inserted by the compiler?
infiniteimprobability wrote:From memory, I think remote references are handled by sending copies across the link and writing them back. If you want the array to play with outside of the case, you need to do an explicit memcpy to your own copy.
Yes, a remote memcpy (or a simpler action) will be used to transfer data to and fro when references are accessed (but not pointers).
The compiler only handles such accesses from within the select-case clause, thus the compiler will error if you attempt to let the reference escape from the clause.
As already mentioned, you should take explicit control when necessary, possibly using memcpy.
N.B. memcpy is well understood by the compiler and it can create optimal code when it is used - it is your friend!
ozel
Active Member
Posts: 45
Joined: Wed Sep 08, 2010 10:16 am

Post by ozel »

Thank you both for your clarifying posts, very much appreciated!
The "new" interfaces enable modular software development really well, it's great to program with them. Just a pity they seem too slow for handling the parsed 40 Mbit/s streams in my case.
Running my rewritten consumer thread back on the same tile as the producer (still using streaming channels) is now not that different anymore. Bit alignment of timed deserialised input is lost only a couple of 32-bit inputs earlier as opposed to running the thread on the other tile.
For now I can live with throttling the input stream into shorter bursts but in the long run I will need to switch to a fast standalone UDP package builder which bypasses xtcp to offload the input stream fast enough from the xmos chip.
Post Reply