• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 #define BOOST_TEST_MODULE TestFlatMap
12 #include <boost/test/unit_test.hpp>
13 
14 #include <utility>
15 
16 #include <boost/concept_check.hpp>
17 
18 #include <boost/compute/source.hpp>
19 #include <boost/compute/container/flat_map.hpp>
20 #include <boost/compute/type_traits/type_name.hpp>
21 #include <boost/compute/type_traits/type_definition.hpp>
22 
23 #include "context_setup.hpp"
24 
BOOST_AUTO_TEST_CASE(concept_check)25 BOOST_AUTO_TEST_CASE(concept_check)
26 {
27     BOOST_CONCEPT_ASSERT((boost::Container<boost::compute::flat_map<int, float> >));
28 //    BOOST_CONCEPT_ASSERT((boost::SimpleAssociativeContainer<boost::compute::flat_map<int, float> >));
29 //    BOOST_CONCEPT_ASSERT((boost::UniqueAssociativeContainer<boost::compute::flat_map<int, float> >));
30     BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<boost::compute::flat_map<int, float>::iterator>));
31     BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<boost::compute::flat_map<int, float>::const_iterator>));
32 }
33 
BOOST_AUTO_TEST_CASE(insert)34 BOOST_AUTO_TEST_CASE(insert)
35 {
36     boost::compute::flat_map<int, float> map(context);
37     map.insert(std::make_pair(1, 1.1f), queue);
38     map.insert(std::make_pair(-1, -1.1f), queue);
39     map.insert(std::make_pair(3, 3.3f), queue);
40     map.insert(std::make_pair(2, 2.2f), queue);
41     BOOST_CHECK_EQUAL(map.size(), size_t(4));
42     BOOST_CHECK(map.find(-1) == map.begin() + 0);
43     BOOST_CHECK(map.find(1) == map.begin() + 1);
44     BOOST_CHECK(map.find(2) == map.begin() + 2);
45     BOOST_CHECK(map.find(3) == map.begin() + 3);
46 
47     map.insert(std::make_pair(2, -2.2f), queue);
48     BOOST_CHECK_EQUAL(map.size(), size_t(4));
49 }
50 
BOOST_AUTO_TEST_CASE(at)51 BOOST_AUTO_TEST_CASE(at)
52 {
53     boost::compute::flat_map<int, float> map(context);
54     map.insert(std::make_pair(1, 1.1f), queue);
55     map.insert(std::make_pair(4, 4.4f), queue);
56     map.insert(std::make_pair(3, 3.3f), queue);
57     map.insert(std::make_pair(2, 2.2f), queue);
58     BOOST_CHECK_EQUAL(float(map.at(1)), float(1.1f));
59     BOOST_CHECK_EQUAL(float(map.at(2)), float(2.2f));
60     BOOST_CHECK_EQUAL(float(map.at(3)), float(3.3f));
61     BOOST_CHECK_EQUAL(float(map.at(4)), float(4.4f));
62 }
63 
BOOST_AUTO_TEST_CASE(index_operator)64 BOOST_AUTO_TEST_CASE(index_operator)
65 {
66     boost::compute::flat_map<int, float> map;
67     map[1] = 1.1f;
68     map[2] = 2.2f;
69     map[3] = 3.3f;
70     map[4] = 4.4f;
71     BOOST_CHECK_EQUAL(float(map[1]), float(1.1f));
72     BOOST_CHECK_EQUAL(float(map[2]), float(2.2f));
73     BOOST_CHECK_EQUAL(float(map[3]), float(3.3f));
74     BOOST_CHECK_EQUAL(float(map[4]), float(4.4f));
75 }
76 
BOOST_AUTO_TEST_CASE(custom_kernel)77 BOOST_AUTO_TEST_CASE(custom_kernel)
78 {
79     typedef boost::compute::flat_map<int, float> MapType;
80 
81     // map from int->float on device
82     MapType map(context);
83     map.insert(std::make_pair(1, 1.2f), queue);
84     map.insert(std::make_pair(3, 3.4f), queue);
85     map.insert(std::make_pair(5, 5.6f), queue);
86     map.insert(std::make_pair(7, 7.8f), queue);
87 
88     // simple linear search for key in map
89     const char lookup_source[] = BOOST_COMPUTE_STRINGIZE_SOURCE(
90         __kernel void lookup(__global const MapType *map,
91                              const int map_size,
92                              const KeyType key,
93                              __global ValueType *result)
94         {
95             for(int i = 0; i < map_size; i++){
96                 if(map[i].first == key){
97                     *result = map[i].second;
98                     break;
99                 }
100             }
101         }
102     );
103 
104     // create program source
105     std::stringstream source;
106 
107     // add type definition for map type
108     source << boost::compute::type_definition<MapType::value_type>();
109 
110     // add lookup function source
111     source << lookup_source;
112 
113     // create lookup program
114     boost::compute::program lookup_program =
115         boost::compute::program::create_with_source(source.str(), context);
116 
117     // program build options
118     std::stringstream options;
119     options << "-DMapType=" << boost::compute::type_name<MapType::value_type>()
120             << " -DKeyType=" << boost::compute::type_name<MapType::key_type>()
121             << " -DValueType=" << boost::compute::type_name<MapType::mapped_type>();
122 
123     // build lookup program with options
124     lookup_program.build(options.str());
125 
126     // create buffer for result value
127     boost::compute::vector<float> result(1, context);
128 
129     // create lookup kernel
130     boost::compute::kernel lookup_kernel = lookup_program.create_kernel("lookup");
131 
132     // set kernel arguments
133     lookup_kernel.set_arg(0, map.begin().get_buffer()); // map buffer
134     lookup_kernel.set_arg<boost::compute::int_>(
135         1, static_cast<boost::compute::int_>(map.size())
136     ); // map size
137     lookup_kernel.set_arg<MapType::key_type>(2, 5); // key
138     lookup_kernel.set_arg(3, result.get_buffer()); // result buffer
139 
140     // run kernel with a single work-item
141     queue.enqueue_task(lookup_kernel);
142 
143     // check result from buffer
144     BOOST_CHECK_EQUAL(result.begin().read(queue), 5.6f);
145 }
146 
147 BOOST_AUTO_TEST_SUITE_END()
148