1 /*******************************************************************************
2 * Copyright 2016-2019 Intel Corporation.
3 *
4 * This software and the related documents are Intel copyrighted  materials,  and
5 * your use of  them is  governed by the  express license  under which  they were
6 * provided to you (License).  Unless the License provides otherwise, you may not
7 * use, modify, copy, publish, distribute,  disclose or transmit this software or
8 * the related documents without Intel's prior written permission.
9 *
10 * This software and the related documents  are provided as  is,  with no express
11 * or implied  warranties,  other  than those  that are  expressly stated  in the
12 * License.
13 *******************************************************************************/
14 
15 #if !defined( __IPP_IW_CORE__ )
16 #define __IPP_IW_CORE__
17 
18 #include "stddef.h" // NULL definition
19 
20 #ifdef ICV_BASE
21 #include "ippicv.h"
22 #else
23 #include "ippcore.h"
24 #endif
25 
26 #include "iw_version.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 // Intel IPP compatibility check
33 #if IPP_VERSION_COMPLEX < IW_MIN_COMPATIBLE_IPP_COMPLEX
34 #define IW_MACRO_TOS(A) #A
35 #define IW_VERSION_ERROR(MAJOR, MINOR, UPDATE) "warning: Unsupported Intel(R) IPP version. Minimal compatible version is " IW_MACRO_TOS(MAJOR)"." IW_MACRO_TOS(MINOR)"." IW_MACRO_TOS(UPDATE)
36 #ifdef _MSC_VER
37 #pragma message(IW_VERSION_ERROR(IW_MIN_COMPATIBLE_IPP_MAJOR, IW_MIN_COMPATIBLE_IPP_MINOR, IW_MIN_COMPATIBLE_IPP_UPDATE))
38 #else
39 #warning IW_VERSION_ERROR
40 #endif
41 #endif
42 
43 /* /////////////////////////////////////////////////////////////////////////////
44 //                   Base IW definitions
45 ///////////////////////////////////////////////////////////////////////////// */
46 
47 // Redefine calling convention for older Intel IPP packages
48 #ifndef IPP_STDCALL
49 #define IPP_STDCALL __STDCALL
50 #endif
51 
52 // Default library linkage
53 #if !defined( _IPP_NO_DEFAULT_LIB ) && !defined( _IW_NO_DEFAULT_LIB )
54   #if defined( _IPP_SEQUENTIAL_DYNAMIC )
55     #pragma comment( lib, __FILE__ "/../../../lib/" _INTEL_PLATFORM "ipp_iw" )
56   #elif defined( _IPP_SEQUENTIAL_STATIC )
57     #pragma comment( lib, __FILE__ "/../../../lib/" _INTEL_PLATFORM "ipp_iw" )
58   #elif defined( _IPP_PARALLEL_DYNAMIC )
59     #pragma comment( lib, __FILE__ "/../../../lib/" _INTEL_PLATFORM "ipp_iw" )
60   #elif defined( _IPP_PARALLEL_STATIC )
61     #pragma comment( lib, __FILE__ "/../../../lib/" _INTEL_PLATFORM "ipp_iw" )
62   #endif
63 #endif
64 
65 // Common IW API declaration macro
66 #if defined IW_BUILD_DLL
67 #if defined _WIN32
68 #define IW_DECL(RET_TYPE) __declspec(dllexport) RET_TYPE IPP_STDCALL
69 #else
70 #define IW_DECL(RET_TYPE) RET_TYPE IPP_STDCALL
71 #endif
72 #else
73 #define IW_DECL(RET_TYPE) RET_TYPE IPP_STDCALL
74 #endif
75 
76 #ifdef _MSC_VER
77 #define IW_INLINE __inline
78 #else
79 #define IW_INLINE inline
80 #endif
81 
82 #define IwValueMin (-IPP_MAXABS_64F)
83 #define IwValueMax (IPP_MAXABS_64F)
84 
85 typedef IppSizeL IwSize;
86 
87 // Extended status declaration
88 #define iwStsErr                   -100000          // Extended errors offset
89 #define iwStsWrn                    100000          // Extended warnings offset
90 
91 #define iwStsBorderNegSizeErr       iwStsErr-1      // Negative border size values are not allowed
92 
93 
94 // Transform direction enumerator
95 typedef enum _IwTransDirection
96 {
97     iwTransForward = 0,
98     iwTransInverse = 1
99 } IwTransDirection;
100 
101 // CPUID helpers for ippSetCpuFeatures
102 #define iwCPU_SSE2          ippCPUID_MMX|ippCPUID_SSE|ippCPUID_SSE2
103 #define iwCPU_SSE3          iwCPU_SSE2|ippCPUID_SSE3
104 #define iwCPU_SSSE3         iwCPU_SSE3|ippCPUID_SSSE3
105 #define iwCPU_SSSE3_Atom    iwCPU_SSSE3|ippCPUID_MOVBE
106 #define iwCPU_SSE41         iwCPU_SSSE3|ippCPUID_SSE41
107 #define iwCPU_SSE42         iwCPU_SSE41|ippCPUID_SSE42|ippCPUID_AES
108 #define iwCPU_SSE42_Atom    iwCPU_SSE42|ippCPUID_AES|ippCPUID_CLMUL|ippCPUID_MOVBE|ippCPUID_SHA
109 #define iwCPU_AVX           iwCPU_SSE42|ippCPUID_AVX|ippCPUID_CLMUL|ippCPUID_RDRAND|ippCPUID_F16C
110 #if IPP_VERSION_COMPLEX >= 20170003
111 #define iwCPU_AVX2          iwCPU_AVX|ippCPUID_AVX2|ippCPUID_ADCOX|ippCPUID_RDSEED|ippCPUID_PREFETCHW|ippCPUID_MOVBE|ippCPUID_MPX
112 #else
113 #define iwCPU_AVX2          iwCPU_AVX|ippCPUID_AVX2|ippCPUID_ADCOX|ippCPUID_RDSEED|ippCPUID_PREFETCHW|ippCPUID_MOVBE
114 #endif
115 #define iwCPU_AVX512        iwCPU_AVX2|ippCPUID_AVX512F|ippCPUID_AVX512CD|\
116                             ippCPUID_AVX512VL|ippCPUID_AVX512BW|ippCPUID_AVX512DQ
117 #define iwCPU_AVX512_KNL    iwCPU_SSE42_Atom|ippCPUID_AVX|ippCPUID_AVX2|\
118                             ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512PF|ippCPUID_AVX512ER
119 
120 
121 /* /////////////////////////////////////////////////////////////////////////////
122 //                   Base IW utility functions
123 ///////////////////////////////////////////////////////////////////////////// */
124 
125 // Convert IppDataType to actual size in bytes
126 // Returns:
127 //      Size of IppDataType in bytes
128 IW_DECL(int) iwTypeToSize(
129     IppDataType type    // Data type
130 );
131 
132 // Returns 1 if data type is of float type and 0 otherwise
133 // Returns:
134 //      Float flag
135 IW_DECL(int) iwTypeIsFloat(
136     IppDataType type    // Data type
137 );
138 
139 // Returns 1 if data type is of signed type and 0 otherwise
140 // Returns:
141 //      Signed flag
142 IW_DECL(int) iwTypeIsSigned(
143     IppDataType type    // Data type
144 );
145 
146 // Returns minimum possible value for specified data type
147 // Returns:
148 //      Minimum value
149 IW_DECL(double) iwTypeGetMin(
150     IppDataType type    // Data type for min value
151 );
152 
153 // Returns maximum possible value for specified data type
154 // Returns:
155 //      Maximum value
156 IW_DECL(double) iwTypeGetMax(
157     IppDataType type    // Data type for max value
158 );
159 
160 // Returns values range for specified data type
161 // Returns:
162 //      Range value
163 IW_DECL(double) iwTypeGetRange(
164     IppDataType type    // Data type for range value
165 );
166 
167 // Cast double value to input type with rounding and saturation
168 // Returns:
169 //      Rounded and saturated value
170 IW_DECL(double) iwValueSaturate(
171     double      val,    // Input value
172     IppDataType dstType // Data type for saturation range
173 );
174 
175 // Converts relative value in range of [0,1] to the absolute value according to specified type
176 // Returns:
177 //      Absolute value
178 IW_DECL(double) iwValueRelToAbs(
179     double      val,    // Relative value. From 0 to 1
180     IppDataType type    // Data type for the absolute range
181 );
182 
183 // Converts absolute value in range of the given type to the relative value in range [0,1]
184 // Returns:
185 //      Relative value
186 IW_DECL(double) iwValueAbsToRel(
187     double      val,    // Absolute value
188     IppDataType type    // Data type for the absolute range
189 );
190 
191 // Returns relative weight disproportion of signed range, by adjusting to which middle of the signed range will be at 0 value
192 // Returns:
193 //      Relative correction value
194 IW_DECL(double) iwRangeWeightCorrector(
195     IppDataType type    // Data type for the absolute range
196 );
197 
198 
199 /* /////////////////////////////////////////////////////////////////////////////
200 //                   IW with Threading Layer control
201 ///////////////////////////////////////////////////////////////////////////// */
202 
203 // This function sets number of threads for IW functions with parallel execution support
204 IW_DECL(void) iwSetThreadsNum(
205     int threads     // Number of threads to use
206 );
207 
208 // This function returns number of threads used by IW functions with parallel execution support
209 // Returns:
210 //      Number of threads or 0 if compiled without internal threading support
211 IW_DECL(int)  iwGetThreadsNum(void);
212 
213 // This function returns initial number of threads used by IW functions with parallel execution support
214 // Returns:
215 //      Default number of threads or 0 if compiled without internal threading support
216 IW_DECL(int)  iwGetThreadsNumDefault(void);
217 
218 
219 /* /////////////////////////////////////////////////////////////////////////////
220 //                   IwAtomic - Atomic operations layer
221 ///////////////////////////////////////////////////////////////////////////// */
222 
223 // This function performs thread safe addition operation on integer variable.
224 // Returns:
225 //      Value of the variable before the operation
226 IW_DECL(int) iwAtomic_AddInt(int *pInt, int delta);
227 
228 /* /////////////////////////////////////////////////////////////////////////////
229 //                   IwTls - TLS data storage interface
230 ///////////////////////////////////////////////////////////////////////////// */
231 typedef void (IPP_STDCALL *IwTlsDestructor)(void*); // Pointer to destructor function for TLS object
232 
233 // TLS abstraction layer structure
234 // This API can help with threading of IW functions by allowing easy platform-independent per-thread data storage and initialization
235 typedef struct _IwTls
236 {
237     IwTlsDestructor m_desctuctor;  // Pointer to destruction function
238     size_t          m_idx;         // Internal TLS index
239     void           *m_pTlsStorage; // TLS object
240 } IwTls;
241 
242 // This function initializes TLS structure, reserves TLS index and assign destruction function if necessary.
243 // Destruction function is required to properly deallocate user object for every thread.
244 // Returns:
245 //      ippStsErr                           internal TLS error
246 //      ippStsNullPtrErr                    unexpected NULL pointer
247 //      ippStsNoErr                         no errors
248 IW_DECL(IppStatus) iwTls_Init(
249     IwTls          *pTls,       // Pointer to IwTls structure
250     IwTlsDestructor destructor  // Pointer to object destruction function
251 );
252 
253 // Writes pointer to object into TLS storage for current thread. If data already exist IwTlsDestructor will be called first.
254 // Returns:
255 //      ippStsErr                           internal TLS error
256 //      ippStsNullPtrErr                    unexpected NULL pointer
257 //      ippStsNoErr                         no errors
258 IW_DECL(IppStatus) iwTls_Set(
259     IwTls *pTls, // Pointer to IwTls structure
260     void  *pData // Pointer to user object
261 );
262 
263 // Tries to get pointer to object from TLS storage for current thread.
264 // If no object has been yet created for current thread it returns NULL.
265 // Returns:
266 //      Pointer to stored data for current thread or NULL if no data was stored
267 IW_DECL(void*)     iwTls_Get(
268     const IwTls *pTls // Pointer to IwTls structure
269 );
270 
271 // Releases data for all threads, but not TLS object itself.
272 // Internal object data for different threads can be released here automatically only if IwTlsDestructor pointer was initialized
273 // Returns:
274 //      ippStsErr                           internal TLS error
275 //      ippStsNullPtrErr                    unexpected NULL pointer
276 //      ippStsNoErr                         no errors
277 IW_DECL(IppStatus) iwTls_ReleaseData(
278     IwTls *pTls // Pointer to IwTls structure
279 );
280 
281 // Releases TLS object and all data associated with it for all threads.
282 // Internal object data for different threads can be released here automatically only if IwTlsDestructor pointer was initialized
283 // Returns:
284 //      ippStsErr                           internal TLS error
285 //      ippStsNullPtrErr                    unexpected NULL pointer
286 //      ippStsNoErr                         no errors
287 IW_DECL(IppStatus) iwTls_Release(
288     IwTls *pTls // Pointer to IwTls structure
289 );
290 
291 /* /////////////////////////////////////////////////////////////////////////////
292 //                   IW version info
293 ///////////////////////////////////////////////////////////////////////////// */
294 
295 // IW version structure
296 typedef struct _IwVersion
297 {
298     const IppLibraryVersion *m_pIppVersion;   // Pointer to version structure with version of linked Intel IPP library
299 
300     int         m_major;
301     int         m_minor;
302     int         m_update;
303     const char* m_versionStr;
304     int         m_bUserBuild;   // Manual build flag. Must be false for prebuilt library and true for custom user build
305 } IwVersion;
306 
307 // Writes version information in IwVersion structure
308 IW_DECL(void) iwGetLibVersion(
309     IwVersion *pVersion // Pointer to IwVersion structure
310 );
311 
312 /* /////////////////////////////////////////////////////////////////////////////
313 //                   IW status
314 ///////////////////////////////////////////////////////////////////////////// */
315 
316 // Convert the library status code to a readable string
317 // This function supports extended status codes used in IW on top the of regular Intel IPP codes
318 // Returns:
319 //      Pointer to constant string describing the library status code
320 IW_DECL(const char*) iwGetStatusString(
321     IppStatus status    // Library status code
322 );
323 
324 #ifdef __cplusplus
325 }
326 #endif
327 
328 #endif
329