Exemple #1
0
void nqueens_rec(int column, list_node* head) {

    cilk_for (int i=0; i<SIZE; i++) {
        if (addok(head, i, column)) {
            // add the node
            list_node new_node;
            new_node.next = head;
            new_node.row  = i;

            if (column+1<SIZE) {
#ifdef CUTOFF
                if (column+1>=CUTOFF_LEVEL)
                    ser_nqueens_rec(column+1, &new_node);
                else
                    nqueens_rec(column+1, &new_node);
#else
                nqueens_rec(column+1, &new_node);
#endif
            } else { // found a solution 
                //solution_count += 1;
            }
        }
        // else do nothing -- dead computation branch
    }
}
Exemple #2
0
    void operator () (const tbb::blocked_range<int> &range) const {
        for(int i=range.begin(); i<range.end(); i++) {
            list_node *node;
            if (addok(head, i, column)) {
                // add the node

#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                if (node!=NULL && solution == NULL) {
#endif
                    list_node new_node;
                    new_node.next = head;
                    new_node.row  = i;
                    if (column+1<SIZE) {
#ifdef CUTOFF
                        if (column+1>=CUTOFF_LEVEL)
                            ser_nqueens_rec(column+1, &new_node);
                        else
                            nqueens_rec(column+1, &new_node);
#else
                        nqueens_rec(column+1, &new_node);
#endif

                    } else { // found a solution 
                        //solution = &new_node;
                        solution_count++; //atomic
                        //abort()
                    }
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                }
#endif
            } // end if addok
        // else do nothing -- dead computation branch
        }
    }
Exemple #3
0
int nqueens() {
    solution_count = 0;   
#ifdef CUTOFF
    if (0>=CUTOFF_LEVEL)
        ser_nqueens_rec(0, NULL);
    else
        nqueens_rec(0, NULL);
#else
    nqueens_rec(0, NULL);
#endif
    return solution_count;    
}
Exemple #4
0
    void operator () (tbb::blocked_range<int> &range, tbb::task* parent_task) const {

        tbb::blocked_range<int> subrange = range.get_some_safe();
        long savedcnt = 0;
        //while ( subrange.empty() == false && parent_task->bflws_pushed == false) {
        while ( subrange.empty() == false ) {
            for(int i=subrange.begin(); i<subrange.end(); i++) {
                list_node *node;
                if (addok(head, i, column)) {
                    // add the node

#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                    if (node!=NULL && solution == NULL) {
#endif
                        list_node new_node;
                        new_node.next = head;
                        new_node.row  = i;
                        if (column+1<SIZE) {
#ifdef CUTOFF
                            if (column+1>=CUTOFF_LEVEL)
                                ser_nqueens_rec(column+1, &new_node);
                            else
                                nqueens_rec(column+1, &new_node, parent_task);
#else
                            nqueens_rec(column+1, &new_node, parent_task);
#endif

                        } else { // found a solution 
                            //solution = &new_node;
                            solution_count++; //atomic
                            //abort()
                        }
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                    }
#endif
                } // end if addok
            // else do nothing -- dead computation branch
            } // end for-loop over range

#ifdef DEQUE_THRESH
            if ( parent_task->task_pool_size() < DEQUE_THRESH) break;
#else
            if ( parent_task->is_task_pool_empty() ) break;
#endif

            subrange = range.get_some_safe();
            //printf("Saved one ping-pong!\n");
            //std::cout << "Saved one\n" ;
            //savedcnt ++;
        } // end while
        //printf("Saved %d ping-pongs\n", savedcnt);
        //std::cout << "Saved " << savedcnt << "\n" ;
    }
Exemple #5
0
    void operator () (tbb::blocked_range<int> &range, tbb::task* parent_task) const {

        //int cnt = 0;
        for(int i = range.begin(); i < range.end() /*&& parent_task->bflws_pushed == false*/; i++) {
            range.remove_some_safe();
            list_node *node;
            if (addok(head, i, column)) {
                // add the node
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                if (node!=NULL && solution == NULL) {
#endif
                    list_node new_node;
                    new_node.next = head;
                    new_node.row  = i;
                    if (column+1<SIZE) {
#ifdef CUTOFF
                        if (column+1>=CUTOFF_LEVEL)
                            ser_nqueens_rec(column+1, &new_node);
                        else
                            nqueens_rec(column+1, &new_node, parent_task);
#else
                        nqueens_rec(column+1, &new_node, parent_task);
#endif
                    } else { // found a solution 
                        //solution = &new_node;
                        solution_count++; //atomic
                        //abort()
                    }
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                }
#endif
            } // end if addok
            // else do nothing -- dead computation branch

            //cnt++;
            //if (cnt == GRAINSIZE)) {
                //cnt = 0;
                //subrange = range.remove_some_safe();
            DEQUE_CHECK_CODE (parent_task);
                //else end = range.end();
            //}

            //printf("Saved one ping-pong!\n");
            //std::cout << "Saved one\n" ;
            //savedcnt ++;
            //i++;
        } // end for-loop over range
        //printf("Saved %d ping-pongs\n", savedcnt);
        //std::cout << "Saved " << savedcnt << "\n" ;
    }
