szd_float.c 11.6 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 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
/**
 *  @file szd_float.c
 *  @author Sheng Di, Dingwen Tao, Xin Liang, Xiangyu Zou, Tao Lu, Wen Xia, Xuan Wang, Weizhe Zhang
 *  @date Aug, 2018
 *  @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_float.h"
#include "TightDataPointStorageF.h"
#include "sz.h"
#include "Huffman.h"
#include "szd_float_pwr.h"
#include "utility.h"


//struct timeval startTime_;
//struct timeval endTime_;  /* Start and end times */
//struct timeval costStart_; /*only used for recording the cost*/
//double totalCost_ = 0;

/*void cost_start_()
{
	totalCost_ = 0;
	gettimeofday(&costStart_, NULL);
}

void cost_end_()
{
	double elapsed;
	struct timeval costEnd;
	gettimeofday(&costEnd, NULL);
	elapsed = ((costEnd.tv_sec*1000000+costEnd.tv_usec)-(costStart_.tv_sec*1000000+costStart_.tv_usec))/1000000.0;
	totalCost_ += elapsed;
}*/


/**
 * 
 * int compressionType: 1 (time-based compression) ; 0 (space-based compression)
 * hist_data: only valid when compressionType==1, hist_data is the historical dataset such as the data in previous time step
 * 
T
tickduan 已提交
47
 * @return status SUCCESSFUL (SZ_SUCCESS) or not (other error codes) f
T
tickduan 已提交
48
 * */
T
tickduan 已提交
49 50
int SZ_decompress_args_float(float* newData, size_t r1, unsigned char* cmpBytes, 
                            size_t cmpSize, int compressionType, float* hist_data, sz_exedata* pde_exe, sz_params* pde_params)
