Commit 15ea9a26 authored by Quentin Khan's avatar Quentin Khan
Browse files

FAdaptiveTask: reformat to decorelate task creation from tree traversal

parent eef4d796
......@@ -135,6 +135,7 @@ protected:
} else if(I == dep_t::P_t) {
return (const char*) node->getParticleContainer();
}
return nullptr;
}
......@@ -305,10 +306,20 @@ public:
}
}
// P2M
/** \brief Walk through leaves and queue P2M tasks */
void source_to_up() {
for(node_t* leaf : _tree.leaves()) {
this->create_P2M_task(leaf);
}
// #pragma omp taskwait
}
/**
* \brief Create and queue a P2M task
*
* \param leaf The P2M leaf
*/
void create_P2M_task(node_t* leaf) {
const char* ps_dep = get_dependency<dep_t::P_s>(leaf);(void)ps_dep;
const char* m_dep = get_dependency<dep_t::M>(leaf);(void)m_dep;
......@@ -320,16 +331,27 @@ public:
_kernels[thread_num]->P2M(leaf->getData(), leaf->getParticleContainer());
}
}
// #pragma omp taskwait
}
// M2M
void up_to_up() {
/** \brief Walk through tree and queue M2M tasks */
void up_to_up() {
for(node_t& n : _tree.post_order_walk()) {
node_t* node = &n;
if(! node->is_leaf()) {
if(! n.is_leaf()) {
create_M2M_task(&n);
}
}
// #pragma omp taskwait
}
/**
* \brief Create and queue an M2M task
*
* \param node An internal node
*
* \warning node is assumed not to be a leaf.
*/
void create_M2M_task(node_t* node) {
assert(! node->is_leaf());
// Setup task dependencies
// children data
const char* children_dep[node_t::child_count] = {};
......@@ -357,7 +379,7 @@ public:
// Fill array of children data
std::array<typename node_t::data_t*, node_t::child_count> child_data;
for(node_t* child : node->getChildren()) {
/// Last bits of child index give the index relative to parent
// Last bits of child index give the index relative to parent
child_data[child->getIndex() & (node_t::child_count-1)] = child->getData();
}
......@@ -366,23 +388,30 @@ public:
static_cast<int>(node->getDepth()));
}
}
}
// #pragma omp taskwait
}
// M2L
void v_list_step() {
/** \brief Walk through tree and queue M2L tasks */
void v_list_step() {
for(node_t& n : _tree.in_order_walk()) {
node_t* node = &n;
if(node->is_leaf() && node->getParticleContainer()->size() == 0) {
if(n.is_leaf() && n.getParticleContainer()->size() == 0) {
continue;
}
create_M2L_task(&n);
}
// #pragma omp taskwait
}
// Generate task dependencies
// The array of dependencies, we know that there cannot be more than
// 7^Dim cells involved in a M2L, in 3D, this is 343
/**
* \brief Create and queue an M2L task
*
* \param node A tree node
*/
void create_M2L_task(node_t* node) {
// Generate task dependencies
// There cannot be more than 7^Dim cells involved in a M2L, in 3D, this is 343
const char* task_deps[343];
const char* data_dep = get_dependency<dep_t::L>(node);(void) data_dep;
std::size_t idx_dep = 0;
......@@ -767,12 +796,9 @@ public:
// Call kernel M2L operator
this->_kernels[thread_num]->M2L(node->getData(), v_item_data_list.data(), v_item_indices.data(), static_cast<int>(v_item_data_list.size()), static_cast<int>(node->getDepth()));
}
}
// #pragma omp taskwait
}
// P2L
/** \brief Walk through leaves and queue P2L tasks */
void x_list_step() {
/* NOTE: the X list and W list are complementary: if A is in X(B) then B
* is in W(A).
......@@ -781,6 +807,19 @@ public:
*/
for(node_t* leaf : _tree.leaves()) {
if(leaf->getParticleContainer()->size() > 0) {
this->create_P2L_task(leaf);
}
}
// #pragma omp taskwait
}
/**
* \brief Create and queue a P2L task
*
* \param leaf A tree leaf
*/
void create_P2L_task(node_t* leaf) {
for(node_t* w_item : leaf->W) {
if(w_item->is_leaf() && w_item->getParticleContainer()->size() == 0) {
continue;
......@@ -796,15 +835,28 @@ public:
}
}
}
/** Walk through tree and queue L2L tasks */
void down_to_down() {
for(node_t& n : _tree.pre_order_walk()) {
if(! n.is_leaf()) {
this->create_L2L_task(&n);
}
}
// #pragma omp taskwait
}
// L2L
void down_to_down() {
for(node_t& n : _tree.pre_order_walk()) {
node_t* node = &n;
if(! node->is_leaf()) {
/**
* \brief Create and queue an L2L task
*
* \param node An internal tree node
*
* \node node is assumed not to be a leaf
*/
void create_L2L_task(node_t* node) {
assert(! node->is_leaf());
const char* parent_dep = get_dependency<dep_t::L>(node);(void)parent_dep;
const char* children_dep[node_t::child_count];
for(std::size_t i = 0; i < node_t::child_count; ++i) {
......@@ -833,14 +885,25 @@ public:
this->_kernels[thread_num]->L2L(node->getData(), child_data, static_cast<int>(node->getDepth()));
}
}
}
// #pragma omp taskwait
}
// M2P
/** \brief Walk through the leaves an queue M2P tasks */
void w_list_step() {
for(node_t* leaf : _tree.leaves()) {
if(leaf->getParticleContainer()->size() > 0) {
create_M2P_task(leaf);
}
}
// #pragma omp taskwait
}
/**
* \brief Create and queue an M2P task
*
* \param leaf A leaf
*/
void create_M2P_task(node_t* leaf) {
for(node_t* w_item : leaf->W) {
if(w_item->is_leaf() && w_item->getParticleContainer()->size() == 0) {
continue;
......@@ -856,14 +919,24 @@ public:
}
}
}
}
// #pragma omp taskwait
}
// L2P
/** \brief Walk through the leaves and queue L2P tasks */
void down_to_target() {
for(node_t* leaf : _tree.leaves()) {
if(leaf->getParticleContainer()->size() != 0) {
this->create_L2P_task(leaf);
}
}
// #pragma omp taskwait
}
/**
* \brief Create and queue an L2P task
*
* \param leaf A leaf
*/
void create_L2P_task(node_t* leaf) {
const char* data_dep = get_dependency<dep_t::L>(leaf); (void)data_dep;
const char* pt_dep = get_dependency<dep_t::P_t>(leaf); (void)pt_dep;
#pragma omp task depend(inout: pt_dep[:1]) depend(in: data_dep[:1])
......@@ -872,6 +945,12 @@ public:
this->_kernels[thread_num]->L2P(leaf->getData(), leaf->getParticleContainer());
}
}
/** \brief Walk through the leaves and queue P2P tasks */
void u_list_step() {
for(node_t* leaf : _tree.leaves()) {
this->create_P2P_task(leaf);
}
// #pragma omp taskwait
}
......@@ -903,14 +982,9 @@ public:
* given to the kernel P2P method.
*
*/
void u_list_step() {
void create_P2P_task(node_t* leaf) {
using container_t = typename node_t::particle_container_t;
// The following containers are reused for each leaf to avoid repeated
// dynamic allocation.
for(node_t* leaf : _tree.leaves()) {
container_t* const leaf_source_particle_container =
leaf->getParticleContainer();
container_t* const leaf_target_particle_container =
......@@ -919,7 +993,7 @@ public:
// Skip empty leaves
if( leaf_source_particle_container->size() == 0
&& leaf_target_particle_container->size() == 0) {
continue;
return;
}
auto it = leaf->U.begin();
......@@ -1017,8 +1091,6 @@ public:
}
}
// #pragma omp taskwait
}
/** Compute resulting index in pre-computation array.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment