Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

SMUCNGPerfOperator.cpp 21.6 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
//================================================================================
// Name        : SMUCNGPerfOperator.cpp
// Author      : Carla Guillen
// Contact     : info@dcdb.it
// Copyright   : Leibniz Supercomputing Centre
// Description : Template implementing features to use Units in Operators.
//================================================================================

//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2018-2019 Leibniz Supercomputing Centre
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//================================================================================
27

28
#include "SMUCNGPerfOperator.h"
29

30 31 32 33 34 35 36 37
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/formatting_ostream.hpp>
#include <boost/parameter/keyword.hpp>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
38
#include <numeric>
39 40 41 42 43 44 45 46

#include "../../../common/include/cacheentry.h"
#include "../../../common/include/logging.h"
#include "../../../common/include/sensorbase.h"
#include "../../../common/include/timestamp.h"
#include "../../includes/QueryEngine.h"
#include "../../includes/UnitTemplate.h"
#include "SKXPMUMetrics.h"
47
#include "../../includes/CommonStatistics.h"
48

Carla Guillen's avatar
Carla Guillen committed
49
SMUCNGPerfOperator::SMUCNGPerfOperator(const std::string& name): OperatorTemplate(name), _go_back_ns(0), _measuring_interval_s(1) {
50
    _buffers.resize(64);
51 52
    _metricPerSecToId[SMUCSensorBase::INSTRUCTIONS_PER_SECOND] = SMUCSensorBase::INSTRUCTIONS;
    _metricPerSecToId[SMUCSensorBase::EXPENSIVE_INSTRUCTIONS_PER_SECOND] = SMUCSensorBase::ARITH_FPU_DIVIDER_ACTIVE;
Carla Guillen's avatar
Carla Guillen committed
53
//    _metricToPerSecId[SMUCSensorBase::L2_HITS] = SMUCSensorBase::L2_HITS_PER_SECOND;
54 55 56 57
    _metricPerSecToId[SMUCSensorBase::L2_MISSES_PER_SECOND] = SMUCSensorBase::L2_RQSTS_MISS;
    _metricPerSecToId[SMUCSensorBase::L3_HITS_PER_SECOND] = SMUCSensorBase::MEM_LOAD_RETIRED_L3_HIT;
    _metricPerSecToId[SMUCSensorBase::L3_MISSES_PER_SECOND] = SMUCSensorBase::MEM_LOAD_RETIRED_L3_MISS;
    _metricPerSecToId[SMUCSensorBase::MISSBRANCHES_PER_SECOND] = SMUCSensorBase::PERF_COUNT_HW_BRANCH_MISSES;
58 59
    _metricPerSecToId[SMUCSensorBase::NETWORK_BYTES_XMIT_PER_SECOND] = SMUCSensorBase::NETWORK_XMIT_BYTES;
    _metricPerSecToId[SMUCSensorBase::NETWORK_BYTES_RCVD_PER_SECOND] = SMUCSensorBase::NETWORK_RCVD_BYTES;
60 61 62 63 64 65
    _metricPerSecToId[SMUCSensorBase::IOOPENS_PER_SECOND] = SMUCSensorBase::IOOPENS;
    _metricPerSecToId[SMUCSensorBase::IOCLOSES_PER_SECOND] = SMUCSensorBase::IOCLOSES;
    _metricPerSecToId[SMUCSensorBase::IOBYTESREAD_PER_SECOND] = SMUCSensorBase::IOBYTESREAD;
    _metricPerSecToId[SMUCSensorBase::IOBYTESWRITE_PER_SECOND] = SMUCSensorBase::IOBYTESWRITE;
    _metricPerSecToId[SMUCSensorBase::IOREADS_PER_SECOND] = SMUCSensorBase::IOREADS;
    _metricPerSecToId[SMUCSensorBase::IOWRITES_PER_SECOND] = SMUCSensorBase::IOWRITES;
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::L3_TO_INSTRUCTIONS_RATIO),
			std::forward_as_tuple(SMUCSensorBase::MEM_LOAD_UOPS_RETIRED_L3_MISS, SMUCSensorBase::INSTRUCTIONS));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::CPI),
				std::forward_as_tuple(SMUCSensorBase::CLOCKS, SMUCSensorBase::INSTRUCTIONS));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::LOADS_TO_STORES),
			std::forward_as_tuple(SMUCSensorBase::MEM_INST_RETIRED_ALL_LOADS, SMUCSensorBase::MEM_INST_RETIRED_ALL_STORES));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::BRANCH_PER_INSTRUCTIONS),
			std::forward_as_tuple(SMUCSensorBase::PERF_COUNT_HW_BRANCH_MISSES, SMUCSensorBase::INSTRUCTIONS));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::MISSBRANCHES_TO_TOTAL_BRANCH_RATIO),
			std::forward_as_tuple(SMUCSensorBase::PERF_COUNT_HW_BRANCH_MISSES,SMUCSensorBase::PERF_COUNT_HW_BRANCH_INSTRUCTIONS));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::LOADS_TOL3MISS_RATIO),
			std::forward_as_tuple(SMUCSensorBase::MEM_INST_RETIRED_ALL_LOADS, SMUCSensorBase::MEM_LOAD_UOPS_RETIRED_L3_MISS));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::IO_BYTES_READ_PER_OP),
			std::forward_as_tuple(SMUCSensorBase::IOBYTESREAD, SMUCSensorBase::IOREADS));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::IO_BYTES_WRITE_PER_OP),
				std::forward_as_tuple(SMUCSensorBase::IOBYTESWRITE, SMUCSensorBase::IOWRITES));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::NETWORK_XMIT_BYTES_PER_PKT),
					std::forward_as_tuple(SMUCSensorBase::NETWORK_XMIT_BYTES, SMUCSensorBase::NETWORK_XMIT_PKTS));
	_metricRatioToPair.emplace(std::piecewise_construct, std::forward_as_tuple(SMUCSensorBase::NETWORK_RCV_BYTES_PER_PKT),
					std::forward_as_tuple(SMUCSensorBase::NETWORK_RCVD_BYTES, SMUCSensorBase::NETWORK_RCVD_PKTS));
