test_flat_map.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #define BOOST_TEST_MODULE TestFlatMap
  11. #include <boost/test/unit_test.hpp>
  12. #include <utility>
  13. #include <boost/concept_check.hpp>
  14. #include <boost/compute/source.hpp>
  15. #include <boost/compute/container/flat_map.hpp>
  16. #include <boost/compute/type_traits/type_name.hpp>
  17. #include <boost/compute/type_traits/type_definition.hpp>
  18. #include "context_setup.hpp"
  19. BOOST_AUTO_TEST_CASE(concept_check)
  20. {
  21. BOOST_CONCEPT_ASSERT((boost::Container<boost::compute::flat_map<int, float> >));
  22. // BOOST_CONCEPT_ASSERT((boost::SimpleAssociativeContainer<boost::compute::flat_map<int, float> >));
  23. // BOOST_CONCEPT_ASSERT((boost::UniqueAssociativeContainer<boost::compute::flat_map<int, float> >));
  24. BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<boost::compute::flat_map<int, float>::iterator>));
  25. BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<boost::compute::flat_map<int, float>::const_iterator>));
  26. }
  27. BOOST_AUTO_TEST_CASE(insert)
  28. {
  29. boost::compute::flat_map<int, float> map(context);
  30. map.insert(std::make_pair(1, 1.1f), queue);
  31. map.insert(std::make_pair(-1, -1.1f), queue);
  32. map.insert(std::make_pair(3, 3.3f), queue);
  33. map.insert(std::make_pair(2, 2.2f), queue);
  34. BOOST_CHECK_EQUAL(map.size(), size_t(4));
  35. BOOST_CHECK(map.find(-1) == map.begin() + 0);
  36. BOOST_CHECK(map.find(1) == map.begin() + 1);
  37. BOOST_CHECK(map.find(2) == map.begin() + 2);
  38. BOOST_CHECK(map.find(3) == map.begin() + 3);
  39. map.insert(std::make_pair(2, -2.2f), queue);
  40. BOOST_CHECK_EQUAL(map.size(), size_t(4));
  41. }
  42. BOOST_AUTO_TEST_CASE(at)
  43. {
  44. boost::compute::flat_map<int, float> map(context);
  45. map.insert(std::make_pair(1, 1.1f), queue);
  46. map.insert(std::make_pair(4, 4.4f), queue);
  47. map.insert(std::make_pair(3, 3.3f), queue);
  48. map.insert(std::make_pair(2, 2.2f), queue);
  49. BOOST_CHECK_EQUAL(float(map.at(1)), float(1.1f));
  50. BOOST_CHECK_EQUAL(float(map.at(2)), float(2.2f));
  51. BOOST_CHECK_EQUAL(float(map.at(3)), float(3.3f));
  52. BOOST_CHECK_EQUAL(float(map.at(4)), float(4.4f));
  53. }
  54. BOOST_AUTO_TEST_CASE(index_operator)
  55. {
  56. boost::compute::flat_map<int, float> map;
  57. map[1] = 1.1f;
  58. map[2] = 2.2f;
  59. map[3] = 3.3f;
  60. map[4] = 4.4f;
  61. BOOST_CHECK_EQUAL(float(map[1]), float(1.1f));
  62. BOOST_CHECK_EQUAL(float(map[2]), float(2.2f));
  63. BOOST_CHECK_EQUAL(float(map[3]), float(3.3f));
  64. BOOST_CHECK_EQUAL(float(map[4]), float(4.4f));
  65. }
  66. BOOST_AUTO_TEST_CASE(custom_kernel)
  67. {
  68. typedef boost::compute::flat_map<int, float> MapType;
  69. // map from int->float on device
  70. MapType map(context);
  71. map.insert(std::make_pair(1, 1.2f), queue);
  72. map.insert(std::make_pair(3, 3.4f), queue);
  73. map.insert(std::make_pair(5, 5.6f), queue);
  74. map.insert(std::make_pair(7, 7.8f), queue);
  75. // simple linear search for key in map
  76. const char lookup_source[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
  77. __kernel void lookup(__global const MapType *map,
  78. const int map_size,
  79. const KeyType key,
  80. __global ValueType *result)
  81. {
  82. for(int i = 0; i < map_size; i++){
  83. if(map[i].first == key){
  84. *result = map[i].second;
  85. break;
  86. }
  87. }
  88. }
  89. );
  90. // create program source
  91. std::stringstream source;
  92. // add type definition for map type
  93. source << boost::compute::type_definition<MapType::value_type>();
  94. // add lookup function source
  95. source << lookup_source;
  96. // create lookup program
  97. boost::compute::program lookup_program =
  98. boost::compute::program::create_with_source(source.str(), context);
  99. // program build options
  100. std::stringstream options;
  101. options << "-DMapType=" << boost::compute::type_name<MapType::value_type>()
  102. << " -DKeyType=" << boost::compute::type_name<MapType::key_type>()
  103. << " -DValueType=" << boost::compute::type_name<MapType::mapped_type>();
  104. // build lookup program with options
  105. lookup_program.build(options.str());
  106. // create buffer for result value
  107. boost::compute::vector<float> result(1, context);
  108. // create lookup kernel
  109. boost::compute::kernel lookup_kernel = lookup_program.create_kernel("lookup");
  110. // set kernel arguments
  111. lookup_kernel.set_arg(0, map.begin().get_buffer()); // map buffer
  112. lookup_kernel.set_arg<boost::compute::int_>(
  113. 1, static_cast<boost::compute::int_>(map.size())
  114. ); // map size
  115. lookup_kernel.set_arg<MapType::key_type>(2, 5); // key
  116. lookup_kernel.set_arg(3, result.get_buffer()); // result buffer
  117. // run kernel with a single work-item
  118. queue.enqueue_task(lookup_kernel);
  119. // check result from buffer
  120. BOOST_CHECK_EQUAL(result.begin().read(queue), 5.6f);
  121. }
  122. BOOST_AUTO_TEST_SUITE_END()