szd_float.c 7.3 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 39 40
	unsigned char* szTmpBytes;	
	
	if(cmpSize!=8+4+MetaDataByteLength && cmpSize!=8+8+MetaDataByteLength) //4,8 means two posibilities of SZ_SIZE_TYPE
	{
T
tickduan 已提交
41 42
		pde_params->losslessCompressor = is_lossless_compressed_data(cmpBytes, cmpSize);
		if(pde_params->szMode!=SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
43
		{
T
tickduan 已提交
44 45
			if(pde_params->losslessCompressor!=-1)
				pde_params->szMode = SZ_BEST_COMPRESSION;
T
tickduan 已提交
46
			else
T
tickduan 已提交
47
				pde_params->szMode = SZ_BEST_SPEED;			
T
tickduan 已提交
48 49
		}
		
T
tickduan 已提交
50
		if(pde_params->szMode==SZ_BEST_SPEED)
T
tickduan 已提交
51 52 53 54
		{
			tmpSize = cmpSize;
			szTmpBytes = cmpBytes;	
		}
T
tickduan 已提交
55
		else if(pde_params->szMode==SZ_BEST_COMPRESSION || pde_params->szMode==SZ_DEFAULT_COMPRESSION || pde_params->szMode==SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
56 57 58
		{
			if(targetUncompressSize<MIN_ZLIB_DEC_ALLOMEM_BYTES) //Considering the minimum size
				targetUncompressSize = MIN_ZLIB_DEC_ALLOMEM_BYTES; 
T
tickduan 已提交
59
			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 已提交
60
	
T
tickduan 已提交
61 62 63
		}
		else
		{
T
tickduan 已提交
64
			printf("Wrong value of pde_params->szMode in the double compressed bytes.\n");
T
tickduan 已提交
65 66 67 68 69 70 71
			status = SZ_MERR;
			return status;
		}	
	}
	else
		szTmpBytes = cmpBytes;	
		
T
tickduan 已提交
72 73
	// 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 已提交
74 75
		
	//TODO: convert szTmpBytes to data array.
T
tickduan 已提交
76
	TightDataPointStorageF* tdps = NULL;
T
tickduan 已提交
77
	int errBoundMode = new_TightDataPointStorageF_fromFlatBytes(&tdps, szTmpBytes, tmpSize, pde_exe, pde_params);
T
tickduan 已提交
78 79 80 81
	if(tdps == NULL)
	{
		return SZ_FORMAT_ERR;
	}
T
tickduan 已提交
82 83 84 85
	
	int floatSize = sizeof(float);
	if(tdps->isLossless)
	{
T
tickduan 已提交
86
		//*newData = (float*)malloc(floatSize*dataLength);  comment by tickduan
T
tickduan 已提交
87 88
		if(sysEndianType==BIG_ENDIAN_SYSTEM)
		{
T
tickduan 已提交
89
			memcpy(newData, szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE, dataLength*floatSize);
T
tickduan 已提交
90 91 92 93 94
		}
		else
		{
			unsigned char* p = szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE;
			for(i=0;i<dataLength;i++,p+=floatSize)
T
tickduan 已提交
95
				newData[i] = bytesToFloat(p);
T
tickduan 已提交
96 97
		}		
	}
T
tickduan 已提交
98
	else //pde_params->sol_ID==SZ
T
tickduan 已提交
99 100 101
	{
		if(tdps->raBytes_size > 0) //v2.0
		{
T
tickduan 已提交
102
			getSnapshotData_float_1D(newData,r1,tdps, errBoundMode, 0, hist_data, pde_params);
T
tickduan 已提交
103 104 105
		}
		else //1.4.13 or time-based compression
		{
T
tickduan 已提交
106
			getSnapshotData_float_1D(newData,r1,tdps, errBoundMode, compressionType, hist_data, pde_params);
T
tickduan 已提交
107 108 109 110 111 112 113
		}
	}

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

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

T
tickduan 已提交
216
void getSnapshotData_float_1D(float* data, size_t dataSeriesLength, TightDataPointStorageF* tdps, int errBoundMode, int compressionType, float* hist_data, sz_params* pde_params)
T
tickduan 已提交
217 218 219
{	
	size_t i;

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