87 88 89 90 91 92 93

	_profileMetricToMetricIds[SMUCSensorBase::IOBYTESREAD_PER_SECOND_PROF]=	{SMUCSensorBase::IOBYTESREAD};
	_profileMetricToMetricIds[SMUCSensorBase::IOBYTESWRITE_PER_SECOND_PROF] = {SMUCSensorBase::IOBYTESWRITE};
	_profileMetricToMetricIds[SMUCSensorBase::IOREADS_PER_SECOND_PROF] = {SMUCSensorBase::IOREADS};
	_profileMetricToMetricIds[SMUCSensorBase::IOWRITES_PER_SECOND_PROF] = {SMUCSensorBase::IOWRITES};
	_profileMetricToMetricIds[SMUCSensorBase::IO_BYTES_READ_PER_OP_PROF] = {SMUCSensorBase::IOBYTESREAD, SMUCSensorBase::IOREADS};
	_profileMetricToMetricIds[SMUCSensorBase::IO_BYTES_WRITE_PER_OP_PROF] = {SMUCSensorBase::IOBYTESWRITE, SMUCSensorBase::IOWRITES};
94 95
}

96
SMUCNGPerfOperator::~SMUCNGPerfOperator() {
97 98
}

99
SMUCNGPerfOperator::SMUCNGPerfOperator(const SMUCNGPerfOperator& other) : OperatorTemplate(other){
100
    copy(other);
101 102 103
}

SMUCNGPerfOperator& SMUCNGPerfOperator::operator=(const SMUCNGPerfOperator& other){
Carla Guillen's avatar
Carla Guillen committed
104
    OperatorTemplate::operator =(other);
105 106 107 108 109
    copy(other);
    return *this;
}

void SMUCNGPerfOperator::copy(const SMUCNGPerfOperator& other){
Carla Guillen's avatar
Carla Guillen committed
110 111
    this->_buffers = other._buffers;
    this->_metricToPosition = other._metricToPosition;
Carla Guillen's avatar
Carla Guillen committed
112 113
    this->_measuring_interval_s = other._measuring_interval_s;
    this->_go_back_ns = other._go_back_ns;
114
    this->_metricPerSecToId = other._metricPerSecToId;
115 116
}

117
void SMUCNGPerfOperator::printConfig(LOG_LEVEL ll) {
118
    OperatorTemplate<SMUCSensorBase>::printConfig(ll);
119
    LOG_VAR(ll) << "Operator " << _name << ":";
120
    LOG_VAR(ll) << "Metric to position map size(" << _metricToPosition.size() << "):";
121
    for(auto &kv : _metricToPosition){
122
    	LOG_VAR(ll) << "\tMetric = " << kv.first << " Position = " << kv.second;
123
    }
Carla Guillen's avatar
Carla Guillen committed
124 125
    LOG_VAR(ll) << "_measuring_interval_s = " << _measuring_interval_s;
    LOG_VAR(ll) << "_go_back_ns = " << _go_back_ns;
126 127
}

