sz.c 5.4 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
/**
 *  @file sz.c
 *  @author Sheng Di and Dingwen Tao
 *  @date Aug, 2016
 *  @brief SZ_Init, Compression and Decompression functions
 *  (C) 2016 by Mathematics and Computer Science (MCS), Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "sz.h"
#include "CompressElement.h"
#include "DynamicByteArray.h"
#include "TightDataPointStorageD.h"
#include "TightDataPointStorageF.h"
#include "zlib.h"
#include "rw.h"
#include "Huffman.h"
#include "conf.h"
#include "utility.h"
T
tickduan 已提交
25

T
tickduan 已提交
26 27
//#include "CurveFillingCompressStorage.h"

T
tickduan 已提交
28
unsigned char versionNumber = SZ_VER_MAJOR;
T
tickduan 已提交
29
int SZ_SIZE_TYPE_DEFUALT = 4;
T
tickduan 已提交
30 31

int dataEndianType = LITTLE_ENDIAN_DATA; //*endian type of the data read from disk
T
tickduan 已提交
32
int sysEndianType  = LITTLE_ENDIAN_SYSTEM ; //*sysEndianType is actually set automatically.
T
tickduan 已提交
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

//the confparams should be separate between compression and decopmression, in case of mutual-affection when calling compression/decompression alternatively
sz_params *confparams_cpr = NULL; //used for compression
sz_params *confparams_dec = NULL; //used for decompression 

sz_exedata *exe_params = NULL;

/*following global variables are desgined for time-series based compression*/
/*sz_varset is not used in the single-snapshot data compression*/
SZ_VarSet* sz_varset = NULL;
sz_multisteps *multisteps = NULL;
sz_tsc_metadata *sz_tsc = NULL;

//only for Pastri compressor
#ifdef PASTRI
pastri_params pastri_par;
#endif

HuffmanTree* SZ_Reset()
{
	return createDefaultHuffmanTree();
}

int SZ_Init(const char *configFilePath)
{
T
tickduan 已提交
58 59 60 61 62 63 64 65
	// check CPU EndianType
	int x = 1;
	char *y = (char*)&x;
	if(*y==1)
		sysEndianType = LITTLE_ENDIAN_SYSTEM;
	else //=0
		sysEndianType = BIG_ENDIAN_SYSTEM;

T
tickduan 已提交
66
	int loadFileResult = SZ_LoadConf(configFilePath);
T
tickduan 已提交
67 68
	if(loadFileResult==SZ_FAILED)
		return SZ_FAILED;
T
tickduan 已提交
69
	
T
tickduan 已提交
70
	exe_params->SZ_SIZE_TYPE = SZ_SIZE_TYPE_DEFUALT;
T
tickduan 已提交
71 72 73 74
	if(confparams_cpr->szMode == SZ_TEMPORAL_COMPRESSION)
	{
		initSZ_TSC();
	}
T
tickduan 已提交
75
	return SZ_SUCCESS;
T
tickduan 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
}

int SZ_Init_Params(sz_params *params)
{
	SZ_Init(NULL);

	if(params->losslessCompressor!=GZIP_COMPRESSOR && params->losslessCompressor!=ZSTD_COMPRESSOR)
		params->losslessCompressor = ZSTD_COMPRESSOR;

	if(params->max_quant_intervals > 0)
		params->maxRangeRadius = params->max_quant_intervals/2;
		
	memcpy(confparams_cpr, params, sizeof(sz_params));

	if(params->quantization_intervals%2!=0)
	{
		printf("Error: quantization_intervals must be an even number!\n");
T
tickduan 已提交
93
		return SZ_FAILED;
T
tickduan 已提交
94 95
	}

T
tickduan 已提交
96
	return SZ_SUCCESS;
T
tickduan 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109
}


