~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to extern/Eigen3/Eigen/src/Core/Redux.h

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5
5
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6
6
//
7
 
// Eigen is free software; you can redistribute it and/or
8
 
// modify it under the terms of the GNU Lesser General Public
9
 
// License as published by the Free Software Foundation; either
10
 
// version 3 of the License, or (at your option) any later version.
11
 
//
12
 
// Alternatively, you can redistribute it and/or
13
 
// modify it under the terms of the GNU General Public License as
14
 
// published by the Free Software Foundation; either version 2 of
15
 
// the License, or (at your option) any later version.
16
 
//
17
 
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18
 
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20
 
// GNU General Public License for more details.
21
 
//
22
 
// You should have received a copy of the GNU Lesser General Public
23
 
// License and a copy of the GNU General Public License along with
24
 
// Eigen. If not, see <http://www.gnu.org/licenses/>.
 
7
// This Source Code Form is subject to the terms of the Mozilla
 
8
// Public License v. 2.0. If a copy of the MPL was not distributed
 
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
25
10
 
26
11
#ifndef EIGEN_REDUX_H
27
12
#define EIGEN_REDUX_H
28
13
 
 
14
namespace Eigen { 
 
15
 
29
16
namespace internal {
30
17
 
31
18
// TODO
95
82
 
96
83
  typedef typename Derived::Scalar Scalar;
97
84
 
98
 
  EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func& func)
 
85
  static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
99
86
  {
100
87
    return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
101
88
                redux_novec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func));
112
99
 
113
100
  typedef typename Derived::Scalar Scalar;
114
101
 
115
 
  EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func&)
 
102
  static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&)
116
103
  {
117
104
    return mat.coeffByOuterInner(outer, inner);
118
105
  }
125
112
struct redux_novec_unroller<Func, Derived, Start, 0>
126
113
{
127
114
  typedef typename Derived::Scalar Scalar;
128
 
  EIGEN_STRONG_INLINE static Scalar run(const Derived&, const Func&) { return Scalar(); }
 
115
  static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); }
129
116
};
130
117
 
131
118
/*** vectorization ***/
141
128
  typedef typename Derived::Scalar Scalar;
142
129
  typedef typename packet_traits<Scalar>::type PacketScalar;
143
130
 
144
 
  EIGEN_STRONG_INLINE static PacketScalar run(const Derived &mat, const Func& func)
 
131
  static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func)
145
132
  {
146
133
    return func.packetOp(
147
134
            redux_vec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
162
149
  typedef typename Derived::Scalar Scalar;
163
150
  typedef typename packet_traits<Scalar>::type PacketScalar;
164
151
 
165
 
  EIGEN_STRONG_INLINE static PacketScalar run(const Derived &mat, const Func&)
 
152
  static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&)
166
153
  {
167
154
    return mat.template packetByOuterInner<alignment>(outer, inner);
168
155
  }
214
201
    const Index size = mat.size();
215
202
    eigen_assert(size && "you are using an empty matrix");
216
203
    const Index packetSize = packet_traits<Scalar>::size;
217
 
    const Index alignedStart = first_aligned(mat);
 
204
    const Index alignedStart = internal::first_aligned(mat);
218
205
    enum {
219
206
      alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit)
220
207
                ? Aligned : Unaligned
221
208
    };
222
 
    const Index alignedSize = ((size-alignedStart)/packetSize)*packetSize;
223
 
    const Index alignedEnd = alignedStart + alignedSize;
 
209
    const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
 
210
    const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
 
211
    const Index alignedEnd2 = alignedStart + alignedSize2;
 
212
    const Index alignedEnd  = alignedStart + alignedSize;
224
213
    Scalar res;
225
214
    if(alignedSize)
226
215
    {
227
 
      PacketScalar packet_res = mat.template packet<alignment>(alignedStart);
228
 
      for(Index index = alignedStart + packetSize; index < alignedEnd; index += packetSize)
229
 
        packet_res = func.packetOp(packet_res, mat.template packet<alignment>(index));
230
 
      res = func.predux(packet_res);
 
216
      PacketScalar packet_res0 = mat.template packet<alignment>(alignedStart);
 
217
      if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop
 
218
      {
 
219
        PacketScalar packet_res1 = mat.template packet<alignment>(alignedStart+packetSize);
 
220
        for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
 
221
        {
 
222
          packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(index));
 
223
          packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment>(index+packetSize));
 
224
        }
 
225
 
 
226
        packet_res0 = func.packetOp(packet_res0,packet_res1);
 
227
        if(alignedEnd>alignedEnd2)
 
228
          packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(alignedEnd2));
 
229
      }
 
230
      res = func.predux(packet_res0);
231
231
 
232
232
      for(Index index = 0; index < alignedStart; ++index)
233
233
        res = func(res,mat.coeff(index));
296
296
    Size = Derived::SizeAtCompileTime,
297
297
    VectorizedSize = (Size / PacketSize) * PacketSize
298
298
  };
299
 
  EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func)
 
299
  static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func)
300
300
  {
301
301
    eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
302
302
    Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
401
401
  return derived().diagonal().sum();
402
402
}
403
403
 
 
404
} // end namespace Eigen
 
405
 
404
406
#endif // EIGEN_REDUX_H