128
void SMUCNGPerfOperator::compute(U_Ptr unit) {
129
	auto inputs = unit->getInputs();
Carla Guillen's avatar
Carla Guillen committed
130
	auto timestamp = getTimestamp() - _go_back_ns;
131
	for(auto& outSensor : unit->getOutputs()){
132 133 134 135
		if(outSensor->getMetadata() == nullptr){
			LOG(error) << "No metadata defined, sensor " << outSensor->getName() <<  " can't compute anything.";
			continue;
		}
136
		if (outSensor->getMetric() == SMUCSensorBase::FREQUENCY) {
137 138 139 140 141
			computeFREQUENCY(inputs, outSensor, timestamp);
		} else if (outSensor->getMetric() == SMUCSensorBase::FLOPS || outSensor->getMetric() == SMUCSensorBase::PACKED_FLOPS ||
				outSensor->getMetric() == SMUCSensorBase::AVX512_TOVECTORIZED_RATIO || outSensor->getMetric() == SMUCSensorBase::VECTORIZED_RATIO ||
				outSensor->getMetric() == SMUCSensorBase::SINGLE_PRECISION_TO_TOTAL_RATIO) {
			computeFLOPS(inputs, outSensor, timestamp);
Carla Guillen Carias's avatar
Carla Guillen Carias committed
142 143 144 145
		} else if (outSensor->getMetric() == SMUCSensorBase::L3HIT_TO_L3MISS_RATIO ){
			computeL3HIT_TO_L3MISS_RATIO(inputs, outSensor, timestamp);
		} else if (outSensor->getMetric() == SMUCSensorBase::MEMORY_BANDWIDTH) {
			computeMEMORY_BANDWIDTH(inputs, outSensor, timestamp);
Carla Guillen's avatar
Carla Guillen committed
146
		} else if (isAMetricPerSecond(outSensor->getMetric())){
147 148 149
			computeMetricPerSecond(inputs, outSensor, timestamp);
		} else if (isAMetricRatio(outSensor->getMetric())){
			computeMetricRatio(inputs, outSensor, timestamp);
150 151 152 153 154
		} else if (isAProfileMetric(outSensor->getMetric())){
			computeProfileMetric(inputs, outSensor, timestamp);
		} else if (outSensor->getMetric() == SMUCSensorBase::INTER_NODE_LOADIMBALANCE ||
				outSensor->getMetric() == SMUCSensorBase::INTRA_NODE_LOADIMBALANCE) {
			computeLOADIMBALANCES(inputs, outSensor, timestamp);
155 156
		} else {
			LOG(error) << "Derived metric " << outSensor->getMetric() << " not implemented.";
157
		}
Carla Guillen Carias's avatar
Carla Guillen Carias committed
158 159 160 161
		resetBuffers();
	}
}

Carla Guillen's avatar
Carla Guillen committed
162
void SMUCNGPerfOperator::query(const std::string & sensor_name, const uint64_t timestamp, vector<reading_t> &buffer){
Carla Guillen's avatar
Bug fix  
Carla Guillen committed
163
	if(!_queryEngine.querySensor(sensor_name, timestamp, timestamp, buffer, false)) {
164
		//LOG(debug) << "SMUCNGPerf Operator " << _name << " cannot read from sensor " << sensor_name  << "!";
Carla Guillen's avatar
Carla Guillen committed
165
	}
166 167
}

