Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:25:46

0001 /*  This file is part of the Vc library. {{{
0002 Copyright © 2014-2015 Matthias Kretz <kretz@kde.org>
0003 
0004 Redistribution and use in source and binary forms, with or without
0005 modification, are permitted provided that the following conditions are met:
0006     * Redistributions of source code must retain the above copyright
0007       notice, this list of conditions and the following disclaimer.
0008     * Redistributions in binary form must reproduce the above copyright
0009       notice, this list of conditions and the following disclaimer in the
0010       documentation and/or other materials provided with the distribution.
0011     * Neither the names of contributing organizations nor the
0012       names of its contributors may be used to endorse or promote products
0013       derived from this software without specific prior written permission.
0014 
0015 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
0016 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0017 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0018 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
0019 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0020 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0021 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0022 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0023 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 
0026 }}}*/
0027 
0028 #ifndef Vc_CURRENT_CLASS_NAME
0029 #error "incorrect use of common/gatherinterface.h: Vc_CURRENT_CLASS_NAME must be defined to the current class name for declaring constructors."
0030 #endif
0031 
0032 ///////////////////////////////////////////////////////////////////////////////////////////
0033 // gathers
0034 // A gather takes the following arguments:
0035 // 1. A const pointer to memory of any type that can convert to EntryType
0036 // 2. An indexes “vector”. The requirement is that the type implements the subscript operator,
0037 //    stores «Size» valid index values, and each offset to the pointer above yields a valid
0038 //    memory location for reading.
0039 // 3. Optionally the third argument may be a mask. The mask disables several memory reads and
0040 //    thus removes the requirements in (2.) for the disabled entries.
0041 
0042 private:
0043     /**\internal
0044      * This function implements a gather given a pointer to memory \p mem and some
0045      * container object storing the gather \p indexes.
0046      *
0047      * \param mem This pointer must be aligned correctly for the type \p MT. This is the
0048      * natural behavior of C++, so this is typically the case.
0049      * \param indexes This object contains at least \VSize{T} indexes that denote the
0050      * offset in \p mem where the components for the current vector should be copied from.
0051      * The offset is not in Bytes, but in multiples of `sizeof(MT)`.
0052      */
0053     // enable_if<std::can_convert<MT, EntryType>::value &&
0054     // has_subscript_operator<IT>::value>
0055     template <class MT, class IT, int Scale = 1>
0056     inline void gatherImplementation(const Common::GatherArguments<MT, IT, Scale> &);
0057 
0058     /**\internal
0059      * This overload of the above function adds a \p mask argument to disable memory
0060      * accesses at the \p indexes offsets where \p mask is \c false.
0061      */
0062     template <class MT, class IT, int Scale = 1>
0063     inline void gatherImplementation(const Common::GatherArguments<MT, IT, Scale> &,
0064                                      MaskArgument mask);
0065 
0066 public:
0067 #define Vc_ASSERT_GATHER_PARAMETER_TYPES_                                                \
0068     static_assert(                                                                       \
0069         std::is_convertible<MT, EntryType>::value,                                       \
0070         "The memory pointer needs to point to a type that can be converted to the "      \
0071         "EntryType of this SIMD vector type.");                                          \
0072     static_assert(                                                                       \
0073         Vc::Traits::has_subscript_operator<IT>::value,                                   \
0074         "The indexes argument must be a type that implements the subscript operator.");  \
0075     static_assert(                                                                       \
0076         !Traits::is_simd_vector<IT>::value ||                                            \
0077             Traits::simd_vector_size<IT>::value >= Size,                                 \
0078         "If you use a SIMD vector for the indexes parameter, the index vector must "     \
0079         "have at least as many entries as this SIMD vector.");                           \
0080     static_assert(                                                                       \
0081         !std::is_array<T>::value ||                                                      \
0082             (std::rank<T>::value == 1 &&                                                 \
0083              (std::extent<T>::value == 0 || std::extent<T>::value >= Size)),             \
0084         "If you use a simple array for the indexes parameter, the array must have "      \
0085         "at least as many entries as this SIMD vector.")
0086 
0087     /**
0088      * \name Gather constructors and member functions
0089      *
0090      * Constructs or loads a vector from the objects at `mem[indexes[0]]`,
0091      * `mem[indexes[1]]`, `mem[indexes[2]]`, ...
0092      *
0093      * All gather functions optionally take a mask as last argument. In that case only the
0094      * entries that are selected in the mask are accessed in memory and copied to the
0095      * vector. This enables invalid indexes in the \p indexes vector if those are masked
0096      * off in \p mask.
0097      *
0098      * Gathers from structured data (AoS: arrays of struct) are possible via a special
0099      * subscript operator of the container (array). You can use \ref Vc::array and \ref
0100      * Vc::vector as drop-in replacements for \c std::array and \c std::vector. These
0101      * container classes contain the necessary subscript operator overload. Example:
0102      * \code
0103      * Vc::vector<float> data(100);
0104      * std::iota(data.begin(), data.end(), 0.f);  // fill with values 0, 1, 2, ...
0105      * auto indexes = float_v::IndexType::IndexesFromZero();
0106      * float_v gathered = data[indexes];  // gathered == [0, 1, 2, ...]
0107      * \endcode
0108      *
0109      * This also works for gathers into arrays of structures:
0110      * \code
0111      * struct Point { float x, y, z; };
0112      * Vc::array<Point, 100> points;
0113      * // fill points ...
0114      * auto indexes = float_v::IndexType::IndexesFromZero();
0115      * float_v xs = data[indexes][&Point::x];  // [points[0].x, points[1].x, points[2].x, ...]
0116      * float_v ys = data[indexes][&Point::y];  // [points[0].y, points[1].y, points[2].y, ...]
0117      * float_v zs = data[indexes][&Point::z];  // [points[0].z, points[1].z, points[2].z, ...]
0118      * \endcode
0119      *
0120      * Alternatively, you can use Vc::Common::AdaptSubscriptOperator to extend a given
0121      * container class with the necessary subscript operator. Example:
0122      * \code
0123      * template <typename T, typename Allocator = std::allocator<T>>
0124      * using my_vector = Vc::Common::AdaptSubscriptOperator<std::vector<T, Allocator>>;
0125      * \endcode
0126      *
0127      * \param mem A pointer to memory which contains objects of type \p MT at the offsets
0128      *            given by \p indexes.
0129      * \param indexes A container/vector of offsets into \p mem.
0130      *                The type of \p indexes (\p IT) may either be a pointer to integers
0131      *                (C-array) or a vector of integers (preferrably IndexType).
0132      * \param mask If a mask is given, only the active entries will be copied from memory.
0133      *
0134      * \note If you use a masked gather constructor the masked-off entries of the vector
0135      * are zero-initilized.
0136      */
0137     ///@{
0138 
0139     /// Gather constructor
0140     template <typename MT, typename IT,
0141               typename = enable_if<Traits::has_subscript_operator<IT>::value>>
0142     Vc_INTRINSIC Vc_CURRENT_CLASS_NAME(const MT *mem, const IT &indexes)
0143     {
0144         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0145         gatherImplementation(
0146             Common::make_gather<1>(mem, Common::convertIndexVector(indexes)));
0147     }
0148 
0149     template <class MT, class IT, int Scale>
0150     Vc_INTRINSIC Vc_CURRENT_CLASS_NAME(const Common::GatherArguments<MT, IT, Scale> &args)
0151     {
0152         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0153         gatherImplementation(args);
0154     }
0155 
0156     /// Masked gather constructor
0157     template <typename MT, typename IT,
0158               typename = enable_if<Vc::Traits::has_subscript_operator<IT>::value>>
0159     Vc_INTRINSIC Vc_CURRENT_CLASS_NAME(const MT *mem, const IT &indexes,
0160                                        MaskArgument mask)
0161     {
0162         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0163         gatherImplementation(
0164             Common::make_gather<1>(mem, Common::convertIndexVector(indexes)), mask);
0165     }
0166 
0167     template <class MT, class IT, int Scale>
0168     Vc_INTRINSIC Vc_CURRENT_CLASS_NAME(const Common::GatherArguments<MT, IT, Scale> &args,
0169                                        MaskArgument mask)
0170     {
0171         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0172         gatherImplementation(args, mask);
0173     }
0174 
0175     /// Gather function
0176     template <typename MT, typename IT,
0177               typename = enable_if<Vc::Traits::has_subscript_operator<IT>::value>>
0178     Vc_INTRINSIC void gather(const MT *mem, const IT &indexes)
0179     {
0180         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0181         gatherImplementation(
0182             Common::make_gather<1>(mem, Common::convertIndexVector(indexes)));
0183     }
0184 
0185     /// Masked gather function
0186     template <typename MT, typename IT,
0187               typename = enable_if<Vc::Traits::has_subscript_operator<IT>::value>>
0188     Vc_INTRINSIC void gather(const MT *mem, const IT &indexes, MaskArgument mask)
0189     {
0190         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0191         gatherImplementation(
0192             Common::make_gather<1>(mem, Common::convertIndexVector(indexes)), mask);
0193     }
0194     ///@}
0195 
0196 #include "gatherinterface_deprecated.h"
0197 
0198     /**\internal
0199      * \name Gather function to use from Vc::Common::subscript_operator
0200      *
0201      * \param args
0202      * \param mask
0203      */
0204     ///@{
0205     template <class MT, class IT, int Scale>
0206     Vc_INTRINSIC void gather(const Common::GatherArguments<MT, IT, Scale> &args)
0207     {
0208         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0209         gatherImplementation(args);
0210     }
0211 
0212     template <class MT, class IT, int Scale>
0213     Vc_INTRINSIC void gather(const Common::GatherArguments<MT, IT, Scale> &args,
0214                              MaskArgument mask)
0215     {
0216         Vc_ASSERT_GATHER_PARAMETER_TYPES_;
0217         gatherImplementation(args, mask);
0218     }
0219     ///@}
0220 
0221 #undef Vc_ASSERT_GATHER_PARAMETER_TYPES_