T
tickduan 已提交
51
{
T
tickduan 已提交
52 53
	int status = SZ_SUCCESS;
	size_t dataLength = r1;
T
tickduan 已提交
54 55 56 57
	
	//unsigned char* tmpBytes;
	size_t targetUncompressSize = dataLength <<2; //i.e., *4
	//tmpSize must be "much" smaller than dataLength
T
tickduan 已提交
58
	size_t i, tmpSize = 8+MetaDataByteLength+pde_exe->SZ_SIZE_TYPE;
T
tickduan 已提交
59 60 61 62
	unsigned char* szTmpBytes;	
	
	if(cmpSize!=8+4+MetaDataByteLength && cmpSize!=8+8+MetaDataByteLength) //4,8 means two posibilities of SZ_SIZE_TYPE
	{
T
tickduan 已提交
63 64
		pde_params->losslessCompressor = is_lossless_compressed_data(cmpBytes, cmpSize);
		if(pde_params->szMode!=SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
65
		{
T
tickduan 已提交
66 67
			if(pde_params->losslessCompressor!=-1)
				pde_params->szMode = SZ_BEST_COMPRESSION;
T
tickduan 已提交
68
			else
T
tickduan 已提交
69
				pde_params->szMode = SZ_BEST_SPEED;			
T
tickduan 已提交
70 71
		}
		
T
tickduan 已提交
72
		if(pde_params->szMode==SZ_BEST_SPEED)
T
tickduan 已提交
73 74 75 76
		{
			tmpSize = cmpSize;
			szTmpBytes = cmpBytes;	
		}
T
tickduan 已提交
77
		else if(pde_params->szMode==SZ_BEST_COMPRESSION || pde_params->szMode==SZ_DEFAULT_COMPRESSION || pde_params->szMode==SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
78 79 80
		{
			if(targetUncompressSize<MIN_ZLIB_DEC_ALLOMEM_BYTES) //Considering the minimum size
				targetUncompressSize = MIN_ZLIB_DEC_ALLOMEM_BYTES; 
T
tickduan 已提交
81
			tmpSize = sz_lossless_decompress(pde_params->losslessCompressor, cmpBytes, (unsigned long)cmpSize, &szTmpBytes, (unsigned long)targetUncompressSize+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE);//		(unsigned long)targetUncompressSize+8: consider the total length under lossless compression mode is actually 3+4+1+targetUncompressSize
T
tickduan 已提交
82
	
T
tickduan 已提交
83 84 85
		}
		else
		{
T
tickduan 已提交
86
			printf("Wrong value of pde_params->szMode in the double compressed bytes.\n");
T
tickduan 已提交
87 88 89 90 91 92 93
			status = SZ_MERR;
			return status;
		}	
	}
	else
		szTmpBytes = cmpBytes;	
		
T
tickduan 已提交
94 95
	// calc sol_ID
	//pde_params->sol_ID = szTmpBytes[1+3-2+14-4]; //szTmpBytes: version(1bytes), samebyte(1byte), [14-4]:sol_ID=SZ or SZ_Transpose
T
tickduan 已提交
96 97 98
		
	//TODO: convert szTmpBytes to data array.
	TightDataPointStorageF* tdps;
T
tickduan 已提交
99
	int errBoundMode = new_TightDataPointStorageF_fromFlatBytes(&tdps, szTmpBytes, tmpSize, pde_exe, pde_params);
T
tickduan 已提交
100 101 102 103 104
	
	//writeByteData(tdps->typeArray, tdps->typeArray_size, "decompress-typebytes.tbt");
	int floatSize = sizeof(float);
	if(tdps->isLossless)
	{
T
tickduan 已提交
105
		//*newData = (float*)malloc(floatSize*dataLength);  comment by tickduan
T
tickduan 已提交
106 107
		if(sysEndianType==BIG_ENDIAN_SYSTEM)
		{
T
tickduan 已提交
108
			memcpy(newData, szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE, dataLength*floatSize);
T
tickduan 已提交
109 110 111 112 113
		}
		else
		{
			unsigned char* p = szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE;
			for(i=0;i<dataLength;i++,p+=floatSize)
T
tickduan 已提交
114
				newData[i] = bytesToFloat(p);
T
tickduan 已提交
115 116
		}		
	}
T
tickduan 已提交
117
	else //pde_params->sol_ID==SZ
T
tickduan 已提交
118 119 120
	{
		if(tdps->raBytes_size > 0) //v2.0
		{
T
tickduan 已提交
121
			getSnapshotData_float_1D(newData,r1,tdps, errBoundMode, 0, hist_data, pde_params);
T
tickduan 已提交
122 123 124
		}
		else //1.4.13 or time-based compression
		{
T
tickduan 已提交
125
			getSnapshotData_float_1D(newData,r1,tdps, errBoundMode, compressionType, hist_data, pde_params);
T
tickduan 已提交
126 127 128 129 130 131 132
		}
	}

	//cost_start_();	
	//cost_end_();
	//printf("totalCost_=%f\n", totalCost_);
	free_TightDataPointStorageF2(tdps);
T
tickduan 已提交
133
	if(pde_params->szMode!=SZ_BEST_SPEED && cmpSize!=8+MetaDataByteLength+exe_params->SZ_SIZE_TYPE)
T
tickduan 已提交
134 135 136 137
		free(szTmpBytes);
	return status;
}

T
tickduan 已提交
138
void decompressDataSeries_float_1D(float* data, size_t dataSeriesLength, float* hist_data, TightDataPointStorageF* tdps) 
T
tickduan 已提交
139 140 141 142 143 144 145 146 147 148 149
{
	//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;
	float interval = tdps->realPrecision*2;
	
	convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
T
tickduan 已提交
150
	//data = (float*)malloc(sizeof(float)*dataSeriesLength); // comment by tickduan 
T
tickduan 已提交
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 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214

	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[4];
	unsigned char curBytes[4];
	
	memset(preBytes, 0, 4);

	size_t curByteIndex = 0;
	int reqBytesLength, resiBitsLength, resiBits; 
	unsigned char leadingNum;	
	float 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, 4);
			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 = bytesToFloat(curBytes);
T
tickduan 已提交
215
			data[i] = exactData + medianValue;
T
tickduan 已提交
216 217 218
			memcpy(preBytes,curBytes,4);
			break;
		default:
T
tickduan 已提交
219 220 221
			//predValue = 2 * data[i-1] - data[i-2];
			predValue = data[i-1];
			data[i] = predValue + (float)(type_-intvRadius)*interval;
T
tickduan 已提交
222 223
			break;
		}
T
tickduan 已提交
224
		//printf("%.30G\n",data[i]);
T
tickduan 已提交
225 226 227 228 229 230 231
	}
	
	free(leadNum);
	free(type);
	return;
}

