Metric Api: execution query implementation.

Allows to skip workload execution between query begin / end.

Change-Id: Ice462f15eb828be1634d38027b7228f72dd96c55
This commit is contained in:
Piotr Maciejewski 2020-08-24 10:11:39 +02:00 committed by sys_ocldev
parent 90d67f3df2
commit dcb5353200
3 changed files with 301 additions and 4 deletions

View File

@ -420,7 +420,8 @@ bool MetricQueryPoolImp::create() {
switch (description.type) {
case ZET_METRIC_QUERY_POOL_TYPE_PERFORMANCE:
return createMetricQueryPool();
case ZET_METRIC_QUERY_POOL_TYPE_EXECUTION:
return createSkipExecutionQueryPool();
default:
DEBUG_BREAK_IF(true);
return false;
@ -435,7 +436,9 @@ ze_result_t MetricQueryPoolImp::destroy() {
metricsLibrary.destroyMetricQuery(query);
delete this;
break;
case ZET_METRIC_QUERY_POOL_TYPE_EXECUTION:
delete this;
break;
default:
DEBUG_BREAK_IF(true);
break;
@ -463,6 +466,16 @@ bool MetricQueryPoolImp::createMetricQueryPool() {
return metricsLibrary.createMetricQuery(description.count, query, pAllocation);
}
bool MetricQueryPoolImp::createSkipExecutionQueryPool() {
pool.reserve(description.count);
for (uint32_t i = 0; i < description.count; ++i) {
pool.push_back({metricContext, *this, i});
}
return true;
}
MetricQueryPool *MetricQueryPool::fromHandle(zet_metric_query_pool_handle_t handle) {
return static_cast<MetricQueryPool *>(handle);
}
@ -489,7 +502,8 @@ ze_result_t MetricQueryImp::appendBegin(CommandList &commandList) {
switch (pool.description.type) {
case ZET_METRIC_QUERY_POOL_TYPE_PERFORMANCE:
return writeMetricQuery(commandList, nullptr, 0, nullptr, true);
case ZET_METRIC_QUERY_POOL_TYPE_EXECUTION:
return writeSkipExecutionQuery(commandList, nullptr, 0, nullptr, true);
default:
DEBUG_BREAK_IF(true);
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
@ -501,7 +515,8 @@ ze_result_t MetricQueryImp::appendEnd(CommandList &commandList, ze_event_handle_
switch (pool.description.type) {
case ZET_METRIC_QUERY_POOL_TYPE_PERFORMANCE:
return writeMetricQuery(commandList, hSignalEvent, numWaitEvents, phWaitEvents, false);
case ZET_METRIC_QUERY_POOL_TYPE_EXECUTION:
return writeSkipExecutionQuery(commandList, hSignalEvent, numWaitEvents, phWaitEvents, false);
default:
DEBUG_BREAK_IF(true);
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
@ -568,6 +583,36 @@ ze_result_t MetricQueryImp::writeMetricQuery(CommandList &commandList, ze_event_
return result ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
}
ze_result_t MetricQueryImp::writeSkipExecutionQuery(CommandList &commandList, ze_event_handle_t hSignalEvent,
uint32_t numWaitEvents, ze_event_handle_t *phWaitEvents,
const bool begin) {
bool writeCompletionEvent = hSignalEvent && !begin;
bool result = false;
// Obtain gpu commands.
CommandBufferData_1_0 commandBuffer = {};
commandBuffer.CommandsType = ObjectType::OverrideNullHardware;
commandBuffer.Override.Enable = begin;
commandBuffer.Type = metricContext.isComputeUsed()
? GpuCommandBufferType::Compute
: GpuCommandBufferType::Render;
// Wait for events before executing query.
zeCommandListAppendWaitOnEvents(commandList.toHandle(), numWaitEvents, phWaitEvents);
// Get query commands.
result = metricsLibrary.getGpuCommands(commandList, commandBuffer);
// Write completion event.
if (result && writeCompletionEvent) {
result = zeCommandListAppendSignalEvent(commandList.toHandle(), hSignalEvent) ==
ZE_RESULT_SUCCESS;
}
return result ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
}
ze_result_t MetricQuery::appendMemoryBarrier(CommandList &commandList) {
auto &metricContext = commandList.device->getMetricContext();
auto &metricsLibrary = metricContext.getMetricsLibrary();

View File

@ -113,6 +113,9 @@ struct MetricQueryImp : MetricQuery {
ze_result_t writeMetricQuery(CommandList &commandList, ze_event_handle_t hSignalEvent,
uint32_t numWaitEvents, ze_event_handle_t *phWaitEvents,
const bool begin);
ze_result_t writeSkipExecutionQuery(CommandList &commandList, ze_event_handle_t hSignalEvent,
uint32_t numWaitEvents, ze_event_handle_t *phWaitEvents,
const bool begin);
protected:
MetricContext &metricContext;
@ -132,6 +135,7 @@ struct MetricQueryPoolImp : MetricQueryPool {
protected:
bool createMetricQueryPool();
bool createSkipExecutionQueryPool();
public:
MetricContext &metricContext;

View File

@ -634,5 +634,253 @@ TEST_F(MetricQueryPoolTest, givenCorrectArgumentsWhenZetMetricQueryGetDataIsCall
EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS);
}
TEST_F(MetricQueryPoolTest, givenExecutionQueryTypeWhenZetMetricQueryPoolCreateIsCalledThenQueryPoolIsObtained) {
zet_device_handle_t metricDevice = device->toHandle();
zet_metric_query_pool_handle_t poolHandle = {};
zet_metric_query_pool_desc_t poolDesc = {};
poolDesc.stype = ZET_STRUCTURE_TYPE_METRIC_QUERY_POOL_DESC;
poolDesc.count = 1;
poolDesc.type = ZET_METRIC_QUERY_POOL_TYPE_EXECUTION;
TypedValue_1_0 value = {};
value.Type = ValueType::Uint32;
value.ValueUInt32 = 64;
QueryHandle_1_0 queryHandle = {&value};
ContextHandle_1_0 contextHandle = {&value};
EXPECT_CALL(*mockMetricsLibrary, load())
.Times(0);
EXPECT_EQ(zetMetricQueryPoolCreate(context->toHandle(), metricDevice, nullptr, &poolDesc, &poolHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(poolHandle, nullptr);
EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS);
}
TEST_F(MetricQueryPoolTest, givenExecutionQueryTypeWhenAppendMetricQueryBeginAndEndIsCalledThenReturnSuccess) {
zet_device_handle_t metricDevice = device->toHandle();
zet_metric_query_pool_handle_t poolHandle = {};
zet_metric_query_handle_t queryHandle = {};
zet_metric_query_pool_desc_t poolDesc = {};
poolDesc.stype = ZET_STRUCTURE_TYPE_METRIC_QUERY_POOL_DESC;
poolDesc.count = 1;
poolDesc.type = ZET_METRIC_QUERY_POOL_TYPE_EXECUTION;
std::unique_ptr<L0::CommandList> commandList(CommandList::create(productFamily, device, false));
zet_command_list_handle_t commandListHandle = commandList->toHandle();
TypedValue_1_0 value = {};
value.Type = ValueType::Uint32;
value.ValueUInt32 = 64;
QueryHandle_1_0 metricsLibraryQueryHandle = {&value};
ContextHandle_1_0 metricsLibraryContextHandle = {&value};
CommandBufferSize_1_0 commandBufferSize = {};
commandBufferSize.GpuMemorySize = 100;
EXPECT_CALL(*mockMetricEnumeration, isInitialized())
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(*mockMetricsLibrary, getContextData(_, _))
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(*mockMetricsLibrary, load())
.Times(0);
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextCreate(_, _, _))
.Times(1)
.WillOnce(DoAll(::testing::SetArgPointee<2>(metricsLibraryContextHandle), Return(StatusCode::Success)));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextDelete(_))
.Times(1)
.WillOnce(Return(StatusCode::Success));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockCommandBufferGetSize(_, _))
.Times(2)
.WillRepeatedly(DoAll(::testing::SetArgPointee<1>(::testing::ByRef(commandBufferSize)), Return(StatusCode::Success)));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockCommandBufferGet(_))
.Times(2)
.WillRepeatedly(Return(StatusCode::Success));
EXPECT_EQ(zetMetricQueryPoolCreate(context->toHandle(), metricDevice, nullptr, &poolDesc, &poolHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryCreate(poolHandle, 0, &queryHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(queryHandle, nullptr);
EXPECT_EQ(zetCommandListAppendMetricQueryBegin(commandListHandle, queryHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetCommandListAppendMetricQueryEnd(commandListHandle, queryHandle, nullptr, 0, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryDestroy(queryHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS);
}
TEST_F(MetricQueryPoolTest, givenExecutionQueryTypeAndCompletionEventWhenAppendMetricQueryBeginAndEndIsCalledThenReturnSuccess) {
zet_device_handle_t metricDevice = device->toHandle();
zet_metric_query_pool_handle_t poolHandle = {};
zet_metric_query_handle_t queryHandle = {};
zet_metric_query_pool_desc_t poolDesc = {};
poolDesc.stype = ZET_STRUCTURE_TYPE_METRIC_QUERY_POOL_DESC;
poolDesc.count = 1;
poolDesc.type = ZET_METRIC_QUERY_POOL_TYPE_EXECUTION;
std::unique_ptr<L0::CommandList> commandList(CommandList::create(productFamily, device, false));
zet_command_list_handle_t commandListHandle = commandList->toHandle();
TypedValue_1_0 value = {};
value.Type = ValueType::Uint32;
value.ValueUInt32 = 64;
QueryHandle_1_0 metricsLibraryQueryHandle = {&value};
ContextHandle_1_0 metricsLibraryContextHandle = {&value};
CommandBufferSize_1_0 commandBufferSize = {};
commandBufferSize.GpuMemorySize = 100;
EXPECT_CALL(*mockMetricEnumeration, isInitialized())
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(*mockMetricsLibrary, getContextData(_, _))
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(*mockMetricsLibrary, load())
.Times(0);
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextCreate(_, _, _))
.Times(1)
.WillOnce(DoAll(::testing::SetArgPointee<2>(metricsLibraryContextHandle), Return(StatusCode::Success)));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextDelete(_))
.Times(1)
.WillOnce(Return(StatusCode::Success));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockCommandBufferGetSize(_, _))
.Times(2)
.WillRepeatedly(DoAll(::testing::SetArgPointee<1>(::testing::ByRef(commandBufferSize)), Return(StatusCode::Success)));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockCommandBufferGet(_))
.Times(2)
.WillRepeatedly(Return(StatusCode::Success));
ze_event_pool_handle_t eventPoolHandle = {};
ze_event_pool_desc_t eventPoolDesc = {};
eventPoolDesc.count = 1;
eventPoolDesc.flags = 0;
eventPoolDesc.stype = ZE_STRUCTURE_TYPE_EVENT_POOL_DESC;
ze_event_handle_t eventHandle = {};
ze_event_desc_t eventDesc = {};
eventDesc.index = 0;
eventDesc.stype = ZE_STRUCTURE_TYPE_EVENT_DESC;
eventDesc.wait = ZE_EVENT_SCOPE_FLAG_HOST;
eventDesc.signal = ZE_EVENT_SCOPE_FLAG_DEVICE;
EXPECT_EQ(zeEventPoolCreate(context->toHandle(), &eventPoolDesc, 1, &metricDevice, &eventPoolHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(eventPoolHandle, nullptr);
EXPECT_EQ(zeEventCreate(eventPoolHandle, &eventDesc, &eventHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(eventHandle, nullptr);
EXPECT_EQ(zetMetricQueryPoolCreate(context->toHandle(), metricDevice, nullptr, &poolDesc, &poolHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryCreate(poolHandle, 0, &queryHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(queryHandle, nullptr);
EXPECT_EQ(zetCommandListAppendMetricQueryBegin(commandListHandle, queryHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetCommandListAppendMetricQueryEnd(commandListHandle, queryHandle, eventHandle, 0, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryDestroy(queryHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zeEventDestroy(eventHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zeEventPoolDestroy(eventPoolHandle), ZE_RESULT_SUCCESS);
}
TEST_F(MetricQueryPoolTest, givenExecutionQueryTypeAndMetricsLibraryWillFailWhenAppendMetricQueryBeginAndEndIsCalledThenReturnFail) {
zet_device_handle_t metricDevice = device->toHandle();
zet_metric_query_pool_handle_t poolHandle = {};
zet_metric_query_handle_t queryHandle = {};
zet_metric_query_pool_desc_t poolDesc = {};
poolDesc.stype = ZET_STRUCTURE_TYPE_METRIC_QUERY_POOL_DESC;
poolDesc.count = 1;
poolDesc.type = ZET_METRIC_QUERY_POOL_TYPE_EXECUTION;
std::unique_ptr<L0::CommandList> commandList(CommandList::create(productFamily, device, false));
zet_command_list_handle_t commandListHandle = commandList->toHandle();
TypedValue_1_0 value = {};
value.Type = ValueType::Uint32;
value.ValueUInt32 = 64;
QueryHandle_1_0 metricsLibraryQueryHandle = {&value};
ContextHandle_1_0 metricsLibraryContextHandle = {&value};
CommandBufferSize_1_0 commandBufferSize = {};
commandBufferSize.GpuMemorySize = 100;
EXPECT_CALL(*mockMetricEnumeration, isInitialized())
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(*mockMetricsLibrary, getContextData(_, _))
.Times(1)
.WillOnce(Return(true));
EXPECT_CALL(*mockMetricsLibrary, load())
.Times(0);
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextCreate(_, _, _))
.Times(1)
.WillOnce(DoAll(::testing::SetArgPointee<2>(metricsLibraryContextHandle), Return(StatusCode::Success)));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextDelete(_))
.Times(1)
.WillOnce(Return(StatusCode::Success));
EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockCommandBufferGetSize(_, _))
.Times(2)
.WillRepeatedly(DoAll(::testing::SetArgPointee<1>(::testing::ByRef(commandBufferSize)), Return(StatusCode::Failed)));
ze_event_pool_handle_t eventPoolHandle = {};
ze_event_pool_desc_t eventPoolDesc = {};
eventPoolDesc.count = 1;
eventPoolDesc.flags = 0;
eventPoolDesc.stype = ZE_STRUCTURE_TYPE_EVENT_POOL_DESC;
ze_event_handle_t eventHandle = {};
ze_event_desc_t eventDesc = {};
eventDesc.index = 0;
eventDesc.stype = ZE_STRUCTURE_TYPE_EVENT_DESC;
eventDesc.wait = ZE_EVENT_SCOPE_FLAG_HOST;
eventDesc.signal = ZE_EVENT_SCOPE_FLAG_DEVICE;
EXPECT_EQ(zeEventPoolCreate(context->toHandle(), &eventPoolDesc, 1, &metricDevice, &eventPoolHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(eventPoolHandle, nullptr);
EXPECT_EQ(zeEventCreate(eventPoolHandle, &eventDesc, &eventHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(eventHandle, nullptr);
EXPECT_EQ(zetMetricQueryPoolCreate(context->toHandle(), metricDevice, nullptr, &poolDesc, &poolHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryCreate(poolHandle, 0, &queryHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(queryHandle, nullptr);
EXPECT_NE(zetCommandListAppendMetricQueryBegin(commandListHandle, queryHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(zetCommandListAppendMetricQueryEnd(commandListHandle, queryHandle, eventHandle, 0, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryDestroy(queryHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zeEventDestroy(eventHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(zeEventPoolDestroy(eventPoolHandle), ZE_RESULT_SUCCESS);
}
} // namespace ult
} // namespace L0