Collecting interfaces into an array for a parameter

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
User avatar
aclassifier
Respected Member
Posts: 376
Joined: Wed Apr 25, 2012 8:52 pm

Collecting interfaces into an array for a parameter

Postby aclassifier » Tue Dec 22, 2020 3:43 pm

Instead of doing it like this

Code: Select all

[[combinable]]
void Node_A_clients (
        client conn_session_if_t i_conn_session_0,
        client conn_session_if_t i_conn_session_1,
        client conn_session_if_t i_conn_session_2) {
with setup in main like this:

Code: Select all

[[combine]]
par {
    //                                                                    irow ihor
    Node_B_servers (hor_conns[0][1], ver_conns[1][0], hor_conns[0][2]); // 0    1
    Node_B_servers (hor_conns[0][3], ver_conns[1][1], hor_conns[0][0]); // 0    3
    Node_B_servers (hor_conns[1][1], ver_conns[2][0], hor_conns[1][2]); // 1    1
    Node_B_servers (hor_conns[1][3], ver_conns[2][1], hor_conns[1][0]); // 1    3
I'd like to do

Code: Select all

[[combinable]]
void Node_A_clients (
        client conn_session_if_t i_conn_sessions [3]) {

Code: Select all

[[combine]]
par {
    //                                                                    irow ihor
    Node_B_servers ({hor_conns[0][1], ver_conns[1][0], hor_conns[0][2]}); // 0    1
    Node_B_servers ({hor_conns[0][3], ver_conns[1][1], hor_conns[0][0]}); // 0    3
    Node_B_servers ({hor_conns[1][1], ver_conns[2][0], hor_conns[1][2])}; // 1    1
    Node_B_servers ({hor_conns[1][3], ver_conns[2][1], hor_conns[1][0]}); // 1    3
or

Code: Select all

conn_session_if_t hor_conns_arr [NUM_ROWS];
hor_conns_arr [0] = hor_conns[0][1];
or

Code: Select all

const conn_session_if_t hor_conns_arr [NUM_ROWS] = {hor_conns[0][1], ver_conns[1][0], hor_conns[0][2]}; // const not to allocate new interfaces..
The compiler won't let me do this, causing me not to be able to use replicated case on an interface array like i_conn_sessions [3]on the server side.

I would really want to have retyping of interfaces (and channels for that matter) collected into an array of retyped interfaces. occam had RETYPES and I loved it!

I MAY HAVE MISSED SOMETHING HERE!?
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
CousinItt
XCore Addict
Posts: 212
Joined: Wed May 31, 2017 6:55 pm

Postby CousinItt » Tue Dec 22, 2020 5:40 pm

You haven't said what the error messages are or posted a complete chunk of code demonstrating the problem. My guess is that you're violating sharing rules by using a 2d arrays of interfaces.

It may not be as elegant, but you could just try using one dimensional arrays with an ordinal number allocated for each row/column position.
User avatar
aclassifier
Respected Member
Posts: 376
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Wed Dec 23, 2020 11:44 am

Thanks, @CousinItt,

I didn't show any error messages because they were sentering around syntax, and it was obvious that this was far from anything the language supported.

The basic code I'm struggling with would be something like this, if provided with a guard array as you suggest.

This one compiles, but is not what I want:

Code: Select all

    typedef interface _conn_session_if_t {
        [[guarded]] work_result_t start_work (const work_param_t);
    } conn_session_if_t; 

[[combinable]]
void Test (
          server conn_session_if_t i_conn_session [NUM_CONNS_PER_NODE],
          const bool guards_in[NUM_CONNS_PER_NODE]) {

    timer      timeout_tmr;
    time32_t   timeout_ticks;
    
    bool          do_background_processing_chunks = false;
    work_result_t work_result [NUM_CONNS_PER_NODE];
    work_param_t  work_param  [NUM_CONNS_PER_NODE];
    
    bool guards [NUM_CONNS_PER_NODE];
    unsigned iy = 0;
    
    for (unsigned ix = 0; ix<NUM_CONNS_PER_NODE; ix++) {
      guards[ix] = guards_in[ix];
    }
    
    while (1) {
      select {
          case do_background_processing_chunks => timeout_tmr when timerafter (timeout_ticks) :> void : {
               // Do some work here with work_param[x] as param and place result(s) in work_result[x]
              do_background_processing_chunks= false;
          } break;
          case guards_in[iy] => i_conn_session[unsigned ix].start_work (const work_param_t work_param_par) -> work_result_t notified_return : { // Compiles, not what I want
          case guards[iy] => i_conn_session[unsigned ix].start_work (const work_param_t work_param_par) -> work_result_t notified_return : { // Compiles, not what I want
          case guards_in => i_conn_session[unsigned ix].start_work (const work_param_t work_param_par) -> work_result_t notified_return : { // guards_in : error: case expression is not arithmetic
              // Any work in here and it will hold the client
              notified_return = work_result[ix];
              work_param[ix] = work_param_par;
              do_background_processing_chunks = true;
              timeout_tmr :> timeout_ticks; // Immediate
              // OUTPUTS TO CLIENT BY RETURNING FROM THE "RPC"
          } break;
      }
    }
} 
However, I could use individual cases like this and use your idea, but I do need it to be [[combinable]]. This compiles and would work I think:

Code: Select all

//[[combinable]]
void Test (
          server conn_session_if_t i_conn_session [NUM_CONNS_PER_NODE],
          const bool guards_in[NUM_CONNS_PER_NODE]) {

    timer      timeout_tmr;
    time32_t   timeout_ticks;

    bool          do_background_processing_chunks = false;
    work_result_t work_result [NUM_CONNS_PER_NODE];
    work_param_t  work_param  [NUM_CONNS_PER_NODE];

    while (1) {
      select {
          case do_background_processing_chunks => timeout_tmr when timerafter (timeout_ticks) :> void : {
               // Do some work here with work_param[x] as param and place result(s) in work_result[x]
              do_background_processing_chunks= false;
          } break;
          case guards_in[0] => i_conn_session[0].start_work (const work_param_t work_param_par) -> work_result_t notified_return : { // INPUT
              // Any work in here and it will hold the client
              notified_return = work_result[0];
              work_param[0] = work_param_par;
              do_background_processing_chunks = true;
              timeout_tmr :> timeout_ticks; // Immediate
              // OUTPUTS TO CLIENT BY RETURNING FROM THE "RPC"
          } break;
          case guards_in[1] => i_conn_session[1].start_work (const work_param_t work_param_par) -> work_result_t notified_return : { // INPUT
              // Any work in here and it will hold the client
              notified_return = work_result[1];
              work_param[0] = work_param_par;
              do_background_processing_chunks = true;
              timeout_tmr :> timeout_ticks; // Immediate
              // OUTPUTS TO CLIENT BY RETURNING FROM THE "RPC"
          } break;
          case guards_in[2] => i_conn_session[2].start_work (const work_param_t work_param_par) -> work_result_t notified_return : { // INPUT
              // Any work in here and it will hold the client
              notified_return = work_result[2];
              work_param[2] = work_param_par;
              do_background_processing_chunks = true;
              timeout_tmr :> timeout_ticks; // Immediate
              // OUTPUTS TO CLIENT BY RETURNING FROM THE "RPC"
          } break;
      }
    }
}
As [[combinable]] I would get

Code: Select all

error: interface cases that do not select over the entire array are not supported [[combinable]] functions
I have not spelt out your idea any further, but it would be interesting to see how the compiler would do interface usage checks when the internal select cases are dependent on some parameter I set up in the guard_in array.

Øyvind
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
aclassifier
Respected Member
Posts: 376
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Sat Dec 26, 2020 1:52 pm

I have studied this further. I think I have a conclusion. It is not possbile to use a parameterised value for the index.

This situation will sooner or later stop inside the select case, like

Code: Select all

const unsigned index = iof_start_work[0]; // just testing using const array parameter
while (1) {
  select {
      case i_conn_session[index].start_work (const work_param_t work_param_par) -> work_result_t notified_return : { // INPUT
      error: interface expression in select case must be a simple variable reference
This means that index cannot be a parameter, a local value, be it const or not. It can only be a written number, like i_conn_session[1].start_work

The only XC that could have helped me (I think) would be to be able to make a new interface array by collecting interfaces from somewhere else. Back to square one. Any other suggestion out there?
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/

Who is online

Users browsing this forum: No registered users and 2 guests