Replicated pars and combining

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Replicated pars and combining

Post by Folknology »

This does not compile :

Code: Select all

#define DELAY 50000000;

[[combinable]]
void com() {
	timer t;
	unsigned time;
	t :> time;
	printf("hi\n");
	while(1) {
		select {
			case t when timerafter(time) :> void :
				printf("com tick \n");
				t :> time;
				time += DELAY;
				break;
		}
	}
}

[[combinable]]
void task(int n) {
	timer t;
	unsigned time;
	t :> time;

	printf("hello from %d\n",n);
	while(1) {
		select {
			case t when timerafter(time) :> void :
				printf("task %d tick\n",n);
				t :> time;
				time += DELAY;
				break;
		}
	}
}

int main (void) {
	[[combine]]
 	par {
 		com();
 		[[combine]]
 		par (unsigned i = 0; i < 4; i++)
 			task(i);
 	}
 	return 0;
}
The complaint is :
error: statement in combinable par must be a call to a com
binable function
par (unsigned i = 0; i < 4; i++) {
However this does compile;

Code: Select all

#define DELAY 50000000;

[[combinable]]
void com() {
	timer t;
	unsigned time;
	t :> time;
	printf("hi\n");
	while(1) {
		select {
			case t when timerafter(time) :> void :
				printf("com tick \n");
				t :> time;
				time += DELAY;
				break;
		}
	}
}

[[combinable]]
void task(int n) {
	timer t;
	unsigned time;
	t :> time;

	printf("hello from %d\n",n);
	while(1) {
		select {
			case t when timerafter(time) :> void :
				printf("task %d tick\n",n);
				t :> time;
				time += DELAY;
				break;
		}
	}
}

[[combinable]]
void tasks() {
	[[combine]]
 		par (unsigned i = 0; i < 4; i++) 
 			task(i);
}


int main (void) {
	[[combine]]
 	par {
 		com();
 		tasks();
 	}
 	return 0;
}
Am I trying to do something daft or missing some syntactical subtlety when trying to combine all of these tasks? Or is it the compiler getting mixed up?
>xcc --version
Community_14.0.1 (build 16721, Mar-31-2015)
Compiler version: 14.0.1
Copyright (C) XMOS Limited 2008-2015. All Rights Reserved.
regards
Al


User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

I know nothing about XC, but the par in main is special,
isn't it?
User avatar
ers35
Active Member
Posts: 62
Joined: Mon Jun 10, 2013 2:14 pm

Post by ers35 »

I tried adding [[combinable]] and the compiler gives a warning that seems to answer the question. See this simpler example which demonstrates the problem:

Code: Select all

// xcc -report -target=XS1-L16A-128-QF124-C10 combine.xc
// error: statement in combinable par must be a call to a combinable function
void test(void)
{
  [[combine]]
  par
  {
    // warning: ignoring attribute `combinable' (cannot apply to statement)
    [[combinable]]
    {
      
    }
  }
}
Only a function marked combinable can be called in a combinable par. Since the replicated par is not a function, it cannot be marked combinable and cannot be called in the combinable par.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

ers35 wrote:I tried adding [[combinable]] and the compiler gives a warning that seems to answer the question. See this simpler example which demonstrates the problem:

Code: Select all

// xcc -report -target=XS1-L16A-128-QF124-C10 combine.xc
// error: statement in combinable par must be a call to a combinable function
void test(void)
{
  [[combine]]
  par
  {
    // warning: ignoring attribute `combinable' (cannot apply to statement)
    [[combinable]]
    {
      
    }
  }
}
Only a function marked combinable can be called in a combinable par. Since the replicated par is not a function, it cannot be marked combinable and cannot be called in the combinable par.
Sure but a par replicator is just shorthand (syntactical sugar) for manually enumerating tasks which I would imagine includes combinable tasks no?
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Segher I seem to remember something similar from way back about main but not sure that is the case here as tried this and got same complaint :

Code: Select all

#include <platform.h>
#include <stdio.h>

#define DELAY 50000000;

[[combinable]]
void com() {
   timer t;
   unsigned time;
   t :> time;
   printf("hi\n");
   while(1) {
      select {
         case t when timerafter(time) :> void :
            printf("com tick \n");
            t :> time;
            time += DELAY;
            break;
      }
   }
}

[[combinable]]
void task(int n) {
   timer t;
   unsigned time;
   t :> time;

   printf("hello from %d\n",n);
   while(1) {
      select {
         case t when timerafter(time) :> void :
            printf("task %d tick\n",n);
            t :> time;
            time += DELAY;
            break;
      }
   }
}

void run(){
  [[combine]]
    par {
       com();
       [[combine]]
       par (unsigned i = 0; i < 4; i++)
          task(i);
    }
}

int main (void) {
  run();
  return 0;
}
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

ers35 we also know that the compiler is ok with :

Code: Select all

[[combinable]]
void tasks() {
   [[combine]]
       par (unsigned i = 0; i < 4; i++) 
          task(i);
}
So it's clearly contextual..
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

For the record this compiles without a hitch for the curious :

Code: Select all

int main (void) {
    par {
       com();
       [[combine]]
       par (unsigned i = 0; i < 4; i++)
          task(i);
    }
    return 0;
}
But of course uses 2 logical cores rather than the desired single core.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Anyone at Xmos care to comment on this, is this correct behaviour, shouldn't we be able to use combined replicated pars in this manner?
User avatar
davelacey
Experienced Member
Posts: 104
Joined: Fri Dec 11, 2009 8:29 pm

Post by davelacey »

Combined pars do not work with nested pars at the moment (replicated pars are OK). So this is invalid:

Code: Select all

[[combine]]
par {
   f();
   [[combine]]
   par {
      g();
      h();
   }
}
Your options are to flatten the par:

Code: Select all

[[combine]]
par {
   f();
   g();
   h();
}
or to define an intermediate function:

Code: Select all

[[combinable]]
void gh() {
  [[combine]]
  par {
     g();
     h();
  }
}

[[combine]]
par {
   f();
   gh();
}
Dave
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

davelacey wrote:Combined pars do not work with nested pars at the moment (replicated pars are OK). So this is invalid:
..
Dave
But in my case I am actually using a replicated par

Code: Select all

[[combine]]
par {
   f();
   [[combine]]
   par (unsigned i = 0; i < 4; i++)
      g();
   }
}
But to get it too compile I am having to use option 2:

Code: Select all

...
[[combinable]]
void gs(){
[[combine]]
   par (unsigned i = 0; i < 4; i++)
      g();
   }
}

...

[[combine]]
par {
   f();
   gs();
}
In order to convince the compiler, a more subtle case perhaps?