Exemple #6
0
void nqueens() {
    //solution_count.set_value(0);
    nqueens_rec(0, NULL);
}
Exemple #7
0
int nqueens() {
    solution_count = 0;
    nqueens_rec(0, NULL, NULL);
    return solution_count;    
}
Exemple #8
0
void nqueens_rec(int column, list_node* head, tbb::task* parent_task) {
    PARTITIONER partitioner;
    tbb::blocked_range<int> range(0,SIZE,GRAINSIZE);
#ifdef _TBB_MELD_ALLOW_CODE_DUPLICATION
    for(int i = range.begin(); i < range.end() /*&& parent_task->bflws_pushed == false*/; i++) {
       // DEQUE CHECK
       if ( parent_task==NULL || parent_task->is_task_pool_empty() ) {
            tbb::parallel_for (range, nqueensMeldFlatBody(column,head), partitioner);
            break;
        } // else
        range.remove_some_safe();
        list_node *node;
        if (addok(head, i, column)) {
            // add the node
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
            if (node!=NULL && solution == NULL) {
#endif
                list_node new_node;
                new_node.next = head;
                new_node.row  = i;
                if (column+1<SIZE) {
#ifdef CUTOFF
                    if (column+1>=CUTOFF_LEVEL)
                        ser_nqueens_rec(column+1, &new_node);
                    else
                        nqueens_rec(column+1, &new_node, parent_task);
#else
                    nqueens_rec(column+1, &new_node, parent_task);
#endif
                } else { // found a solution 
                    //solution = &new_node;
                    solution_count++; //atomic
                    //abort()
                }
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
            }
#endif
        } // end if addok
    } // end for-loop over range
#else  // TBB_MELD_DONT_ALLOW_CODE_DUPLICATION
    nqueensMeldFlatBody body(column,head);
    // create task
    //start_for<tbb::blocked_range<int>, nqueensMeldFlatBody, PARTITIONER> *self = NULL;
    //self = new(task::allocate_root()) start_for(range,body,const_cast<PARTITIONER&>(partitioner));
    start_for<tbb::blocked_range<int>, nqueensMeldFlatBody, PARTITIONER>& a = *new(task::allocate_root()) start_for(range,body,const_cast<Partitioner&>(partitioner));

    // add to postponed deque
    self->next_postponed = NULL;
    // enqueue postponed task
    tbb::task* saved_tail = self->push_postponed_task();

    do {
        //if ( parent_task==NULL || parent_task->is_task_pool_empty() ) {
        if ( self->is_task_pool_empty() ) {
            // TODO: optim if possible split ancestor postponed and continue:
            // note: this will always be possible since we already added it to
            // the postponed deque.
            parallel_for (range, body, partitioner);
            break;
        } // else
        body(range,parent_task);
    } while(range.empty()==false);
    // TODO detect if a split has occurred, in which case some synchronization is needed
#endif
}
Exemple #9
0
void ser_nqueens_rec(int column, list_node* head) {
    int i;
    for (i=0; i<SIZE; i++) {
        list_node *node;
        if (addok(head, i, column)) {
            // add the node
            node = (list_node*)scalable_malloc(sizeof(list_node));
#ifdef DEBUG
            if(node==NULL) out_of_memory = 1;
#endif
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
            if (node!=NULL && solution == NULL) {
#else 			// Don't quit. Instead keep scanning the whole search space.
            if (node!=NULL) {
#endif
                node->next = head;
                node->row  = i;
                if (column+1<SIZE) {
                    ser_nqueens_rec(column+1, node);
                } else { // found a solution 
                  //solution = node;
                  solution_count++; // atomic
                }
            }
        }
        // else do nothing -- dead computation branch
    }
}

void nqueens_rec(int column, list_node* head);

class nqueensBody {
public:
    int column;
    list_node* head;

    void operator () (const tbb::blocked_range<int> &range) const {
        for(int i=range.begin(); i<range.end(); i++) {
            list_node *node;
            if (addok(head, i, column)) {
                // add the node
                node = (list_node*)scalable_malloc(sizeof(list_node));
#ifdef DEBUG
                if(node==NULL) out_of_memory = 1;
#endif
#ifdef QUIT_ON_SOLUTION // QUIT as soon as a solution is found
                if (node!=NULL && solution == NULL) {
#else 			// Don't quit. Instead keep scanning the whole search space.
                if (node!=NULL) {
#endif
                    node->next = head;
                    node->row  = i;
                    if (column+1<SIZE) {
#ifdef CUTOFF
                        if (column+1>=CUTOFF_LEVEL)
                            ser_nqueens_rec(column+1, node);
                        else
                            nqueens_rec(column+1, node);
#else
                        nqueens_rec(column+1, node);
#endif

                    } else { // found a solution 
                        //solution = node;
                        solution_count++; //atomic
                        //abort()
                    }
                }
            } // end if addok
        // else do nothing -- dead computation branch
        }
    }

    // Constructor
    nqueensBody(int col, list_node* hd) : column(col), head(hd) { }
};

void nqueens_rec(int column, list_node* head) {
#ifdef TWOLVL_SCHED
    tbb::auto_partitioner firstLevelPartitioner;
    PARTITIONER partitioner;
//    tbb::parallel_for (tbb::blocked_range<int>(0,SIZE,GRAINSIZE), nqueensBody(column,head), ((column==0)?firstLevelPartitioner:partitioner) );
    if (column==0)
        tbb::parallel_for (tbb::blocked_range<int>(0,SIZE,GRAINSIZE), nqueensBody(column,head), firstLevelPartitioner );
    else
        tbb::parallel_for (tbb::blocked_range<int>(0,SIZE,GRAINSIZE), nqueensBody(column,head), partitioner );
#else
    PARTITIONER partitioner;
    tbb::parallel_for (tbb::blocked_range<int>(0,SIZE,GRAINSIZE), nqueensBody(column,head), partitioner);
#endif
}