Skip to content

Commit a6d898a

Browse files
Improve GPU breakpoint support
handle user confirmations in gpu modes: always, only before, only after handle multiple confirmations when pausing on each enqueue Signed-off-by: Mateusz Jablonski <[email protected]>
1 parent 7b7ad9a commit a6d898a

File tree

2 files changed

+217
-40
lines changed

2 files changed

+217
-40
lines changed

opencl/test/unit_test/command_stream/command_stream_receiver_tests.cpp

Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2018-2020 Intel Corporation
2+
* Copyright (C) 2018-2021 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -1175,6 +1175,180 @@ HWTEST_F(CommandStreamReceiverTest, givenDebugPauseThreadWhenSettingFlagProgress
11751175
EXPECT_THAT(output, testing::HasSubstr(std::string("Debug break: Workload ended, press enter to continue")));
11761176
}
11771177

1178+
HWTEST_F(CommandStreamReceiverTest, givenDebugPauseThreadBeforeWalkerOnlyWhenSettingFlagProgressThenFunctionAsksOnceForConfirmation) {
1179+
DebugManagerStateRestore restore;
1180+
DebugManager.flags.PauseOnEnqueue.set(0);
1181+
DebugManager.flags.PauseOnGpuMode.set(0);
1182+
testing::internal::CaptureStdout();
1183+
int32_t executionStamp = 0;
1184+
auto mockCSR = new MockCsr<FamilyType>(executionStamp, *pDevice->executionEnvironment, pDevice->getRootDeviceIndex(), pDevice->getDeviceBitfield());
1185+
1186+
uint32_t confirmationCounter = 0;
1187+
1188+
mockCSR->debugConfirmationFunction = [&confirmationCounter, &mockCSR]() {
1189+
EXPECT_EQ(0u, confirmationCounter);
1190+
EXPECT_TRUE(DebugPauseState::waitingForUserStartConfirmation == *mockCSR->debugPauseStateAddress);
1191+
confirmationCounter++;
1192+
};
1193+
1194+
pDevice->resetCommandStreamReceiver(mockCSR);
1195+
1196+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserStartConfirmation;
1197+
1198+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserStartConfirmation)
1199+
;
1200+
1201+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserEndConfirmation;
1202+
1203+
EXPECT_EQ(1u, confirmationCounter);
1204+
1205+
auto output = testing::internal::GetCapturedStdout();
1206+
EXPECT_THAT(output, testing::HasSubstr(std::string("Debug break: Press enter to start workload")));
1207+
EXPECT_THAT(output, testing::Not(testing::HasSubstr(std::string("Debug break: Workload ended, press enter to continue"))));
1208+
}
1209+
1210+
HWTEST_F(CommandStreamReceiverTest, givenDebugPauseThreadAfterWalkerOnlyWhenSettingFlagProgressThenFunctionAsksOnceForConfirmation) {
1211+
DebugManagerStateRestore restore;
1212+
DebugManager.flags.PauseOnEnqueue.set(0);
1213+
DebugManager.flags.PauseOnGpuMode.set(1);
1214+
testing::internal::CaptureStdout();
1215+
int32_t executionStamp = 0;
1216+
auto mockCSR = new MockCsr<FamilyType>(executionStamp, *pDevice->executionEnvironment, pDevice->getRootDeviceIndex(), pDevice->getDeviceBitfield());
1217+
1218+
uint32_t confirmationCounter = 0;
1219+
1220+
mockCSR->debugConfirmationFunction = [&confirmationCounter, &mockCSR]() {
1221+
EXPECT_EQ(0u, confirmationCounter);
1222+
EXPECT_TRUE(DebugPauseState::waitingForUserEndConfirmation == *mockCSR->debugPauseStateAddress);
1223+
confirmationCounter++;
1224+
};
1225+
1226+
pDevice->resetCommandStreamReceiver(mockCSR);
1227+
1228+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserEndConfirmation;
1229+
1230+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserEndConfirmation)
1231+
;
1232+
1233+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserEndConfirmation;
1234+
1235+
EXPECT_EQ(1u, confirmationCounter);
1236+
1237+
auto output = testing::internal::GetCapturedStdout();
1238+
EXPECT_THAT(output, testing::Not(testing::HasSubstr(std::string("Debug break: Press enter to start workload"))));
1239+
EXPECT_THAT(output, testing::HasSubstr(std::string("Debug break: Workload ended, press enter to continue")));
1240+
}
1241+
1242+
HWTEST_F(CommandStreamReceiverTest, givenDebugPauseThreadOnEachEnqueueWhenSettingFlagProgressThenFunctionAsksMultipleTimesForConfirmation) {
1243+
DebugManagerStateRestore restore;
1244+
DebugManager.flags.PauseOnEnqueue.set(-2);
1245+
testing::internal::CaptureStdout();
1246+
int32_t executionStamp = 0;
1247+
auto mockCSR = new MockCsr<FamilyType>(executionStamp, *pDevice->executionEnvironment, pDevice->getRootDeviceIndex(), pDevice->getDeviceBitfield());
1248+
1249+
uint32_t confirmationCounter = 0;
1250+
1251+
mockCSR->debugConfirmationFunction = [&confirmationCounter, &mockCSR]() {
1252+
if (confirmationCounter == 0) {
1253+
EXPECT_TRUE(DebugPauseState::waitingForUserStartConfirmation == *mockCSR->debugPauseStateAddress);
1254+
confirmationCounter++;
1255+
} else if (confirmationCounter == 1) {
1256+
EXPECT_TRUE(DebugPauseState::waitingForUserEndConfirmation == *mockCSR->debugPauseStateAddress);
1257+
confirmationCounter++;
1258+
} else if (confirmationCounter == 2) {
1259+
EXPECT_TRUE(DebugPauseState::waitingForUserStartConfirmation == *mockCSR->debugPauseStateAddress);
1260+
confirmationCounter++;
1261+
} else if (confirmationCounter == 3) {
1262+
EXPECT_TRUE(DebugPauseState::waitingForUserEndConfirmation == *mockCSR->debugPauseStateAddress);
1263+
confirmationCounter++;
1264+
DebugManager.flags.PauseOnEnqueue.set(-1);
1265+
}
1266+
};
1267+
1268+
pDevice->resetCommandStreamReceiver(mockCSR);
1269+
1270+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserStartConfirmation;
1271+
1272+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserStartConfirmation)
1273+
;
1274+
1275+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserEndConfirmation;
1276+
1277+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserEndConfirmation)
1278+
;
1279+
1280+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserStartConfirmation;
1281+
1282+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserStartConfirmation)
1283+
;
1284+
1285+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserEndConfirmation;
1286+
1287+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserEndConfirmation)
1288+
;
1289+
1290+
EXPECT_EQ(4u, confirmationCounter);
1291+
1292+
auto output = testing::internal::GetCapturedStdout();
1293+
EXPECT_THAT(output, testing::HasSubstr(std::string("Debug break: Press enter to start workload")));
1294+
EXPECT_THAT(output, testing::HasSubstr(std::string("Debug break: Workload ended, press enter to continue")));
1295+
}
1296+
1297+
HWTEST_F(CommandStreamReceiverTest, givenDebugPauseThreadOnEachBlitWhenSettingFlagProgressThenFunctionAsksMultipleTimesForConfirmation) {
1298+
DebugManagerStateRestore restore;
1299+
DebugManager.flags.PauseOnBlitCopy.set(-2);
1300+
testing::internal::CaptureStdout();
1301+
int32_t executionStamp = 0;
1302+
auto mockCSR = new MockCsr<FamilyType>(executionStamp, *pDevice->executionEnvironment, pDevice->getRootDeviceIndex(), pDevice->getDeviceBitfield());
1303+
1304+
uint32_t confirmationCounter = 0;
1305+
1306+
mockCSR->debugConfirmationFunction = [&confirmationCounter, &mockCSR]() {
1307+
if (confirmationCounter == 0) {
1308+
EXPECT_TRUE(DebugPauseState::waitingForUserStartConfirmation == *mockCSR->debugPauseStateAddress);
1309+
confirmationCounter++;
1310+
} else if (confirmationCounter == 1) {
1311+
EXPECT_TRUE(DebugPauseState::waitingForUserEndConfirmation == *mockCSR->debugPauseStateAddress);
1312+
confirmationCounter++;
1313+
} else if (confirmationCounter == 2) {
1314+
EXPECT_TRUE(DebugPauseState::waitingForUserStartConfirmation == *mockCSR->debugPauseStateAddress);
1315+
confirmationCounter++;
1316+
} else if (confirmationCounter == 3) {
1317+
EXPECT_TRUE(DebugPauseState::waitingForUserEndConfirmation == *mockCSR->debugPauseStateAddress);
1318+
confirmationCounter++;
1319+
DebugManager.flags.PauseOnBlitCopy.set(-1);
1320+
}
1321+
};
1322+
1323+
pDevice->resetCommandStreamReceiver(mockCSR);
1324+
1325+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserStartConfirmation;
1326+
1327+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserStartConfirmation)
1328+
;
1329+
1330+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserEndConfirmation;
1331+
1332+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserEndConfirmation)
1333+
;
1334+
1335+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserStartConfirmation;
1336+
1337+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserStartConfirmation)
1338+
;
1339+
1340+
*mockCSR->debugPauseStateAddress = DebugPauseState::waitingForUserEndConfirmation;
1341+
1342+
while (*mockCSR->debugPauseStateAddress != DebugPauseState::hasUserEndConfirmation)
1343+
;
1344+
1345+
EXPECT_EQ(4u, confirmationCounter);
1346+
1347+
auto output = testing::internal::GetCapturedStdout();
1348+
EXPECT_THAT(output, testing::HasSubstr(std::string("Debug break: Press enter to start workload")));
1349+
EXPECT_THAT(output, testing::HasSubstr(std::string("Debug break: Workload ended, press enter to continue")));
1350+
}
1351+
11781352
HWTEST_F(CommandStreamReceiverTest, givenDebugPauseThreadWhenTerminatingAtFirstStageThenFunctionEndsCorrectly) {
11791353
DebugManagerStateRestore restore;
11801354
DebugManager.flags.PauseOnEnqueue.set(0);

shared/source/command_stream/command_stream_receiver.cpp

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2018-2020 Intel Corporation
2+
* Copyright (C) 2018-2021 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -17,6 +17,7 @@
1717
#include "shared/source/helpers/cache_policy.h"
1818
#include "shared/source/helpers/flush_stamp.h"
1919
#include "shared/source/helpers/hw_helper.h"
20+
#include "shared/source/helpers/pause_on_gpu_properties.h"
2021
#include "shared/source/helpers/string.h"
2122
#include "shared/source/helpers/timestamp_packet.h"
2223
#include "shared/source/memory_manager/internal_allocation_storage.h"
@@ -408,48 +409,50 @@ void CommandStreamReceiver::setExperimentalCmdBuffer(std::unique_ptr<Experimenta
408409
void *CommandStreamReceiver::asyncDebugBreakConfirmation(void *arg) {
409410
auto self = reinterpret_cast<CommandStreamReceiver *>(arg);
410411

411-
auto debugPauseStateValue = DebugPauseState::waitingForUserStartConfirmation;
412-
413412
do {
414-
{
415-
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
416-
debugPauseStateValue = *self->debugPauseStateAddress;
417-
}
418-
419-
if (debugPauseStateValue == DebugPauseState::terminate) {
420-
return nullptr;
413+
auto debugPauseStateValue = DebugPauseState::waitingForUserStartConfirmation;
414+
if (DebugManager.flags.PauseOnGpuMode.get() != PauseOnGpuProperties::PauseMode::AfterWorkload) {
415+
do {
416+
{
417+
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
418+
debugPauseStateValue = *self->debugPauseStateAddress;
419+
}
420+
421+
if (debugPauseStateValue == DebugPauseState::terminate) {
422+
return nullptr;
423+
}
424+
std::this_thread::yield();
425+
} while (debugPauseStateValue != DebugPauseState::waitingForUserStartConfirmation);
426+
std::cout << "Debug break: Press enter to start workload" << std::endl;
427+
self->debugConfirmationFunction();
428+
debugPauseStateValue = DebugPauseState::hasUserStartConfirmation;
429+
{
430+
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
431+
*self->debugPauseStateAddress = debugPauseStateValue;
432+
}
421433
}
422-
std::this_thread::yield();
423-
} while (debugPauseStateValue != DebugPauseState::waitingForUserStartConfirmation);
424-
425-
std::cout << "Debug break: Press enter to start workload" << std::endl;
426-
self->debugConfirmationFunction();
427-
428-
debugPauseStateValue = DebugPauseState::hasUserStartConfirmation;
429-
{
430-
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
431-
*self->debugPauseStateAddress = debugPauseStateValue;
432-
}
433434

434-
do {
435-
{
436-
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
437-
debugPauseStateValue = *self->debugPauseStateAddress;
438-
}
439-
if (debugPauseStateValue == DebugPauseState::terminate) {
440-
return nullptr;
435+
if (DebugManager.flags.PauseOnGpuMode.get() != PauseOnGpuProperties::PauseMode::BeforeWorkload) {
436+
do {
437+
{
438+
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
439+
debugPauseStateValue = *self->debugPauseStateAddress;
440+
}
441+
if (debugPauseStateValue == DebugPauseState::terminate) {
442+
return nullptr;
443+
}
444+
std::this_thread::yield();
445+
} while (debugPauseStateValue != DebugPauseState::waitingForUserEndConfirmation);
446+
447+
std::cout << "Debug break: Workload ended, press enter to continue" << std::endl;
448+
self->debugConfirmationFunction();
449+
450+
{
451+
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
452+
*self->debugPauseStateAddress = DebugPauseState::hasUserEndConfirmation;
453+
}
441454
}
442-
std::this_thread::yield();
443-
} while (debugPauseStateValue != DebugPauseState::waitingForUserEndConfirmation);
444-
445-
std::cout << "Debug break: Workload ended, press enter to continue" << std::endl;
446-
self->debugConfirmationFunction();
447-
448-
{
449-
std::unique_lock<SpinLock> lock{self->debugPauseStateLock};
450-
*self->debugPauseStateAddress = DebugPauseState::hasUserEndConfirmation;
451-
}
452-
455+
} while (DebugManager.flags.PauseOnEnqueue.get() == PauseOnGpuProperties::DebugFlagValues::OnEachEnqueue || DebugManager.flags.PauseOnBlitCopy.get() == PauseOnGpuProperties::DebugFlagValues::OnEachEnqueue);
453456
return nullptr;
454457
}
455458

0 commit comments

Comments
 (0)