source: thirdparty/SZ/sz/src/CompressElement.c @ 2c47b73

Revision 2c47b73, 6.6 KB checked in by Hal Finkel <hfinkel@…>, 6 years ago (diff)

more work on adding SZ (latest version)

  • Property mode set to 100644
Line 
1/**
2 *  @file CompressElement.c
3 *  @author Sheng Di
4 *  @date May, 2016
5 *  @brief Functions of CompressElement
6 *  (C) 2015 by Mathematics and Computer Science (MCS), Argonne National Laboratory.
7 *      See COPYRIGHT in top-level directory.
8 */
9
10#pragma GCC diagnostic push
11#pragma GCC diagnostic ignored "-Wchar-subscripts"
12
13#include <stdlib.h>
14#include <stdio.h>
15#include <math.h>
16#include <sz.h>
17#include <CompressElement.h>
18
19char* decompressGroupIDArray(unsigned char* bytes, size_t dataLength)
20{
21        HuffmanTree* huffmanTree = SZ_Reset(); //create a default huffman tree 
22        int* standGroupID = (int*)malloc(dataLength*sizeof(int));
23        decode_withTree(huffmanTree, bytes, dataLength, standGroupID);
24        SZ_ReleaseHuffman(huffmanTree);
25       
26        char* groupID = (char*)malloc(dataLength*sizeof(char));
27        size_t i = 0;
28        int lastGroupIDValue = 0, curStandIDValue = 0, curGroupIDValue = 0;
29        int offset = 2*(GROUP_COUNT + 2);
30       
31        curGroupIDValue = groupID[0] = standGroupID[0] - GROUP_COUNT;
32        lastGroupIDValue = curGroupIDValue;
33        for(i=1;i<dataLength;i++)
34        {
35                curStandIDValue = standGroupID[i];
36                curGroupIDValue = curStandIDValue + lastGroupIDValue - offset;
37                lastGroupIDValue = curGroupIDValue;
38                groupID[i] = curGroupIDValue;
39        }
40        free(standGroupID);
41       
42        return groupID;
43}
44
45inline short computeGroupNum_float(float value)
46{
47        short expo = getExponent_float(value);
48        if(expo < 0)
49                expo = -1;
50        return expo;
51}
52
53inline short computeGroupNum_double(double value)
54{
55        short expo = getExponent_double(value);
56        if(expo < 0)
57                expo = -1;
58        return expo;
59}
60
61/**
62 * Add preceding neighbor values to a buffer.
63 * @param  last3CmprsData buffer
64 * @param  value the value to be added to the buffer
65 * */
66inline void listAdd_double(double last3CmprsData[3], double value)
67{
68        last3CmprsData[2] = last3CmprsData[1];
69        last3CmprsData[1] = last3CmprsData[0];
70        last3CmprsData[0] = value;
71}
72
73inline void listAdd_float(float last3CmprsData[3], float value)
74{
75        last3CmprsData[2] = last3CmprsData[1];
76        last3CmprsData[1] = last3CmprsData[0];
77        last3CmprsData[0] = value;
78}
79
80inline void listAdd_int(int64_t last3CmprsData[3], int64_t value)
81{
82        last3CmprsData[2] = last3CmprsData[1];
83        last3CmprsData[1] = last3CmprsData[0];
84        last3CmprsData[0] = value;
85}
86
87inline void listAdd_float_group(float *groups, int *flags, char groupNum, float oriValue, float decValue, char* curGroupID)
88{
89        if(groupNum>=0)
90        {
91                if(flags[groupNum]==0)
92                        flags[groupNum] = 1;
93                groups[groupNum] = decValue;           
94        }
95        else
96        {
97                groups[0] = decValue;
98                flags[0] = 1;           
99        }
100
101        if(oriValue>=0)
102                *curGroupID = groupNum+2; //+[-1,0,1,2,3,....,16] is mapped to [1,2,....,18]
103        else
104                *curGroupID = -(groupNum+2); //-[-1,0,1,2,3,....,16] is mapped to [-1,-2,....,-18]
105}
106
107inline void listAdd_double_group(double *groups, int *flags, char groupNum, double oriValue, double decValue, char* curGroupID)
108{
109        if(groupNum>=0)
110        {
111                if(flags[groupNum]==0)
112                        flags[groupNum] = 1;
113                groups[groupNum] = decValue;           
114        }
115        else
116        {
117                groups[0] = decValue;
118                flags[0] = 1;           
119        }
120
121        if(oriValue>=0)
122                *curGroupID = groupNum+2; //+[-1,0,1,2,3,....,16] is mapped to [1,2,....,18]
123        else
124                *curGroupID = -(groupNum+2); //-[-1,0,1,2,3,....,16] is mapped to [-1,-2,....,-18]
125}
126
127/**
128 * Determine whether the prediction value minErr is valid.
129 *
130 * */
131inline int validPrediction_double(double minErr, double precision)
132{
133        if(minErr<=precision)
134                return 1;
135        else
136                return 0;
137}
138
139inline int validPrediction_float(float minErr, float precision)
140{
141        if(minErr<=precision)
142                return 1;
143        else
144                return 0;
145}
146
147double* generateGroupErrBounds(int errorBoundMode, double realPrecision, double pwrErrBound)
148{
149        double pwrError;
150        double* result = (double*)malloc(GROUP_COUNT*sizeof(double));
151        int i = 0;
152        for(i=0;i<GROUP_COUNT;i++)
153        {
154                pwrError = ((double)pow(2, i))*pwrErrBound;
155                switch(errorBoundMode)
156                {
157                case ABS_AND_PW_REL:
158                case REL_AND_PW_REL:
159                        result[i] = pwrError<realPrecision?pwrError:realPrecision;
160                        break;
161                case ABS_OR_PW_REL:
162                case REL_OR_PW_REL:
163                        result[i] = pwrError<realPrecision?realPrecision:pwrError;
164                        break;
165                case PW_REL:
166                        result[i] = pwrError;
167                        break;
168                }
169               
170        }
171        return result;
172}
173
174int generateGroupMaxIntervalCount(double* groupErrBounds)
175{
176        int i = 0;
177        int maxCount = 0, count = 0;
178        for(i=0;i<GROUP_COUNT;i++)
179        {
180                count = (int)(pow(2, i)/groupErrBounds[i] + 0.5);
181                if(maxCount<count)
182                        maxCount = count;
183        }
184       
185        return maxCount;
186}
187
188void new_LossyCompressionElement(LossyCompressionElement *lce, int leadingNum, unsigned char* intMidBytes, 
189int intMidBytes_Length, int resiMidBitsLength, int resiBits)
190{
191        lce->leadingZeroBytes = leadingNum; //0,1,2,or 3
192        memcpy(lce->integerMidBytes,intMidBytes,intMidBytes_Length);
193        lce->integerMidBytes_Length = intMidBytes_Length; //they are mid_bits actually
194        lce->resMidBitsLength = resiMidBitsLength;
195        lce->residualMidBits = resiBits;
196}
197
198void updateLossyCompElement_Double(unsigned char* curBytes, unsigned char* preBytes, 
199                int reqBytesLength, int resiBitsLength,  LossyCompressionElement *lce)
200{
201        int resiIndex, intMidBytes_Length = 0;
202        int leadingNum = compIdenticalLeadingBytesCount_double(preBytes, curBytes); //in fact, float is enough for both single-precision and double-precisiond ata.
203        int fromByteIndex = leadingNum;
204        int toByteIndex = reqBytesLength; //later on: should use "< toByteIndex" to tarverse....
205        if(fromByteIndex < toByteIndex)
206        {
207                intMidBytes_Length = reqBytesLength - leadingNum;
208                memcpy(lce->integerMidBytes, &(curBytes[fromByteIndex]), intMidBytes_Length);
209        }
210        int resiBits = 0;
211        if(resiBitsLength!=0)
212        {
213                resiIndex = reqBytesLength;
214                if(resiIndex < 8)
215                        resiBits = (curBytes[resiIndex] & 0xFF) >> (8-resiBitsLength);
216        }
217        lce->leadingZeroBytes = leadingNum;
218        lce->integerMidBytes_Length = intMidBytes_Length;
219        lce->resMidBitsLength = resiBitsLength;
220        lce->residualMidBits = resiBits;
221}
222
223void updateLossyCompElement_Float(unsigned char* curBytes, unsigned char* preBytes, 
224                int reqBytesLength, int resiBitsLength,  LossyCompressionElement *lce)
225{
226        int resiIndex, intMidBytes_Length = 0;
227        int leadingNum = compIdenticalLeadingBytesCount_float(preBytes, curBytes); //in fact, float is enough for both single-precision and double-precisiond ata.
228        int fromByteIndex = leadingNum;
229        int toByteIndex = reqBytesLength; //later on: should use "< toByteIndex" to tarverse....
230        if(fromByteIndex < toByteIndex)
231        {
232                intMidBytes_Length = reqBytesLength - leadingNum;
233                memcpy(lce->integerMidBytes, &(curBytes[fromByteIndex]), intMidBytes_Length);
234        }
235        int resiBits = 0;
236        if(resiBitsLength!=0)
237        {
238                resiIndex = reqBytesLength;
239                if(resiIndex < 8)
240                        resiBits = (curBytes[resiIndex] & 0xFF) >> (8-resiBitsLength);
241        }
242        lce->leadingZeroBytes = leadingNum;
243        lce->integerMidBytes_Length = intMidBytes_Length;
244        lce->resMidBitsLength = resiBitsLength;
245        lce->residualMidBits = resiBits;
246}
247
248#pragma GCC diagnostic pop
Note: See TracBrowser for help on using the repository browser.