Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:58

0001 //---------------------------------------------------------------------------//
0002 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // See http://boostorg.github.com/compute for more information.
0009 //---------------------------------------------------------------------------//
0010 
0011 #ifndef BOOST_COMPUTE_CONTAINER_ARRAY_HPP
0012 #define BOOST_COMPUTE_CONTAINER_ARRAY_HPP
0013 
0014 #include <cstddef>
0015 #include <iterator>
0016 #include <exception>
0017 
0018 #include <boost/array.hpp>
0019 #include <boost/throw_exception.hpp>
0020 
0021 #include <boost/compute/buffer.hpp>
0022 #include <boost/compute/system.hpp>
0023 #include <boost/compute/algorithm/fill.hpp>
0024 #include <boost/compute/algorithm/swap_ranges.hpp>
0025 #include <boost/compute/iterator/buffer_iterator.hpp>
0026 #include <boost/compute/type_traits/detail/capture_traits.hpp>
0027 #include <boost/compute/detail/buffer_value.hpp>
0028 
0029 namespace boost {
0030 namespace compute {
0031 
0032 /// \class array
0033 /// \brief A fixed-size container.
0034 ///
0035 /// The array container is very similar to the \ref vector container except
0036 /// its size is fixed at compile-time rather than being dynamically resizable
0037 /// at run-time.
0038 ///
0039 /// For example, to create a fixed-size array with eight values on the device:
0040 /// \code
0041 /// boost::compute::array<int, 8> values(context);
0042 /// \endcode
0043 ///
0044 /// The Boost.Compute \c array class provides a STL-like API and is modeled
0045 /// after the \c std::array class from the C++ standard library.
0046 ///
0047 /// \see \ref vector "vector<T>"
0048 template<class T, std::size_t N>
0049 class array
0050 {
0051 public:
0052     typedef T value_type;
0053     typedef std::size_t size_type;
0054     typedef ptrdiff_t difference_type;
0055     typedef detail::buffer_value<T> reference;
0056     typedef const detail::buffer_value<T> const_reference;
0057     typedef T* pointer;
0058     typedef const T* const_pointer;
0059     typedef buffer_iterator<T> iterator;
0060     typedef buffer_iterator<T> const_iterator;
0061     typedef std::reverse_iterator<iterator> reverse_iterator;
0062     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0063 
0064     enum {
0065         static_size = N
0066     };
0067 
0068     explicit array(const context &context = system::default_context())
0069         : m_buffer(context, sizeof(T) * N)
0070     {
0071     }
0072 
0073     array(const array<T, N> &other)
0074         : m_buffer(other.m_buffer.get_context(), sizeof(T) * N)
0075     {
0076         command_queue queue = default_queue();
0077         boost::compute::copy(other.begin(), other.end(), begin(), queue);
0078         queue.finish();
0079     }
0080 
0081     array(const boost::array<T, N> &array,
0082           const context &context = system::default_context())
0083         : m_buffer(context, sizeof(T) * N)
0084     {
0085         command_queue queue = default_queue();
0086         boost::compute::copy(array.begin(), array.end(), begin(), queue);
0087         queue.finish();
0088     }
0089 
0090     array(const array<T, N> &other,
0091           const command_queue &queue)
0092         : m_buffer(other.m_buffer.get_context(), sizeof(T) * N)
0093     {
0094         boost::compute::copy(other.begin(), other.end(), begin(), queue);
0095     }
0096 
0097     array<T, N>& operator=(const array<T, N> &other)
0098     {
0099         if(this != &other){
0100             command_queue queue = default_queue();
0101             boost::compute::copy(other.begin(), other.end(), begin(), queue);
0102             queue.finish();
0103         }
0104 
0105         return *this;
0106     }
0107 
0108     array<T, N>& operator=(const boost::array<T, N> &array)
0109     {
0110         command_queue queue = default_queue();
0111         boost::compute::copy(array.begin(), array.end(), begin(), queue);
0112         queue.finish();
0113 
0114         return *this;
0115     }
0116 
0117     ~array()
0118     {
0119     }
0120 
0121     iterator begin()
0122     {
0123         return buffer_iterator<T>(m_buffer, 0);
0124     }
0125 
0126     const_iterator begin() const
0127     {
0128         return buffer_iterator<T>(m_buffer, 0);
0129     }
0130 
0131     const_iterator cbegin() const
0132     {
0133         return begin();
0134     }
0135 
0136     iterator end()
0137     {
0138         return buffer_iterator<T>(m_buffer, N);
0139     }
0140 
0141     const_iterator end() const
0142     {
0143         return buffer_iterator<T>(m_buffer, N);
0144     }
0145 
0146     const_iterator cend() const
0147     {
0148         return end();
0149     }
0150 
0151     reverse_iterator rbegin()
0152     {
0153         return reverse_iterator(end() - 1);
0154     }
0155 
0156     const_reverse_iterator rbegin() const
0157     {
0158         return reverse_iterator(end() - 1);
0159     }
0160 
0161     const_reverse_iterator crbegin() const
0162     {
0163         return rbegin();
0164     }
0165 
0166     reverse_iterator rend()
0167     {
0168         return reverse_iterator(begin() - 1);
0169     }
0170 
0171     const_reverse_iterator rend() const
0172     {
0173         return reverse_iterator(begin() - 1);
0174     }
0175 
0176     const_reverse_iterator crend() const
0177     {
0178         return rend();
0179     }
0180 
0181     size_type size() const
0182     {
0183         return N;
0184     }
0185 
0186     bool empty() const
0187     {
0188         return N == 0;
0189     }
0190 
0191     size_type max_size() const
0192     {
0193         return N;
0194     }
0195 
0196     reference operator[](size_type index)
0197     {
0198         return *(begin() + static_cast<difference_type>(index));
0199     }
0200 
0201     const_reference operator[](size_type index) const
0202     {
0203         return *(begin() + static_cast<difference_type>(index));
0204     }
0205 
0206     reference at(size_type index)
0207     {
0208         if(index >= N){
0209             BOOST_THROW_EXCEPTION(std::out_of_range("index out of range"));
0210         }
0211 
0212         return operator[](index);
0213     }
0214 
0215     const_reference at(size_type index) const
0216     {
0217         if(index >= N){
0218             BOOST_THROW_EXCEPTION(std::out_of_range("index out of range"));
0219         }
0220 
0221         return operator[](index);
0222     }
0223 
0224     reference front()
0225     {
0226         return *begin();
0227     }
0228 
0229     const_reference front() const
0230     {
0231         return *begin();
0232     }
0233 
0234     reference back()
0235     {
0236         return *(end() - static_cast<difference_type>(1));
0237     }
0238 
0239     const_reference back() const
0240     {
0241         return *(end() - static_cast<difference_type>(1));
0242     }
0243 
0244     void fill(const value_type &value, const command_queue &queue)
0245     {
0246         ::boost::compute::fill(begin(), end(), value, queue);
0247     }
0248 
0249     void swap(array<T, N> &other, const command_queue &queue)
0250     {
0251         ::boost::compute::swap_ranges(begin(), end(), other.begin(), queue);
0252     }
0253 
0254     void fill(const value_type &value)
0255     {
0256         command_queue queue = default_queue();
0257         ::boost::compute::fill(begin(), end(), value, queue);
0258         queue.finish();
0259     }
0260 
0261     void swap(array<T, N> &other)
0262     {
0263         command_queue queue = default_queue();
0264         ::boost::compute::swap_ranges(begin(), end(), other.begin(), queue);
0265         queue.finish();
0266     }
0267 
0268     const buffer& get_buffer() const
0269     {
0270         return m_buffer;
0271     }
0272 
0273 private:
0274     buffer m_buffer;
0275 
0276     command_queue default_queue() const
0277     {
0278         const context &context = m_buffer.get_context();
0279         command_queue queue(context, context.get_device());
0280         return queue;
0281     }
0282 };
0283 
0284 namespace detail {
0285 
0286 // set_kernel_arg specialization for array<T, N>
0287 template<class T, std::size_t N>
0288 struct set_kernel_arg<array<T, N> >
0289 {
0290     void operator()(kernel &kernel_, size_t index, const array<T, N> &array)
0291     {
0292         kernel_.set_arg(index, array.get_buffer());
0293     }
0294 };
0295 
0296 // for capturing array<T, N> with BOOST_COMPUTE_CLOSURE()
0297 template<class T, size_t N>
0298 struct capture_traits<array<T, N> >
0299 {
0300     static std::string type_name()
0301     {
0302         return std::string("__global ") + ::boost::compute::type_name<T>() + "*";
0303     }
0304 };
0305 
0306 // meta_kernel streaming operator for array<T, N>
0307 template<class T, size_t N>
0308 meta_kernel& operator<<(meta_kernel &k, const array<T, N> &array)
0309 {
0310   return k << k.get_buffer_identifier<T>(array.get_buffer());
0311 }
0312 
0313 } // end detail namespace
0314 } // end compute namespace
0315 } // end boost namespace
0316 
0317 #endif // BOOST_COMPUTE_CONTAINER_ARRAY_HPP