profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
+ // A 1mSec timeout should be enough to slow the command handler thread a little.
CommandHandler commandHandler0(1, true, commandHandlerRegistry, packetVersionResolver);
+ // This should start the command handler thread return the connection ack and put the profiling
+ // service into active state.
commandHandler0.Start(testProfilingConnectionBase);
- commandHandler0.Start(testProfilingConnectionBase);
+ // Try to start the send thread many times, it must only start once
commandHandler0.Start(testProfilingConnectionBase);
- commandHandler0.Stop();
+ // This could take up to 20mSec but we'll check often.
+ for (int i = 0; i < 10; i++)
+ {
+ if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
+ {
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(2));
+ }
BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
+ // Close the thread again.
+ commandHandler0.Stop();
+
profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
- // commandHandler1 should give up after one timeout
- CommandHandler commandHandler1(10, true, commandHandlerRegistry, packetVersionResolver);
- commandHandler1.Start(testProfilingConnectionTimeOutError);
+ // In this test we'll simulate a timeout without a connection ack packet being received.
+ // Stop after timeout is set so we expect the command handler to stop almost immediately.
+ CommandHandler commandHandler1(1, true, commandHandlerRegistry, packetVersionResolver);
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ commandHandler1.Start(testProfilingConnectionTimeOutError);
+ // Wait until we know a timeout exception has been sent at least once.
+ for (int i = 0; i < 10; i++)
+ {
+ if (testProfilingConnectionTimeOutError.ReadCalledCount())
+ {
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(2));
+ }
+ // and leave another short period for the timeout exception to be processed and the loop to break.
+ std::this_thread::sleep_for(std::chrono::milliseconds(3));
+ // The command handler loop should have stopped after the timeout.
BOOST_CHECK(!commandHandler1.IsRunning());
- commandHandler1.Stop();
+ commandHandler1.Stop();
+ // The state machine should never have received the ack so will still be in WaitingForAck.
BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
- // Now commandHandler1 should persist after a timeout
+
+ // Disable stop after timeout and now commandHandler1 should persist after a timeout
commandHandler1.SetStopAfterTimeout(false);
+ // Restart the thread.
commandHandler1.Start(testProfilingConnectionTimeOutError);
- for (int i = 0; i < 100; i++)
+ // Wait for at the three timeouts and the ack to be sent.
+ for (int i = 0; i < 10; i++)
{
- if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
+ if (testProfilingConnectionTimeOutError.ReadCalledCount() > 3)
{
break;
}
-
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ std::this_thread::sleep_for(std::chrono::milliseconds(2));
}
-
commandHandler1.Stop();
+ // Even after the 3 exceptions the ack packet should have transitioned the command handler to active.
BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
- CommandHandler commandHandler2(100, false, commandHandlerRegistry, packetVersionResolver);
+ // A command handler that gets exceptions other than timeouts should keep going.
+ CommandHandler commandHandler2(1, false, commandHandlerRegistry, packetVersionResolver);
commandHandler2.Start(testProfilingConnectionArmnnError);
- // commandHandler2 should not stop once it encounters a non timing error
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ // Wait for two exceptions to be thrown.
+ for (int i = 0; i < 10; i++)
+ {
+ if (testProfilingConnectionTimeOutError.ReadCalledCount() >= 2)
+ {
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(2));
+ }
BOOST_CHECK(commandHandler2.IsRunning());
commandHandler2.Stop();
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabled)
-{
- // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
- LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
-
- armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
- options.m_EnableProfiling = true;
- ProfilingService& profilingService = ProfilingService::Instance();
- profilingService.ResetExternalProfilingOptions(options, true);
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- profilingService.Update();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
-
- // Redirect the output to a local stream so that we can parse the warning message
- std::stringstream ss;
- StreamRedirector streamRedirector(std::cout, ss.rdbuf());
- profilingService.Update();
- BOOST_CHECK(boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"));
-}
-
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabledRuntime)
-{
- // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
- LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
-
- armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
- ProfilingService& profilingService = ProfilingService::Instance();
- profilingService.ResetExternalProfilingOptions(options, true);
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- profilingService.Update();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- options.m_EnableProfiling = true;
- profilingService.ResetExternalProfilingOptions(options);
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- profilingService.Update();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
-
- // Redirect the output to a local stream so that we can parse the warning message
- std::stringstream ss;
- StreamRedirector streamRedirector(std::cout, ss.rdbuf());
- profilingService.Update();
- BOOST_CHECK(boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"));
-}
-
BOOST_AUTO_TEST_CASE(CheckProfilingServiceCounterDirectory)
{
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
BOOST_CHECK(counterDirectory1.GetCounterCount() == 0);
profilingService.Update();
BOOST_CHECK(counterDirectory1.GetCounterCount() != 0);
+ // Reset the profiling service to stop any running thread
+ options.m_EnableProfiling = false;
+ profilingService.ResetExternalProfilingOptions(options, true);
}
BOOST_AUTO_TEST_CASE(CheckProfilingServiceCounterValues)
writers.push_back(std::thread(&ProfilingService::AddCounterValue, profilingServicePtr, counterUid, 10));
writers.push_back(std::thread(&ProfilingService::SubtractCounterValue, profilingServicePtr, counterUid, 5));
}
-
std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
uint32_t counterValue = 0;
BOOST_CHECK_NO_THROW(profilingService.SetCounterValue(counterUid, 0));
BOOST_CHECK_NO_THROW(counterValue = profilingService.GetCounterValue(counterUid));
BOOST_CHECK(counterValue == 0);
+ // Reset the profiling service to stop any running thread
+ options.m_EnableProfiling = false;
+ profilingService.ResetExternalProfilingOptions(options, true);
}
BOOST_AUTO_TEST_CASE(CheckProfilingObjectUids)
BOOST_TEST(header2Word1 == 419); // data length
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadConnectionAcknowledgedPacket)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodConnectionAcknowledgedPacket)
{
- // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
- LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
-
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
- // Redirect the standard output to a local stream so that we can parse the warning message
- std::stringstream ss;
- StreamRedirector streamRedirector(std::cout, ss.rdbuf());
-
// Calculate the size of a Stream Metadata packet
std::string processName = GetProcessName().substr(0, 60);
unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
mockProfilingConnection->Clear();
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
- profilingService.Update();
+ profilingService.Update(); // Start the command handler and the send thread
// Wait for the Stream Metadata packet to be sent
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Check that the mock profiling connection contains one Stream Metadata packet
const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
- BOOST_TEST(writtenData.size() == 1);
- BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
+ if (writtenData.size() > 1)
+ {
+ // If this thread has been blocked for some time a second or more Stream Metadata packet could have been sent.
+ // In these cases make sure all packet are of length streamMetadataPacketsize
+ for(uint32_t packetLength : writtenData)
+ {
+ BOOST_TEST(packetLength == streamMetadataPacketsize);
+ }
+ }
+ else
+ {
+ BOOST_TEST(writtenData.size() == 1);
+ BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
+ }
// Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
// reply from an external profiling service
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 37; // Wrong packet id!!!
+ uint32_t packetId = 1;
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
// Create the Connection Acknowledged Packet
// Write the packet to the mock profiling connection
mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
- // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
- // the Connection Acknowledged packet gets processed by the profiling service
- std::this_thread::sleep_for(std::chrono::seconds(2));
-
- // Check that the expected error has occurred and logged to the standard output
- BOOST_CHECK(boost::contains(ss.str(), "Functor with requested PacketId=37 and Version=4194304 does not exist"));
+ // Wait for the counter directory packet to ensure the ConnectionAcknowledgedCommandHandler has run.
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection, 5000);
- // The Connection Acknowledged Command Handler should not have updated the profiling state
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
+ // The Connection Acknowledged Command Handler should have updated the profiling state accordingly
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
// Reset the profiling service to stop any running thread
options.m_EnableProfiling = false;
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodConnectionAcknowledgedPacket)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodRequestCounterDirectoryPacket)
{
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
- // Calculate the size of a Stream Metadata packet
- std::string processName = GetProcessName().substr(0, 60);
- unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
- unsigned int streamMetadataPacketsize = 118 + processNameSize;
-
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
ProfilingService& profilingService = ProfilingService::Instance();
profilingService.ResetExternalProfilingOptions(options, true);
- // Bring the profiling service to the "WaitingForAck" state
+ // Bring the profiling service to the "Active" state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
profilingService.Update(); // Initialize the counter directory
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
profilingService.Update(); // Create the profiling connection
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
+ profilingService.Update(); // Start the command handler and the send thread
// Get the mock profiling connection
MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
BOOST_CHECK(mockProfilingConnection);
- // Remove the packets received so far
- mockProfilingConnection->Clear();
-
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
- profilingService.Update(); // Start the command handler and the send thread
+ // Wait for the Stream Metadata packet the be sent
+ // (we are not testing the connection acknowledgement here so it will be ignored by this test)
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
- // Wait for the Stream Metadata packet to be sent
- helper.WaitForProfilingPacketsSent();
+ // Force the profiling service to the "Active" state
+ helper.ForceTransitionToState(ProfilingState::Active);
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Check that the mock profiling connection contains one Stream Metadata packet
- const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
- BOOST_TEST(writtenData.size() == 1);
- BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
+ // Remove the packets received so far
+ mockProfilingConnection->Clear();
- // Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
+ // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
// reply from an external profiling service
- // Connection Acknowledged Packet header (word 0, word 1 is always zero):
+ // Request Counter Directory packet header (word 0, word 1 is always zero):
// 26:31 [6] packet_family: Control Packet Family, value 0b000000
- // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
+ // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 1;
+ uint32_t packetId = 3;
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
- // Create the Connection Acknowledged Packet
- Packet connectionAcknowledgedPacket(header);
+ // Create the Request Counter Directory packet
+ Packet requestCounterDirectoryPacket(header);
// Write the packet to the mock profiling connection
- mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
+ mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
// Wait for the Counter Directory packet to be sent
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection, 5000);
- // The Connection Acknowledged Command Handler should have updated the profiling state accordingly
+ // Check that the mock profiling connection contains one Counter Directory packet
+ const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
+ BOOST_TEST(writtenData.size() == 2);
+ BOOST_TEST(writtenData[0] == 427); // The size of the expected Timeline Directory packet
+ BOOST_TEST(writtenData[1] == 416); // The size of the expected Counter Directory packet
+
+ // The Request Counter Directory Command Handler should not have updated the profiling state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
// Reset the profiling service to stop any running thread
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadRequestCounterDirectoryPacket)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadPeriodicCounterSelectionPacketInvalidCounterUid)
{
- // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
- LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
-
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
- // Redirect the standard output to a local stream so that we can parse the warning message
- std::stringstream ss;
- StreamRedirector streamRedirector(std::cout, ss.rdbuf());
-
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
// Bring the profiling service to the "Active" state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- helper.ForceTransitionToState(ProfilingState::NotConnected);
+ profilingService.Update(); // Initialize the counter directory
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
profilingService.Update(); // Create the profiling connection
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
-
// Remove the packets received so far
mockProfilingConnection->Clear();
- // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
- // reply from an external profiling service
+ // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
+ // external profiling service
- // Request Counter Directory packet header (word 0, word 1 is always zero):
+ // Periodic Counter Selection packet header:
// 26:31 [6] packet_family: Control Packet Family, value 0b000000
- // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
+ // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 123; // Wrong packet id!!!
+ uint32_t packetId = 4;
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
- // Create the Request Counter Directory packet
- Packet requestCounterDirectoryPacket(header);
+ uint32_t capturePeriod = 123456; // Some capture period (microseconds)
+
+ // Get the first valid counter UID
+ const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
+ const Counters& counters = counterDirectory.GetCounters();
+ BOOST_CHECK(counters.size() > 1);
+ uint16_t counterUidA = counters.begin()->first; // First valid counter UID
+ uint16_t counterUidB = 9999; // Second invalid counter UID
+
+ uint32_t length = 8;
+
+ auto data = std::make_unique<unsigned char[]>(length);
+ WriteUint32(data.get(), 0, capturePeriod);
+ WriteUint16(data.get(), 4, counterUidA);
+ WriteUint16(data.get(), 6, counterUidB);
+
+ // Create the Periodic Counter Selection packet
+ Packet periodicCounterSelectionPacket(header, length, data); // Length > 0, this will start the Period Counter
+ // Capture thread
// Write the packet to the mock profiling connection
- mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
+ mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
- // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
- // the Create the Request Counter packet gets processed by the profiling service
- std::this_thread::sleep_for(std::chrono::seconds(2));
+ // Expecting one Periodic Counter Selection packet and at least one Periodic Counter Capture packet
+ int expectedPackets = 2;
+ std::vector<uint32_t> receivedPackets;
- // Check that the expected error has occurred and logged to the standard output
- BOOST_CHECK(boost::contains(ss.str(), "Functor with requested PacketId=123 and Version=4194304 does not exist"));
+ // Keep waiting until all the expected packets have been received
+ do
+ {
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
+ const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
+ if (writtenData.empty())
+ {
+ BOOST_ERROR("Packets should be available for reading at this point");
+ return;
+ }
+ receivedPackets.insert(receivedPackets.end(), writtenData.begin(), writtenData.end());
+ expectedPackets -= boost::numeric_cast<int>(writtenData.size());
+ } while (expectedPackets > 0);
+ BOOST_TEST(!receivedPackets.empty());
- // The Request Counter Directory Command Handler should not have updated the profiling state
+ // The size of the expected Periodic Counter Selection packet
+ BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 14) != receivedPackets.end()));
+ // The size of the expected Periodic Counter Capture packet
+ BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 22) != receivedPackets.end()));
+
+ // The Periodic Counter Selection Handler should not have updated the profiling state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
// Reset the profiling service to stop any running thread
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodRequestCounterDirectoryPacket)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPeriodicCounterSelectionPacketNoCounters)
{
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
-
// Remove the packets received so far
mockProfilingConnection->Clear();
- // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
- // reply from an external profiling service
+ // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
+ // external profiling service
- // Request Counter Directory packet header (word 0, word 1 is always zero):
+ // Periodic Counter Selection packet header:
// 26:31 [6] packet_family: Control Packet Family, value 0b000000
- // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
+ // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 3;
+ uint32_t packetId = 4;
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
- // Create the Request Counter Directory packet
- Packet requestCounterDirectoryPacket(header);
+ // Create the Periodic Counter Selection packet
+ Packet periodicCounterSelectionPacket(header); // Length == 0, this will disable the collection of counters
// Write the packet to the mock profiling connection
- mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
+ mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
- // Wait for the Counter Directory packet to be sent
- helper.WaitForProfilingPacketsSent();
-
- // Check that the mock profiling connection contains one Counter Directory packet
- const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
- BOOST_TEST(writtenData.size() == 2);
- BOOST_TEST(writtenData[0] == 427); // The size of the expected Timeline Directory packet
- BOOST_TEST(writtenData[1] == 416); // The size of the expected Counter Directory packet
+ // Wait for the Periodic Counter Selection packet to be sent
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection, 5000);
- // The Request Counter Directory Command Handler should not have updated the profiling state
+ // The Periodic Counter Selection Handler should not have updated the profiling state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
+ // Check that the mock profiling connection contains one Periodic Counter Selection
+ const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
+ BOOST_TEST(writtenData.size() == 1); // Only one packet is expected (no Periodic Counter packets)
+ BOOST_TEST(writtenData[0] == 12); // The size of the expected Periodic Counter Selection (echos the sent one)
+
// Reset the profiling service to stop any running thread
options.m_EnableProfiling = false;
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadPeriodicCounterSelectionPacket)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPeriodicCounterSelectionPacketSingleCounter)
{
- // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
- LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
-
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
- // Redirect the standard output to a local stream so that we can parse the warning message
- std::stringstream ss;
- StreamRedirector streamRedirector(std::cout, ss.rdbuf());
-
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
-
// Remove the packets received so far
mockProfilingConnection->Clear();
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 999; // Wrong packet id!!!
+ uint32_t packetId = 4;
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
+ uint32_t capturePeriod = 123456; // Some capture period (microseconds)
+
+ // Get the first valid counter UID
+ const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
+ const Counters& counters = counterDirectory.GetCounters();
+ BOOST_CHECK(!counters.empty());
+ uint16_t counterUid = counters.begin()->first; // Valid counter UID
+
+ uint32_t length = 6;
+
+ auto data = std::make_unique<unsigned char[]>(length);
+ WriteUint32(data.get(), 0, capturePeriod);
+ WriteUint16(data.get(), 4, counterUid);
+
// Create the Periodic Counter Selection packet
- Packet periodicCounterSelectionPacket(header); // Length == 0, this will disable the collection of counters
+ Packet periodicCounterSelectionPacket(header, length, data); // Length > 0, this will start the Period Counter
+ // Capture thread
// Write the packet to the mock profiling connection
mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
- // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
- // the Periodic Counter Selection packet gets processed by the profiling service
- std::this_thread::sleep_for(std::chrono::seconds(2));
+ // Expecting one Periodic Counter Selection packet and at least one Periodic Counter Capture packet
+ int expectedPackets = 2;
+ std::vector<uint32_t> receivedPackets;
- // Check that the expected error has occurred and logged to the standard output
- BOOST_CHECK(boost::contains(ss.str(), "Functor with requested PacketId=999 and Version=4194304 does not exist"));
+ // Keep waiting until all the expected packets have been received
+ do
+ {
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
+ const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
+ if (writtenData.empty())
+ {
+ BOOST_ERROR("Packets should be available for reading at this point");
+ return;
+ }
+ receivedPackets.insert(receivedPackets.end(), writtenData.begin(), writtenData.end());
+ expectedPackets -= boost::numeric_cast<int>(writtenData.size());
+ } while (expectedPackets > 0);
+ BOOST_TEST(!receivedPackets.empty());
+
+ // The size of the expected Periodic Counter Selection packet (echos the sent one)
+ BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 14) != receivedPackets.end()));
+ // The size of the expected Periodic Counter Capture packet
+ BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 22) != receivedPackets.end()));
// The Periodic Counter Selection Handler should not have updated the profiling state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadPeriodicCounterSelectionPacketInvalidCounterUid)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPeriodicCounterSelectionPacketMultipleCounters)
{
- // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
- LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
-
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
-
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
-
// Remove the packets received so far
mockProfilingConnection->Clear();
const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
const Counters& counters = counterDirectory.GetCounters();
BOOST_CHECK(counters.size() > 1);
- uint16_t counterUidA = counters.begin()->first; // First valid counter UID
- uint16_t counterUidB = 9999; // Second invalid counter UID
+ uint16_t counterUidA = counters.begin()->first; // First valid counter UID
+ uint16_t counterUidB = (counters.begin()++)->first; // Second valid counter UID
uint32_t length = 8;
// Keep waiting until all the expected packets have been received
do
{
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
if (writtenData.empty())
{
} while (expectedPackets > 0);
BOOST_TEST(!receivedPackets.empty());
- // The size of the expected Periodic Counter Selection packet
- BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 14) != receivedPackets.end()));
+ // The size of the expected Periodic Counter Selection packet (echos the sent one)
+ BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 16) != receivedPackets.end()));
// The size of the expected Periodic Counter Capture packet
- BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 22) != receivedPackets.end()));
+ BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 28) != receivedPackets.end()));
// The Periodic Counter Selection Handler should not have updated the profiling state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPeriodicCounterSelectionPacketNoCounters)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceDisconnect)
{
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
-
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
ProfilingService& profilingService = ProfilingService::Instance();
profilingService.ResetExternalProfilingOptions(options, true);
- // Bring the profiling service to the "Active" state
+ // Try to disconnect the profiling service while in the "Uninitialised" state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ profilingService.Disconnect();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); // The state should not change
+
+ // Try to disconnect the profiling service while in the "NotConnected" state
profilingService.Update(); // Initialize the counter directory
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
+ profilingService.Disconnect();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should not change
+
+ // Try to disconnect the profiling service while in the "WaitingForAck" state
profilingService.Update(); // Create the profiling connection
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
+ profilingService.Disconnect();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); // The state should not change
+
+ // Try to disconnect the profiling service while in the "Active" state
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
-
- // Remove the packets received so far
- mockProfilingConnection->Clear();
-
- // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
- // external profiling service
-
- // Periodic Counter Selection packet header:
- // 26:31 [6] packet_family: Control Packet Family, value 0b000000
- // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
- // 8:15 [8] reserved: Reserved, value 0b00000000
- // 0:7 [8] reserved: Reserved, value 0b00000000
- uint32_t packetFamily = 0;
- uint32_t packetId = 4;
- uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
-
- // Create the Periodic Counter Selection packet
- Packet periodicCounterSelectionPacket(header); // Length == 0, this will disable the collection of counters
-
- // Write the packet to the mock profiling connection
- mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
-
- // Wait for the Periodic Counter Selection packet to be sent
- helper.WaitForProfilingPacketsSent();
+ // Check that the profiling connection is open
+ BOOST_CHECK(mockProfilingConnection->IsOpen());
- // The Periodic Counter Selection Handler should not have updated the profiling state
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
+ profilingService.Disconnect();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should have changed
- // Check that the mock profiling connection contains one Periodic Counter Selection
- const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
- BOOST_TEST(writtenData.size() == 1); // Only one packet is expected (no Periodic Counter packets)
- BOOST_TEST(writtenData[0] == 12); // The size of the expected Periodic Counter Selection (echos the sent one)
+ // Check that the profiling connection has been reset
+ mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection == nullptr);
// Reset the profiling service to stop any running thread
options.m_EnableProfiling = false;
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPeriodicCounterSelectionPacketSingleCounter)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPerJobCounterSelectionPacket)
{
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
-
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
-
// Remove the packets received so far
mockProfilingConnection->Clear();
- // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
+ // Write a "Per-Job Counter Selection" packet into the mock profiling connection, to simulate an input from an
// external profiling service
- // Periodic Counter Selection packet header:
+ // Per-Job Counter Selection packet header:
// 26:31 [6] packet_family: Control Packet Family, value 0b000000
// 16:25 [10] packet_id: Packet identifier, value 0b0000000100
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 4;
+ uint32_t packetId = 5;
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
- uint32_t capturePeriod = 123456; // Some capture period (microseconds)
-
- // Get the first valid counter UID
- const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
- const Counters& counters = counterDirectory.GetCounters();
- BOOST_CHECK(!counters.empty());
- uint16_t counterUid = counters.begin()->first; // Valid counter UID
-
- uint32_t length = 6;
-
- auto data = std::make_unique<unsigned char[]>(length);
- WriteUint32(data.get(), 0, capturePeriod);
- WriteUint16(data.get(), 4, counterUid);
-
- // Create the Periodic Counter Selection packet
- Packet periodicCounterSelectionPacket(header, length, data); // Length > 0, this will start the Period Counter
- // Capture thread
+ // Create the Per-Job Counter Selection packet
+ Packet periodicCounterSelectionPacket(header); // Length == 0, this will disable the collection of counters
// Write the packet to the mock profiling connection
mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
- // Expecting one Periodic Counter Selection packet and at least one Periodic Counter Capture packet
- int expectedPackets = 2;
- std::vector<uint32_t> receivedPackets;
-
- // Keep waiting until all the expected packets have been received
- do
- {
- helper.WaitForProfilingPacketsSent();
- const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
- if (writtenData.empty())
- {
- BOOST_ERROR("Packets should be available for reading at this point");
- return;
- }
- receivedPackets.insert(receivedPackets.end(), writtenData.begin(), writtenData.end());
- expectedPackets -= boost::numeric_cast<int>(writtenData.size());
- } while (expectedPackets > 0);
- BOOST_TEST(!receivedPackets.empty());
+ // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
+ // the Per-Job Counter Selection packet gets processed by the profiling service
+ std::this_thread::sleep_for(std::chrono::milliseconds(5));
- // The size of the expected Periodic Counter Selection packet (echos the sent one)
- BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 14) != receivedPackets.end()));
- // The size of the expected Periodic Counter Capture packet
- BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 22) != receivedPackets.end()));
+ // The Per-Job Counter Selection packets are dropped silently, so there should be no reply coming
+ // from the profiling service
+ const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
+ BOOST_TEST(writtenData.empty());
- // The Periodic Counter Selection Handler should not have updated the profiling state
+ // The Per-Job Counter Selection Command Handler should not have updated the profiling state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
// Reset the profiling service to stop any running thread
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPeriodicCounterSelectionPacketMultipleCounters)
+BOOST_AUTO_TEST_CASE(CheckConfigureProfilingServiceOn)
{
- // Swap the profiling connection factory in the profiling service instance with our mock one
- SwapProfilingConnectionFactoryHelper helper;
-
- // Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
ProfilingService& profilingService = ProfilingService::Instance();
- profilingService.ResetExternalProfilingOptions(options, true);
-
- // Bring the profiling service to the "Active" state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- profilingService.Update(); // Initialize the counter directory
+ profilingService.ConfigureProfilingService(options);
+ // should get as far as NOT_CONNECTED
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
- profilingService.Update(); // Create the profiling connection
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
- profilingService.Update(); // Start the command handler and the send thread
+ // Reset the profiling service to stop any running thread
+ options.m_EnableProfiling = false;
+ profilingService.ResetExternalProfilingOptions(options, true);
+}
- // Wait for the Stream Metadata packet the be sent
- // (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+BOOST_AUTO_TEST_CASE(CheckConfigureProfilingServiceOff)
+{
+ armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
+ ProfilingService& profilingService = ProfilingService::Instance();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ profilingService.ConfigureProfilingService(options);
+ // should not move from Uninitialised
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ // Reset the profiling service to stop any running thread
+ options.m_EnableProfiling = false;
+ profilingService.ResetExternalProfilingOptions(options, true);
+}
- // Force the profiling service to the "Active" state
- helper.ForceTransitionToState(ProfilingState::Active);
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabled)
+{
+ // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
+ LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
+ armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
+ options.m_EnableProfiling = true;
+ ProfilingService& profilingService = ProfilingService::Instance();
+ profilingService.ResetExternalProfilingOptions(options, true);
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ profilingService.Update();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
+
+ // Redirect the output to a local stream so that we can parse the warning message
+ std::stringstream ss;
+ StreamRedirector streamRedirector(std::cout, ss.rdbuf());
+ profilingService.Update();
+ streamRedirector.CancelRedirect();
+
+ // Check that the expected error has occurred and logged to the standard output
+ if (!boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"))
+ {
+ std::cout << ss.str();
+ BOOST_FAIL("Expected string not found.");
+ }
+ // Reset the profiling service to stop any running thread
+ options.m_EnableProfiling = false;
+ profilingService.ResetExternalProfilingOptions(options, true);
+}
+
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabledRuntime)
+{
+ // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
+ LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
+ armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
+ ProfilingService& profilingService = ProfilingService::Instance();
+ profilingService.ResetExternalProfilingOptions(options, true);
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ profilingService.Update();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ options.m_EnableProfiling = true;
+ profilingService.ResetExternalProfilingOptions(options);
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ profilingService.Update();
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
+
+ // Redirect the output to a local stream so that we can parse the warning message
+ std::stringstream ss;
+ StreamRedirector streamRedirector(std::cout, ss.rdbuf());
+ profilingService.Update();
+
+ streamRedirector.CancelRedirect();
+
+ // Check that the expected error has occurred and logged to the standard output
+ if (!boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"))
+ {
+ std::cout << ss.str();
+ BOOST_FAIL("Expected string not found.");
+ }
+ // Reset the profiling service to stop any running thread
+ options.m_EnableProfiling = false;
+ profilingService.ResetExternalProfilingOptions(options, true);
+}
+
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadConnectionAcknowledgedPacket)
+{
+ // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
+ LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
+ // Swap the profiling connection factory in the profiling service instance with our mock one
+ SwapProfilingConnectionFactoryHelper helper;
+
+ // Redirect the standard output to a local stream so that we can parse the warning message
+ std::stringstream ss;
+ StreamRedirector streamRedirector(std::cout, ss.rdbuf());
+
+ // Calculate the size of a Stream Metadata packet
+ std::string processName = GetProcessName().substr(0, 60);
+ unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
+ unsigned int streamMetadataPacketsize = 118 + processNameSize;
+
+ // Reset the profiling service to the uninitialized state
+ armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
+ options.m_EnableProfiling = true;
+ ProfilingService& profilingService = ProfilingService::Instance();
+ profilingService.ResetExternalProfilingOptions(options, true);
+
+ // Bring the profiling service to the "WaitingForAck" state
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
+ profilingService.Update(); // Initialize the counter directory
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
+ profilingService.Update(); // Create the profiling connection
// Get the mock profiling connection
MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
// Remove the packets received so far
mockProfilingConnection->Clear();
- // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
- // external profiling service
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
+ profilingService.Update();
- // Periodic Counter Selection packet header:
+ // Wait for the Stream Metadata packet to be sent
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
+
+ // Check that the mock profiling connection contains one Stream Metadata packet
+ const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
+ if (writtenData.size() > 1)
+ {
+ // If this thread has been blocked for some time a second or more Stream Metadata packet could have been sent.
+ // In these cases make sure all packet are of length streamMetadataPacketsize
+ for(uint32_t packetLength : writtenData)
+ {
+ BOOST_TEST(packetLength == streamMetadataPacketsize);
+ }
+ }
+ else
+ {
+ BOOST_TEST(writtenData.size() == 1);
+ BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
+ }
+
+ // Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
+ // reply from an external profiling service
+
+ // Connection Acknowledged Packet header (word 0, word 1 is always zero):
// 26:31 [6] packet_family: Control Packet Family, value 0b000000
- // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
+ // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 4;
+ uint32_t packetId = 37; // Wrong packet id!!!
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
- uint32_t capturePeriod = 123456; // Some capture period (microseconds)
-
- // Get the first valid counter UID
- const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
- const Counters& counters = counterDirectory.GetCounters();
- BOOST_CHECK(counters.size() > 1);
- uint16_t counterUidA = counters.begin()->first; // First valid counter UID
- uint16_t counterUidB = (counters.begin()++)->first; // Second valid counter UID
-
- uint32_t length = 8;
-
- auto data = std::make_unique<unsigned char[]>(length);
- WriteUint32(data.get(), 0, capturePeriod);
- WriteUint16(data.get(), 4, counterUidA);
- WriteUint16(data.get(), 6, counterUidB);
-
- // Create the Periodic Counter Selection packet
- Packet periodicCounterSelectionPacket(header, length, data); // Length > 0, this will start the Period Counter
- // Capture thread
+ // Create the Connection Acknowledged Packet
+ Packet connectionAcknowledgedPacket(header);
// Write the packet to the mock profiling connection
- mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
+ mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
- // Expecting one Periodic Counter Selection packet and at least one Periodic Counter Capture packet
- int expectedPackets = 2;
- std::vector<uint32_t> receivedPackets;
+ // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
+ // the Connection Acknowledged packet gets processed by the profiling service
+ std::this_thread::sleep_for(std::chrono::milliseconds(7));
- // Keep waiting until all the expected packets have been received
- do
- {
- helper.WaitForProfilingPacketsSent();
- const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
- if (writtenData.empty())
- {
- BOOST_ERROR("Packets should be available for reading at this point");
- return;
- }
- receivedPackets.insert(receivedPackets.end(), writtenData.begin(), writtenData.end());
- expectedPackets -= boost::numeric_cast<int>(writtenData.size());
- } while (expectedPackets > 0);
- BOOST_TEST(!receivedPackets.empty());
+ streamRedirector.CancelRedirect();
- // The size of the expected Periodic Counter Selection packet (echos the sent one)
- BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 16) != receivedPackets.end()));
- // The size of the expected Periodic Counter Capture packet
- BOOST_TEST((std::find(receivedPackets.begin(), receivedPackets.end(), 28) != receivedPackets.end()));
+ // Check that the expected error has occurred and logged to the standard output
+ if (!boost::contains(ss.str(), "Functor with requested PacketId=37 and Version=4194304 does not exist"))
+ {
+ std::cout << ss.str();
+ BOOST_FAIL("Expected string not found.");
+ }
- // The Periodic Counter Selection Handler should not have updated the profiling state
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
+ // The Connection Acknowledged Command Handler should not have updated the profiling state
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
// Reset the profiling service to stop any running thread
options.m_EnableProfiling = false;
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceDisconnect)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadRequestCounterDirectoryPacket)
{
+ // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
+ LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
+ // Redirect the standard output to a local stream so that we can parse the warning message
+ std::stringstream ss;
+ StreamRedirector streamRedirector(std::cout, ss.rdbuf());
+
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
ProfilingService& profilingService = ProfilingService::Instance();
profilingService.ResetExternalProfilingOptions(options, true);
- // Try to disconnect the profiling service while in the "Uninitialised" state
+ // Bring the profiling service to the "Active" state
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- profilingService.Disconnect();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); // The state should not change
-
- // Try to disconnect the profiling service while in the "NotConnected" state
- profilingService.Update(); // Initialize the counter directory
+ helper.ForceTransitionToState(ProfilingState::NotConnected);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
- profilingService.Disconnect();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should not change
-
- // Try to disconnect the profiling service while in the "WaitingForAck" state
profilingService.Update(); // Create the profiling connection
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
- profilingService.Disconnect();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); // The state should not change
-
- // Try to disconnect the profiling service while in the "Active" state
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
+ // Remove the packets received so far
+ mockProfilingConnection->Clear();
- // Check that the profiling connection is open
- BOOST_CHECK(mockProfilingConnection->IsOpen());
+ // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
+ // reply from an external profiling service
- profilingService.Disconnect();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should have changed
+ // Request Counter Directory packet header (word 0, word 1 is always zero):
+ // 26:31 [6] packet_family: Control Packet Family, value 0b000000
+ // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
+ // 8:15 [8] reserved: Reserved, value 0b00000000
+ // 0:7 [8] reserved: Reserved, value 0b00000000
+ uint32_t packetFamily = 0;
+ uint32_t packetId = 123; // Wrong packet id!!!
+ uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
- // Check that the profiling connection has been reset
- mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection == nullptr);
+ // Create the Request Counter Directory packet
+ Packet requestCounterDirectoryPacket(header);
+
+ // Write the packet to the mock profiling connection
+ mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
+
+ // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
+ // the Create the Request Counter packet gets processed by the profiling service
+ std::this_thread::sleep_for(std::chrono::milliseconds(7));
+
+ streamRedirector.CancelRedirect();
+
+ // Check that the expected error has occurred and logged to the standard output
+ if (!boost::contains(ss.str(), "Functor with requested PacketId=123 and Version=4194304 does not exist"))
+ {
+ std::cout << ss.str();
+ BOOST_FAIL("Expected string not found.");
+ }
+
+ // The Request Counter Directory Command Handler should not have updated the profiling state
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
// Reset the profiling service to stop any running thread
options.m_EnableProfiling = false;
profilingService.ResetExternalProfilingOptions(options, true);
}
-BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPerJobCounterSelectionPacket)
+BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadPeriodicCounterSelectionPacket)
{
+ // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
+ LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
// Swap the profiling connection factory in the profiling service instance with our mock one
SwapProfilingConnectionFactoryHelper helper;
+ // Redirect the standard output to a local stream so that we can parse the warning message
+ std::stringstream ss;
+ StreamRedirector streamRedirector(std::cout, ss.rdbuf());
+
// Reset the profiling service to the uninitialized state
armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
options.m_EnableProfiling = true;
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
profilingService.Update(); // Start the command handler and the send thread
+ // Get the mock profiling connection
+ MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
+ BOOST_CHECK(mockProfilingConnection);
+
// Wait for the Stream Metadata packet the be sent
// (we are not testing the connection acknowledgement here so it will be ignored by this test)
- helper.WaitForProfilingPacketsSent();
+ helper.WaitForProfilingPacketsSent(mockProfilingConnection);
// Force the profiling service to the "Active" state
helper.ForceTransitionToState(ProfilingState::Active);
BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
- // Get the mock profiling connection
- MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
- BOOST_CHECK(mockProfilingConnection);
-
// Remove the packets received so far
mockProfilingConnection->Clear();
- // Write a "Per-Job Counter Selection" packet into the mock profiling connection, to simulate an input from an
+ // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
// external profiling service
- // Per-Job Counter Selection packet header:
+ // Periodic Counter Selection packet header:
// 26:31 [6] packet_family: Control Packet Family, value 0b000000
// 16:25 [10] packet_id: Packet identifier, value 0b0000000100
// 8:15 [8] reserved: Reserved, value 0b00000000
// 0:7 [8] reserved: Reserved, value 0b00000000
uint32_t packetFamily = 0;
- uint32_t packetId = 5;
+ uint32_t packetId = 999; // Wrong packet id!!!
uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
- // Create the Per-Job Counter Selection packet
+ // Create the Periodic Counter Selection packet
Packet periodicCounterSelectionPacket(header); // Length == 0, this will disable the collection of counters
// Write the packet to the mock profiling connection
mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
// Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
- // the Per-Job Counter Selection packet gets processed by the profiling service
- std::this_thread::sleep_for(std::chrono::seconds(2));
-
- // The Per-Job Counter Selection packets are dropped silently, so there should be no reply coming
- // from the profiling service
- const std::vector<uint32_t> writtenData = mockProfilingConnection->GetWrittenData();
- BOOST_TEST(writtenData.empty());
+ // the Periodic Counter Selection packet gets processed by the profiling service
+ std::this_thread::sleep_for(std::chrono::milliseconds(7));
- // The Per-Job Counter Selection Command Handler should not have updated the profiling state
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
+ // Check that the expected error has occurred and logged to the standard output
+ streamRedirector.CancelRedirect();
- // Reset the profiling service to stop any running thread
- options.m_EnableProfiling = false;
- profilingService.ResetExternalProfilingOptions(options, true);
-}
+ // Check that the expected error has occurred and logged to the standard output
+ if (!boost::contains(ss.str(), "Functor with requested PacketId=999 and Version=4194304 does not exist"))
+ {
+ std::cout << ss.str();
+ BOOST_FAIL("Expected string not found.");
+ }
-BOOST_AUTO_TEST_CASE(CheckConfigureProfilingServiceOn)
-{
- armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
- options.m_EnableProfiling = true;
- ProfilingService& profilingService = ProfilingService::Instance();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- profilingService.ConfigureProfilingService(options);
- // should get as far as NOT_CONNECTED
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
- // Reset the profiling service to stop any running thread
- options.m_EnableProfiling = false;
- profilingService.ResetExternalProfilingOptions(options, true);
-}
+ // The Periodic Counter Selection Handler should not have updated the profiling state
+ BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
-BOOST_AUTO_TEST_CASE(CheckConfigureProfilingServiceOff)
-{
- armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
- ProfilingService& profilingService = ProfilingService::Instance();
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
- profilingService.ConfigureProfilingService(options);
- // should not move from Uninitialised
- BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
// Reset the profiling service to stop any running thread
options.m_EnableProfiling = false;
profilingService.ResetExternalProfilingOptions(options, true);