Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

sensoroperations.cpp 6.09 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
//================================================================================
// Name        : sensoroperations.cpp
// Author      : Daniele Tafani
// Copyright   : Leibniz Supercomputing Centre
// Description : C++ API implementation for sensor operations.
//================================================================================

//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2018-2019 Leibniz Supercomputing Centre
11
//
12
13
14
15
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
16
//
17
18
19
20
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
21
//
22
23
24
25
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//================================================================================
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

#include <limits>
#include <cmath>
#include "dcdb/sensoroperations.h"

namespace DCDB {
    
void doubleToFraction(int64_t* num, int64_t* den, double number) {
    
    *den = 1;
    while((std::abs(number) - std::abs(floor(number)))) {
        number *= 10;
        *den *= 10;
    }
    *num = number;
}

/* Safe implementation of addition between 64-bit integers */
DCDB_OP_RESULT safeAdd(int64_t lh, int64_t rh, int64_t* result) {
    
    if ( (lh < 0.0) == (rh < 0.0)
        && std::abs(lh) > std::numeric_limits<int64_t>::max() - std::abs(rh) )
        return DCDB_OP_OVERFLOW;
    
    *result = (int64_t) lh + rh;
    
    return DCDB_OP_SUCCESS;
}

/* Safe multiplication for 64-bit integers */
DCDB_OP_RESULT safeMult(int64_t lh, int64_t rh, int64_t* result) {
    
    if (lh > 0 && rh > 0 && lh > std::numeric_limits<int64_t>::max() / rh) {
        *result = std::numeric_limits<int64_t>::max();
        return DCDB_OP_OVERFLOW;
    }
    if (lh < 0 && rh > 0 && lh < std::numeric_limits<int64_t>::min() / rh) {
        *result = std::numeric_limits<int64_t>::min();
        return DCDB_OP_OVERFLOW;
    }
    if (lh > 0 && rh < 0 && rh < std::numeric_limits<int64_t>::min() / lh) {
        *result = std::numeric_limits<int64_t>::min();
        return DCDB_OP_OVERFLOW;
    }
    if (lh < 0 && rh < 0 && (lh <= std::numeric_limits<int64_t>::min()
                             || rh <= std::numeric_limits<int64_t>::min()
                             || -lh > std::numeric_limits<int64_t>::max() / -rh)) {
        *result = std::numeric_limits<int64_t>::max();
        return DCDB_OP_OVERFLOW;
    }
    *result = lh*rh;
    
    return DCDB_OP_SUCCESS;
}
    
/* Scale function for double  */
DCDB_OP_RESULT scale(int64_t* result, double scalingFactor, double baseScalingFactor) {
    
    double factor = scalingFactor * baseScalingFactor;
    int64_t product = *result;
    
    if(std::abs(factor) - std::abs(floor(factor))) {
        
        int64_t num = 0;
        int64_t denom = 0;
        
        doubleToFraction(&num, &denom, factor);
        
        DCDB_OP_RESULT multResult = safeMult(num, *result, &product);
        
        if(multResult != DCDB_OP_SUCCESS) {
            *result = product;
            return multResult;
        }
        
        *result = product / denom;
        return DCDB_OP_SUCCESS;
    }
        
    return safeMult((int64_t) factor, product, result);
};

/* Safe delta function */
DCDB_OP_RESULT delta(int64_t lh, int64_t rh, int64_t* result) {
    
Daniele Tafani's avatar
Daniele Tafani committed
111
112
    //TODO: Need to address overflow for monotonic sensor data, e.g., energy reaching max value.
    //Maybe need to add another field to sensorconfig ("monotonic")?
113
114
115
116
117
    //Or need to pass the maximum value detectable by the sensor?
    
    *result = lh - rh;
    
    return DCDB_OP_SUCCESS;
118
119
120
121
122
123
124
125
126
127
128
};

DCDB_OP_RESULT delta(uint64_t lh, uint64_t rh, int64_t* result) {
	
	//TODO: Need to address overflow for monotonic sensor data, e.g., energy reaching max value.
	//Maybe need to add another field to sensorconfig ("monotonic")?
	//Or need to pass the maximum value detectable by the sensor?
	
	*result = lh - rh;
	
	return DCDB_OP_SUCCESS;
129
130
131
};

/* Safe implementation of a derivative */
132
DCDB_OP_RESULT derivative(int64_t lhx, int64_t rhx, uint64_t lht, uint64_t rht, int64_t* result, DCDB::Unit unit) {
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    
    int64_t dx = 0;
    uint64_t dt = 0;
    
    DCDB_OP_RESULT deltaResult = delta(lhx, rhx, &dx);
    
    if(deltaResult != DCDB_OP_SUCCESS) {
        *result = dx;
        return deltaResult;
    }
    
    dt = (int64_t) lht - rht;
    
    if(dt == 0)
        return DCDB_OP_DIVISION_BY_ZERO; //Presumably it's always != 0...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    
    uint64_t tsDivisor = 1;
    switch (unit) {
	case DCDB::Unit_Joules:
	case DCDB::Unit_KiloJoules:
	case DCDB::Unit_MegaJoules:
	    tsDivisor = 1000000000ll;
	    break;
	case DCDB::Unit_WattHours:
	case DCDB::Unit_KiloWattHours:
	case DCDB::Unit_MegaWattHours:
	    tsDivisor = 1000000000ll * 3600;
	    break;
	default:
	    break;
    }
    
    if (tsDivisor == 1) {
	*result = dx / dt;
    } else {
	*result = dx / ((double) dt / tsDivisor);
    }
170
171
172
173
174
    
    return DCDB_OP_SUCCESS;
};

/* Safe implementation of an integral */
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
200
201
DCDB_OP_RESULT integral(int64_t x, uint64_t lht, uint64_t rht, int64_t* result, DCDB::Unit unit) {
    int64_t dt = (int64_t) lht - rht;
    
    uint64_t tsDivisor = 1;
    switch (unit) {
	case DCDB::Unit_Watt:
	case DCDB::Unit_KiloWatt:
	case DCDB::Unit_MegaWatt:
	    tsDivisor = 1000000000ll;
	    break;
	default:
	    break;
    }

    if (tsDivisor == 1) {
	return safeMult(x, dt, result);
    } else {
	if (dt > 1000000000ll) {
	    dt/= 1000000;
	    tsDivisor/= 1000000;
	} else if (dt > 1000000ll) {
	    dt/= 1000;
	    tsDivisor/= 1000;
	}
	DCDB_OP_RESULT rc = safeMult(x, dt, result);
	*result = *result / tsDivisor;
	return rc;
202
203
204
205
    }
};

} /* end DCDB namespace */