SMIL  1.0.4
DBaseLineOperations.hpp
1 /*
2  * Copyright (c) 2011-2016, Matthieu FAESSEL and ARMINES
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 #ifndef _BASE_LINE_OPERATIONS_HPP
31 #define _BASE_LINE_OPERATIONS_HPP
32 
33 
34 #include "Core/include/private/DImage.hpp"
35 
36 
37 namespace smil
38 {
39 
40  template <class T> class Image;
41 
42 
43  // Base abstract struct of line unary function
44  template <class T, class T_out=T>
46  {
47  typedef Image<T> imageInType;
48  typedef typename imageInType::restrictLineType lineInType;
49  typedef typename imageInType::sliceType sliceInType;
50 
51  typedef Image<T_out> imageOutType;
52  typedef typename imageOutType::restrictLineType lineOutType;
53  typedef typename imageOutType::sliceType sliceOutType;
54 
55  typedef lineInType lineType;
56 
58  unaryLineFunctionBase(const lineInType lineIn, const size_t size, lineOutType lineOut)
59  {
60  this->_exec(lineIn, size, lineOut);
61  }
62  virtual ~unaryLineFunctionBase() {}
63 
64  virtual void _exec(const lineInType, const size_t, lineOutType) = 0;
65  virtual void _exec_aligned(const lineInType lineIn, const size_t size, lineOutType lineOut) { _exec(lineIn, size, lineOut); }
66  virtual void _exec(lineOutType, const size_t, const T_out) {}
67  virtual void _exec_aligned(lineOutType lineOut, const size_t size, T_out value) { _exec(lineOut, size, value); }
68  inline void operator()(const lineInType lineIn, const size_t size, lineOutType lineOut)
69  {
70  unsigned long ptrOffset1 = ImDtTypes<T>::ptrOffset(lineIn);
71  unsigned long ptrOffset2 = ImDtTypes<T_out>::ptrOffset(lineOut);
72 
73  // both aligned
74  if (!ptrOffset1 && !ptrOffset2)
75  {
76  _exec_aligned(lineIn, size, lineOut);
77  }
78  // both misaligned but with same misalignment
79  else if (ptrOffset1==ptrOffset2)
80  {
81  unsigned long misAlignSize = SIMD_VEC_SIZE - ptrOffset1;
82  _exec(lineIn, misAlignSize, lineOut);
83  _exec_aligned(lineIn+misAlignSize, size-misAlignSize, lineOut+misAlignSize);
84  }
85  // both misaligned with different misalignments
86  else
87  {
88  _exec(lineIn, size, lineOut);
89  }
90  }
91  inline void operator()(const lineInType lineIn, const size_t size, T_out value)
92  {
93  if (size<SIMD_VEC_SIZE)
94  {
95  _exec(lineIn, size, value);
96  return;
97  }
98  size_t ptrOffset = ImDtTypes<T>::ptrOffset(lineIn);
99  size_t misAlignSize = ptrOffset==0 ? 0 : SIMD_VEC_SIZE - ptrOffset;
100  if (misAlignSize)
101  _exec(lineIn, misAlignSize, value);
102  _exec_aligned(lineIn+misAlignSize, size-misAlignSize, value);
103  }
104  };
105 
106 
107  // Base abstract struct of line binary function
108  template <class T1, class T2=T1, class T_out=T1>
110  {
111  virtual ~binaryLineFunctionBase() {}
112  typedef typename Image<T1>::restrictLineType lineType1;
113  typedef typename Image<T2>::restrictLineType lineType2;
114  typedef typename Image<T_out>::restrictLineType lineOutType;
115  typedef lineType1 lineType;
116 
117  typedef typename Image<T1>::sliceType sliceType;
118 
119  virtual void _exec(const lineType1, const lineType2, const size_t, lineOutType) = 0;
120  virtual void _exec_aligned(const lineType1 lineIn1, const lineType2 lineIn2, const size_t size, lineOutType lineOut) { _exec(lineIn1, lineIn2, size, lineOut); }
121  inline void operator()(const lineType1 lineIn1, const lineType2 lineIn2, const size_t size, lineOutType lineOut)
122  {
123  return _exec(lineIn1, lineIn2, size, lineOut);
124  if (size<SIMD_VEC_SIZE)
125  {
126  _exec(lineIn1, lineIn2, size, lineOut);
127  return;
128  }
129  size_t ptrOffset1 = ImDtTypes<T1>::ptrOffset(lineIn1);
130  size_t ptrOffset2 = ImDtTypes<T2>::ptrOffset(lineIn2);
131  size_t ptrOffset3 = ImDtTypes<T_out>::ptrOffset(lineOut);
132 
133  // all aligned
134  if (!ptrOffset1 && !ptrOffset2 && !ptrOffset3)
135  {
136  _exec_aligned(lineIn1, lineIn2, size, lineOut);
137  }
138  // all misaligned but with same misalignment
139  else if (ptrOffset1==ptrOffset2 && ptrOffset2==ptrOffset3)
140  {
141  size_t misAlignSize = SIMD_VEC_SIZE - ptrOffset1;
142  _exec(lineIn1, lineIn2, misAlignSize, lineOut);
143  _exec_aligned(lineIn1+misAlignSize, lineIn2+misAlignSize, size-misAlignSize, lineOut+misAlignSize);
144  }
145  // all misaligned with different misalignments
146  else
147  {
148  _exec(lineIn1, lineIn2, size, lineOut);
149  }
150 
151  }
152  inline void operator()(const lineType1 lineIn1, const T2 value, const size_t size, lineOutType lineOut)
153  {
154  if (size<SIMD_VEC_SIZE)
155  {
156  _exec(lineIn1, value, size, lineOut);
157  return;
158  }
159  unsigned long ptrOffset1 = ImDtTypes<T1>::ptrOffset(lineIn1);
160  unsigned long ptrOffset2 = ImDtTypes<T2>::ptrOffset(lineOut);
161 
162  // all aligned
163  if (!ptrOffset1 && !ptrOffset2)
164  {
165  _exec_aligned(lineIn1, value, size, lineOut);
166  }
167  // all misaligned but with same misalignment
168  else if (ptrOffset1==ptrOffset2)
169  {
170  unsigned long misAlignSize = SIMD_VEC_SIZE - ptrOffset1;
171  _exec(lineIn1, value, misAlignSize, lineOut);
172  _exec_aligned(lineIn1+misAlignSize, value, size-misAlignSize, lineOut+misAlignSize);
173  }
174  // all misaligned with different misalignments
175  else
176  {
177  _exec(lineIn1, value, size, lineOut);
178  }
179 
180  }
181  };
182 
183 
184  // Base abstract struct of line binary function
185  template <class T1, class T2=T1, class T3=T1, class T_out=T1>
187  {
188  virtual ~tertiaryLineFunctionBase() {}
189  typedef typename Image<T1>::restrictLineType lineType1;
190  typedef typename Image<T2>::restrictLineType lineType2;
191  typedef typename Image<T3>::restrictLineType lineType3;
192  typedef typename Image<T_out>::restrictLineType lineOutType;
193  typedef lineType1 lineType;
194 
195  virtual void _exec(const lineType1 /*lineIn1*/, const lineType2 /*lineIn2*/, const lineType3 /*lineIn3*/, const size_t /*size*/, lineOutType /*lineOut*/) = 0;
196  virtual void _exec_aligned(const lineType1 lineIn1, const lineType2 lineIn2, const lineType3 lineIn3, const size_t size, lineOutType lineOut) { _exec(lineIn1, lineIn2, lineIn3, size, lineOut); }
197  virtual void operator()(const lineType1 lineIn1, const lineType2 lineIn2, const lineType3 lineIn3, const size_t size, lineOutType lineOut)
198  {
199  if (size<SIMD_VEC_SIZE)
200  {
201  _exec(lineIn1, lineIn2, lineIn3, size, lineOut);
202  return;
203  }
204  unsigned long ptrOffset1 = ImDtTypes<T1>::ptrOffset(lineIn1);
205  unsigned long ptrOffset2 = ImDtTypes<T2>::ptrOffset(lineIn2);
206  unsigned long ptrOffset3 = ImDtTypes<T3>::ptrOffset(lineIn3);
207  unsigned long ptrOffset4 = ImDtTypes<T_out>::ptrOffset(lineOut);
208 
209  // all aligned
210  if (!ptrOffset1 && !ptrOffset2 && !ptrOffset3 && !ptrOffset4)
211  {
212  _exec_aligned(lineIn1, lineIn2, lineIn3, size, lineOut);
213  }
214  // all misaligned but with same misalignment
215  else if (ptrOffset1==ptrOffset2 && ptrOffset2==ptrOffset3)
216  {
217  size_t misAlignSize = SIMD_VEC_SIZE - ptrOffset1;
218  _exec(lineIn1, lineIn2, lineIn3, misAlignSize, lineOut);
219  _exec_aligned(lineIn1+misAlignSize, lineIn2+misAlignSize, lineIn3+misAlignSize, size-misAlignSize, lineOut+misAlignSize);
220  }
221  // all misaligned with different misalignments
222  else
223  {
224  _exec(lineIn1, lineIn2, lineIn3, size, lineOut);
225  }
226  }
227  };
228 
229 } // namespace smil
230 
231 
232 
233 
234 #endif
Main Image class.
Definition: DImage.hpp:57
Definition: DTypes.hpp:88
Definition: DBaseLineOperations.hpp:110
Definition: DBaseLineOperations.hpp:187
Definition: DBaseLineOperations.hpp:46