I am currently working on a parallel game of life implementation which can use any number of workers (understand threads which simulate a tick for a portion of the image) as long as it is a square number. To achieve such a goal I need to automatically generate those n workers in function of the constant number of workers defined in the code in addition to generate and assign channels for between worker communications. I achieve this using two nested par loops, but here the compilers output errors saying I am using channels in more than two threads, when I am definitely not, because if I create the workers manually using the same reasoning for the attributions of the channels, it compiles! Everything may be a bit abstract, that is why I will try to give you some code samples. Here is the worker signature:
Code: Select all
void worker(int const xID, int const yID, chanend c, //Not relevant for this problem
chanend up, chanend down, chanend left, chanend right) //Represent the channels between neighbouring workers.
Code: Select all
chan betweenWorkersChannel[SQRT_AVAILABLE_WORKERS_THREAD][SQRT_AVAILABLE_WORKERS_THREAD][2];

Now I have explained how my system works, here is the portion of code generating the workers and not passing the compiler checks:
Code: Select all
par (size_t i = 0; i < SQRT_AVAILABLE_WORKERS_THREAD; ++i) {
par (size_t j = 0; j < SQRT_AVAILABLE_WORKERS_THREAD; ++j) {
//Create and start worker
if((i+j)%2 == 0){
worker(i, j, channels[i][j], betweenWorkersChannel[i][j][0], betweenWorkersChannel[i][j][1], betweenWorkersChannel[i][(j-1+ SQRT_AVAILABLE_WORKERS_THREAD)% SQRT_AVAILABLE_WORKERS_THREAD][1], betweenWorkersChannel[i][(j+1+ SQRT_AVAILABLE_WORKERS_THREAD)% SQRT_AVAILABLE_WORKERS_THREAD][0]);
}
else{
worker(i, j, channels[i][j], betweenWorkersChannel[(i-1 + SQRT_AVAILABLE_WORKERS_THREAD)% SQRT_AVAILABLE_WORKERS_THREAD][j][1], betweenWorkersChannel[(i+1+ SQRT_AVAILABLE_WORKERS_THREAD)% SQRT_AVAILABLE_WORKERS_THREAD][j][0], betweenWorkersChannel[i][j][0], betweenWorkersChannel[i][j][1]);
}
}
}
Code: Select all
worker(0, 0, channels[0][0], betweenWorkersChannel[0][0][0], betweenWorkersChannel[0][0][1], betweenWorkersChannel[0][1][1], betweenWorkersChannel[0][1][0]);
worker(1, 1, channels[1][1], betweenWorkersChannel[1][1][0], betweenWorkersChannel[1][1][1], betweenWorkersChannel[1][0][1], betweenWorkersChannel[1][0][0]);
worker(0, 1, channels[0][1], betweenWorkersChannel[1][1][1], betweenWorkersChannel[1][1][0], betweenWorkersChannel[0][1][0], betweenWorkersChannel[0][1][1]);
worker(1, 0, channels[1][0], betweenWorkersChannel[0][0][1], betweenWorkersChannel[0][0][0], betweenWorkersChannel[1][0][0], betweenWorkersChannel[1][0][1]);
Thank you very much for your help and sorry if everything seems a bit confusing, I tried to do my best to explain you my system, do not hesitate to ask me to explain something further!