/*-------------------------------------------------------------------------*/
/**
    @brief      Perform Compression 
    @param      data           data to be compressed
    @param      outSize        the size (in bytes) after compression
    @param		r5,r4,r3,r2,r1	the sizes of each dimension (supporting only 5 dimensions at most in this version.
    @return     compressed data (in binary stream) or NULL(0) if any errors

 **/
/*-------------------------------------------------------------------------*/
T
tickduan 已提交
110 111 112 113 114

//
//  compress output data to outData and return outSize
//
size_t SZ_compress_args(int dataType, void *data, size_t r1, unsigned char* outData, sz_params* params)
T
tickduan 已提交
115
{
T
tickduan 已提交
116
	size_t outSize = 0;
T
tickduan 已提交
117
	int status;
T
tickduan 已提交
118 119
	if(dataType==SZ_FLOAT)
	{
T
tickduan 已提交
120
		status = SZ_compress_args_float((float *)data, r1, outData,  &outSize, params);		
T
tickduan 已提交
121 122 123
	}
	else if(dataType==SZ_DOUBLE)
	{
T
tickduan 已提交
124
		status = SZ_compress_args_double((double *)data, r1, outData,  &outSize, params);
T
tickduan 已提交
125 126 127
	}
	else
	{
T
tickduan 已提交
128 129
		printf("Error: dataType can only be SZ_FLOAT, SZ_DOUBLE .\n");
		return 0;
T
tickduan 已提交
130 131
	}

T
tickduan 已提交
132
	return outSize;
T
tickduan 已提交
133 134
}

T
tickduan 已提交
135 136 137 138
//
// decompress output data to outData and return outSize
//
size_t SZ_decompress(int dataType, unsigned char *bytes, size_t byteLength, size_t r1, unsigned char* outData)
T
tickduan 已提交
139
{
T
tickduan 已提交
140 141 142 143 144 145
	sz_exedata de_exe;
	memset(&de_exe, 0, sizeof(sz_exedata));

	sz_params  de_params;
	memset(&de_params, 0, sizeof(sz_params));
	
T
tickduan 已提交
146 147
	size_t outSize = 0;

T
tickduan 已提交
148 149
	if(dataType == SZ_FLOAT)
	{
T
tickduan 已提交
150 151 152 153 154 155
		int status = SZ_decompress_args_float((float*)outData, r1, bytes, byteLength, 0, NULL, &de_exe, &de_params);
		if(status == SZ_SUCCESS)
		{
			return r1*sizeof(float);
		}
		return 0;	
T
tickduan 已提交
156 157
	}
	else if(dataType == SZ_DOUBLE)
T
tickduan 已提交
158 159 160 161 162 163 164
	{		
		int status =  SZ_decompress_args_double((double*)outData, r1, bytes, byteLength, 0, NULL, &de_exe, &de_params);
		if(status == SZ_SUCCESS)
		{
			return r1*sizeof(double);
		}
		return 0;	
T
tickduan 已提交
165 166 167
	}
	else 
	{
T
tickduan 已提交
168
		printf("Error: data type cannot be the types other than SZ_FLOAT or SZ_DOUBLE\n");	
T
tickduan 已提交
169 170
	}

T
tickduan 已提交
171
    return outSize;
T
tickduan 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
}


void SZ_Finalize()
{
	if(confparams_dec!=NULL)
	{
		free(confparams_dec);
		confparams_dec = NULL;
	}
	if(confparams_cpr!=NULL)
	{
		free(confparams_cpr);
		confparams_cpr = NULL;
	}	
	if(exe_params!=NULL)
	{
		free(exe_params);
		exe_params = NULL;
	}
}

T
tickduan 已提交
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225



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);
}

double cost_end(const char* tag)
{
    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;
    double use_ms = totalCost*1000;
    printf(" timecost %s : %.3f ms\n", tag, use_ms);
    return use_ms; 
}

void show_rate(int in_len, int out_len)
{
  float rate=100*(float)out_len/(float)in_len;
  printf(" in_len=%d out_len=%d compress rate=%.4f%%\n", in_len, out_len, rate);
}