예제 #1
0
bool Clustering::perform_single_move(const SingleMove& move) {
	if (move.c1 == move.c2) return false;
	
	// update stats
	Stats delta1 = node_stats[move.i]; delta1.self += 2.0 * move.weight_i_c1;
	Stats delta2 = node_stats[move.i]; delta2.self += 2.0 * move.weight_i_c2;
	clus_stats[move.c1] -= delta1;
	clus_stats[move.c2] += delta2;
	clus_stats.total -= delta1;
	clus_stats.total += delta2;
	// update loss
	sum_local_loss = move.sum_local_after;
	loss = move.loss_after;
	// update cluster assignment
	if(node_clus[move.i] != move.c1) throw std::logic_error("node_clus[move.i] != move.c2");
	node_clus[move.i] = move.c2;
	// update
	update_clus_size(move.c1, -1);
	update_clus_size(move.c2, +1);
	
	// recheck invariants
	if (params.check_invariants) verify_invariants();
	if (params.verbosity >= 6) {
		params.debug_out << "     moved " << move.i << " from " << move.c1;
		if (!node_partition.empty()) params.debug_out << " in " << node_partition[move.c1];
		params.debug_out << " to " << move.c2;
		if (!node_partition.empty()) params.debug_out << " in " << node_partition[move.c2];
		params.debug_out << " loss " << setprecision(12) << move.loss_after << " in " << num_clusters() << " clusters" << endl;
	}
	return true;
}
예제 #2
0
//
// wrapper_type:  0 for kernel functions, 1 for entry point epwrapper_ functions
// Returns the current driver call stack after entering the driver
//
//  gen_enter_driver is called after the associated kernel function executes
//  gen_enter_driver is called before the associated driver function executes.
//
// Interesting functions: 0 if not interesting, 1 if interesting.
//  Note that both driver functions and kernel functions can be interesting
//  We can distinguish that based on wrapper_type
//
int gen_enter_driver (const char *fn,
                      int line,
                      enum symdrive_WRAPPER_TYPE wrapper_type,
                      int retval_valid,
                      unsigned long retval,
                      const char *interesting_fn,
                      void (*gen_register_all_param)(void))
{
    // Moved from generated code.
    // Call interrupt handlers if we're entering the driver from
    // a call into the kernel.
    static char first_time_in_driver = 1;
    if (first_time_in_driver == 1) {
        gen_register_all_param();
        first_time_in_driver = 0;
    }

    if (wrapper_type == STUBWRAPPER) {
        // Pause/Resume accumulation if needed
        //s2e_disable_trackperf(__LINE__, SYMDRIVE_PAUSE_IRQ);
        call_interrupt_handlers(fn, line);
        execute_completions(fn, line);
        //s2e_enable_trackperf(__LINE__, SYMDRIVE_CONTINUE_IRQ);
    }

    acquire_global_lock();

    // Entering driver:
    if (driver_call_stack == 0) {
        //if (cleanup_path == 0 && strcmp (fn, "cleanup_module") == 0) { // TODO HACK
        //    cleanup_path = 1;
        //}
        //if (cleanup_path == 0) {
        //    s2e_disable_all_apic_interrupts();
        //}

        verify_retval(fn, line, wrapper_type, ENTRANCE, retval_valid, retval);

        // Reset success path on first entry into driver
        s2e_success_path (line, fn, 0);
    }
    verify_invariants(fn, line, 1, wrapper_type);

    // Track performance / basic blocks
    //if (strcmp (fn, g_sym_trackperf_fn) == 0) {
    //    // start accumulation
    //    s2e_enable_trackperf(__LINE__, SYMDRIVE_START_AUTO);
    //}

    // Entering driver/kernel function:
    s2e_enter_function(line, fn, wrapper_type);

    handle_interesting_function(fn, line, wrapper_type, retval_valid, retval, interesting_fn, ENTRANCE);
    handle_max_coverage(fn, line, retval_valid, retval, wrapper_type, ENTRANCE);
    release_global_lock();

    // Not used as far as I know:
    return driver_call_stack;
}
예제 #3
0
// go over nodes in a random order, and try to move to neighboring cluster
bool Clustering::optimize_single_moves_pass() {
	if (params.check_invariants) verify_invariants();
	bool changes = false;
	std::random_shuffle(node_perm.begin(), node_perm.end());
	for (vector<int>::const_iterator i_it = node_perm.begin() ; i_it != node_perm.end() ; ++i_it) {
		//OCTAVE_QUIT;
		if (optimize_single_move_for_node(*i_it)) changes = true;
	}
	if (changes) {
		// it is important to recalculate the loss, otherwise we accumulate numerical errors
		recalc_internal_data();
	}
	return changes;
}
예제 #4
0
//
// This function is called in the postfn_ generated function
//
int gen_exit_driver (const char *fn,
                     int line,
                     enum symdrive_WRAPPER_TYPE wrapper_type,
                     int retval_valid,
                     unsigned long retval,
                     const char *interesting_fn,
                     void (*gen_register_all_param)(void))
{
    //static int alternate_sym = 0;
    acquire_global_lock();

    // Exiting driver/kernel function:
    s2e_exit_function(line, fn, wrapper_type);

    // Track performance / basic blocks
    // Do this before calling verify_retval
    // Do this before max coverage.
    //if (strcmp (fn, g_sym_trackperf_fn) == 0) {
    //    s2e_disable_trackperf(__LINE__, SYMDRIVE_STOP_AUTO);
    //}

    // Starting the full-coverage mode
    handle_max_coverage(fn, line, retval_valid, retval, wrapper_type, EXIT);
    handle_interesting_function(fn, line, wrapper_type, retval_valid, retval, interesting_fn, EXIT);
    // If the retval is valid and not symbolic then prioritize or deprioritize.
    // If it is symbolic, then do nothing on the assumption that it's a hardware
    // value -- we should not be prioritizing hardware values.
    if (retval_valid) {
        if (s2e_is_symbolic_symdrive(line, retval) == 0) {
            s2e_prioritize(line);

            if (g_symdrive_annotations == 0) {
                // Proceed normally
            } else {
                // Convert retval to success
                uprintk ("Prioritization:  allowing our path per annotation\n",
                         fn, line, s2e_get_example_uint (retval));
                g_symdrive_annotations = 0;
                retval = 0;
            }

            if (!IS_ERR_VALUE(retval)) {
                s2e_success_path(line, fn, 1);
                uprintk ("Prioritizing line %d, example val %lu\n", line, s2e_get_example_uint(retval));
            } else {
                uprintk ("Deprioritizing line %d, example val %lu\n", line, s2e_get_example_uint(retval));
                s2e_success_path(line, fn, -1);
                s2e_deprioritize(line);
            }
        } else {
            uprintk ("Line %d: symbolic retval, example %lu.\n", line, s2e_get_example_uint(retval));
        }
    }

    // Exiting driver:
    verify_invariants(fn, line, -1, wrapper_type);

    if (driver_call_stack == 0) {
        verify_retval(fn, line, wrapper_type, EXIT, retval_valid, retval);
        reset_new_objects (fn);
        
        //if (cleanup_path == 0) {
        //    s2e_enable_all_apic_interrupts();
        //}
    }
    release_global_lock();

    // Moved from generated code.
    // Call interrupt handlers if we're returning to the kernel.
    if (wrapper_type == PREPOSTFN && driver_call_stack == 0) {
        //s2e_disable_trackperf(__LINE__, SYMDRIVE_PAUSE_IRQ); // Pause accumulation
        call_interrupt_handlers(fn, line);
        execute_completions(fn, line);
        //s2e_enable_trackperf(__LINE__, SYMDRIVE_CONTINUE_IRQ); // Resume accumulation
    }

    // Not used as far as I know:
    return driver_call_stack;
}