From 8099e07f40f2f8a6f678f3e2b2b209461b976c15 Mon Sep 17 00:00:00 2001 From: Jakub Szuppe Date: Sat, 3 Oct 2015 16:07:18 +0200 Subject: [PATCH] Fix find_extrema_with_atomics Now find_extrema_with_atomics always return the first extremum in the given range. --- .../detail/find_extrema_with_atomics.hpp | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/include/boost/compute/algorithm/detail/find_extrema_with_atomics.hpp b/include/boost/compute/algorithm/detail/find_extrema_with_atomics.hpp index 5ebaf835..406d1bec 100644 --- a/include/boost/compute/algorithm/detail/find_extrema_with_atomics.hpp +++ b/include/boost/compute/algorithm/detail/find_extrema_with_atomics.hpp @@ -29,6 +29,7 @@ inline InputIterator find_extrema_with_atomics(InputIterator first, const bool find_minimum, command_queue &queue) { + typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; const context &context = queue.get_context(); @@ -40,12 +41,32 @@ inline InputIterator find_extrema_with_atomics(InputIterator first, "const uint gid = get_global_id(0);\n" << "uint old_index = *index;\n" << - "#ifndef BOOST_COMPUTE_FIND_MAXIMUM\n" << - "while(" << compare(first[k.var("gid")], - first[k.var("old_index")]) << "){\n" << + k.decl("old") << + " = " << first[k.var("old_index")] << ";\n" << + k.decl("new") << + " = " << first[k.var("gid")] << ";\n" << + + k.decl("compare_result") << ";\n" << + "#ifdef BOOST_COMPUTE_FIND_MAXIMUM\n" << + "while(" << + "(compare_result = " << compare(k.var("old"), + k.var("new")) << ")" << + " || (!(compare_result" << + " || " << compare(k.var("new"), + k.var("old")) << ") " + "&& gid < old_index)){\n" << "#else\n" << - "while(" << compare(first[k.var("old_index")], - first[k.var("gid")]) << "){\n" << + // while condition explained for minimum case with less (<) + // as comparison function: + // while(new_value < old_value + // OR (new_value == old_value AND new_index < old_index)) + "while(" << + "(compare_result = " << compare(k.var("new"), + k.var("old")) << ")" << + " || (!(compare_result" << + " || " << compare(k.var("old"), + k.var("new")) << ") " + "&& gid < old_index)){\n" << "#endif\n" << " if(" << atomic_cmpxchg_uint(k.var("index"), @@ -54,6 +75,7 @@ inline InputIterator find_extrema_with_atomics(InputIterator first, " break;\n" << " else\n" << " old_index = *index;\n" << + "old = " << first[k.var("old_index")] << ";\n" << "}\n"; size_t index_arg_index = k.add_arg(memory_object::global_memory, "index");