source: trunk/lib_ir/utility.h @ 3909

Last change on this file since 3909 was 3909, checked in by linmengl, 5 years ago

initial commit of lib_ir

File size: 6.9 KB
Line 
1#include "bitblock.hpp"
2#define USE_SSE
3typedef __m128i SIMD_type;
4#include <vector>
5#include <iostream>
6#include <sstream>
7#include <string>
8#include <cstring>
9#include <cstdio>
10#include <cstdlib>
11#include <stdint.h>
12
13//#define BUFFER_PROFILING 1
14
15//#include "perfsec.h"
16
17using namespace std;
18
19//#ifdef BUFFER_PROFILING
20//      BOM_Table * parser_timer;
21//#endif
22
23char strBuf[10000];
24vector< vector<string> > ReadTestData(const char *inFile)
25{
26        vector< vector<string> > data;
27
28        FILE *ifp = fopen(inFile, "r");
29
30        if(ifp==NULL)
31        {
32                printf("%s can't be read", inFile);
33                fclose(ifp);
34                return data;
35        }
36
37        while(fgets(strBuf, 10000, ifp))
38        {
39                int n = strlen(strBuf);
40                vector<string> tuple;
41                string s = "";
42                //char buf[1024];
43                //cout << "line:===\n";
44                for(int i=0; i<n; i++)
45                {
46                        //fscanf(ifp, "%s", buf);
47                        //string s = buf;
48                        if(strBuf[i] == ' ')
49                        {
50                                if(s!="")
51                                        tuple.push_back(s);
52                                s = "";
53                        }
54                        else s = s + strBuf[i];
55                        //cout << s << " ";
56                }
57                //cout << endl;
58                data.push_back(tuple);
59        }
60        fclose(ifp);
61        return data;
62}
63
64void WriteResult(const char *outFile, vector<string> strs)
65{
66        FILE *ifp = fopen(outFile, "w");
67        int i, sz = strs.size();
68        for(i=0; i<sz; i++)
69        {
70                fprintf(ifp, "%s\n", strs[i].c_str());
71        }
72        fclose(ifp);
73}
74
75int BitString2Int(string s)
76{
77        int sz = 32;
78        int ans = 0;
79        for(int i=0; i<sz; i++) if(s[i]=='1')
80        {
81                ans += (1 << (sz-i-1));
82        }
83        return ans;
84}
85
86uint64_t DigitString2Int(string s)
87{
88    int i, sz = s.length();
89    uint64_t x = 0;
90    for(i=0; i<sz; i++)
91    {
92        x = x * (uint64_t)10 + (uint64_t)(s[i] - '0');
93    }
94    return x;
95}
96
97string Int2BitString(int x)
98{
99        string ans = "";
100        int sz = 32;
101        for(int i=sz-1; i>=0; i--)
102        {
103                if((1<<i)&x) ans = ans + "1";
104                else ans = ans + "0";
105        }
106        return ans;
107}
108
109string Int2String(uint64_t x)
110{
111        stringstream stm;
112        stm << x;
113        string rslt = stm.str();
114        return rslt;
115}
116
117//opt <=> instruction set
118// 0  <=> MMX(64)
119// 1  <=> SSE(128)
120// 2  <=> AVX(256)
121// 3  <=> NEON(128)
122SIMD_type LoadfromString(string s, int opt)
123{
124        int regSize = 0;
125        SIMD_type ans;
126        switch(opt)
127        {
128                case 0:
129                        break;
130                case 1:
131{
132                        int buf[4];
133                        regSize = 128;
134
135                        /*
136                        //big endian
137                        for(int i=0; i<regSize; i+=32)
138                        {
139                                buf[i/32] = BitString2Int(s.substr(i, 32));
140                                //cout << buf[i/32] << " ";
141                        }
142                        */
143
144                        //little endian
145                        for(int i=0; i<regSize; i+=32)
146                        {
147                                buf[3-i/32] = BitString2Int(s.substr(i, 32));
148                        }
149                        //cout << endl;
150#ifdef USE_SSE
151                        ans = _mm_loadu_si128((SIMD_type *)buf);
152#else
153                        ans = bitblock::load_unaligned((SIMD_type *)buf);
154#endif
155}
156                        break;
157                case 2:
158{
159                        int buf[8];
160                        regSize = 256;
161
162                        for(int i=0; i<regSize; i+=32)
163                        {
164                                buf[7-i/32] = BitString2Int(s.substr(i, 32));
165                        }
166
167#ifdef USE_AVX
168                        __m128i ans1 = _mm_loadu_si128((__m128i *)(buf+4));//high part
169                        __m128i ans2 = _mm_loadu_si128((__m128i *)(buf));//low part
170
171                        ans = _mm256_insertf128_ps(_mm256_castps128_ps256((__m128) ans2), (__m128) ans1, 1);
172#endif
173
174#ifdef USE_AVX2
175                        ans = _mm256_loadu_si256((__m256i *)(buf));
176#endif
177}
178                        break;
179                case 3:
180{
181#ifdef USE_NEON
182                        int buf[4];
183                        regSize = 128;
184
185                        /*
186                        //big endian
187                        for(int i=0; i<regSize; i+=32)
188                        {
189                                buf[i/32] = BitString2Int(s.substr(i, 32));
190                                //cout << buf[i/32] << " ";
191                        }
192                        */
193
194                        //little endian
195                        for(int i=0; i<regSize; i+=32)
196                        {
197                                buf[3-i/32] = BitString2Int(s.substr(i, 32));
198                        }
199                        //cout << endl;
200                        ans = vld1q_u64((uint64_t const *) buf);
201#endif
202}
203                        break;
204                default:
205                        cerr << "LoadfromString Invalid opt code! Get opt code = " << opt << endl;
206                        break;
207        }
208        return ans;
209}
210
211//opt <=> instruction set
212// 0  <=> MMX(64)
213// 1  <=> SSE(128)
214// 2  <=> AVX(256)
215// 3  <=> NEON(128)
216SIMD_type LoadfromInt(int x, int opt)
217{
218        int regSize = 0;
219        SIMD_type ans;
220
221        switch(opt)
222        {
223                case 0:
224                        break;
225                case 1:
226{
227                        int buf[4];
228
229                        buf[0] = buf[1] = buf[2] = buf[3] = x;
230
231#ifdef USE_SSE
232                        ans = _mm_loadu_si128((SIMD_type *)buf);
233#else
234                        ans = bitblock::load_unaligned((SIMD_type *)buf);
235#endif
236}
237                        break;
238                case 2:
239{
240                        int buf[8];
241                        regSize = 256;
242
243                        buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = buf[7] = x;
244
245#ifdef USE_AVX
246                        __m128i ans1 = _mm_loadu_si128((__m128i *)(buf+4));//high part
247                        __m128i ans2 = _mm_loadu_si128((__m128i *)(buf));//low part
248
249                        ans = _mm256_insertf128_ps(_mm256_castps128_ps256((__m128) ans2), (__m128) ans1, 1);
250#endif
251
252#ifdef USE_AVX2
253                        ans = _mm256_loadu_si256((__m256i *)(buf));
254#endif
255}
256                        break;
257                case 3:
258{
259#ifdef USE_NEON
260                        int buf[4];
261
262                        buf[0] = buf[1] = buf[2] = buf[3] = x;
263
264                        ans = vld1q_u64((uint64_t const *) buf);
265#endif
266}
267                        break;
268                default:
269                        cerr << "LoadfromInt Invalid opt code! Get opt code = " << opt << endl;
270                        break;
271        }
272        return ans;
273}
274
275//opt <=> instruction set
276// 0  <=> MMX(64)
277// 1  <=> SSE(128)
278// 2  <=> AVX(256)
279// 3  <=> NEON(128)
280string Store2String(SIMD_type v, int opt)
281{
282        string ans = "";
283        switch(opt)
284        {
285                case 0:
286                        break;
287                case 1:
288{
289                        int buf[4];
290#ifdef USE_SSE
291                        _mm_storeu_si128((SIMD_type *)buf, v);
292#else
293                        bitblock::store_unaligned(v, (SIMD_type *)buf);
294#endif
295                        /*
296                        //big endian
297                        for(int i=0; i<4; i++)
298                        {
299                                ans = ans + Int2BitString(buf[i]);
300                        }
301                        */
302                        //little endian
303                        for(int i=3; i>=0; i--)
304                        {
305                                ans = ans + Int2BitString(buf[i]);
306                        }
307}
308                        break;
309                case 2:
310{
311#ifdef USE_AVX
312                        __m128i hiPart = ((__m128i)(_mm256_extractf128_ps(v, 1)));
313                        __m128i loPart = ((__m128i)_mm256_castps256_ps128(v));
314                        int buf[4];
315
316                        _mm_storeu_si128((__m128i *)buf, hiPart);
317                        for(int i=3; i>=0; i--)
318                        {
319                                ans = ans + Int2BitString(buf[i]);
320                        }
321
322                        _mm_storeu_si128((__m128i *)buf, loPart);
323                        for(int i=3; i>=0; i--)
324                        {
325                                ans = ans + Int2BitString(buf[i]);
326                        }
327#endif
328
329#ifdef USE_AVX2
330                        int buf[8];
331                        _mm256_storeu_si256((__m256i *)buf, v);
332
333                        //little endian
334                        for (int i =7;i>=0;i--)
335                        {
336                                ans += Int2BitString(buf[i]);
337                        }
338#endif
339}
340                        break;
341                case 3:
342{
343#ifdef USE_NEON
344                        int buf[4];
345                        //_mm_storeu_si128((SIMD_type *)buf, v);
346                        vst1q_u64((uint64_t *)buf, v);
347
348                        /*
349                        //big endian
350                        for(int i=0; i<4; i++)
351                        {
352                                ans = ans + Int2BitString(buf[i]);
353                        }
354                        */
355                        //little endian
356                        for(int i=3; i>=0; i--)
357                        {
358                                ans = ans + Int2BitString(buf[i]);
359                        }
360#endif
361}
362                        break;
363                default:
364                        cerr << "Store2String opt code wrong! Get opt code = " << opt << endl;
365                        break;
366        }
367        return ans;
368}
369
370void GetRandomNums(uint64_t low, uint64_t up, uint64_t *arr, int ct)
371{
372        int i, ptr = 0;
373        arr[ptr++] = low;
374        arr[ptr++] = up;
375        uint64_t diff = up - low;
376        for(i=0; i<ct-2; i++)
377        {
378            uint64_t tmp = rand();
379            tmp = ((uint64_t)(tmp * (uint64_t)rand())) % diff;
380            arr[ptr++] = low + tmp;
381        }
382}
383
384void GetRandomSIMD_typeNums(SIMD_type *arr, int ct, int opt)
385{
386        for(int i=0; i<ct; i++)
387                arr[i] = LoadfromInt(rand(), opt);
388}
389
390/* Prints the SIMD register representation of a SIMD value. */
391static void print_simd_register(const char * var_name, SIMD_type v) {
392  union {SIMD_type vec; unsigned char elems[8];} x;
393  x.vec = v;
394  unsigned char c;
395  printf("%30s = ", var_name);
396  for(int i=sizeof(SIMD_type)-1; i>=0; i--) {
397    c = x.elems[i];
398    printf("%02X ", c);
399  }
400  printf("\n");
401}
Note: See TracBrowser for help on using the repository browser.