sz.c 5.0 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
/**
 *  @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 "sz.h"
#include "CompressElement.h"
#include "DynamicByteArray.h"
#include "TightDataPointStorageD.h"
#include "TightDataPointStorageF.h"
#include "zlib.h"
#include "conf.h"
#include "utility.h"
T
tickduan 已提交
22

T
tickduan 已提交
23

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

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

int dataEndianType = LITTLE_ENDIAN_DATA; //*endian type of the data read from disk
T
tickduan 已提交
30
int sysEndianType  = LITTLE_ENDIAN_SYSTEM ; //*sysEndianType is actually set automatically.
T
tickduan 已提交
31 32 33 34 35 36 37

//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_exedata *exe_params = NULL;

int SZ_Init(const char *configFilePath)
{
T
tickduan 已提交
38 39 40 41 42 43 44 45
	// 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 已提交
46
	int loadFileResult = SZ_LoadConf(configFilePath);
T
tickduan 已提交
47 48
	if(loadFileResult==SZ_FAILED)
		return SZ_FAILED;
T
tickduan 已提交
49
	
T
tickduan 已提交
50
	exe_params->SZ_SIZE_TYPE = SZ_SIZE_TYPE_DEFUALT;
T
tickduan 已提交
51
	return SZ_SUCCESS;
T
tickduan 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
}

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 已提交
69
		return SZ_FAILED;
T
tickduan 已提交
70 71
	}

T
tickduan 已提交
72
	return SZ_SUCCESS;
T
tickduan 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85
}


/*-------------------------------------------------------------------------*/
/**
    @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 已提交
86 87 88 89 90

//
//  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 已提交
91
{
T
tickduan 已提交
92
	size_t outSize = 0;
T
tickduan 已提交
93 94
	if(dataType==SZ_FLOAT)
	{
T
tickduan 已提交
95
		SZ_compress_args_float((float *)data, r1, outData,  &outSize, params);		
T
tickduan 已提交
96 97 98
	}
	else if(dataType==SZ_DOUBLE)
	{
T
tickduan 已提交
99
		SZ_compress_args_double((double *)data, r1, outData,  &outSize, params);
T
tickduan 已提交
100 101 102
	}
	else
	{
T
tickduan 已提交
103 104
		printf("Error: dataType can only be SZ_FLOAT, SZ_DOUBLE .\n");
		return 0;
T
tickduan 已提交
105 106
	}

T
tickduan 已提交
107
	return outSize;
T
tickduan 已提交
108 109
}

T
tickduan 已提交
110 111 112 113
//
// 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 已提交
114
{
T
tickduan 已提交
115 116 117 118 119 120
	sz_exedata de_exe;
	memset(&de_exe, 0, sizeof(sz_exedata));

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

T
tickduan 已提交
123 124
	if(dataType == SZ_FLOAT)
	{
T
tickduan 已提交
125 126 127 128 129 130
		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 已提交
131 132
	}
	else if(dataType == SZ_DOUBLE)
T
tickduan 已提交
133 134 135 136 137 138 139
	{		
		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 已提交
140 141 142
	}
	else 
	{
T
tickduan 已提交
143
		printf("Error: data type cannot be the types other than SZ_FLOAT or SZ_DOUBLE\n");	
T
tickduan 已提交
144 145
	}

T
tickduan 已提交
146
    return outSize;
T
tickduan 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
}

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

T
tickduan 已提交
163

T
tickduan 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
#ifdef WINDOWS
int gettimeofday(struct timeval *tv, struct timezone *tz) {
  time_t t;
  t = time(NULL);
  SYSTEMTIME st;
  GetLocalTime(&st);

  tv->tv_sec = (long)t;
  tv->tv_usec = st.wMilliseconds * 1000;

  return 0;
}
#else
#include <sys/time.h>
#endif
T
tickduan 已提交
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

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);
}
T
tickduan 已提交
208