246 lines
7.7 KiB
C++
246 lines
7.7 KiB
C++
/*
|
|
* Copyright (C) 2017-2019 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "runtime/os_interface/performance_counters.h"
|
|
|
|
#include "runtime/utilities/tag_allocator.h"
|
|
|
|
using namespace MetricsLibraryApi;
|
|
|
|
namespace NEO {
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters constructor.
|
|
//////////////////////////////////////////////////////
|
|
PerformanceCounters::PerformanceCounters() {
|
|
metricsLibrary = std::make_unique<MetricsLibrary>();
|
|
UNRECOVERABLE_IF(metricsLibrary == nullptr);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getReferenceNumber
|
|
//////////////////////////////////////////////////////
|
|
uint32_t PerformanceCounters::getReferenceNumber() {
|
|
std::lock_guard<std::mutex> lockMutex(mutex);
|
|
return referenceCounter;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::enable
|
|
//////////////////////////////////////////////////////
|
|
bool PerformanceCounters::enable(bool ccsEngine) {
|
|
std::lock_guard<std::mutex> lockMutex(mutex);
|
|
|
|
if (referenceCounter == 0) {
|
|
available = openMetricsLibrary();
|
|
this->usingCcsEngine = ccsEngine;
|
|
}
|
|
|
|
referenceCounter++;
|
|
|
|
return available && (this->usingCcsEngine == ccsEngine);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::shutdown
|
|
//////////////////////////////////////////////////////
|
|
void PerformanceCounters::shutdown() {
|
|
std::lock_guard<std::mutex> lockMutex(mutex);
|
|
|
|
if (referenceCounter >= 1) {
|
|
if (referenceCounter == 1) {
|
|
available = false;
|
|
closeMetricsLibrary();
|
|
}
|
|
referenceCounter--;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getMetricsLibraryInterface
|
|
//////////////////////////////////////////////////////
|
|
MetricsLibrary *PerformanceCounters::getMetricsLibraryInterface() {
|
|
return metricsLibrary.get();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::setMetricsLibraryInterface
|
|
//////////////////////////////////////////////////////
|
|
void PerformanceCounters::setMetricsLibraryInterface(std::unique_ptr<MetricsLibrary> newMetricsLibrary) {
|
|
metricsLibrary = std::move(newMetricsLibrary);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getMetricsLibraryContext
|
|
//////////////////////////////////////////////////////
|
|
ContextHandle_1_0 PerformanceCounters::getMetricsLibraryContext() {
|
|
return context;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::openMetricsLibrary
|
|
//////////////////////////////////////////////////////
|
|
bool PerformanceCounters::openMetricsLibrary() {
|
|
|
|
// Open metrics library.
|
|
bool result = metricsLibrary->open();
|
|
DEBUG_BREAK_IF(!result);
|
|
|
|
// Create metrics library context.
|
|
if (result) {
|
|
result = metricsLibrary->contextCreate(
|
|
clientType,
|
|
clientData,
|
|
contextData,
|
|
context);
|
|
|
|
// Validate gpu report size.
|
|
DEBUG_BREAK_IF(!metricsLibrary->hwCountersGetGpuReportSize());
|
|
}
|
|
|
|
// Error handling.
|
|
if (!result) {
|
|
closeMetricsLibrary();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::closeMetricsLibrary
|
|
//////////////////////////////////////////////////////
|
|
void PerformanceCounters::closeMetricsLibrary() {
|
|
// Destroy oa/user mmio configuration.
|
|
releaseCountersConfiguration();
|
|
|
|
// Destroy hw counters query.
|
|
if (query.IsValid()) {
|
|
metricsLibrary->hwCountersDelete(query);
|
|
}
|
|
|
|
// Destroy metrics library context.
|
|
if (context.IsValid()) {
|
|
metricsLibrary->contextDelete(context);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getQueryHandle
|
|
//////////////////////////////////////////////////////
|
|
QueryHandle_1_0 PerformanceCounters::getQueryHandle() {
|
|
if (!query.IsValid()) {
|
|
metricsLibrary->hwCountersCreate(
|
|
context,
|
|
1,
|
|
userConfiguration,
|
|
query);
|
|
}
|
|
|
|
DEBUG_BREAK_IF(!query.IsValid());
|
|
return query;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getGpuCommandsSize
|
|
//////////////////////////////////////////////////////
|
|
uint32_t PerformanceCounters::getGpuCommandsSize(
|
|
const MetricsLibraryApi::GpuCommandBufferType commandBufferType,
|
|
const bool begin) {
|
|
CommandBufferData_1_0 bufferData = {};
|
|
CommandBufferSize_1_0 bufferSize = {};
|
|
|
|
if (begin) {
|
|
// Load currently activated (through metrics discovery) oa/user mmio configuration and use it.
|
|
// It will allow to change counters configuration between subsequent clEnqueueNDCommandRange calls.
|
|
if (!enableCountersConfiguration()) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
bufferData.HandleContext = context;
|
|
bufferData.CommandsType = ObjectType::QueryHwCounters;
|
|
bufferData.Type = commandBufferType;
|
|
|
|
bufferData.QueryHwCounters.Begin = begin;
|
|
bufferData.QueryHwCounters.Handle = getQueryHandle();
|
|
bufferData.QueryHwCounters.HandleUserConfiguration = userConfiguration;
|
|
|
|
return metricsLibrary->commandBufferGetSize(bufferData, bufferSize)
|
|
? bufferSize.GpuMemorySize
|
|
: 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getGpuCommands
|
|
//////////////////////////////////////////////////////
|
|
bool PerformanceCounters::getGpuCommands(
|
|
const MetricsLibraryApi::GpuCommandBufferType commandBufferType,
|
|
TagNode<HwPerfCounter> &performanceCounters,
|
|
const bool begin,
|
|
const uint32_t bufferSize,
|
|
void *pBuffer) {
|
|
|
|
// Command Buffer data.
|
|
CommandBufferData_1_0 bufferData = {};
|
|
bufferData.HandleContext = context;
|
|
bufferData.CommandsType = ObjectType::QueryHwCounters;
|
|
bufferData.Data = pBuffer;
|
|
bufferData.Size = bufferSize;
|
|
bufferData.Type = commandBufferType;
|
|
|
|
// Gpu memory allocation for query hw counters.
|
|
bufferData.Allocation.CpuAddress = reinterpret_cast<uint8_t *>(performanceCounters.tagForCpuAccess);
|
|
bufferData.Allocation.GpuAddress = performanceCounters.getGpuAddress();
|
|
|
|
// Query hw counters specific data.
|
|
bufferData.QueryHwCounters.Begin = begin;
|
|
bufferData.QueryHwCounters.Handle = getQueryHandle();
|
|
bufferData.QueryHwCounters.HandleUserConfiguration = userConfiguration;
|
|
|
|
return metricsLibrary->commandBufferGet(bufferData);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getApiReportSize
|
|
//////////////////////////////////////////////////////
|
|
uint32_t PerformanceCounters::getApiReportSize() {
|
|
return metricsLibrary->hwCountersGetApiReportSize();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getGpuReportSize
|
|
//////////////////////////////////////////////////////
|
|
uint32_t PerformanceCounters::getGpuReportSize() {
|
|
return metricsLibrary->hwCountersGetGpuReportSize();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// PerformanceCounters::getApiReport
|
|
//////////////////////////////////////////////////////
|
|
bool PerformanceCounters::getApiReport(const size_t inputParamSize, void *pInputParam, size_t *pOutputParamSize, bool isEventComplete) {
|
|
const uint32_t outputSize = metricsLibrary->hwCountersGetApiReportSize();
|
|
|
|
if (pOutputParamSize) {
|
|
*pOutputParamSize = outputSize;
|
|
}
|
|
|
|
if (pInputParam == nullptr && inputParamSize == 0 && pOutputParamSize) {
|
|
return true;
|
|
}
|
|
|
|
if (pInputParam == nullptr || isEventComplete == false) {
|
|
return false;
|
|
}
|
|
|
|
if (inputParamSize < outputSize) {
|
|
return false;
|
|
}
|
|
|
|
return metricsLibrary->hwCountersGetReport(query, 0, 1, outputSize, pInputParam);
|
|
}
|
|
} // namespace NEO
|