2017-12-21 07:45:38 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2017, Intel Corporation
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
|
* in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "runtime/event/event_builder.h"
|
|
|
|
#include "runtime/event/user_event.h"
|
|
|
|
#include "runtime/utilities/arrayref.h"
|
|
|
|
#include "unit_tests/mocks/mock_event.h"
|
|
|
|
#include "unit_tests/mocks/mock_context.h"
|
|
|
|
#include "unit_tests/mocks/mock_command_queue.h"
|
|
|
|
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
namespace OCLRT {
|
|
|
|
|
|
|
|
struct SmallEventBuilderEventMock : MockEvent<Event> {
|
|
|
|
SmallEventBuilderEventMock(int param1, float param2)
|
|
|
|
: MockEvent<Event>(nullptr, CL_COMMAND_NDRANGE_KERNEL, 0, 0), constructionParam1(param1), constructionParam2(param2) {
|
|
|
|
}
|
|
|
|
|
|
|
|
SmallEventBuilderEventMock()
|
|
|
|
: SmallEventBuilderEventMock(1, 2.0f) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void overrideMagic(cl_long newMagic) {
|
|
|
|
this->magic = newMagic;
|
|
|
|
}
|
|
|
|
|
|
|
|
int constructionParam1 = 1;
|
|
|
|
float constructionParam2 = 2.0f;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SmallEventBuilderMock : EventBuilder {
|
|
|
|
void clear() {
|
|
|
|
EventBuilder::clear();
|
|
|
|
}
|
|
|
|
void clearEvent() {
|
|
|
|
event = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
ArrayRef<Event *> getParentEvents() {
|
|
|
|
return this->parentEvents;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenCreatingNewEventForwardsArgumentsToEventConstructor) {
|
|
|
|
EventBuilder eventBuilder;
|
|
|
|
EXPECT_EQ(nullptr, eventBuilder.getEvent());
|
|
|
|
|
|
|
|
constexpr int constrParam1 = 7;
|
|
|
|
constexpr float constrParam2 = 13.0f;
|
|
|
|
eventBuilder.create<SmallEventBuilderEventMock>(constrParam1, constrParam2);
|
|
|
|
Event *peekedEvent = eventBuilder.getEvent();
|
|
|
|
ASSERT_NE(nullptr, peekedEvent);
|
|
|
|
auto finalizedEvent = static_cast<SmallEventBuilderEventMock *>(eventBuilder.finalizeAndRelease());
|
|
|
|
EXPECT_EQ(peekedEvent, peekedEvent);
|
|
|
|
EXPECT_EQ(constrParam1, finalizedEvent->constructionParam1);
|
|
|
|
EXPECT_EQ(constrParam2, finalizedEvent->constructionParam2);
|
|
|
|
|
|
|
|
finalizedEvent->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenDestroyingEventBuilderImplicitFinalizeIscalled) {
|
|
|
|
SmallEventBuilderEventMock *ev = nullptr;
|
|
|
|
auto parentEvent = new UserEvent;
|
|
|
|
{
|
|
|
|
EventBuilder eventBuilder{};
|
|
|
|
eventBuilder.create<SmallEventBuilderEventMock>();
|
|
|
|
eventBuilder.addParentEvent(*parentEvent);
|
|
|
|
ev = static_cast<SmallEventBuilderEventMock *>(eventBuilder.getEvent());
|
|
|
|
ASSERT_NE(nullptr, ev);
|
|
|
|
EXPECT_EQ(0U, ev->peekNumEventsBlockingThis());
|
|
|
|
}
|
|
|
|
// make sure that finalize was called on EventBuilder's d-tor and parent was added properly
|
|
|
|
EXPECT_EQ(1U, ev->peekNumEventsBlockingThis());
|
|
|
|
ev->release();
|
|
|
|
parentEvent->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenFinalizeIsCalledTwiceOnEventBuilderThenSecondRequestIsDropped) {
|
|
|
|
SmallEventBuilderEventMock *ev = nullptr;
|
|
|
|
EventBuilder eventBuilder{};
|
|
|
|
eventBuilder.create<SmallEventBuilderEventMock>();
|
|
|
|
ev = static_cast<SmallEventBuilderEventMock *>(eventBuilder.getEvent());
|
|
|
|
ASSERT_NE(nullptr, ev);
|
|
|
|
eventBuilder.finalize();
|
|
|
|
auto *falseParentEvent = new UserEvent();
|
|
|
|
auto *falseChildEvent = new SmallEventBuilderEventMock;
|
|
|
|
auto numParents = ev->peekNumEventsBlockingThis();
|
|
|
|
auto numChildren = (ev->peekChildEvents() != nullptr) ? 1U + ev->peekChildEvents()->countSuccessors() : 0;
|
|
|
|
eventBuilder.addParentEvent(*falseParentEvent);
|
|
|
|
eventBuilder.finalize();
|
|
|
|
// make sure that new parent was not added in second finalize
|
|
|
|
EXPECT_EQ(numParents, ev->peekNumEventsBlockingThis());
|
|
|
|
EXPECT_EQ(numChildren, (ev->peekChildEvents() != nullptr) ? 1U + ev->peekChildEvents()->countSuccessors() : 0);
|
|
|
|
falseParentEvent->release();
|
|
|
|
falseChildEvent->release();
|
|
|
|
ev->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenFinalizeAndReleaseIsCalledThenEventBuilderReleasesReferenceToEvent) {
|
|
|
|
EventBuilder eventBuilder;
|
|
|
|
eventBuilder.create<SmallEventBuilderEventMock>();
|
|
|
|
auto ev = static_cast<SmallEventBuilderEventMock *>(eventBuilder.finalizeAndRelease());
|
|
|
|
ASSERT_NE(nullptr, ev);
|
|
|
|
ASSERT_EQ(nullptr, eventBuilder.getEvent());
|
|
|
|
ASSERT_EQ(nullptr, eventBuilder.finalizeAndRelease());
|
|
|
|
ev->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenClearIsCalledThenAllEventsAndReferencesAreDropped) {
|
|
|
|
auto parentEvent = new UserEvent();
|
|
|
|
SmallEventBuilderMock eventBuilder;
|
|
|
|
eventBuilder.addParentEvent(*parentEvent);
|
|
|
|
eventBuilder.clear();
|
|
|
|
|
|
|
|
EXPECT_EQ(0U, eventBuilder.getParentEvents().size());
|
|
|
|
EXPECT_EQ(nullptr, eventBuilder.getEvent());
|
|
|
|
|
|
|
|
parentEvent->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenCParentEventsGetAddedThenTheirReferenceCountGetsIncreasedUntilFinalizeIsCalled) {
|
|
|
|
UserEvent evParent1;
|
|
|
|
UserEvent evParent2;
|
|
|
|
|
|
|
|
EXPECT_EQ(1, evParent1.getRefInternalCount());
|
|
|
|
EXPECT_EQ(1, evParent2.getRefInternalCount());
|
|
|
|
|
|
|
|
EventBuilder eventBuilder;
|
|
|
|
eventBuilder.create<SmallEventBuilderEventMock>();
|
|
|
|
eventBuilder.addParentEvent(evParent1);
|
|
|
|
EXPECT_EQ(2, evParent1.getRefInternalCount());
|
|
|
|
eventBuilder.addParentEvent(evParent2);
|
|
|
|
EXPECT_EQ(2, evParent2.getRefInternalCount());
|
|
|
|
auto createdEvent = static_cast<SmallEventBuilderEventMock *>(eventBuilder.finalizeAndRelease());
|
|
|
|
EXPECT_EQ(2U, createdEvent->peekNumEventsBlockingThis());
|
|
|
|
createdEvent->release();
|
|
|
|
evParent1.setStatus(CL_COMPLETE);
|
|
|
|
evParent2.setStatus(CL_COMPLETE);
|
|
|
|
|
|
|
|
EXPECT_EQ(1, evParent1.getRefInternalCount());
|
|
|
|
EXPECT_EQ(1, evParent2.getRefInternalCount());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenFinalizeIsCalledWithEmptyEventsListsThenParentAndChildListsAreEmpty) {
|
|
|
|
EventBuilder eventBuilder;
|
|
|
|
eventBuilder.create<MockEvent<Event>>(nullptr, CL_COMMAND_MARKER, 0, 0);
|
|
|
|
Event *event = eventBuilder.finalizeAndRelease();
|
|
|
|
EXPECT_EQ(0U, event->peekNumEventsBlockingThis());
|
|
|
|
EXPECT_EQ(nullptr, event->peekChildEvents());
|
|
|
|
event->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenFinalizeIsCalledAndBuildersEventsListAreNotEmptyThenEventsListsAreAddedToEvent) {
|
|
|
|
MockEvent<UserEvent> *parentEvent = new MockEvent<UserEvent>();
|
|
|
|
|
|
|
|
EventBuilder eventBuilder;
|
|
|
|
eventBuilder.create<MockEvent<Event>>(nullptr, CL_COMMAND_MARKER, 0, 0);
|
|
|
|
eventBuilder.addParentEvent(*parentEvent);
|
|
|
|
Event *event = eventBuilder.finalizeAndRelease();
|
|
|
|
|
|
|
|
EXPECT_EQ(1U, event->peekNumEventsBlockingThis());
|
|
|
|
ASSERT_NE(nullptr, parentEvent->peekChildEvents());
|
|
|
|
EXPECT_EQ(event, parentEvent->peekChildEvents()->ref);
|
|
|
|
parentEvent->setStatus(CL_COMPLETE);
|
|
|
|
EXPECT_EQ(0U, event->peekNumEventsBlockingThis());
|
|
|
|
EXPECT_EQ(nullptr, parentEvent->peekChildEvents());
|
|
|
|
|
|
|
|
event->release();
|
|
|
|
parentEvent->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenFinalizeIsCalledAndParentsListContainsManyEventsFromWhichOnlyFirstOnesAreCompletedThenEventIsNotCompleted) {
|
|
|
|
MockEvent<UserEvent> *userEventNotCompleted = new MockEvent<UserEvent>();
|
|
|
|
MockEvent<UserEvent> *userEventCompleted = new MockEvent<UserEvent>();
|
|
|
|
userEventCompleted->setStatus(CL_COMPLETE);
|
|
|
|
|
|
|
|
EventBuilder eventBuilder;
|
|
|
|
eventBuilder.create<MockEvent<Event>>(nullptr, CL_COMMAND_MARKER, 0, 0);
|
|
|
|
eventBuilder.addParentEvent(*userEventCompleted);
|
|
|
|
eventBuilder.addParentEvent(*userEventNotCompleted);
|
|
|
|
Event *event = eventBuilder.finalizeAndRelease();
|
2017-12-22 18:44:41 +08:00
|
|
|
EXPECT_FALSE(event->updateStatusAndCheckCompletion());
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_EQ(1U, event->peekNumEventsBlockingThis());
|
|
|
|
ASSERT_EQ(nullptr, userEventCompleted->peekChildEvents());
|
|
|
|
ASSERT_NE(nullptr, userEventNotCompleted->peekChildEvents());
|
|
|
|
EXPECT_EQ(event, userEventNotCompleted->peekChildEvents()->ref);
|
|
|
|
userEventNotCompleted->setStatus(CL_COMPLETE);
|
|
|
|
EXPECT_EQ(0U, event->peekNumEventsBlockingThis());
|
|
|
|
EXPECT_EQ(nullptr, userEventNotCompleted->peekChildEvents());
|
|
|
|
event->release();
|
|
|
|
userEventCompleted->release();
|
|
|
|
userEventNotCompleted->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenAddingNullptrAsNewParentEventThenItIsIgnored) {
|
|
|
|
SmallEventBuilderMock eventBuilder;
|
|
|
|
EXPECT_EQ(0U, eventBuilder.getParentEvents().size());
|
|
|
|
eventBuilder.addParentEvent(nullptr);
|
|
|
|
EXPECT_EQ(0U, eventBuilder.getParentEvents().size());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenAddingValidEventAsNewParentEventThenItIsProperlyAddedToParentsList) {
|
|
|
|
auto event = new SmallEventBuilderEventMock;
|
|
|
|
SmallEventBuilderMock eventBuilder;
|
2017-12-20 21:28:42 +08:00
|
|
|
eventBuilder.create<MockEvent<Event>>(nullptr, CL_COMMAND_MARKER, 0, 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_EQ(0U, eventBuilder.getParentEvents().size());
|
|
|
|
eventBuilder.addParentEvent(event);
|
|
|
|
EXPECT_EQ(1U, eventBuilder.getParentEvents().size());
|
|
|
|
event->release();
|
2017-12-20 21:28:42 +08:00
|
|
|
eventBuilder.finalize();
|
|
|
|
eventBuilder.getEvent()->release();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, whenAddingMultipleEventsAsNewParentsThenOnlyValidOnesAreInsertedIntoParentsList) {
|
|
|
|
auto event = new SmallEventBuilderEventMock;
|
|
|
|
auto invalidEvent = new SmallEventBuilderEventMock;
|
|
|
|
invalidEvent->overrideMagic(0);
|
|
|
|
cl_event eventsList[] = {nullptr, event, invalidEvent};
|
|
|
|
SmallEventBuilderMock eventBuilder;
|
2017-12-20 21:28:42 +08:00
|
|
|
eventBuilder.create<MockEvent<Event>>(nullptr, CL_COMMAND_MARKER, 0, 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_EQ(0U, eventBuilder.getParentEvents().size());
|
|
|
|
eventBuilder.addParentEvents(ArrayRef<cl_event>(eventsList));
|
|
|
|
ASSERT_EQ(1U, eventBuilder.getParentEvents().size());
|
|
|
|
EXPECT_EQ(event, *eventBuilder.getParentEvents().begin());
|
|
|
|
invalidEvent->release();
|
|
|
|
event->release();
|
2017-12-20 21:28:42 +08:00
|
|
|
eventBuilder.finalize();
|
|
|
|
eventBuilder.getEvent()->release();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(EventBuilder, parentListDoesNotHaveDuplicates) {
|
|
|
|
MockContext mockContext;
|
|
|
|
MockCommandQueue mockCommandQueue(&mockContext, nullptr, nullptr);
|
|
|
|
|
|
|
|
SmallEventBuilderMock *eventBuilder = new SmallEventBuilderMock;
|
|
|
|
eventBuilder->create<MockEvent<Event>>(&mockCommandQueue, CL_COMMAND_MARKER, 0, 0);
|
|
|
|
Event *event = eventBuilder->getEvent();
|
|
|
|
|
|
|
|
Event *parentEvent = new Event(&mockCommandQueue, CL_COMMAND_NDRANGE_KERNEL, 0, 0);
|
|
|
|
Event *parentEvent2 = new Event(&mockCommandQueue, CL_COMMAND_NDRANGE_KERNEL, 0, 0);
|
|
|
|
Event *parentEvent3 = new Event(&mockCommandQueue, CL_COMMAND_NDRANGE_KERNEL, 0, 0);
|
|
|
|
|
|
|
|
eventBuilder->addParentEvent(parentEvent);
|
|
|
|
eventBuilder->addParentEvent(parentEvent2);
|
|
|
|
eventBuilder->addParentEvent(parentEvent3);
|
|
|
|
// add duplicate
|
|
|
|
eventBuilder->addParentEvent(parentEvent);
|
|
|
|
|
|
|
|
auto parents = eventBuilder->getParentEvents();
|
|
|
|
size_t numberOfParents = parents.size();
|
|
|
|
EXPECT_EQ(3u, numberOfParents);
|
|
|
|
|
|
|
|
event->release();
|
|
|
|
parentEvent->release();
|
|
|
|
parentEvent2->release();
|
|
|
|
parentEvent3->release();
|
|
|
|
eventBuilder->clear();
|
|
|
|
eventBuilder->clearEvent();
|
|
|
|
|
|
|
|
delete eventBuilder;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace OCLRT
|