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);
    }
}
Exemple #2
0
  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;
}