Carla Guillen Carias's avatar
Carla Guillen Carias committed
168 169 170
void SMUCNGPerfOperator::resetBuffers(){
	for(auto &buffer: _buffers){
		buffer.clear();
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
void SMUCNGPerfOperator::computeMetricPerSecond(std::vector<SMUCNGPtr> &inputs, SMUCNGPtr& outSensor, const uint64_t timestamp) {
	auto found = _metricPerSecToId.find(outSensor->getMetric());
	if(found == _metricPerSecToId.end()) { //not found
		LOG(error) << "Metric per second " << outSensor->getMetric() << " not implemented.";
		return;
	}
	SMUCSensorBase::Metric_t metric = found->second;
	query(inputs[_metricToPosition[metric]]->getName(), timestamp, _buffers[0]);
	reading_t metricpersec;
	if(_buffers[0].size() > 0 && calculateMetricPerSec(_buffers[0][0], _measuring_interval_s, metricpersec, outSensor->getMetadata()->scale)){
		outSensor->storeReading(metricpersec);
	}
}

void SMUCNGPerfOperator::computeMetricRatio(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr &outSensor, const uint64_t timestamp){
	std::vector<reading_t> & dividend = _buffers[0];
	std::vector<reading_t> & divisor = _buffers[1];
	auto found = _metricRatioToPair.find(outSensor->getMetric());
	if(found == _metricRatioToPair.end()) { //not found
		LOG(error) << "Metric ratio " << outSensor->getMetric() << " not implemented.";
		return;
	}
	SMUCSensorBase::Metric_t metric_dividend = found->second.first;
	SMUCSensorBase::Metric_t metric_divisor = found->second.second;
	query(inputs[_metricToPosition[metric_dividend]]->getName(), timestamp, dividend);
	query(inputs[_metricToPosition[metric_divisor]]->getName(), timestamp, divisor);
200 201
	bool wascalced = false;
	reading_t cpi;
202
	if (dividend.size() > 0 && divisor.size() > 0 && calculateMetricRatio(dividend[0], divisor[0], cpi, outSensor->getMetadata()->scale)) {
203 204 205 206
		outSensor->storeReading(cpi);
	}
}

207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
void SMUCNGPerfOperator::computeProfileMetric(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr &outSensor, const uint64_t timestamp){
	auto queryMetrics = _profileMetricToMetricIds[outSensor->getMetric()]; //should be here since this was queried in the compute() member function
	for(std::size_t i = 0; i < queryMetrics.size(); ++i){
		if(!_queryEngine.querySensor(inputs[_metricToPosition[queryMetrics[i]]]->getName(), timestamp - (_interval * 1e6), timestamp, _buffers[i], false)){
			LOG(debug) << "Could not find data for " << queryMetrics[i] << " metric.";
			return;
		}
	}
	auto value = computeSum(_buffers[0]);
	reading_t result;
	if(queryMetrics.size()==2){ //_buffer[0] and _buffer[1] should have been filled
		auto second_value = computeSum(_buffers[1]);
		if(second_value != 0){
			result.value =  value / (outSensor->getMetadata()->scale * static_cast<double>(second_value));
			result.timestamp =  _buffers[0][0].timestamp;
			outSensor->storeReading(result);
		}
	} else { //only one buffer was filled
		result.value = value / (outSensor->getMetadata()->scale * (_interval/1000.0));
		result.timestamp = _buffers[0][0].timestamp;
		outSensor->storeReading(result);
	}

}

void SMUCNGPerfOperator::computeLOADIMBALANCES(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr &outSensor, const uint64_t timestamp){
	//query for every cpu
	std::vector<reading_t> & cpus_vec = _buffers[0];
	for(auto & input: inputs){
		query(input->getName(), timestamp, cpus_vec);
	}
	if(cpus_vec.size() == 0) {
		return;
	}
	reading_t result;
	result.timestamp = cpus_vec.begin()->timestamp;
	if(outSensor->getMetric() == SMUCSensorBase::INTRA_NODE_LOADIMBALANCE){
		//calculate max - min
		auto smallest = std::min_element(cpus_vec.begin(), cpus_vec.end(),
				[](const reading_t& l, const reading_t& r) -> bool {return l.value < r.value;});

		auto largest = std::max_element(cpus_vec.begin(), cpus_vec.end(),
				[](const reading_t& l, const reading_t& r) -> bool {return l.value < r.value;});

		result.value = largest->value - smallest->value;

	} else if (outSensor->getMetric() == SMUCSensorBase::INTRA_NODE_LOADIMBALANCE) {
		//calculate avg
		result.value = computeAvg(cpus_vec);
	}
	outSensor->storeReading(result);
}



262 263 264 265 266 267
void SMUCNGPerfOperator::computeFREQUENCY(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr& outSensor, const uint64_t timestamp) {
	std::vector<reading_t> & clocks = _buffers[0];
	std::vector<reading_t> & clocks_ref = _buffers[1];
	query(inputs[_metricToPosition[SMUCSensorBase::CLOCKS]]->getName(), timestamp, clocks);
	query(inputs[_metricToPosition[SMUCSensorBase::CLOCKS_REF]]->getName(), timestamp, clocks_ref);
	reading_t frequency;
268
	if( clocks.size() > 0 && clocks_ref.size() > 0 && calculateFrequency(clocks_ref[0],clocks[0], MIN_FREQ_MHZ, MAX_FREQ_MHZ, frequency, outSensor->getMetadata()->scale)) {
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
		outSensor->storeReading(frequency);
	}
}

void SMUCNGPerfOperator::computeFLOPS(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr& outSensor, const uint64_t timestamp) {
	SMUCSensorBase::Metric_t flop_metric = outSensor->getMetric();
	std::vector<reading_t> & fp_arith_scalar_double = _buffers[0];
	std::vector<reading_t> & fp_arith_scalar_single = _buffers[1];
	std::vector<reading_t> & fp_arith_128b_packed_double = _buffers[2];
	std::vector<reading_t> & fp_arith_128b_packed_single = _buffers[3];
	std::vector<reading_t> & fp_arith_256b_packed_double = _buffers[4];
	std::vector<reading_t> & fp_arith_256b_packed_single = _buffers[5];
	std::vector<reading_t> & fp_arith_512b_packed_double = _buffers[6];
	std::vector<reading_t> & fp_arith_512b_packed_single = _buffers[7];


	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_SCALAR_DOUBLE]]->getName(), timestamp, fp_arith_scalar_double);
	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_SCALAR_SINGLE]]->getName(), timestamp, fp_arith_scalar_single);
	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_128B_PACKED_DOUBLE]]->getName(), timestamp, fp_arith_128b_packed_double);
	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_128B_PACKED_SINGLE]]->getName(), timestamp, fp_arith_128b_packed_single);
	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_256B_PACKED_DOUBLE]]->getName(), timestamp, fp_arith_256b_packed_double);
	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_256B_PACKED_SINGLE]]->getName(), timestamp, fp_arith_256b_packed_single);
	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_512B_PACKED_DOUBLE]]->getName(), timestamp, fp_arith_512b_packed_double);
	query(inputs[_metricToPosition[SMUCSensorBase::FP_ARITH_512B_PACKED_SINGLE]]->getName(), timestamp, fp_arith_512b_packed_single);
	reading_t empty;
	empty.value = 0;
	empty.timestamp = 0;
	reading_t & scalar_double = fp_arith_scalar_double.size() > 0 ? fp_arith_scalar_double[0]: empty;
	reading_t & scalar_single = fp_arith_scalar_single.size() > 0 ? fp_arith_scalar_single[0]: empty;
	reading_t & packed128_double = fp_arith_128b_packed_double.size() > 0 ? fp_arith_128b_packed_double[0] : empty;
	reading_t & packed128_single = fp_arith_128b_packed_single.size() > 0 ? fp_arith_128b_packed_single[0] : empty;
	reading_t & packed256_double =  fp_arith_256b_packed_double.size() > 0 ?  fp_arith_256b_packed_double[0] : empty;
	reading_t & packed256_single = fp_arith_256b_packed_single.size() > 0 ? fp_arith_256b_packed_single[0] : empty;
	reading_t & packed512_double =  fp_arith_512b_packed_double.size() > 0 ?  fp_arith_512b_packed_double[0] :empty;
	reading_t & packed512_single = fp_arith_512b_packed_single.size() > 0 ? fp_arith_512b_packed_single[0] : empty;

	reading_t result;
	if(flop_metric == SMUCSensorBase::FLOPS) {
307
		if (calculateFlopsPerSec(scalar_double, scalar_single, packed128_double,
308
				packed128_single, packed256_double, packed256_single,
309
				packed512_double, packed512_single, result, outSensor->getMetadata()->scale, _measuring_interval_s) ) {
310 311 312
			outSensor->storeReading(result);
		}
	} else if(flop_metric == SMUCSensorBase::PACKED_FLOPS){
313 314 315
		if (calculatePackedFlopsPerSec(packed128_double, packed128_single,
				packed256_double, packed256_single, packed512_double,
				packed512_single, result, outSensor->getMetadata()->scale, _measuring_interval_s)) {
316 317 318 319 320
			outSensor->storeReading(result);
		}
	} else if(flop_metric == SMUCSensorBase::VECTORIZED_RATIO) {
		if(calculateVectorizationRatio(scalar_double, scalar_single, packed128_double,
				packed128_single, packed256_double, packed256_single,
321
				packed512_double, packed512_single, result, outSensor->getMetadata()->scale)) {
322 323 324 325 326
			outSensor->storeReading(result);
		}
	} else if (flop_metric == SMUCSensorBase::AVX512_TOVECTORIZED_RATIO) {
		if (calculateAVX512FlopsToVectorizedRatio(packed128_double,
				packed128_single, packed256_double, packed256_single,
327
				packed512_double, packed512_single, result, outSensor->getMetadata()->scale )) {
328 329 330 331 332
			outSensor->storeReading(result);
		}
	} else if (flop_metric == SMUCSensorBase::SINGLE_PRECISION_TO_TOTAL_RATIO) {
		if(calculateSP_TO_TOTAL_RATIO(scalar_double, scalar_single, packed128_double,
				packed128_single, packed256_double, packed256_single,
333
				packed512_double, packed512_single, result, outSensor->getMetadata()->scale)){
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
			outSensor->storeReading(result);
		}
	}
}



