namespace partition
{
- template<typename Worker, bool blocked=false>
+ template<typename Worker>
class CellWork : public tbb::task
{
public:
CellWork (const Worker &worker_in,
const unsigned int partition_in,
- const internal::MatrixFreeFunctions::TaskInfo &task_info_in)
+ const internal::MatrixFreeFunctions::TaskInfo &task_info_in,
+ const bool is_blocked_in)
:
worker (worker_in),
partition (partition_in),
- task_info (task_info_in)
+ task_info (task_info_in),
+ is_blocked (is_blocked_in)
{};
tbb::task *execute ()
{
(task_info.partition_color_blocks_data[partition],
task_info.partition_color_blocks_data[partition+1]);
worker(cell_range);
- if (blocked==true)
+ if (is_blocked==true)
dummy->spawn (*dummy);
return NULL;
}
const Worker &worker;
const unsigned int partition;
const internal::MatrixFreeFunctions::TaskInfo &task_info;
+ const bool is_blocked;
};
- template<typename Worker, bool blocked=false>
+ template<typename Worker>
class PartitionWork : public tbb::task
{
public:
PartitionWork (const Worker &function_in,
const unsigned int partition_in,
- const internal::MatrixFreeFunctions::TaskInfo &task_info_in)
+ const internal::MatrixFreeFunctions::TaskInfo &task_info_in,
+ const bool is_blocked_in = false)
:
function (function_in),
partition (partition_in),
- task_info (task_info_in)
+ task_info (task_info_in),
+ is_blocked (is_blocked_in)
{};
tbb::task *execute ()
{
- if (false)
- {
- std::pair<unsigned int, unsigned int> cell_range
- (task_info.partition_color_blocks_data
- [task_info.partition_color_blocks_row_index[partition]],
- task_info.partition_color_blocks_data
- [task_info.partition_color_blocks_row_index[partition+1]]);
- function(cell_range);
- }
- else
+ tbb::empty_task *root = new( tbb::task::allocate_root() )
+ tbb::empty_task;
+ unsigned int evens = task_info.partition_evens[partition];
+ unsigned int odds = task_info.partition_odds[partition];
+ unsigned int n_blocked_workers =
+ task_info.partition_n_blocked_workers[partition];
+ unsigned int n_workers = task_info.partition_n_workers[partition];
+ std::vector<CellWork<Worker>*> worker(n_workers);
+ std::vector<CellWork<Worker>*> blocked_worker(n_blocked_workers);
+
+ root->set_ref_count(evens+1);
+ for (unsigned int j=0; j<evens; j++)
{
- tbb::empty_task *root = new( tbb::task::allocate_root() )
- tbb::empty_task;
- unsigned int evens = task_info.partition_evens[partition];
- unsigned int odds = task_info.partition_odds[partition];
- unsigned int n_blocked_workers =
- task_info.partition_n_blocked_workers[partition];
- unsigned int n_workers = task_info.partition_n_workers[partition];
- std::vector<CellWork<Worker,false>*> worker(n_workers);
- std::vector<CellWork<Worker,true>*> blocked_worker(n_blocked_workers);
-
- root->set_ref_count(evens+1);
- for (unsigned int j=0; j<evens; j++)
+ worker[j] = new(root->allocate_child())
+ CellWork<Worker>(function, task_info.
+ partition_color_blocks_row_index[partition]+2*j,
+ task_info, false);
+ if (j>0)
{
- worker[j] = new(root->allocate_child())
- CellWork<Worker,false>(function,task_info.
- partition_color_blocks_row_index
- [partition] + 2*j, task_info);
- if (j>0)
- {
- worker[j]->set_ref_count(2);
- blocked_worker[j-1]->dummy = new(worker[j]->allocate_child())
- tbb::empty_task;
- worker[j-1]->spawn(*blocked_worker[j-1]);
- }
- else
- worker[j]->set_ref_count(1);
- if (j<evens-1)
+ worker[j]->set_ref_count(2);
+ blocked_worker[j-1]->dummy = new(worker[j]->allocate_child())
+ tbb::empty_task;
+ worker[j-1]->spawn(*blocked_worker[j-1]);
+ }
+ else
+ worker[j]->set_ref_count(1);
+ if (j<evens-1)
+ {
+ blocked_worker[j] = new(worker[j]->allocate_child())
+ CellWork<Worker>(function, task_info.
+ partition_color_blocks_row_index
+ [partition] + 2*j+1, task_info, true);
+ }
+ else
+ {
+ if (odds==evens)
{
- blocked_worker[j] = new(worker[j]->allocate_child())
- CellWork<Worker,true>(function,task_info.
- partition_color_blocks_row_index
- [partition] + 2*j+1, task_info);
+ worker[evens] = new(worker[j]->allocate_child())
+ CellWork<Worker>(function, task_info.
+ partition_color_blocks_row_index[partition]+2*j+1,
+ task_info, false);
+ worker[j]->spawn(*worker[evens]);
}
else
{
- if (odds==evens)
- {
- worker[evens] = new(worker[j]->allocate_child())
- CellWork<Worker,false>(function,
- task_info.
- partition_color_blocks_row_index
- [partition]+2*j+1,task_info);
- worker[j]->spawn(*worker[evens]);
- }
- else
- {
- tbb::empty_task *child = new(worker[j]->allocate_child())
- tbb::empty_task();
- worker[j]->spawn(*child);
- }
+ tbb::empty_task *child = new(worker[j]->allocate_child())
+ tbb::empty_task();
+ worker[j]->spawn(*child);
}
}
-
- root->wait_for_all();
- root->destroy(*root);
}
- if (blocked==true)
+
+ root->wait_for_all();
+ root->destroy(*root);
+ if (is_blocked==true)
dummy->spawn (*dummy);
return NULL;
}
const Worker &function;
const unsigned int partition;
const internal::MatrixFreeFunctions::TaskInfo &task_info;
+ const bool is_blocked;
};
} // end of namespace partition
};
- template<typename Worker, bool blocked=false>
+ template<typename Worker>
class PartitionWork : public tbb::task
{
public:
PartitionWork (const Worker &worker_in,
const unsigned int partition_in,
- const internal::MatrixFreeFunctions::TaskInfo &task_info_in)
+ const internal::MatrixFreeFunctions::TaskInfo &task_info_in,
+ const bool is_blocked_in)
:
worker (worker_in),
partition (partition_in),
- task_info (task_info_in)
+ task_info (task_info_in),
+ is_blocked (is_blocked_in)
{};
tbb::task *execute ()
{
upper = task_info.partition_color_blocks_data[partition+1];
parallel_for(tbb::blocked_range<unsigned int>(lower,upper,1),
CellWork<Worker> (worker,task_info));
- if (blocked==true)
+ if (is_blocked==true)
dummy->spawn (*dummy);
return NULL;
}
const Worker &worker;
const unsigned int partition;
const internal::MatrixFreeFunctions::TaskInfo &task_info;
+ const bool is_blocked;
};
} // end of namespace color
root->set_ref_count(evens+1);
unsigned int n_blocked_workers = task_info.n_blocked_workers;
unsigned int n_workers = task_info.n_workers;
- std::vector<internal::partition::PartitionWork<Worker,false>*>
+ std::vector<internal::partition::PartitionWork<Worker>*>
worker(n_workers);
- std::vector<internal::partition::PartitionWork<Worker,true>*>
+ std::vector<internal::partition::PartitionWork<Worker>*>
blocked_worker(n_blocked_workers);
internal::MPIComCompress<OutVector> *worker_compr =
new(root->allocate_child())
if (j>0)
{
worker[j] = new(root->allocate_child())
- internal::partition::PartitionWork<Worker,false>
- (func,2*j,task_info);
+ internal::partition::PartitionWork<Worker>
+ (func,2*j,task_info,false);
worker[j]->set_ref_count(2);
blocked_worker[j-1]->dummy = new(worker[j]->allocate_child())
tbb::empty_task;
else
{
worker[j] = new(worker_compr->allocate_child())
- internal::partition::PartitionWork<Worker,false>
- (func,2*j,task_info);
+ internal::partition::PartitionWork<Worker>
+ (func,2*j,task_info,false);
worker[j]->set_ref_count(2);
internal::MPIComDistribute<InVector> *worker_dist =
new (worker[j]->allocate_child())
if (j<evens-1)
{
blocked_worker[j] = new(worker[j]->allocate_child())
- internal::partition::PartitionWork<Worker,true>
- (func,2*j+1,task_info);
+ internal::partition::PartitionWork<Worker>
+ (func,2*j+1,task_info,true);
}
else
{
if (odds==evens)
{
worker[evens] = new(worker[j]->allocate_child())
- internal::partition::PartitionWork<Worker,false>
- (func,2*j+1,task_info);
+ internal::partition::PartitionWork<Worker>
+ (func,2*j+1,task_info,false);
worker[j]->spawn(*worker[evens]);
}
else
unsigned int n_blocked_workers = odds-(odds+evens+1)%2;
unsigned int n_workers = task_info.partition_color_blocks_data.size()-1-
n_blocked_workers;
- std::vector<internal::color::PartitionWork<Worker,false>*> worker(n_workers);
- std::vector<internal::color::PartitionWork<Worker,true>*> blocked_worker(n_blocked_workers);
+ std::vector<internal::color::PartitionWork<Worker>*> worker(n_workers);
+ std::vector<internal::color::PartitionWork<Worker>*> blocked_worker(n_blocked_workers);
unsigned int worker_index = 0, slice_index = 0;
unsigned int spawn_index = 0, spawn_index_new = 0;
int spawn_index_child = -2;
spawn_index_new = worker_index;
if (part == 0)
worker[worker_index] = new(worker_compr->allocate_child())
- internal::color::PartitionWork<Worker,false>(func,slice_index,task_info);
+ internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
else
worker[worker_index] = new(root->allocate_child())
- internal::color::PartitionWork<Worker,false>(func,slice_index,task_info);
+ internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
slice_index++;
for (; slice_index<task_info.partition_color_blocks_row_index[part+1];
slice_index++)
worker[worker_index]->set_ref_count(1);
worker_index++;
worker[worker_index] = new (worker[worker_index-1]->allocate_child())
- internal::color::PartitionWork<Worker,false>(func,slice_index,task_info);
+ internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
}
worker[worker_index]->set_ref_count(2);
if (part>0)
if (part<task_info.partition_color_blocks_row_index.size()-2)
{
blocked_worker[part/2] = new(worker[worker_index-1]->allocate_child())
- internal::color::PartitionWork<Worker,true>(func,slice_index,task_info);
+ internal::color::PartitionWork<Worker>(func,slice_index,task_info,true);
slice_index++;
if (slice_index<
task_info.partition_color_blocks_row_index[part+1])
{
blocked_worker[part/2]->set_ref_count(1);
worker[worker_index] = new(blocked_worker[part/2]->allocate_child())
- internal::color::PartitionWork<Worker,false>(func,slice_index,task_info);
+ internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
slice_index++;
}
else
worker_index++;
}
worker[worker_index] = new (worker[worker_index-1]->allocate_child())
- internal::color::PartitionWork<Worker,false>(func,slice_index,task_info);
+ internal::color::PartitionWork<Worker>(func,slice_index,task_info,false);
}
spawn_index_child = worker_index;
worker_index++;