File: tst_quantize_par.c

package info (click to toggle)
netcdf-parallel 1%3A4.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 113,164 kB
  • sloc: ansic: 267,893; sh: 12,869; cpp: 5,822; yacc: 2,613; makefile: 1,813; lex: 1,216; xml: 173; awk: 2
file content (190 lines) | stat: -rw-r--r-- 5,722 bytes parent folder | download | duplicates (2)
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
/* This is part of the netCDF package.
   Copyright 2021 University Corporation for Atmospheric Research/Unidata
   See COPYRIGHT file for conditions of use.

   Test quantization of netcdf-4 variables with parallel
   I/O. Quantization is the zeroing-out of bits in float or double
   data beyond a desired precision.

   Ed Hartnett, 9/2/21
*/

#include <nc_tests.h>
#include "err_macros.h"
#include "netcdf.h"

#define TEST "tst_quantize"
#define FILE_NAME "tst_quantize_par.nc"
#define NDIM1 1
#define DIM_NAME_1 "DIM_1"
#define DIM_LEN_5 5
#define DIM_LEN_20 20
#define VAR_NAME_1 "VAR_1"
#define VAR_NAME_2 "VAR_2"
#define NSD_3 3
#define NSD_9 9

/* This var used to help print a float in hex. */
char pf_str[20];

/* This struct allows us to treat float as uint32_t
 * types. */
union FU {
    float f;
    uint32_t u;
};

/* This struct allows us to treat double points as uint64_t
 * types. */
union DU {
    double d;
    uint64_t u;
};

/* This function prints a float as hex. */
char *
pf(float myf)
{
    union {
	float f;
	uint32_t u;
    } fu;
    fu.f = myf;
    sprintf(pf_str, "0x%x", fu.u);
    return pf_str;
}

/* This function prints a double as hex. */
char *
pd(double myd)
{
    union {
	double d;
	uint64_t u;
    } du;
    du.d = myd;
    sprintf(pf_str, "0x%lx", du.u);
    return pf_str;
}

int
main(int argc, char **argv)
{

    int mpi_size, mpi_rank;
    MPI_Comm comm = MPI_COMM_WORLD;
    MPI_Info info = MPI_INFO_NULL;

    /* Initialize MPI. */
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);

    /* Must be run on exactly 4 processors. */
    if (mpi_size != 4)
    {
        if (mpi_rank == 0)
            printf("Test must be run on 4 processors.\n");
        return 2;
    }

    if (mpi_rank == 0)
    {
        printf("\n*** Testing netcdf-4 variable quantization with parallel I/O.\n");
        printf("**** testing quantization on four processors...");
    }
    {
        int ncid, dimid, varid1, varid2;
        int quantize_mode_in, nsd_in;
        float float_data[DIM_LEN_5] = {1.11111111, 1.0, 9.99999999, 12345.67, .1234567};
        double double_data[DIM_LEN_5] = {1.1111111, 1.0, 9.999999999, 1234567890.12345, 123456789012345.0};
        size_t start[NDIM1], count[NDIM1] = {DIM_LEN_5};
        int x;

        /* Create a netcdf-4 file with two vars. */
        if (nc_create_par(FILE_NAME, NC_NETCDF4|NC_CLOBBER, comm, info, &ncid)) ERR;
        if (nc_def_dim(ncid, DIM_NAME_1, DIM_LEN_20, &dimid)) ERR;
        if (nc_def_var(ncid, VAR_NAME_1, NC_FLOAT, NDIM1, &dimid, &varid1)) ERR;
        if (nc_def_var(ncid, VAR_NAME_2, NC_DOUBLE, NDIM1, &dimid, &varid2)) ERR;

        /* Turn on quantize for both vars. */
        if (nc_def_var_quantize(ncid, varid1, NC_QUANTIZE_BITGROOM, NSD_3)) ERR;
        if (nc_def_var_quantize(ncid, varid2, NC_QUANTIZE_BITGROOM, NSD_3)) ERR;

        /* Write some data. Each of the 4 processes writes the same 5
         * values, writing 20 in all. */
        start[0] = mpi_rank * DIM_LEN_5;
        if (nc_put_vara_float(ncid, varid1, start, count, float_data)) ERR;
        if (nc_put_vara_double(ncid, varid2, start, count, double_data)) ERR;

        /* Close the file. */
        if (nc_close(ncid)) ERR;

        {
            float float_in[DIM_LEN_5];
            double double_in[DIM_LEN_5];
            union FU {
                float f;
                uint32_t u;
            };

            union FU fin;
            /* union FU fout; */
            union FU xpect[DIM_LEN_5];
            union DU dfin;
            /* union DU dfout; */
            union DU double_xpect[DIM_LEN_5];

            xpect[0].u = 0x3f8e3000;
            xpect[1].u = 0x3f800fff;
            xpect[2].u = 0x41200000;
            xpect[3].u = 0x4640efff;
            xpect[4].u = 0x3dfcd000;
	    double_xpect[0].u = 0x3ff1c60000000000;
	    double_xpect[1].u = 0x3ff001ffffffffff;
	    double_xpect[2].u = 0x4023fe0000000000;
	    double_xpect[3].u = 0x41d265ffffffffff;
	    double_xpect[4].u = 0x42dc120000000000;

            /* Open the file and check metadata. */
            if (nc_open_par(FILE_NAME, NC_WRITE, comm, info, &ncid)) ERR;
            if (nc_inq_var_quantize(ncid, 0, &quantize_mode_in, &nsd_in)) ERR;
            if (quantize_mode_in != NC_QUANTIZE_BITGROOM || nsd_in != NSD_3) ERR;
            if (nc_inq_var_quantize(ncid, 1, &quantize_mode_in, &nsd_in)) ERR;
            if (quantize_mode_in != NC_QUANTIZE_BITGROOM || nsd_in != NSD_3) ERR;

            /* Check the data. */
            start[0] = mpi_rank * DIM_LEN_5;
            if (nc_get_vara_float(ncid, varid1, start, count, float_in)) ERR;
            if (nc_get_vara_double(ncid, varid2, start, count, double_in)) ERR;
            
            /* printf("\n"); */
            for (x = 0; x < DIM_LEN_5; x++)
            {
                /* fout.f = float_data[x]; */
                fin.f = float_in[x];
                /* printf ("float_data: %10f   : 0x%x  float_data_in: %10f   : 0x%x\n", */
                /*         float_data[x], fout.u, float_data[x], fin.u); */
                if (fin.u != xpect[x].u) ERR;
                /* dfout.d = double_data[x];		 */
	        dfin.d = double_in[x];
                /* printf("double_data: %15g   : 0x%16lx  double_data_in: %15g   : 0x%16lx\n", */
	        /*        double_data[x], dfout.u, double_data[x], dfin.u); */
                if (dfin.u != double_xpect[x].u) ERR;
            }

            /* Close the file again. */
            if (nc_close(ncid)) ERR;
        }
    }

    /* Shut down MPI. */
    MPI_Finalize();

    if (mpi_rank == 0)
    {
        SUMMARIZE_ERR;
        FINAL_RESULTS;
    }
    return 0;
}