/*void SMUCNGPerfOperator::computeINSTR_INTRA_NODE_LOADIMBALANCE(std::vector<SMUCNGPtr>& inputs,
		SMUCNGPtr& outSensor, const uint64_t timestamp) {
}*/

void SMUCNGPerfOperator::computeL3_BANDWIDTH(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr& outSensor,
		const uint64_t timestamp) {
}

void SMUCNGPerfOperator::computeL3HIT_TO_L3MISS_RATIO(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr& outSensor,
		const uint64_t timestamp) {
Carla Guillen Carias's avatar
Carla Guillen Carias committed
351 352 353 354 355 356 357 358
	//MEM_LOAD_UOPS_RETIRED_L3_MISS/(MEM_LOAD_RETIRED_L3_HIT+MEM_LOAD_RETIRED_L3_MISS
	std::vector<reading_t> & l3_misses = _buffers[0];
	std::vector<reading_t> & l3_hits = _buffers[1];
	std::vector<reading_t> & l3_load_miss = _buffers[2];
	query(inputs[_metricToPosition[SMUCSensorBase::MEM_LOAD_UOPS_RETIRED_L3_MISS]]->getName(), timestamp, l3_misses);
	query(inputs[_metricToPosition[SMUCSensorBase::MEM_LOAD_RETIRED_L3_HIT]]->getName(), timestamp, l3_hits);
	query(inputs[_metricToPosition[SMUCSensorBase::MEM_LOAD_RETIRED_L3_MISS]]->getName(), timestamp, l3_load_miss);
	reading_t l3hitToMissRatio;
359
	if (l3_misses.size() > 0 && l3_hits.size() > 0 && l3_load_miss.size() > 0 && calculateL3HitToL3MissRatio(l3_misses[0], l3_hits[0], l3_load_miss[0], l3hitToMissRatio, outSensor->getMetadata()->scale)) {
Carla Guillen Carias's avatar
Carla Guillen Carias committed
360 361
		outSensor->storeReading(l3hitToMissRatio);
	}
362 363
}

