inline void merge_sort_by_key_on_gpu(KeyIterator keys_first, KeyIterator keys_last, ValueIterator values_first, Compare compare, bool stable, command_queue &queue) { typedef typename std::iterator_traits<KeyIterator>::value_type key_type; typedef typename std::iterator_traits<ValueIterator>::value_type value_type; size_t count = iterator_range_size(keys_first, keys_last); if(count < 2){ return; } size_t block_size = block_sort( keys_first, values_first, compare, count, true /* sort_by_key */, stable /* stable */, queue ); // for small input size only block sort is performed if(count <= block_size) { return; } const context &context = queue.get_context(); bool result_in_temporary_buffer = false; ::boost::compute::vector<key_type> temp_keys(count, context); ::boost::compute::vector<value_type> temp_values(count, context); for(; block_size < count; block_size *= 2) { result_in_temporary_buffer = !result_in_temporary_buffer; if(result_in_temporary_buffer) { merge_blocks_on_gpu(keys_first, values_first, temp_keys.begin(), temp_values.begin(), compare, count, block_size, true /* sort_by_key */, queue); } else { merge_blocks_on_gpu(temp_keys.begin(), temp_values.begin(), keys_first, values_first, compare, count, block_size, true /* sort_by_key */, queue); } } if(result_in_temporary_buffer) { copy_async(temp_keys.begin(), temp_keys.end(), keys_first, queue); copy_async(temp_values.begin(), temp_values.end(), values_first, queue); } }
void bucket_sort(ForwardIterator begin, ForwardIterator end, ItemToRankMap rank, SizeType range = 0) { #ifdef BOOST_GRAPH_PREFER_STD_LIB std::stable_sort(begin, end, rank_comparison<ItemToRankMap>(rank)); #else typedef std::vector < typename boost::property_traits<ItemToRankMap>::key_type > vector_of_values_t; typedef std::vector< vector_of_values_t > vector_of_vectors_t; if (!range) { rank_comparison<ItemToRankMap> cmp(rank); ForwardIterator max_by_rank = std::max_element(begin, end, cmp); if (max_by_rank == end) return; range = get(rank, *max_by_rank) + 1; } vector_of_vectors_t temp_values(range); for(ForwardIterator itr = begin; itr != end; ++itr) { temp_values[get(rank, *itr)].push_back(*itr); } ForwardIterator orig_seq_itr = begin; typename vector_of_vectors_t::iterator itr_end = temp_values.end(); for(typename vector_of_vectors_t::iterator itr = temp_values.begin(); itr != itr_end; ++itr ) { typename vector_of_values_t::iterator jtr_end = itr->end(); for(typename vector_of_values_t::iterator jtr = itr->begin(); jtr != jtr_end; ++jtr ) { *orig_seq_itr = *jtr; ++orig_seq_itr; } } #endif }
double SteepestDescent::do_optimize(unsigned int max_steps) { IMP_OBJECT_LOG; Float last_score, new_score = 0.0; // set up the indexes FloatIndexes float_indexes=get_optimized_attributes(); Float current_step_size = step_size_; // ... and space for the old values algebra::VectorKD temp_derivs(Floats(float_indexes.size(), 0)); algebra::VectorKD temp_values(Floats(float_indexes.size(), 0)); for (unsigned int step = 0; step < max_steps; step++) { // model.show(std::cout); int cnt = 0; // evaluate the last model state last_score = get_scoring_function()->evaluate(true); IMP_LOG(TERSE, "start score: " << last_score << std::endl); // store the old values for (unsigned int i = 0; i < temp_derivs.get_dimension(); i++) { temp_derivs[i] = get_derivative(float_indexes[i]); temp_values[i] = get_value(float_indexes[i]); } bool constant_score=false; while (true) { cnt++; // try new values based on moving down the gradient at the current // step size IMP_LOG(VERBOSE, "step: " << temp_derivs * current_step_size << std::endl); for (unsigned int i = 0; i < float_indexes.size(); i++) { set_value(float_indexes[i], temp_values[i] - temp_derivs[i] * current_step_size); } // check the new model new_score = get_scoring_function()->evaluate(false); IMP_LOG(TERSE, "last score: " << last_score << " new score: " << new_score << " step size: " << current_step_size << std::endl); // if the score got better, we'll take it if (new_score < last_score) { IMP_LOG(TERSE, "Accepting step of size " << current_step_size); update_states(); if (new_score <= threshold_) { IMP_LOG(TERSE, "Below threshold, returning." << std::endl); return new_score; } current_step_size= std::min(current_step_size* 1.4, max_step_size_); break; } // if the score is the same, keep going one more time if (std::abs(new_score- last_score) < .0000001) { if (constant_score) { break; } current_step_size *= 0.9; constant_score = true; } else { constant_score=false; current_step_size*=.7; } if (cnt>200) { // stuck for (unsigned int i = 0; i < float_indexes.size(); i++) { set_value(float_indexes[i], temp_values[i]); } IMP_LOG(TERSE, "Unable to find a good step. Returning" << std::endl); return last_score; } if (current_step_size <.00000001) { // here is as good as any place we found update_states(); IMP_LOG(TERSE, "Unable to make progress, returning." << std::endl); return new_score; } } } return new_score; }