int march_solve_rec() { int branch_literal = 0, _result, _percentage_forced; int skip_left = 0, skip_right = 0, top_flag = 0; #ifdef DISTRIBUTION int record_index = current_record; top_flag = TOP_OF_TREE; if( fix_recorded_literals(record_index) == UNSAT ) return UNSAT; if( record_index == 0 ) record_index = init_new_record( ); #endif #ifdef SUPER_LINEAR if( depth < sl_depth ) subtree_size = 0; else if( subtree_size == SL_MAX ) return UNSAT; else subtree_size++; #endif #ifdef TIMEOUT if( (int) clock() > CLOCKS_PER_SEC * TIMEOUT ) return UNKNOWN; #endif #ifdef SUBTREE_SIZE path_length++; #endif #ifdef CUT_OFF if( depth <= CUT_OFF ) last_SAT_bin = -1; if( solution_bin == last_SAT_bin ) { #ifdef DISTRIBUTION records[ record_index ].UNSAT_flag = 1; #endif return UNSAT; } #endif #ifdef DETECT_COMPONENTS determine_components(); #endif #ifdef DISTRIBUTION branch_literal = records[record_index].branch_literal; if( branch_literal != 0 ) dist_acc_flag = 1; else // if( branch_literal == 0 ) #endif do { #ifdef LOCAL_AUTARKY int _depth; _depth = analyze_autarky(); if( _depth == 0 ) printf("c global autarky found at depth %i\n", depth ); else if( _depth != depth ) printf("c autarky found at depth %i (from %i)\n", depth, _depth ); #endif nodeCount++; // printf("node %i @ depth %i\n", nodeCount, depth ); if( ConstructCandidatesSet() == 0 ) { if( depth > 0 ) { if( checkSolution() == SAT ) return verifySolution(); } if( PreselectAll() == 0 ) return verifySolution(); } else ConstructPreselectedSet(); if( lookahead() == UNSAT ) { lookDead++; return UNSAT; } if( propagate_forced_literals() == UNSAT ) return UNSAT; branch_literal = get_signedBranchVariable(); // printf("c branch literal %i", branch_literal ); } while( (percentage_forced > 50.0) || (branch_literal == 0) ); #ifdef PLOT if( plotCount++ >= 10000 ) return UNSAT; printf("\t%i\t%.3f\t%i\n", plotCount, sum_plot / count_plot, depth ); #endif _percentage_forced = percentage_forced; #ifdef PARALLEL if( depth < para_depth ) if( para_bin & (1 << (para_depth - depth - 1) ) ) branch_literal *= -1; #endif // printf("branch_literal = %i at depth %i\n", branch_literal, depth ); #ifdef GLOBAL_AUTARKY if( depth == 0 ) { int i; for( i = 1; i <= nrofvars; i++ ) { TernaryImpReduction[ i ] = 0; TernaryImpReduction[ -i ] = 0; if( kSAT_flag ) { btb_size[ i ] = 0; btb_size[ -i ] = 0; } } if( kSAT_flag ) for( i = 0; i < nrofbigclauses; ++i ) clause_reduction[ i ] = 0; // branch_literal = 10; } #endif NODE_START(); #ifdef BLOCK_PRESELECT set_block_stamps( branch_literal ); #endif #ifdef DISTRIBUTION if( top_flag ) { branch_literal *= -1; current_rights++; UPDATE_BIN(); } skip_left = skip_node(); #endif if( (skip_left==0) && IFIUP( branch_literal, FIX_BRANCH_VARIABLE ) ) { #ifdef DISTRIBUTION current_record = LEFT_CHILD; #endif _result = recursive_solve(); #ifdef DISTRIBUTION LEFT_CHILD = current_record; #endif if( _result == SAT || _result == UNKNOWN ) return _result; } else { #ifdef DISTRIBUTION if( (LEFT_CHILD != 0) && records[ LEFT_CHILD ].UNSAT_flag == 0 ) { records[ LEFT_CHILD ].UNSAT_flag = 1; // printf("c left child %i UNSAT by parent!\n", LEFT_CHILD ); } #endif PUSH( r, STACK_BLOCK );} NODE_END(); #ifdef BACKJUMP if( backjump_literal != 0 ) if( timeAssignments[ backjump_literal ] >= NARY_MAX ) { // printf("backjumping at depth %i due to literal %i\n", depth, backjump_literal ); return UNSAT; } backjump_literal = 0; #endif #ifdef DISTRIBUTION if( top_flag ) { current_rights--; UPDATE_BIN(); } #endif percentage_forced = _percentage_forced; #ifdef PARALLEL if( depth < para_depth ) goto parallel_skip_node; #endif #ifdef GLOBAL_AUTARKY if( depth == 0 ) if( kSAT_flag ) { int i; for( i = 1; i <= nrofvars; ++i ) { assert( TernaryImpReduction[ i ] == 0 ); assert( TernaryImpReduction[ -i ] == 0 ); assert( btb_size[ i ] == 0 ); assert( btb_size[ -i ] == 0 ); } for( i = 0; i < nrofbigclauses; ++i ) { clause_red_depth[ i ] = nrofvars; clause_SAT_flag[ i ] = 0; } } if( kSAT_flag ) { int i; for( i = 1; i <= nrofvars; ++i ) { assert( TernaryImpReduction[ i ] >= 0 ); assert( TernaryImpReduction[ -i ] >= 0 ); assert( btb_size[ i ] >= 0 ); assert( btb_size[ -i ] >= 0 ); } } #endif NODE_START(); #ifdef BLOCK_PRESELECT set_block_stamps( branch_literal ); #endif if( top_flag == 0 ) { #ifdef DISTRIBUTION current_rights++; #endif UPDATE_BIN(); } #ifdef DISTRIBUTION skip_right = skip_node(); #endif if( (skip_right == 0) && IFIUP( -branch_literal, FIX_BRANCH_VARIABLE ) ) { #ifdef DISTRIBUTION current_record = RIGHT_CHILD; #endif _result = recursive_solve(); #ifdef DISTRIBUTION RIGHT_CHILD = current_record; #endif if( _result == SAT || _result == UNKNOWN ) return _result;} else { #ifdef DISTRIBUTION if( (RIGHT_CHILD != 0) && records[ RIGHT_CHILD ].UNSAT_flag == 0 ) { records[ RIGHT_CHILD ].UNSAT_flag = 1; // printf("c right child %i UNSAT by parent!\n", RIGHT_CHILD ); } #endif PUSH( r, STACK_BLOCK );} NODE_END(); if( top_flag == 0 ) { #ifdef DISTRIBUTION current_rights--; #endif UPDATE_BIN(); } #ifdef PARALLEL parallel_skip_node:; #endif // printf("ended node %i at depth %i\n", nodeCount, depth ); #ifdef SUBTREE_SIZE if( (skip_flag == 0) && (jump_depth == 0) && (current_rights == 0) ) { int subtree = path_length - depth; // float cost = nodeCount * (CLOCKS_PER_SEC / ((float)(clock() + 10 - first_time))); // printf("c nodes per second = %.3f at level %i\n", cost, depth ); if( jump_depth >= 30 ) jump_depth = 999; if( subtree > SUBTREE_SIZE ) { jump_depth = depth; while( subtree > 2*SUBTREE_SIZE ) { jump_depth++; subtree = subtree / 2; } if( jump_depth >= 20 ) jump_depth = 999; skip_flag = 1; } } #endif #ifdef DISTRIBUTION record_node( record_index, branch_literal, skip_left, skip_right ); current_record = record_index; #endif #ifdef BACKJUMP if( kSAT_flag ) { int *_rstackp = rstackp, nrval; while( --_rstackp > rstack ) { nrval = *_rstackp; if( (TernaryImpReduction[ nrval ] + TernaryImpReduction[ -nrval ]) != 0 ) { backjump_literal = nrval; break; } } } #endif #ifdef ADD_CONFLICT printConflict(); #endif return UNSAT; }
CLOP_graph::CLOP_graph( const Epetra_CrsMatrix* A_, // stiffness matrix const Epetra_IntVector* ND_, // nodes for dofs const int overlap_, // overlap const int partition_option_, // partitioning option const int atype_, // analysis type const int ndim_, // spatial dimension int iwork1[], // integer work array int iwork2[], // integer work array int* & dofpart1, // dofpart1[dofpart2[i]:dofpart2[i+1]-1] = int* & dofpart2, // dofs in overlapping subdomain i int & npart) // number of subdomains for processor : A(A_), ND(ND_), overlap(overlap_), partition_option(partition_option_), atype(atype_), ndim(ndim_), count1(iwork1), imap(iwork2) { // // determine target number of dofs for each subdomain // int min_ndof_sub(10), ncdof_sub, nnode, ncomp, ndof_max, NumProc, MyPID; double scale_factor(1.5); if (atype == 1) ncdof_sub = 1; if (atype == 2) { if (ndim == 2) ncdof_sub = 3; if (ndim == 3) ncdof_sub = 6; } if (atype == 3) ncdof_sub = 3; ndof = A->NumMyRows(); A->Comm().MaxAll(&ndof, &ndof_max, 1); MyPID = A->Comm().MyPID(); NumProc = A->Comm().NumProc(); ndof_target = int(sqrt(1.0*ndof_max*NumProc*ncdof_sub)); ndof_target = ndof; if (ndof_target < min_ndof_sub) ndof_target = min_ndof_sub; // cout << "MyPID, ndof, ndof_target = " << MyPID << " " << ndof << " " // << ndof_target << endl; // // construct node graph and determine dofs for each node // nnode = number of nodes // node_con1[node_con2[i]:node_con2[i+1]-1] = nodes connected to node i // dof_for_node1[dof_for_node2[i]:dof_for_node2[i+1]-1] = dofs for node i // int *node_con1, *node_con2, *dof_for_node1, *dof_for_node2; node_con1 = node_con2 = dof_for_node1 = dof_for_node2 = 0; construct_node_graph(node_con1, node_con2, dof_for_node1, dof_for_node2, nnode); // // determine components // ncomp = number of components for original node graph // comp1[comp2[i]:comp2[i+1]-1] = nodes in component i // int *comp1, *comp2; comp1 = comp2 = 0; determine_components(node_con1, node_con2, nnode, comp1, comp2, ncomp); // cout << "MyPID, ncomp = " << MyPID << " " << ncomp << endl; // // determine subdomains // nsub = number of subdomains // nsub1[nsub2[i]:nsub2[i+1]-1] = nodes in subdomain i // int *nsub1, *nsub2; nsub1 = nsub2 = 0; determine_subdomains(comp1, comp2, ncomp, node_con1, node_con2, dof_for_node2, nnode, nsub1, nsub2); delete [] comp1; delete [] comp2; npart = nsub; // cout << "MyPID, nsub = " << MyPID << " " << nsub << endl; // // determine overlapping subdomains // nosub1[nosub2[i]:nosub2[i+1]-1] = nodes in overlapping subdomain i // int *nosub1, *nosub2; nosub1 = nosub2 = 0; determine_overlap(nsub1, nsub2, node_con1, node_con2, nnode, nosub1, nosub2); delete [] node_con1; delete [] node_con2; delete [] nsub1; delete [] nsub2; // // determine dofs in overlapping subdomains // determine_dof_overlap(nosub1, nosub2, nnode, dof_for_node1, dof_for_node2, dofpart1, dofpart2); delete [] nosub1; delete [] nosub2; delete [] dof_for_node1; delete [] dof_for_node2; }