364 365 366 367
void SMUCNGPerfOperator::computeMEMORY_BANDWIDTH(std::vector<SMUCNGPtr>& inputs, SMUCNGPtr& outSensor, const uint64_t timestamp) {
	std::vector<reading_t> & mem_counters = _buffers[0];

	reading_t memory_bw;
368 369 370 371 372 373 374 375 376 377 378 379
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_READ0]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_READ1]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_READ2]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_READ3]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_READ4]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_READ5]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_WRITE0]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_WRITE1]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_WRITE2]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_WRITE3]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_WRITE4]]->getName(), timestamp, mem_counters);	
	query(inputs[_metricToPosition[SMUCSensorBase::CAS_COUNT_WRITE5]]->getName(), timestamp, mem_counters);	
380
	if(mem_counters.size() > 0 && calculateMemoryBandwidth(mem_counters, memory_bw, _measuring_interval_s, outSensor->getMetadata()->scale)){
381 382 383
		outSensor->storeReading(memory_bw);
	}
	
384
}
Carla Guillen's avatar
Carla Guillen committed
385 386

bool SMUCNGPerfOperator::isAMetricPerSecond(SMUCSensorBase::Metric_t comp){
387 388 389 390 391 392 393 394
	if(_metricPerSecToId.find(comp) != _metricPerSecToId.end() ){ //found
		return true;
	}
	return false;
}

bool SMUCNGPerfOperator::isAMetricRatio(SMUCSensorBase::Metric_t comp){
	if(_metricRatioToPair.find(comp) != _metricRatioToPair.end()){
Carla Guillen's avatar
Carla Guillen committed
395 396 397 398
		return true;
	}
	return false;
}
399 400 401 402 403 404 405

bool SMUCNGPerfOperator::isAProfileMetric(SMUCSensorBase::Metric_t comp){
	if(_profileMetricToMetricIds.find(comp) != _profileMetricToMetricIds.end()){
		return true;
	}
	return false;
}