T
tickduan 已提交
232
/*MSST19*/
T
tickduan 已提交
233
void decompressDataSeries_float_1D_MSST19(float* data, size_t dataSeriesLength, TightDataPointStorageF* tdps) 
T
tickduan 已提交
234 235 236
{
	//updateQuantizationInfo(tdps->intervals);
	int intvRadius = tdps->intervals/2;
T
tickduan 已提交
237 238 239 240 241
	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 已提交
242
	unsigned char* leadNum;
T
tickduan 已提交
243 244
	//double interval = tdps->realPrecision*2;
	
T
tickduan 已提交
245
	convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
T
tickduan 已提交
246
	//  *data = (float*)malloc(sizeof(float)*dataSeriesLength); comment by tickduan
T
tickduan 已提交
247 248

	int* type = (int*)malloc(dataSeriesLength*sizeof(int));
T
tickduan 已提交
249
	
T
tickduan 已提交
250
	HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
T
tickduan 已提交
251
	decode_withTree_MSST19(huffmanTree, tdps->typeArray, dataSeriesLength, type, tdps->max_bits);
T
tickduan 已提交
252 253 254
	SZ_ReleaseHuffman(huffmanTree);	
	unsigned char preBytes[4];
	unsigned char curBytes[4];
T
tickduan 已提交
255
	
T
tickduan 已提交
256 257 258 259 260
	memset(preBytes, 0, 4);

	size_t curByteIndex = 0;
	int reqBytesLength, resiBitsLength, resiBits; 
	unsigned char leadingNum;	
T
tickduan 已提交
261
	float exactData, predValue = 0;
T
tickduan 已提交
262 263
	reqBytesLength = tdps->reqLength/8;
	resiBitsLength = tdps->reqLength%8;
T
tickduan 已提交
264 265 266 267 268 269
	//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 已提交
270 271 272
	}

	int type_;
T
tickduan 已提交
273 274 275 276
	for (i = 0; i < dataSeriesLength; i++) {
		type_ = type[i];
		switch (type_) {
		case 0:
T
tickduan 已提交
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
			// 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 已提交
303
			// recover the exact data	
T
tickduan 已提交
304 305 306 307 308 309 310 311 312
			memset(curBytes, 0, 4);
			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 已提交
313 314
			
			exactData = bytesToFloat(curBytes);
T
tickduan 已提交
315
			data[i] = exactData;
T
tickduan 已提交
316
			memcpy(preBytes,curBytes,4);
T
tickduan 已提交
317
			predValue = data[i];
T
tickduan 已提交
318 319
			break;
		default:
T
tickduan 已提交
320 321
			//predValue = 2 * data[i-1] - data[i-2];
			//predValue = data[i-1];
T
tickduan 已提交
322
			predValue = fabs(predValue) * precisionTable[type_];			
T
tickduan 已提交
323
			data[i] = predValue;
T
tickduan 已提交
324
			break;
T
tickduan 已提交
325
		}
T
tickduan 已提交
326
		//printf("%.30G\n",data[i]);
T
tickduan 已提交
327
	}
T
tickduan 已提交
328 329 330 331 332 333
	
	free(precisionTable);
	free(leadNum);
	free(type);
	return;
}
T
tickduan 已提交
334

T
tickduan 已提交
335

T
tickduan 已提交
336
void getSnapshotData_float_1D(float* data, size_t dataSeriesLength, TightDataPointStorageF* tdps, int errBoundMode, int compressionType, float* hist_data, sz_params* pde_params)
T
tickduan 已提交
337 338 339 340 341
{	
	size_t i;

	if (tdps->allSameData) {
		float value = bytesToFloat(tdps->exactMidBytes);
T
tickduan 已提交
342
		//*data = (float*)malloc(sizeof(float)*dataSeriesLength); commnet by tickduan
T
tickduan 已提交
343
		for (i = 0; i < dataSeriesLength; i++)
T
tickduan 已提交
344
			data[i] = value;
T
tickduan 已提交
345 346 347
	} else {
		if (tdps->rtypeArray == NULL) {
			if(errBoundMode < PW_REL)
T
tickduan 已提交
348 349
			{			
				decompressDataSeries_float_1D(data, dataSeriesLength, hist_data, tdps);
T
tickduan 已提交
350 351 352 353 354 355 356 357
			}
			else 
			{
				if(pde_params->accelerate_pw_rel_compression)
					decompressDataSeries_float_1D_pwr_pre_log_MSST19(data, dataSeriesLength, tdps);
				else
					decompressDataSeries_float_1D_pwr_pre_log(data, dataSeriesLength, tdps);
				//decompressDataSeries_float_1D_pwrgroup(data, dataSeriesLength, tdps);
T
tickduan 已提交
358
			}
T
tickduan 已提交
359 360 361
			return;
		} else { //the special version supporting one value to reserve
			//TODO
T
tickduan 已提交
362 363
		}
	}
T
tickduan 已提交
364
}