1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        Pattern.h
4  * Description:  Pattern Header
5  *
6  * $Date:        20. June 2019
7  * $Revision:    V1.0.0
8  *
9  * Target Processor: Cortex-M cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
16  * Licensed under the Apache License, Version 2.0 (the License); you may
17  * not use this file except in compliance with the License.
18  * You may obtain a copy of the License at
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28 #ifndef _PATTERN_H_
29 #define _PATTERN_H_
30 
31 #include "Test.h"
32 #include "Pattern.h"
33 #include "arm_math_types.h"
34 #include "arm_math_types_f16.h"
35 
36 namespace Client {
37 
38 template <typename T>
39 T *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples=MAX_NB_SAMPLES)
40 {
41     (void)id;
42     (void)mgr;
43     (void)nb;
44     (void)maxSamples;
45     return(NULL);
46 };
47 
48 template <>
49 float64_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
50 
51 template <>
52 float32_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
53 
54 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
55 template <>
56 float16_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
57 #endif
58 
59 template <>
60 q63_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
61 
62 template <>
63 q31_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
64 
65 template <>
66 q15_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
67 
68 template <>
69 q7_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
70 
71 template <>
72 uint64_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
73 
74 template <>
75 uint32_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
76 
77 template <>
78 uint16_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
79 
80 template <>
81 uint8_t *loadPattern(Testing::PatternID_t id, PatternMgr *mgr,Testing::nbSamples_t &nb, Testing::nbSamples_t maxSamples);
82 
83 template <typename T>
localPattern(Testing::nbSamples_t id,PatternMgr * mgr)84 T *localPattern(Testing::nbSamples_t id, PatternMgr *mgr)
85 {
86     (void)id;
87     (void)mgr;
88     return(NULL);
89 };
90 
91 template <>
92 float64_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
93 
94 template <>
95 float32_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
96 
97 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
98 template <>
99 float16_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
100 #endif
101 
102 template <>
103 q63_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
104 
105 template <>
106 q31_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
107 
108 template <>
109 q15_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
110 
111 template <>
112 q7_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
113 
114 template <>
115 uint64_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
116 
117 template <>
118 uint32_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
119 
120 template <>
121 uint16_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
122 
123 template <>
124 uint8_t *localPattern(Testing::nbSamples_t nb, PatternMgr *mgr);
125 
126 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t nb,float64_t* data,PatternMgr *mgr);
127 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,float32_t*,PatternMgr *);
128 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
129 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,float16_t*,PatternMgr *);
130 #endif
131 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q63_t*,PatternMgr *);
132 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q31_t*,PatternMgr *);
133 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q15_t*,PatternMgr *);
134 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,q7_t*,PatternMgr *);
135 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint64_t*,PatternMgr *);
136 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint32_t*,PatternMgr *);
137 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint16_t*,PatternMgr *);
138 extern void dumpPattern(Testing::outputID_t id,Testing::nbSamples_t,uint8_t*,PatternMgr *);
139 
140 
141 
142 template <class T>
143 class AnyPattern {
144     protected:
145        // Pattern data
146        T *data;
147        // To know if the pattern has loaded any data
148        bool isLoaded;
149        // Memory generation when the data was loaded.
150        // If memory generation is different when accessing the data
151        // the pattern should return NULL.
152        unsigned long currentGen;
153        PatternMgr *m_mgr;
154        // Nb of samples in the loaded pattern
155        Testing::nbSamples_t m_nbSamples;
156     public:
AnyPattern()157        AnyPattern()
158        {
159             this->data = NULL;
160             this->isLoaded = false;
161             this->currentGen = 0;
162             this->m_mgr=NULL;
163             this->m_nbSamples = 0;
164        }
165 
isTailEmpty()166        bool isTailEmpty()
167        {
168           if (m_mgr)
169           {
170              return(m_mgr->IsTailEmpty((char*)this->ptr(),this->nbSamples()*sizeof(T)));
171           }
172           else
173           {
174             return(true);
175           }
176        }
177 
178        /** Get pointer to the pattern data.
179 
180            Pointer is NULL in following conditions:
181              Memory generation of pattern is different from memory manager's one
182              Pattern not loaded
183              Number of samples i 0
184 
185        */
ptr()186        T *ptr()
187        {
188            if (this->m_mgr == NULL)
189            {
190               return(NULL);
191            }
192 
193            if (this->currentGen != this->m_mgr->generation())
194            {
195               return(NULL);
196            }
197            else
198            {
199               if (this->isLoaded)
200               {
201                  if (this->m_nbSamples > 0)
202                  {
203                    return(this->data);
204                  }
205                  else
206                  {
207                    return(NULL);
208                  }
209               }
210               else
211               {
212                  return(NULL);
213               }
214            }
215        }
216 
nbSamples()217        Testing::nbSamples_t nbSamples()
218        {
219           if (this->m_mgr == NULL)
220           {
221             return(0);
222           }
223 
224           if (this->currentGen != this->m_mgr->generation())
225           {
226               return(0);
227           }
228           if (this->isLoaded)
229           {
230              return(this->m_nbSamples);
231           }
232           else
233           {
234             return(0);
235           }
236        }
237 
238 };
239 
240 /** An input pattern
241 
242 */
243 template <class T>
244 class Pattern : public AnyPattern<T>{
245     private:
246        Testing::PatternID_t m_id;
247     public:
Pattern()248        Pattern()
249        {
250        }
251 
252        /** Reload fresh data for the pattern.
253 
254            If memory manager has not released its memory,
255            reloading an already loaded pattern will leak some memory
256            since the previous pattern will still be allocated
257            in the memory manager.
258 
259            Generally this reload is used in setUp function of tests.
260            The memory being released in the tearDown function.
261 
262        */
263        void reload(Testing::PatternID_t id,PatternMgr *mgr, Testing::nbSamples_t maxSamples=0)
264        {
265            Testing::nbSamples_t nbSamples;
266            this->m_id = id;
267            this->m_mgr=mgr;
268            this->currentGen = this->m_mgr->generation();
269            this->data = loadPattern<T>(this->m_id,this->m_mgr,nbSamples,maxSamples);
270            // Initialize the field with the number of samples read
271            // (which may have been constrained with maxSamples)
272            this->m_nbSamples = nbSamples;
273            this->isLoaded = true;
274        }
275 };
276 
277 /** An reference pattern
278 
279     The difference with input pattern is that reference
280     patterns are not loaded in dump mode and are not wasting
281     memory.
282 
283 */
284 template <class T>
285 class RefPattern : public AnyPattern<T>{
286     private:
287        Testing::PatternID_t m_id;
288     public:
RefPattern()289        RefPattern()
290        {
291        }
292        void reload(Testing::PatternID_t id,PatternMgr *mgr, Testing::nbSamples_t maxSamples=0)
293        {
294            Testing::nbSamples_t nbSamples;
295            this->m_id = id;
296            this->m_mgr=mgr;
297            this->currentGen = this->m_mgr->generation();
298            // Reference patterns are not loaded in dump mode
299            if (this->m_mgr->runningMode() != Testing::kDumpOnly)
300            {
301              this->data = loadPattern<T>(this->m_id,this->m_mgr,nbSamples,maxSamples);
302              this->m_nbSamples = nbSamples;
303              this->isLoaded = true;
304            }
305            else
306            {
307              this->data=NULL;
308              this->m_nbSamples = 0;
309              this->isLoaded = false;
310            }
311        }
312 };
313 
314 /** A local pattern is to be used for an output.
315     It is the only way for the test to allocate memory in the
316     memory manager.
317 
318     Local patterns can be dumped.
319 
320     A local pattern is not dumped when in test mode.
321 
322 */
323 template <class T>
324 class LocalPattern : public AnyPattern<T>{
325     private:
326        Testing::outputID_t m_id;
327     public:
LocalPattern()328        LocalPattern()
329        {
330        }
create(Testing::nbSamples_t nbSamples,Testing::outputID_t id,PatternMgr * mgr)331        void create(Testing::nbSamples_t nbSamples,Testing::outputID_t id,PatternMgr *mgr)
332        {
333            this->m_nbSamples = nbSamples;
334            this->m_mgr=mgr;
335            this->m_id=id;
336            this->currentGen = this->m_mgr->generation();
337            this->data = localPattern<T>(nbSamples,this->m_mgr);
338            this->isLoaded = true;
339        }
340 
dump(PatternMgr * mgr)341        void dump(PatternMgr *mgr)
342        {
343            (void)mgr;
344            /*
345 
346            If the pattern has never been created then m_mgr is NULL.
347 
348            */
349            if (this->m_mgr != NULL)
350            {
351               if (this->m_mgr->runningMode() != Testing::kTestOnly)
352               {
353                  if ((this->ptr() != NULL) && (this->nbSamples() > 0))
354                  {
355                     dumpPattern(this->m_id,this->m_nbSamples,this->data,this->m_mgr);
356                  }
357               }
358            }
359        }
360 };
361 
362 
363 }
364 
365 #endif
366