sz.c 4.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 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 194 195 196 197 198 199
/**
 *  @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 "conf.h"
#include "utility.h"


//#include "CurveFillingCompressStorage.h"

unsigned char versionNumber = DATA_FROMAT_VER1;
int SZ_SIZE_TYPE_DEFUALT = 4;

int dataEndianType = LITTLE_ENDIAN_DATA; //*endian type of the data read from disk
int sysEndianType  = LITTLE_ENDIAN_SYSTEM ; //*sysEndianType is actually set automatically.

//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)
{
	// check CPU EndianType
	int x = 1;
	char *y = (char*)&x;
	if(*y==1)
		sysEndianType = LITTLE_ENDIAN_SYSTEM;
	else //=0
		sysEndianType = BIG_ENDIAN_SYSTEM;

	int loadFileResult = SZ_LoadConf(configFilePath);
	if(loadFileResult==SZ_FAILED)
		return SZ_FAILED;
	
	exe_params->SZ_SIZE_TYPE = SZ_SIZE_TYPE_DEFUALT;
	return SZ_SUCCESS;
}

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");
		return SZ_FAILED;
	}

	return SZ_SUCCESS;
}


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

 **/
/*-------------------------------------------------------------------------*/

//
//  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)
{
	size_t outSize = 0;
	if(dataType==SZ_FLOAT)
	{
		SZ_compress_args_float((float *)data, r1, outData,  &outSize, params);		
	}
	else if(dataType==SZ_DOUBLE)
	{
		SZ_compress_args_double((double *)data, r1, outData,  &outSize, params);
	}
	else
	{
		printf("Error: dataType can only be SZ_FLOAT, SZ_DOUBLE .\n");
		return 0;
	}

	return outSize;
}

//
// 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)
{
	sz_exedata de_exe;
	memset(&de_exe, 0, sizeof(sz_exedata));

	sz_params  de_params;
	memset(&de_params, 0, sizeof(sz_params));
	
	size_t outSize = 0;

	if(dataType == SZ_FLOAT)
	{
		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;	
	}
	else if(dataType == SZ_DOUBLE)
	{		
		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;	
	}
	else 
	{
		printf("Error: data type cannot be the types other than SZ_FLOAT or SZ_DOUBLE\n");	
	}

    return outSize;
}

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


#ifdef WINDOWS
#include <windows.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

#else
#include <sys/time.h>
#endif

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