sz.c 5.5 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
/**
 *  @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 "conf.h"
#include "utility.h"
T
tickduan 已提交
24

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

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

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

//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

T
tickduan 已提交
50

T
tickduan 已提交
51 52 53

int SZ_Init(const char *configFilePath)
{
T
tickduan 已提交
54 55 56 57 58 59 60 61
	// 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 已提交
62
	int loadFileResult = SZ_LoadConf(configFilePath);
T
tickduan 已提交
63 64
	if(loadFileResult==SZ_FAILED)
		return SZ_FAILED;
T
tickduan 已提交
65
	
T
tickduan 已提交
66
	exe_params->SZ_SIZE_TYPE = SZ_SIZE_TYPE_DEFUALT;
T
tickduan 已提交
67 68 69 70
	if(confparams_cpr->szMode == SZ_TEMPORAL_COMPRESSION)
	{
		initSZ_TSC();
	}
T
tickduan 已提交
71
	return SZ_SUCCESS;
T
tickduan 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
}

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 已提交
89
		return SZ_FAILED;
T
tickduan 已提交
90 91
	}

T
tickduan 已提交
92
	return SZ_SUCCESS;
T
tickduan 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105
}


/*-------------------------------------------------------------------------*/
/**
    @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 已提交
106 107 108 109 110

//
//  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 已提交
111
{
T
tickduan 已提交
112
	size_t outSize = 0;
T
tickduan 已提交
113
	int status;
T
tickduan 已提交
114 115
	if(dataType==SZ_FLOAT)
	{
T
tickduan 已提交
116
		status = SZ_compress_args_float((float *)data, r1, outData,  &outSize, params);		
T
tickduan 已提交
117 118 119
	}
	else if(dataType==SZ_DOUBLE)
	{
T
tickduan 已提交
120
		status = SZ_compress_args_double((double *)data, r1, outData,  &outSize, params);
T
tickduan 已提交
121 122 123
	}
	else
	{
T
tickduan 已提交
124 125
		printf("Error: dataType can only be SZ_FLOAT, SZ_DOUBLE .\n");
		return 0;
T
tickduan 已提交
126 127
	}

T
tickduan 已提交
128
	return outSize;
T
tickduan 已提交
129 130
}

T
tickduan 已提交
131 132 133 134
//
// 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 已提交
135
{
T
tickduan 已提交
136 137 138 139 140 141
	sz_exedata de_exe;
	memset(&de_exe, 0, sizeof(sz_exedata));

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

T
tickduan 已提交
144 145
	if(dataType == SZ_FLOAT)
	{
T
tickduan 已提交
146 147 148 149 150 151
		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 已提交
152 153
	}
	else if(dataType == SZ_DOUBLE)
T
tickduan 已提交
154 155 156 157 158 159 160
	{		
		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 已提交
161 162 163
	}
	else 
	{
T
tickduan 已提交
164
		printf("Error: data type cannot be the types other than SZ_FLOAT or SZ_DOUBLE\n");	
T
tickduan 已提交
165 166
	}

T
tickduan 已提交
167
    return outSize;
T
tickduan 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
}


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 已提交
190 191 192 193 194 195 196 197 198
void modulePath(char *buf, int size)
{
  char path[1024];
  sprintf(path, "/proc/%d/exe", getpid());  
  readlink(path, buf, size);
  char* pos = strrchr(buf, '/');
  if(pos)
    pos[1]=0;
}
T
tickduan 已提交
199 200 201 202 203 204 205 206


struct timeval startTime;
struct timeval endTime;  /* Start and end times */
struct timeval costStart; /*only used for recording the cost*/
double totalCost = 0;


T
tickduan 已提交
207

T
tickduan 已提交
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
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);
}