szd_float.c 7.1 KB
Newer Older
T
tickduan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 *  @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 "utility.h"
T
tickduan 已提交
17
#include "Huffman.h"
T
tickduan 已提交
18 19 20 21 22 23 24


/**
 * 
 * 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 已提交
25
 * @return status SUCCESSFUL (SZ_SUCCESS) or not (other error codes) f
T
tickduan 已提交
26
 * */
T
tickduan 已提交
27 28
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 已提交
29
{
T
tickduan 已提交
30 31
	int status = SZ_SUCCESS;
	size_t dataLength = r1;
T
tickduan 已提交
32 33 34 35
	
	//unsigned char* tmpBytes;
	size_t targetUncompressSize = dataLength <<2; //i.e., *4
	//tmpSize must be "much" smaller than dataLength
T
tickduan 已提交
36
	size_t i, tmpSize = 8+MetaDataByteLength+pde_exe->SZ_SIZE_TYPE;
T
tickduan 已提交
37 38
	unsigned char* szTmpBytes = NULL;	
	bool  needFree = false;
T
tickduan 已提交
39 40 41
	
	if(cmpSize!=8+4+MetaDataByteLength && cmpSize!=8+8+MetaDataByteLength) //4,8 means two posibilities of SZ_SIZE_TYPE
	{
T
tickduan 已提交
42 43
		pde_params->losslessCompressor = is_lossless_compressed_data(cmpBytes, cmpSize);
		if(pde_params->szMode!=SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
44
		{
T
tickduan 已提交
45 46
			if(pde_params->losslessCompressor!=-1)
				pde_params->szMode = SZ_BEST_COMPRESSION;
T
tickduan 已提交
47
			else
T
tickduan 已提交
48
				pde_params->szMode = SZ_BEST_SPEED;			
T
tickduan 已提交
49 50
		}
		
T
tickduan 已提交
51
		if(pde_params->szMode==SZ_BEST_SPEED)
T
tickduan 已提交
52 53 54 55
		{
			tmpSize = cmpSize;
			szTmpBytes = cmpBytes;	
		}
T
tickduan 已提交
56
		else
T
tickduan 已提交
57 58 59
		{
			if(targetUncompressSize<MIN_ZLIB_DEC_ALLOMEM_BYTES) //Considering the minimum size
				targetUncompressSize = MIN_ZLIB_DEC_ALLOMEM_BYTES; 
T
tickduan 已提交
60
			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 已提交
61
	        needFree = true;
T
tickduan 已提交
62 63 64 65 66
		}
	}
	else
		szTmpBytes = cmpBytes;	
		
T
tickduan 已提交
67 68
	// 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 已提交
69 70
		
	//TODO: convert szTmpBytes to data array.
T
tickduan 已提交
71
	TightDataPointStorageF* tdps = NULL;
T
tickduan 已提交
72
	int errBoundMode = new_TightDataPointStorageF_fromFlatBytes(&tdps, szTmpBytes, tmpSize, pde_exe, pde_params);
T
tickduan 已提交
73 74 75 76
	if(tdps == NULL)
	{
		return SZ_FORMAT_ERR;
	}
T
tickduan 已提交
77 78 79 80
	
	int floatSize = sizeof(float);
	if(tdps->isLossless)
	{
T
tickduan 已提交
81
		//*newData = (float*)malloc(floatSize*dataLength);  comment by tickduan
T
tickduan 已提交
82 83
		if(sysEndianType==BIG_ENDIAN_SYSTEM)
		{
T
tickduan 已提交
84
			memcpy(newData, szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE, dataLength*floatSize);
T
tickduan 已提交
85 86 87 88 89
		}
		else
		{
			unsigned char* p = szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE;
			for(i=0;i<dataLength;i++,p+=floatSize)
T
tickduan 已提交
90
				newData[i] = bytesToFloat(p);
T
tickduan 已提交
91 92
		}		
	}
T
tickduan 已提交
93
	else //pde_params->sol_ID==SZ
T
tickduan 已提交
94 95 96
	{
		if(tdps->raBytes_size > 0) //v2.0
		{
T
tickduan 已提交
97
			getSnapshotData_float_1D(newData,r1,tdps, errBoundMode, 0, hist_data, pde_params);
T
tickduan 已提交
98 99 100
		}
		else //1.4.13 or time-based compression
		{
T
tickduan 已提交
101
			getSnapshotData_float_1D(newData,r1,tdps, errBoundMode, compressionType, hist_data, pde_params);
T
tickduan 已提交
102 103 104 105 106 107 108
		}
	}

	//cost_start_();	
	//cost_end_();
	//printf("totalCost_=%f\n", totalCost_);
	free_TightDataPointStorageF2(tdps);
T
tickduan 已提交
109
	if(szTmpBytes && needFree)
T
tickduan 已提交
110 111 112 113
		free(szTmpBytes);
	return status;
}

T
tickduan 已提交
114
void decompressDataSeries_float_1D(float* data, size_t dataSeriesLength, float* hist_data, TightDataPointStorageF* tdps) 
T
tickduan 已提交
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;
	float interval = tdps->realPrecision*2;
T
tickduan 已提交
124
    	
T
tickduan 已提交
125
	convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
T
tickduan 已提交
126
	//data = (float*)malloc(sizeof(float)*dataSeriesLength); // comment by tickduan 
T
tickduan 已提交
127
	
T
tickduan 已提交
128 129
	// type tree
	int* types = (int*)malloc(dataSeriesLength*sizeof(int));
T
tickduan 已提交
130
	HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
T
tickduan 已提交
131
	decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, types);
