szd_double.c 10.8 KB
Newer Older
T
tickduan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/**
 *  @file szd_double.c
 *  @author Sheng Di, Dingwen Tao, Xin Liang, Xiangyu Zou, Tao Lu, Wen Xia, Xuan Wang, Weizhe Zhang
 *  @date Aug, 2016
 *  @brief 
 *  (C) 2016 by Mathematics and Computer Science (MCS), Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

#include <stdlib.h> 
#include <stdio.h>
#include <string.h>
#include "szd_double.h"
#include "TightDataPointStorageD.h"
#include "sz.h"
#include "Huffman.h"
#include "szd_double_pwr.h"
#include "szd_double_ts.h"
#include "utility.h"

T
tickduan 已提交
21 22
int SZ_decompress_args_double(double* newData, size_t r1, unsigned char* cmpBytes, 
				size_t cmpSize, int compressionType, double* hist_data, sz_exedata* pde_exe, sz_params* pde_params)
T
tickduan 已提交
23
{
T
tickduan 已提交
24 25
	int status = SZ_SUCCESS;
	size_t dataLength = r1;
T
tickduan 已提交
26 27 28 29 30 31 32 33
	
	//unsigned char* tmpBytes;
	size_t targetUncompressSize = dataLength <<3; //i.e., *8
	//tmpSize must be "much" smaller than dataLength
	size_t i, tmpSize = 12+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE;
	unsigned char* szTmpBytes;
	if(cmpSize!=12+4+MetaDataByteLength_double && cmpSize!=12+8+MetaDataByteLength_double)
	{
T
tickduan 已提交
34 35
		pde_params->losslessCompressor = is_lossless_compressed_data(cmpBytes, cmpSize);
		if(pde_params->szMode!=SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
36
		{
T
tickduan 已提交
37 38
			if(pde_params->losslessCompressor!=-1)
				pde_params->szMode = SZ_BEST_COMPRESSION;
T
tickduan 已提交
39
			else
T
tickduan 已提交
40
				pde_params->szMode = SZ_BEST_SPEED;			
T
tickduan 已提交
41
		}
T
tickduan 已提交
42 43


T
tickduan 已提交
44
		if(pde_params->szMode==SZ_BEST_SPEED)
T
tickduan 已提交
45 46 47 48
		{
			tmpSize = cmpSize;
			szTmpBytes = cmpBytes;	
		}	
T
tickduan 已提交
49
		else if(pde_params->szMode==SZ_BEST_COMPRESSION || pde_params->szMode==SZ_DEFAULT_COMPRESSION || pde_params->szMode==SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
50 51 52
		{
			if(targetUncompressSize<MIN_ZLIB_DEC_ALLOMEM_BYTES) //Considering the minimum size
				targetUncompressSize = MIN_ZLIB_DEC_ALLOMEM_BYTES; 			
T
tickduan 已提交
53
			tmpSize = sz_lossless_decompress(pde_params->losslessCompressor, cmpBytes, (unsigned long)cmpSize, &szTmpBytes, (unsigned long)targetUncompressSize+4+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE);			
T
tickduan 已提交
54 55 56 57 58 59
			//szTmpBytes = (unsigned char*)malloc(sizeof(unsigned char)*tmpSize);
			//memcpy(szTmpBytes, tmpBytes, tmpSize);
			//free(tmpBytes); //release useless memory		
		}
		else
		{
T
tickduan 已提交
60
			printf("Wrong value of pde_params->szMode in the double compressed bytes.\n");
T
tickduan 已提交
61 62 63 64 65 66
			status = SZ_MERR;
			return status;
		}	
	}
	else
		szTmpBytes = cmpBytes;
T
tickduan 已提交
67 68 69
	
	// calc postion 
	//pde_params->sol_ID = szTmpBytes[1+3-2+14-4]; //szTmpBytes: version(3bytes), samebyte(1byte), [14]:sol_ID=SZ or SZ_Transpose		
T
tickduan 已提交
70 71
	//TODO: convert szTmpBytes to double array.
	TightDataPointStorageD* tdps;
T
tickduan 已提交
72
	int errBoundMode = new_TightDataPointStorageD_fromFlatBytes(&tdps, szTmpBytes, tmpSize, pde_exe, pde_params);
T
tickduan 已提交
73

T
tickduan 已提交
74
	int dim = r1;
T
tickduan 已提交
75 76 77
	int doubleSize = sizeof(double);
	if(tdps->isLossless)
	{
T
tickduan 已提交
78
		// *newData = (double*)malloc(doubleSize*dataLength); comment by tickduan
T
tickduan 已提交
79 80
		if(sysEndianType==BIG_ENDIAN_SYSTEM)
		{
T
tickduan 已提交
81
			memcpy(newData, szTmpBytes+4+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE, dataLength*doubleSize);
T
tickduan 已提交
82 83 84 85 86
		}
		else
		{
			unsigned char* p = szTmpBytes+4+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE;
			for(i=0;i<dataLength;i++,p+=doubleSize)
T
tickduan 已提交
87
				newData[i] = bytesToDouble(p);
T
tickduan 已提交
88 89
		}		
	}
T
tickduan 已提交
90
	else if(pde_params->sol_ID==SZ_Transpose)
T
tickduan 已提交
91
	{
T
tickduan 已提交
92
		getSnapshotData_double_1D(newData,dataLength,tdps, errBoundMode, 0, hist_data, pde_params);		
T
tickduan 已提交
93
	}
T
tickduan 已提交
94
	else //pde_params->sol_ID==SZ
T
tickduan 已提交
95 96 97
	{
		if(tdps->raBytes_size > 0) //v2.0
		{
T
tickduan 已提交
98
			getSnapshotData_double_1D(newData,r1,tdps, errBoundMode, 0, hist_data, pde_params);
T
tickduan 已提交
99 100 101
		}
		else //1.4.13 or time-based compression
		{
T
tickduan 已提交
102
			getSnapshotData_double_1D(newData,r1,tdps, errBoundMode, compressionType, hist_data, pde_params);
T
tickduan 已提交
103 104 105 106
		}
	}	

	free_TightDataPointStorageD2(tdps);
T
tickduan 已提交
107
	if(pde_params->szMode!=SZ_BEST_SPEED && cmpSize!=12+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE)
T
tickduan 已提交
108 109 110 111
		free(szTmpBytes);	
	return status;
}

T
tickduan 已提交
112
void decompressDataSeries_double_1D(double* data, size_t dataSeriesLength, double* hist_data, TightDataPointStorageD* tdps) 
T
tickduan 已提交
113 114 115 116 117 118 119 120 121 122 123
{
	//updateQuantizationInfo(tdps->intervals);
	int intvRadius = tdps->intervals/2;
	size_t i, j, k = 0, p = 0, l = 0; // k is to track the location of residual_bit
								// in resiMidBits, p is to track the
								// byte_index of resiMidBits, l is for
								// leadNum
	unsigned char* leadNum;
	double interval = tdps->realPrecision*2;
	
	convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
T
tickduan 已提交
124
	//*data = (double*)malloc(sizeof(double)*dataSeriesLength); comment by tickduan
T
tickduan 已提交
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

	int* type = (int*)malloc(dataSeriesLength*sizeof(int));

	HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
	decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, type);
	SZ_ReleaseHuffman(huffmanTree);	
	
	unsigned char preBytes[8];
	unsigned char curBytes[8];
	
	memset(preBytes, 0, 8);

	size_t curByteIndex = 0;
	int reqBytesLength, resiBitsLength, resiBits; 
	unsigned char leadingNum;	
	double medianValue, exactData, predValue;
	
	reqBytesLength = tdps->reqLength/8;
	resiBitsLength = tdps->reqLength%8;
	medianValue = tdps->medianValue;
	
	int type_;
	for (i = 0; i < dataSeriesLength; i++) {
		type_ = type[i];
		switch (type_) {
		case 0:
			// compute resiBits
			resiBits = 0;
			if (resiBitsLength != 0) {
				int kMod8 = k % 8;
				int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
				if (rightMovSteps > 0) {
					int code = getRightMovingCode(kMod8, resiBitsLength);
					resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
				} else if (rightMovSteps < 0) {
					int code1 = getLeftMovingCode(kMod8);
					int code2 = getRightMovingCode(kMod8, resiBitsLength);
					int leftMovSteps = -rightMovSteps;
					rightMovSteps = 8 - leftMovSteps;
					resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
					p++;
					resiBits = resiBits
							| ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
				} else // rightMovSteps == 0
				{
					int code = getRightMovingCode(kMod8, resiBitsLength);
					resiBits = (tdps->residualMidBits[p] & code);
					p++;
				}
				k += resiBitsLength;
			}

			// recover the exact data
			memset(curBytes, 0, 8);
			leadingNum = leadNum[l++];
			memcpy(curBytes, preBytes, leadingNum);
			for (j = leadingNum; j < reqBytesLength; j++)
				curBytes[j] = tdps->exactMidBytes[curByteIndex++];
			if (resiBitsLength != 0) {
				unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
				curBytes[reqBytesLength] = resiByte;
			}
			
			exactData = bytesToDouble(curBytes);
T
tickduan 已提交
189
			data[i] = exactData + medianValue;
T
tickduan 已提交
190 191 192
			memcpy(preBytes,curBytes,8);
			break;
		default:
T
tickduan 已提交
193 194 195
			//predValue = 2 * data[i-1] - data[i-2];
			predValue = data[i-1];
			data[i] = predValue + (type_-intvRadius)*interval;
T
tickduan 已提交
196 197
			break;
		}
T
tickduan 已提交
198
		//printf("%.30G\n",data[i]);
T
tickduan 已提交
199 200 201 202 203 204 205
	}
	
	free(leadNum);
	free(type);
	return;
}

T
tickduan 已提交
206
/*MSST19*/
T
tickduan 已提交
207
void decompressDataSeries_double_1D_MSST19(double* data, size_t dataSeriesLength, TightDataPointStorageD* tdps) 
T
tickduan 已提交
208 209 210
{
	//updateQuantizationInfo(tdps->intervals);
	int intvRadius = tdps->intervals/2;
T
tickduan 已提交
211 212 213 214 215
	int intvCapacity = tdps->intervals;
	size_t i, j, k = 0, p = 0, l = 0; // k is to track the location of residual_bit
								// in resiMidBits, p is to track the
								// byte_index of resiMidBits, l is for
								// leadNum
T
tickduan 已提交
216
	unsigned char* leadNum;
T
tickduan 已提交
217 218
	//double interval = tdps->realPrecision*2;
	
T
tickduan 已提交
219
	convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
T
tickduan 已提交
220
	//*data = (double*)malloc(sizeof(double)*dataSeriesLength); comment by tickduan
T
tickduan 已提交
221 222

	int* type = (int*)malloc(dataSeriesLength*sizeof(int));
T
tickduan 已提交
223
	
T
tickduan 已提交
224
	HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
T
tickduan 已提交
225 226
	decode_withTree_MSST19(huffmanTree, tdps->typeArray, dataSeriesLength, type, tdps->max_bits);
	//decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, type);
T
tickduan 已提交
227 228 229
	SZ_ReleaseHuffman(huffmanTree);	
	unsigned char preBytes[8];
	unsigned char curBytes[8];
T
tickduan 已提交
230
	
T
tickduan 已提交
231 232 233 234 235
	memset(preBytes, 0, 8);

	size_t curByteIndex = 0;
	int reqBytesLength, resiBitsLength, resiBits; 
	unsigned char leadingNum;	
T
tickduan 已提交
236
	double exactData, predValue = 0;
T
tickduan 已提交
237 238
	reqBytesLength = tdps->reqLength/8;
	resiBitsLength = tdps->reqLength%8;
T
tickduan 已提交
239 240 241 242 243 244
	//float threshold = tdps->minLogValue;
	double* precisionTable = (double*)malloc(sizeof(double) * intvCapacity);
	double inv = 2.0-pow(2, -(tdps->plus_bits));
	for(int i=0; i<intvCapacity; i++){
		double test = pow((1+tdps->realPrecision), inv*(i - intvRadius));
		precisionTable[i] = test;
T
tickduan 已提交
245 246
	}

T
tickduan 已提交
247 248 249 250 251
	int type_;
	for (i = 0; i < dataSeriesLength; i++) {
		type_ = type[i];
		switch (type_) {
		case 0:
T
tickduan 已提交
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
			// compute resiBits
			resiBits = 0;
			if (resiBitsLength != 0) {
				int kMod8 = k % 8;
				int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
				if (rightMovSteps > 0) {
					int code = getRightMovingCode(kMod8, resiBitsLength);
					resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
				} else if (rightMovSteps < 0) {
					int code1 = getLeftMovingCode(kMod8);
					int code2 = getRightMovingCode(kMod8, resiBitsLength);
					int leftMovSteps = -rightMovSteps;
					rightMovSteps = 8 - leftMovSteps;
					resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
					p++;
					resiBits = resiBits
							| ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
				} else // rightMovSteps == 0
				{
					int code = getRightMovingCode(kMod8, resiBitsLength);
					resiBits = (tdps->residualMidBits[p] & code);
					p++;
				}
				k += resiBitsLength;
			}

T
tickduan 已提交
278
			// recover the exact data	
T
tickduan 已提交
279 280 281 282 283 284 285 286 287
			memset(curBytes, 0, 8);
			leadingNum = leadNum[l++];
			memcpy(curBytes, preBytes, leadingNum);
			for (j = leadingNum; j < reqBytesLength; j++)
				curBytes[j] = tdps->exactMidBytes[curByteIndex++];
			if (resiBitsLength != 0) {
				unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
				curBytes[reqBytesLength] = resiByte;
			}
T
tickduan 已提交
288
			
T
tickduan 已提交
289
			exactData = bytesToDouble(curBytes);
T
tickduan 已提交
290
			data[i] = exactData;
T
tickduan 已提交
291
			memcpy(preBytes,curBytes,8);
T
tickduan 已提交
292
			predValue = data[i];
T
tickduan 已提交
293 294
			break;
		default:
T
tickduan 已提交
295 296
			//predValue = 2 * data[i-1] - data[i-2];
			//predValue = data[i-1];
T
tickduan 已提交
297
			predValue = fabs(predValue) * precisionTable[type_];
T
tickduan 已提交
298
			data[i] = predValue;
T
tickduan 已提交
299
			break;
T
tickduan 已提交
300 301
		}
	}
T
tickduan 已提交
302 303
	
	free(precisionTable);
T
tickduan 已提交
304 305 306 307 308
	free(leadNum);
	free(type);
	return;
}

