Page 1 of 1

error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 8:09 am
by aclassifier
What is a "multi-tile par"? I see "multi-tile main" in an older post (error: multi-tile main must consist of single non-empty par) but now I am at a stage where I, in a larger project, don't seem able to work my way around it (as I was a couple of years ago).

Here's a short code example. There is only tile[0] and there should be no hidden use of any other tile.

Code: Select all

#include <platform.h>
#include <timer.h> // XS1_TIMER_HZ etc

typedef signed int time32_t;

interface ifa {
    void but (int x);
};

[[combinable]]
void button (client interface ifa i_but) {
   timer tmr;
   time32_t time;
   tmr :> time;
   while (1) {
       select {
           case tmr when timerafter(time) :> void: {
               i_but.but(time/XS1_TIMER_KHZ); // ms
               time += XS1_TIMER_HZ;
               break;
           }
       }
   }
}

[[combinable]]
void handle (server interface ifa i_but[3]) {
    while (1) {
        select {
            case i_but[int i].but (int val) : {
                break;
            }
        }
    }
}

int main (void) {
    interface ifa i_but[3];
    par {
        on tile[0].core[0]: handle (i_but);
        [[combine]]
        par {
        // ^~~~~ error: cannot apply [[combine]] to multi-tile par
            on tile[0].core[0]: button (i_but[0]);
            on tile[0].core[0]: button (i_but[1]);
            on tile[0].core[0]: button (i_but[2]);
        }
    }
    return 0;
}
By the way, this also fails:

Code: Select all

int main (void) {
    interface ifa i_but[3];
    [[combine]]
    par {
    // ^~~~~ error: cannot apply [[combine]] to multi-tile par
        on tile[0].core[0]: handle (i_but);
        on tile[0].core[0]: button (i_but[0]);
        on tile[0].core[0]: button (i_but[1]);
        on tile[0].core[0]: button (i_but[2]);
    }
    return 0;
}

Re: error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 9:20 am
by infiniteimprobability
Tiles can only communicate via channels - there are no shared resources. This includes memory. Combining functions essentially flattens their select cases into one large select running on the same thread (aka logical core). They of course must be in the same memory space - ie. be on the same tile.
So the compiler is right - trying to combine tasks on different tiles is not going to work..

Re: error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 9:27 am
by aclassifier
infiniteimprobability wrote:Tiles can only communicate via channels - there are no shared resources. This includes memory. Combining functions essentially flattens their select cases into one large select running on the same thread (aka logical core). They of course must be in the same memory space - ie. be on the same tile.
So the compiler is right - trying to combine tasks on different tiles is not going to work..
But have I tried to combine tasks on different tiles? Where is my blind spot?

The channel version also fails:

Code: Select all

#include <platform.h>
#include <timer.h> // XS1_TIMER_HZ etc

 [[combinable]]
 void button (chanend c_out) {
    timer t;
    int s;
    t :> s;
    while (1) {
        select {
            case t when timerafter(s) :> void: {
                c_out <: (s/XS1_TIMER_KHZ); // ms
                s += XS1_TIMER_HZ;
                break;
            }
        }
    }
}

[[combinable]]
void handle (chanend c_but[3]) {
    int val;
    while (1) {
        select {
            case c_but[int i] :> val: {
                break;
            }
        }
    }
}

int main (void) {
    chan c_but[3]; // Using 6 chanends always
    [[combine]]
    par {
    // ^~~~~ error: cannot apply [[combine]] to multi-tile par
        on tile[0].core[0]: handle (c_but);
        on tile[0].core[0]: button (c_but[0]);
        on tile[0].core[0]: button (c_but[1]);
        on tile[0].core[0]: button (c_but[2]);
    }
    return 0;
}

Re: error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 9:32 am
by infiniteimprobability
I see your point. I think it's because you have the on tile[0] placement directive below a combinable directive. What you have done should be valid though.

You are mixing methods of declaring combinable (.core[0] and [[combine]]) although again what you have declared should be valid. Try raising any tile[n] directives to the first level par and using [[combine]] instead..

Re: error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 9:41 am
by aclassifier
In the last two examples tile[n] directives are on the top par, as there is only one par. Removing the core[n] does not help. The full on all have to be removed. Hmm?

Re: error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 10:02 am
by infiniteimprobability
I was thinking this (apologies for poor indenting):

Code: Select all

par {
  on tile[0]:{
    [[combine]]
    par {
        handle (c_but);
        button (c_but[0]);
        button (c_but[1]);
        button (c_but[2]);
    }
}
    return 0;

Re: error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 10:24 am
by aclassifier
OKAY:-)

Code: Select all

par {
    on tile[0]: {
        [[combine]]
        par {
            handle (i_but);
            button (i_but[0]);
            button (i_but[1]);
            button (i_but[2]);
        }
    }
}
/*
Constraint check for tile[0]:
  Cores available:            8,   used:          1 .  OKAY
  Timers available:          10,   used:          1 .  OKAY
  Chanends available:        32,   used:          0 .  OKAY
  Memory available:       65536,   used:       1816 .  OKAY
    (Stack: 384, Code: 1204, Data: 228)
Constraints checks PASSED.
Build Complete
*/
I hadn't noticed that on tile[n] could be used like that! This made my day! Even zero chanends!

However, the channel version does not compile:

Code: Select all

#include <platform.h>
#include <timer.h> // XS1_TIMER_HZ etc

 [[combinable]]
 void button (chanend c_out) {
    timer t;
    int s;
    t :> s;
    while (1) {
        select {
            case t when timerafter(s) :> void: {
                c_out <: (s/XS1_TIMER_KHZ); // ms
                s += XS1_TIMER_HZ;
                break;
            }
        }
    }
}

[[combinable]]
void handle (chanend c_but[3]) {
    int val;
    while (1) {
        select {
            case c_but[int i] :> val: {
                break;
            }
        }
    }
}

#define DO_PLACED 2

int main (void) {
    chan c_but[3];

    #if (DO_PLACED == 1)
        [[combine]]
        par {
        // ^~~~~ error: cannot apply [[combine]] to multi-tile par
            on tile[0].core[0]: handle (c_but);
            on tile[0].core[0]: button (c_but[0]);
            on tile[0].core[0]: button (c_but[1]);
            on tile[0].core[0]: button (c_but[2]);
        }
    #elif (DO_PLACED == 2)
        par {
            on tile[0]: {
                [[combine]]
                par {
                    handle (c_but);
                    //     ^~~~ note: other end is used here
                    button (c_but[0]);
                    //      ^~~~ error: `c_but' used between two combined tasks
                    button (c_but[1]);
                    //      ^~~~ error: `c_but' used between two combined tasks
                    button (c_but[2]);
                    //      ^~~~ error: `c_but' used between two combined tasks
                }
            }
        }
    #endif
    return 0;
}
Off Topic
Should this be noticed to the compiler guys, that my "wrong" syntax should perhaps still make sense?

Re: error: cannot apply [[combine]] to multi-tile par

Posted: Mon Jul 09, 2018 10:38 am
by aclassifier
Just now I think that

Code: Select all

error: components of multi-tile par must have `on' specifier or call a service
probably is just as confusing (to me..?). See example in The combined code: 6 to zero channels!

I've summarised this at “It’s not you” errors - Multi-tile par. Thanks!