T
tickduan 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144 145
	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;
T
tickduan 已提交
146
	medianValue = tdps->medianValue;	
T
tickduan 已提交
147
	
T
tickduan 已提交
148 149 150 151 152 153 154
	// decompress core
    int type;
	for (i = 0; i < dataSeriesLength; i++) 
	{	
		type = types[i];
		switch (type) 
		{
T
tickduan 已提交
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
		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 已提交
194
			data[i] = exactData + medianValue;
T
tickduan 已提交
195 196 197
			memcpy(preBytes,curBytes,4);
			break;
		default:
T
tickduan 已提交
198 199
			//predValue = 2 * data[i-1] - data[i-2];
			predValue = data[i-1];
T
tickduan 已提交
200
			data[i] = predValue + (float)(type - intvRadius) * interval;
T
tickduan 已提交
201
			break;
T
tickduan 已提交
202
		}
T
tickduan 已提交
203
		//printf("%.30G\n",data[i]);
T
tickduan 已提交
204
	}
T
tickduan 已提交
205 206
	
	free(leadNum);
T
tickduan 已提交
207
	free(types);
T
tickduan 已提交
208 209
	return;
}
T
tickduan 已提交
210

T
tickduan 已提交
211
void getSnapshotData_float_1D(float* data, size_t dataSeriesLength, TightDataPointStorageF* tdps, int errBoundMode, int compressionType, float* hist_data, sz_params* pde_params)
T
tickduan 已提交
212 213 214
{	
	size_t i;

T
tickduan 已提交
215 216
	if (tdps->allSameData) 
	{
T
tickduan 已提交
217
		float value = bytesToFloat(tdps->exactMidBytes);
T
tickduan 已提交
218
		//*data = (float*)malloc(sizeof(float)*dataSeriesLength); commnet by tickduan
T
tickduan 已提交
219
		for (i = 0; i < dataSeriesLength; i++)
T
tickduan 已提交
220
			data[i] = value;
T
tickduan 已提交
221 222 223 224
	} 
	else 
	{
	   decompressDataSeries_float_1D(data, dataSeriesLength, hist_data, tdps);
T
tickduan 已提交
225
	}
T
tickduan 已提交
226
}