T
tickduan 已提交
309
void getSnapshotData_double_1D(double* data, size_t dataSeriesLength, TightDataPointStorageD* tdps, int errBoundMode, int compressionType, double* hist_data, sz_params* pde_params) 
T
tickduan 已提交
310
{
T
tickduan 已提交
311 312 313
	size_t i;
	if (tdps->allSameData) {
		double value = bytesToDouble(tdps->exactMidBytes);
T
tickduan 已提交
314 315

		//*data = (double*)malloc(sizeof(double)*dataSeriesLength); comment by tickduan
T
tickduan 已提交
316
		for (i = 0; i < dataSeriesLength; i++)
T
tickduan 已提交
317
			data[i] = value;
T
tickduan 已提交
318 319 320
	} else {
		if (tdps->rtypeArray == NULL) {
			if(errBoundMode < PW_REL)
T
tickduan 已提交
321
			{
T
tickduan 已提交
322
				decompressDataSeries_double_1D(data, dataSeriesLength, hist_data, tdps);
T
tickduan 已提交
323
			}
T
tickduan 已提交
324 325 326 327 328 329 330
			else 
			{
				if(confparams_dec->accelerate_pw_rel_compression)
					decompressDataSeries_double_1D_pwr_pre_log_MSST19(data, dataSeriesLength, tdps);
				else
					decompressDataSeries_double_1D_pwr_pre_log(data, dataSeriesLength, tdps);
				//decompressDataSeries_double_1D_pwrgroup(data, dataSeriesLength, tdps);
T
tickduan 已提交
331 332 333 334 335 336 337 338
			}
			return;
		} else {
			//TODO
		}
	}
}