From 7ee19a1f38cc5688440554289d18dac4aff841f8 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Thu, 14 Jul 2022 14:11:54 +0200 Subject: [PATCH 01/67] DeviceTypeUtil: fixing name in string. --- libNeonCore/src/core/types/DeviceType.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libNeonCore/src/core/types/DeviceType.cpp b/libNeonCore/src/core/types/DeviceType.cpp index 67d12f04..9a8d75c0 100644 --- a/libNeonCore/src/core/types/DeviceType.cpp +++ b/libNeonCore/src/core/types/DeviceType.cpp @@ -120,12 +120,12 @@ auto DeviceTypeUtil::Cli::getStringOptions() -> std::string auto DeviceTypeUtil::Cli::addToReport(Neon::core::Report& report, Neon::core::Report::SubBlock& subBlock) -> void { - report.addMember("Executor", DeviceTypeUtil::toString(this->getOption()), &subBlock); + report.addMember("DeviceType", DeviceTypeUtil::toString(this->getOption()), &subBlock); } auto DeviceTypeUtil::Cli::addToReport(Neon::core::Report& report) -> void { - report.addMember("Executor", DeviceTypeUtil::toString(this->getOption())); + report.addMember("DeviceType", DeviceTypeUtil::toString(this->getOption())); } From 1fe86f4369a8eb2423a1b3b6deb9472239ace153 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Thu, 14 Jul 2022 14:12:49 +0200 Subject: [PATCH 02/67] Adding a mutable version of getBackend in GridBase. --- libNeonDomain/include/Neon/domain/interface/GridBase.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libNeonDomain/include/Neon/domain/interface/GridBase.h b/libNeonDomain/include/Neon/domain/interface/GridBase.h index 966eb840..36ecd27e 100644 --- a/libNeonDomain/include/Neon/domain/interface/GridBase.h +++ b/libNeonDomain/include/Neon/domain/interface/GridBase.h @@ -105,6 +105,12 @@ class GridBase auto getBackend() const -> const Backend&; + /** + * Returns the backed used to create the grid + */ + auto getBackend() + -> Backend&; + /** * Returns the DevSet object used to create the grid. */ From ef1b18aebeb4dbf0d927fd9471ae938147149b83 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Thu, 14 Jul 2022 14:17:13 +0200 Subject: [PATCH 03/67] WIP: New container interface --- .../Neon/set/ContainerTools/ContainerAPI.h | 5 +- .../Neon/set/ContainerTools/ContainerType.h | 3 +- .../ContainerTools/DeviceManagedContainer.h | 54 +++++++++---------- .../DeviceThenHostManagedContainer.h | 1 + .../set/ContainerTools/HostManagedContainer.h | 45 +++++++++++----- .../src/set/kContainerTools/ContainerType.cpp | 23 +++++++- .../src/set/kContainerTools/containerAPI.cpp | 4 +- 7 files changed, 86 insertions(+), 49 deletions(-) diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h index 876654de..67fc7618 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h @@ -69,7 +69,8 @@ struct ContainerAPI auto getTokenRef() -> std::vector&; - auto getDataViewSupport() -> DataViewSupport; + auto getDataViewSupport() const + -> DataViewSupport; /** * Log information on the parsed tokens. @@ -99,4 +100,4 @@ struct ContainerAPI DataViewSupport mDataViewSupport = DataViewSupport::on; }; -} // namespace Neon::set::internal \ No newline at end of file +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerType.h index 1da12d5e..54c4201c 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerType.h @@ -27,7 +27,8 @@ struct ContainerTypeUtils static auto toString(ContainerType option) -> std::string; static auto fromString(const std::string& option) -> ContainerType; static auto getOptions() -> std::array; + static auto isExpandable(ContainerType option) -> bool; }; -} // namespace Neon \ No newline at end of file +} // namespace Neon diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h index a3cb905a..5ffadbdd 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h @@ -24,10 +24,10 @@ struct DeviceManagedContainer : ContainerAPI * @param data * @param userLambda */ - DeviceManagedContainer(const std::string& name, - Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, - const DataContainer& dataIteratorContainer, - std::function loadingLambda) + DeviceManagedContainer(const std::string& name, + Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, + const DataContainer& dataIteratorContainer, + std::function loadingLambda) : mLoadingLambda(loadingLambda), mDataContainer(dataIteratorContainer) { @@ -61,8 +61,9 @@ struct DeviceManagedContainer : ContainerAPI auto parse() -> const std::vector& override { - auto parser = newParser(); - this->mLoadingLambda(parser); + Neon::SetIdx setIdx(0); + auto parser = newParser(); + this->mLoadingLambda(setIdx, parser); return getTokens(); } @@ -81,7 +82,20 @@ struct DeviceManagedContainer : ContainerAPI * @param streamIdx * @param dataView */ - virtual auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override + auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override + { + const Neon::Backend& bk = mDataContainer.getBackend(); + const int setCardinality = bk.devSet().setCardinality(); + +#pragma omp parallel for num_threads(setCardinality) + for (int i = 0; i < setCardinality; ++i) { + run(Neon::SetIdx(i), streamIdx, dataView); + } + } + + auto run(Neon::SetIdx setIdx, + int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) -> void override { if (ContainerType::deviceManaged == this->getContainerType()) { const Neon::Backend& bk = mDataContainer.getBackend(); @@ -89,34 +103,16 @@ struct DeviceManagedContainer : ContainerAPI // We use device 0 as a dummy setIdx to create a loader. // The actual value is not important as the managed container will take care of launching on all devices. SetIdx dummyTargetSetIdx = 0; - Loader loader = this->newLoader(bk.devType(), dummyTargetSetIdx, dataView, LoadingMode_e::EXTRACT_LAMBDA); - ComputeLambdaT computeLambda = this->mLoadingLambda(loader); + Loader loader = this->newLoader(bk.devType(), setIdx, dataView, LoadingMode_e::EXTRACT_LAMBDA); + ComputeLambdaT computeLambda = this->mLoadingLambda(setIdx, loader); computeLambda(streamIdx, dataView); + return; } NEON_THROW_UNSUPPORTED_OPTION(""); } - virtual auto run(Neon::SetIdx setIdx, - int streamIdx = 0, - Neon::DataView dataView = Neon::DataView::STANDARD) -> void override - { - (void)setIdx; - (void)streamIdx; - (void)dataView; - NEON_DEV_UNDER_CONSTRUCTION(""); - // Neon::set::KernelConfig kernelConfig = m_dataContainer.getKernelConfig(streamIdx, dataView); - // if (!isManaged()) { - // NEON_THROW_UNSUPPORTED_OPTION(""); - // } - // const Neon::Backend& bk = m_dataContainer.getBackend(); - // - // Loader loader = this->newLoader(bk.devType(), 0, dataView, LoadingMode_e::EXTRACT_LAMBDA); - // ComputeLambdaT managedLaunchFun = this->m_loadingLambda(loader); - // managedLaunchFun(setIdx, streamIdx, dataView); - } - private: - std::function mLoadingLambda; + std::function mLoadingLambda; /** * This is the container on which the function will be called * Most probably, this is going to be one of the grids: dGrid, eGrid diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h index 38162522..82eacebb 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h @@ -106,6 +106,7 @@ struct DeviceThenHostManagedContainer : ContainerAPI if (Neon::DataView::STANDARD == dataView) { mDevice->run(streamIdx, Neon::DataView::STANDARD); mHost->run(streamIdx, Neon::DataView::STANDARD); + return ; } NEON_THROW_UNSUPPORTED_OPTION("A DeviceThenHostManagedContainer object can not be run directly."); } diff --git a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h index 72d305ff..a471ef24 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h @@ -7,8 +7,9 @@ namespace Neon::set::internal { enum struct HostManagedSyncType { - singleGPU, - multiGPU + intraGPU = 0, + multiGPU = 1, + none = 2 }; /** @@ -38,15 +39,17 @@ struct HostManagedContainer : ContainerAPI HostManagedContainer(const std::string& name, ContainerAPI::DataViewSupport dataViewSupport, const DataContainerT& dataIteratorContainer, - std::function loadingLambda, - HostManagedSyncType syncType) + std::function loadingLambda, + HostManagedSyncType preSyncType, + HostManagedSyncType presSyncType) : mLoadingLambda(loadingLambda), mDataContainer(dataIteratorContainer) { setContainerType(ContainerType::hostManaged); setDataViewSupport(dataViewSupport); setName(name); - mSyncType = syncType; + mPreSyncType = preSyncType; + mPostSyncType = presSyncType; } auto newLoader(Neon::DeviceType devE, @@ -75,22 +78,27 @@ struct HostManagedContainer : ContainerAPI auto parse() -> const std::vector& override { auto parser = newParser(); - this->mLoadingLambda(parser); + Neon::SetIdx setIdx(0); + this->mLoadingLambda(setIdx, parser); return getTokens(); } - auto getHostContainer() -> internal::ContainerAPI& override + auto getHostContainer() -> std::shared_ptr override { NEON_THROW_UNSUPPORTED_OPTION("This is already a host Container."); } + auto getDeviceContainer() -> std::shared_ptr override + { + NEON_THROW_UNSUPPORTED_OPTION("This is a host Container."); + } /** * Run container over streams * @param streamIdx * @param dataView */ - virtual auto run(int streamIdx = 0, - Neon::DataView dataView = Neon::DataView::STANDARD) + auto run(int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) -> void override { const Neon::Backend& bk = mDataContainer.getBackend(); @@ -110,13 +118,13 @@ struct HostManagedContainer : ContainerAPI } // REMEMBER that this is run in parallel withing omp const Neon::Backend& bk = mDataContainer.getBackend(); - switch (mSyncType) { + switch (mPreSyncType) { case HostManagedSyncType::multiGPU: { bk.sync(setIdx, streamIdx); #pragma omp barrier break; } - case HostManagedSyncType::singleGPU: { + case HostManagedSyncType::intraGPU: { bk.sync(setIdx, streamIdx); break; @@ -124,21 +132,30 @@ struct HostManagedContainer : ContainerAPI } Loader loader = this->newLoader(bk.devType(), setIdx, dataView, LoadingMode_e::EXTRACT_LAMBDA); - ComputeLambdaT computeLambda = this->mLoadingLambda(loader); + ComputeLambdaT computeLambda = this->mLoadingLambda(setIdx, loader); computeLambda(streamIdx, dataView); + switch (mPostSyncType) { + case HostManagedSyncType::multiGPU: { #pragma omp barrier + break; + } + case HostManagedSyncType::intraGPU: { + break; + } + } } private: - std::function mLoadingLambda; + std::function mLoadingLambda; /** * This is the container on which the function will be called * Most probably, this is going to be one of the grids: dGrid, eGrid */ DataContainerT mDataContainer; - HostManagedSyncType mSyncType; + HostManagedSyncType mPreSyncType; + HostManagedSyncType mPostSyncType; }; } // namespace Neon diff --git a/libNeonSet/src/set/kContainerTools/ContainerType.cpp b/libNeonSet/src/set/kContainerTools/ContainerType.cpp index 36e076bf..a934f9db 100644 --- a/libNeonSet/src/set/kContainerTools/ContainerType.cpp +++ b/libNeonSet/src/set/kContainerTools/ContainerType.cpp @@ -45,4 +45,25 @@ auto ContainerTypeUtils::getOptions() -> std::array return opts; } -} // namespace Neon \ No newline at end of file +auto ContainerTypeUtils::isExpandable(ContainerType option) -> bool +{ + switch (option) { + case ContainerType::device: { + return false; + } + case ContainerType::deviceManaged: { + return false; + } + case ContainerType::hostManaged: { + return false; + } + case ContainerType::deviceThenHostManaged: { + return true; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +} // namespace internal +} // namespace set +} // namespace Neon diff --git a/libNeonSet/src/set/kContainerTools/containerAPI.cpp b/libNeonSet/src/set/kContainerTools/containerAPI.cpp index d78ffd4d..2a88d4ac 100644 --- a/libNeonSet/src/set/kContainerTools/containerAPI.cpp +++ b/libNeonSet/src/set/kContainerTools/containerAPI.cpp @@ -60,7 +60,7 @@ auto ContainerAPI::getContainerType() const -> ContainerType return mContainerType; } -auto ContainerAPI::getDataViewSupport() -> ContainerAPI::DataViewSupport +auto ContainerAPI::getDataViewSupport() const -> ContainerAPI::DataViewSupport { return mDataViewSupport; } @@ -82,4 +82,4 @@ auto ContainerAPI::toLog(uint64_t uid) -> void NEON_INFO("Container {}: tokens = [{}]", uid, listOfTokes.str()); } -} // namespace Neon \ No newline at end of file +} // namespace Neon From a07f632b8f1de9b79b5bd3fc8f2fcc731695af83 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Thu, 14 Jul 2022 14:17:54 +0200 Subject: [PATCH 04/67] Adding some extra information to report for a device report. --- libNeonSys/src/sys/Report.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libNeonSys/src/sys/Report.cpp b/libNeonSys/src/sys/Report.cpp index 148a9cfc..c1cfdbc8 100644 --- a/libNeonSys/src/sys/Report.cpp +++ b/libNeonSys/src/sys/Report.cpp @@ -136,7 +136,9 @@ auto Report::device() -> void addSubdoc("CUDA", subdoc); } + addMember("Runtime Version", ver, &subdoc); + addMember("CUDA API Version", CUDA_VERSION, &subdoc); addMember("num_gpus", num_gpus); @@ -181,4 +183,4 @@ auto Report::device() -> void } -} // namespace Neon \ No newline at end of file +} // namespace Neon From cc64f771faad844b1ad9c0f9111f856d72cd7a2d Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Thu, 14 Jul 2022 14:18:52 +0200 Subject: [PATCH 05/67] WIP: New container interface --- libNeonSet/include/Neon/set/Containter.h | 91 +++++++++++++++++------- 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 8ffb8530..e74e0d2e 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -19,24 +19,34 @@ struct Container Container() = default; auto run(int streamIdx, - Neon::DataView dataView = Neon::DataView::STANDARD) -> void + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void { mContainer->run(streamIdx, dataView); } auto run(Neon::SetIdx setIdx, int streamIdx, - Neon::DataView dataView = Neon::DataView::STANDARD) -> void + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void { mContainer->run(setIdx, streamIdx, dataView); } - auto getContainerInterface() -> Neon::set::internal::ContainerAPI& + auto getContainerInterface() + -> Neon::set::internal::ContainerAPI& { return mContainer.operator*(); } - auto getContainerInterfaceShrPtr() -> std::shared_ptr + auto getContainerInterface() const + -> const Neon::set::internal::ContainerAPI& + { + return mContainer.operator*(); + } + + auto getContainerInterfaceShrPtr() + -> std::shared_ptr { return mContainer; } @@ -71,7 +81,8 @@ struct Container static auto factoryOldManaged(const std::string& name, Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, DataContainerT a, - const UserLoadingLambdaT& f) -> Container + const UserLoadingLambdaT& f) + -> Container { using ManagedLaunch = typename std::invoke_result::type; auto k = new Neon::set::internal::OldDeviceManagedContainer(name, dataViewSupport, @@ -85,12 +96,17 @@ struct Container typename UserLoadingLambdaT> static auto factoryHostManaged(const std::string& name, Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, + Neon::set::internal::HostManagedSyncType preSyncType, + Neon::set::internal::HostManagedSyncType presSyncType, DataContainerT a, - const UserLoadingLambdaT& f) -> Container + const UserLoadingLambdaT& f) + -> Container { - using ManagedLaunch = typename std::invoke_result::type; + using ManagedLaunch = typename std::invoke_result::type; auto k = new Neon::set::internal::HostManagedContainer(name, dataViewSupport, - a, f); + a, f, + preSyncType, + presSyncType); std::shared_ptr tmp(k); return Container(tmp); @@ -101,9 +117,10 @@ struct Container static auto factoryDeviceManaged(const std::string& name, Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, DataContainerT a, - const UserLoadingLambdaT& f) -> Container + const UserLoadingLambdaT& f) + -> Container { - using ManagedLaunch = typename std::invoke_result::type; + using ManagedLaunch = typename std::invoke_result::type; auto k = new Neon::set::internal::DeviceManagedContainer(name, dataViewSupport, a, f); @@ -123,22 +140,56 @@ struct Container return Container(tmp); } - auto getName() const -> const std::string& + auto getName() const + -> const std::string& { return mContainer->getName(); } - auto getUid() const -> uint64_t + auto getUid() const + -> uint64_t { const auto uid = (uint64_t)mContainer.get(); return uid; } - auto logTokens() -> void + auto logTokens() + -> void { return mContainer->toLog(getUid()); } + auto getHostContainer() const + -> Container + { + std::shared_ptr hostAPI = + mContainer->getHostContainer(); + return Container(hostAPI); + } + + virtual auto getDeviceContainer() const -> Container + { + std::shared_ptr deviceAPI = + mContainer->getDeviceContainer(); + return Container(deviceAPI); + } + + auto getDataViewSupport() const + -> Neon::set::internal::ContainerAPI::DataViewSupport + { + auto& api = this->getContainerInterface(); + auto const dwSupport = api.getDataViewSupport(); + return dwSupport; + } + + auto getContainerType() const + -> Neon::set::internal::ContainerType + { + auto& api = this->getContainerInterface(); + auto const type = api.getContainerType(); + return type; + } + protected: std::shared_ptr mContainer; @@ -152,18 +203,6 @@ struct Container { // Empty } - - auto getHostContainer() -> Container - { - std::shared_ptr hostAPI = mContainer->getHostContainer(); - return Container(hostAPI); - } - - virtual auto getDeviceContainer() -> Container - { - std::shared_ptr deviceAPI = mContainer->getDeviceContainer(); - return Container(deviceAPI); - } }; -} // namespace Neon::set \ No newline at end of file +} // namespace Neon::set From f03bb2ee6ed4711877f06505bd11a80ef2427f13 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Mon, 18 Jul 2022 17:50:46 +0200 Subject: [PATCH 06/67] Documentation --- libNeonSet/include/Neon/set/Containter.h | 40 +++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index e74e0d2e..4687ec33 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -18,46 +18,64 @@ struct Container public: Container() = default; - auto run(int streamIdx, - Neon::DataView dataView = Neon::DataView::STANDARD) + /** + * Run a Neon Container on a given stream and with a given data view + */ + auto run(int streamIdx /**< Target stream */, + Neon::DataView dataView = Neon::DataView::STANDARD /**< Target data view ( STANDARD by default ) */ ) -> void { mContainer->run(streamIdx, dataView); } - auto run(Neon::SetIdx setIdx, - int streamIdx, - Neon::DataView dataView = Neon::DataView::STANDARD) + /** + * Runs a Neon Container on a given stream and with a given data view + */ + auto run(Neon::SetIdx setIdx /**< Set index of a target device */, + int streamIdx /**< Target stream */, + Neon::DataView dataView = Neon::DataView::STANDARD /**< Target data view ( STANDARD by default ) */) -> void { mContainer->run(setIdx, streamIdx, dataView); } + /** + * Returns the internal interface of a Neon Container. + */ auto getContainerInterface() -> Neon::set::internal::ContainerAPI& { return mContainer.operator*(); } + /** + * Returns the internal interface of a Neon Container. + */ auto getContainerInterface() const -> const Neon::set::internal::ContainerAPI& { return mContainer.operator*(); } + /** + * Returns the internal interface of a Neon Container. + */ auto getContainerInterfaceShrPtr() -> std::shared_ptr { return mContainer; } + /** + * Factory function to create a Neon Container + */ template - static auto factory(const std::string& name, - Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, - const DataContainerT& a, - const UserLoadingLambdaT& f, - const index_3d& blockSize, - std::function shMemSizeFun) -> Container + static auto factory(const std::string& name /**< A user's string to identify the computation done by the Container. */, + Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport /**< Defines the data view support for the new Container */, + const DataContainerT& a /**< Multi device object that will be used for the creating of the Container */, + const UserLoadingLambdaT& f /**< User's loading lambda for the new Container */, + const index_3d& blockSize /**< Block size for the thread grid */, + std::function shMemSizeFun /**< User's function to implicitly compute the required shared memory */) -> Container { using LoadingLambda = typename std::invoke_result::type; auto k = new Neon::set::internal::DeviceContainer(name, dataViewSupport, From 1d06c3278f83640bfe144d795a829edaefc03306 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Mon, 18 Jul 2022 18:43:01 +0200 Subject: [PATCH 07/67] Fixing merging issues. --- .../src/domain/interface/GridBase.cpp | 445 ++++++++++-------- .../src/domain/internal/dGrid/dGrid.cpp | 2 +- .../src/set/kContainerTools/ContainerType.cpp | 3 +- libNeonSys/src/sys/Report.cpp | 3 - 4 files changed, 238 insertions(+), 215 deletions(-) diff --git a/libNeonDomain/src/domain/interface/GridBase.cpp b/libNeonDomain/src/domain/interface/GridBase.cpp index 3816cbfc..4eec4169 100644 --- a/libNeonDomain/src/domain/interface/GridBase.cpp +++ b/libNeonDomain/src/domain/interface/GridBase.cpp @@ -2,218 +2,245 @@ namespace Neon::domain::interface { - auto GridBase::init(const std::string &gridImplementationName, - const Neon::Backend &backend, - const Neon::index_3d &dimension, - const Neon::domain::Stencil &stencil, - const Neon::set::DataSet &nPartitionElements, - const Neon::index_3d &defaultBlockSize, - const Vec_3d &spacingData, - const Vec_3d &origin) -> void { - mStorage->backend = backend; - mStorage->dimension = dimension; - mStorage->stencil = stencil; - mStorage->nPartitionElements = nPartitionElements.clone(); - mStorage->spacing = spacingData; - mStorage->origin = origin; - mStorage->gridImplementationName = gridImplementationName; - - for (const auto &dw: DataViewUtil::validOptions()) { - mStorage->defaults.launchParameters[DataViewUtil::toInt(dw)] = backend.devSet().newLaunchParameters(); - } - mStorage->defaults.blockDim = defaultBlockSize; - } - - GridBase::GridBase() - : mStorage(std::make_shared()) { - } - - GridBase::GridBase(const std::string &gridImplementationName, - const Neon::Backend &backend, - const Neon::index_3d &dimension, - const Neon::domain::Stencil &stencil, - const Neon::set::DataSet &nPartitionElements, - const Neon::index_3d &defaultBlockSize, - const Vec_3d &spacingData, - const Vec_3d &origin) - : mStorage(std::make_shared()) { - init(gridImplementationName, - backend, - dimension, - stencil, - nPartitionElements, - defaultBlockSize, - spacingData, - origin); - } - - auto GridBase::getDimension() const -> const Neon::index_3d & { - return mStorage->dimension; - } - - auto GridBase::getStencil() const -> const Neon::domain::Stencil & { - return mStorage->stencil; - } - - auto GridBase::getSpacing() const -> const Vec_3d & { - return mStorage->spacing; - } - - auto GridBase::getOrigin() const -> const Vec_3d & { - return mStorage->origin; - } - - auto GridBase::getNumAllCells() const - -> size_t { - return mStorage->dimension.rMulTyped(); - } - - auto GridBase::getNumActiveCells() const - -> size_t { - size_t count = 0; - for (int idx = 0; idx < mStorage->backend.devSet().setCardinality(); idx++) { - count += mStorage->nPartitionElements[idx]; - } - return count; - } - - auto GridBase::getBackend() const - -> const Backend & { - return mStorage->backend; - } - - auto GridBase::getDevSet() const - -> const Neon::set::DevSet & { - return mStorage->backend.devSet(); - } - - auto GridBase::getDefaultBlock() const - -> const Neon::index_3d & { - return mStorage->defaults.blockDim; - } - - auto GridBase::setDefaultBlock(const Neon::index_3d &blockDim) - -> void { - mStorage->defaults.blockDim = blockDim; - } - - auto GridBase::flattenedLengthSet() const - -> const Neon::set::DataSet & { - return getNumActiveCellsPerPartition(); - } - - auto GridBase::getNumActiveCellsPerPartition() const - -> const Neon::set::DataSet & { - return mStorage->nPartitionElements; - } - - auto GridBase::getDefaultLaunchParameters(Neon::DataView dataView) - -> Neon::set::LaunchParameters & { - return mStorage->defaults.launchParameters[Neon::DataViewUtil::toInt(dataView)]; - } - - auto GridBase::getDefaultLaunchParameters(Neon::DataView dataView) const - -> const Neon::set::LaunchParameters & { - return mStorage->defaults.launchParameters[Neon::DataViewUtil::toInt(dataView)]; - } - - auto GridBase::getImplementationName() const - -> const std::string & { - return mStorage->gridImplementationName; - } - - auto GridBase::toString() const -> std::string { - std::stringstream s; - s << "[Domain Grid]:{" << this->getImplementationName() << "}" - << ", [Background Grid]:{" << this->getDimension() << "}" - << ", [Active Cells]:{" << this->getNumActiveCells() << "}" - << ", [Cell Distribution]:{" << [&] { - std::stringstream tmp; - tmp << "("; - const int nPartitions = int(this->getNumActiveCellsPerPartition().size()); - for (int i = 0; i < nPartitions; i++) { - tmp << this->getNumActiveCellsPerPartition()[i]; - if (i < nPartitions - 1) { - tmp << ","; +auto GridBase::init(const std::string& gridImplementationName, + const Neon::Backend& backend, + const Neon::index_3d& dimension, + const Neon::domain::Stencil& stencil, + const Neon::set::DataSet& nPartitionElements, + const Neon::index_3d& defaultBlockSize, + const Vec_3d& spacingData, + const Vec_3d& origin) -> void +{ + mStorage->backend = backend; + mStorage->dimension = dimension; + mStorage->stencil = stencil; + mStorage->nPartitionElements = nPartitionElements.clone(); + mStorage->spacing = spacingData; + mStorage->origin = origin; + mStorage->gridImplementationName = gridImplementationName; + + for (const auto& dw : DataViewUtil::validOptions()) { + mStorage->defaults.launchParameters[DataViewUtil::toInt(dw)] = backend.devSet().newLaunchParameters(); + } + mStorage->defaults.blockDim = defaultBlockSize; +} + +GridBase::GridBase() + : mStorage(std::make_shared()) +{ +} + +GridBase::GridBase(const std::string& gridImplementationName, + const Neon::Backend& backend, + const Neon::index_3d& dimension, + const Neon::domain::Stencil& stencil, + const Neon::set::DataSet& nPartitionElements, + const Neon::index_3d& defaultBlockSize, + const Vec_3d& spacingData, + const Vec_3d& origin) + : mStorage(std::make_shared()) +{ + init(gridImplementationName, + backend, + dimension, + stencil, + nPartitionElements, + defaultBlockSize, + spacingData, + origin); +} + +auto GridBase::getDimension() const -> const Neon::index_3d& +{ + return mStorage->dimension; +} + +auto GridBase::getStencil() const -> const Neon::domain::Stencil& +{ + return mStorage->stencil; +} + +auto GridBase::getSpacing() const -> const Vec_3d& +{ + return mStorage->spacing; +} + +auto GridBase::getOrigin() const -> const Vec_3d& +{ + return mStorage->origin; +} + +auto GridBase::getNumAllCells() const + -> size_t +{ + return mStorage->dimension.rMulTyped(); +} + +auto GridBase::getNumActiveCells() const + -> size_t +{ + size_t count = 0; + for (int idx = 0; idx < mStorage->backend.devSet().setCardinality(); idx++) { + count += mStorage->nPartitionElements[idx]; + } + return count; +} + +auto GridBase::getBackend() const + -> const Backend& +{ + return mStorage->backend; +} + +auto GridBase::getBackend() + -> Backend& +{ + return mStorage->backend; +} + +auto GridBase::getDevSet() const + -> const Neon::set::DevSet& +{ + return mStorage->backend.devSet(); +} + +auto GridBase::getDefaultBlock() const + -> const Neon::index_3d& +{ + return mStorage->defaults.blockDim; +} + +auto GridBase::setDefaultBlock(const Neon::index_3d& blockDim) + -> void +{ + mStorage->defaults.blockDim = blockDim; +} + +auto GridBase::flattenedLengthSet() const + -> const Neon::set::DataSet& +{ + return getNumActiveCellsPerPartition(); +} + +auto GridBase::getNumActiveCellsPerPartition() const + -> const Neon::set::DataSet& +{ + return mStorage->nPartitionElements; +} + +auto GridBase::getDefaultLaunchParameters(Neon::DataView dataView) + -> Neon::set::LaunchParameters& +{ + return mStorage->defaults.launchParameters[Neon::DataViewUtil::toInt(dataView)]; +} + +auto GridBase::getDefaultLaunchParameters(Neon::DataView dataView) const + -> const Neon::set::LaunchParameters& +{ + return mStorage->defaults.launchParameters[Neon::DataViewUtil::toInt(dataView)]; +} + +auto GridBase::getImplementationName() const + -> const std::string& +{ + return mStorage->gridImplementationName; +} + +auto GridBase::toString() const -> std::string +{ + std::stringstream s; + s << "[Domain Grid]:{" << this->getImplementationName() << "}" + << ", [Background Grid]:{" << this->getDimension() << "}" + << ", [Active Cells]:{" << this->getNumActiveCells() << "}" + << ", [Cell Distribution]:{" << [&] { + std::stringstream tmp; + tmp << "("; + const int nPartitions = int(this->getNumActiveCellsPerPartition().size()); + for (int i = 0; i < nPartitions; i++) { + tmp << this->getNumActiveCellsPerPartition()[i]; + if (i < nPartitions - 1) { + tmp << ","; + } + } + tmp << ")"; + return tmp.str(); + }() + << "}" + << ", [Backend]:{" << getBackend().toString() << "}"; + + return s.str(); +} + +auto GridBase::getGridUID() const -> size_t +{ + return size_t(mStorage.get()); +} + +auto GridBase::toReport(Neon::Report& report, + bool includeBackendInfo) const -> void +{ + auto subdoc = report.getSubdoc(); + + report.addMember("ImplementationName", getImplementationName(), &subdoc); + report.addMember("ActiveCells", getNumActiveCells(), &subdoc); + report.addMember("GridUID", getGridUID(), &subdoc); + + report.addMember( + "Dimension", + [&] { + std::stringstream list; + list << "["; + list << getDimension().x << " " + << getDimension().y << " " + << getDimension().z << "]"; + return list.str(); + }(), + &subdoc); + + report.addMember( + "Stencil", + [&] { + std::stringstream list; + list << "["; + bool isFirst = true; + auto stencil = getStencil(); + auto stencilPoints = stencil.points(); + for (auto& point : stencilPoints) { + if (!isFirst) { + list << " "; } + list << "("; + list << point.x << " " + << point.y << " " + << point.z << ")"; + isFirst = false; } - tmp << ")"; - return tmp.str(); - }() - << "}" - << ", [Backend]:{" << getBackend().toString() << "}"; - - return s.str(); - } + return list.str(); + }(), + &subdoc); + + report.addMember( + "ActiveCellsPerPartition", + [&] { + std::stringstream list; + list << "["; + int i = 0; + for (auto& nCells : getNumActiveCellsPerPartition().vec()) { + if (i != 0) { + list << " "; + } + list << nCells; + i = 1; + } + list << "]"; + return list.str(); + }(), + &subdoc); - auto GridBase::getGridUID() const -> size_t { - return size_t(mStorage.get()); - } + if (includeBackendInfo) + getBackend().toReport(report, &subdoc); - auto GridBase::toReport(Neon::Report &report, - bool includeBackendInfo) const -> void { - auto subdoc = report.getSubdoc(); - - report.addMember("ImplementationName", getImplementationName(), &subdoc); - report.addMember("ActiveCells", getNumActiveCells(), &subdoc); - report.addMember("GridUID", getGridUID(), &subdoc); - - report.addMember( - "Dimension", - [&] { - std::stringstream list; - list << "["; - list << getDimension().x << " " - << getDimension().y << " " - << getDimension().z << "]"; - return list.str(); - }(), - &subdoc); - - report.addMember( - "Stencil", - [&] { - std::stringstream list; - list << "["; - bool isFirst = true; - auto stencil = getStencil(); - auto stencilPoints = stencil.points(); - for (auto &point: stencilPoints) { - if (!isFirst) { - list << " "; - } - list << "("; - list << point.x << " " - << point.y << " " - << point.z << ")"; - isFirst = false; - } - return list.str(); - }(), - &subdoc); - - report.addMember( - "ActiveCellsPerPartition", - [&] { - std::stringstream list; - list << "["; - int i = 0; - for (auto &nCells: getNumActiveCellsPerPartition().vec()) { - if (i != 0) { - list << " "; - } - list << nCells; - i = 1; - } - list << "]"; - return list.str(); - }(), - &subdoc); - - if (includeBackendInfo) - getBackend().toReport(report, &subdoc); - - report.addSubdoc("Grid", subdoc); - } + report.addSubdoc("Grid", subdoc); +} } // namespace Neon::domain::interface \ No newline at end of file diff --git a/libNeonDomain/src/domain/internal/dGrid/dGrid.cpp b/libNeonDomain/src/domain/internal/dGrid/dGrid.cpp index 952b57a3..5babc2f5 100644 --- a/libNeonDomain/src/domain/internal/dGrid/dGrid.cpp +++ b/libNeonDomain/src/domain/internal/dGrid/dGrid.cpp @@ -163,7 +163,7 @@ auto dGrid::getKernelConfig(int streamIdx, getDefaultBlock(), 0); kernelConfig.expertSetLaunchParameters(launchInfoSet); - kernelConfig.expertSetBackend(getBackend()); + kernelConfig.expertSetBackend(this->getBackend()); return kernelConfig; } diff --git a/libNeonSet/src/set/kContainerTools/ContainerType.cpp b/libNeonSet/src/set/kContainerTools/ContainerType.cpp index a934f9db..d03b6697 100644 --- a/libNeonSet/src/set/kContainerTools/ContainerType.cpp +++ b/libNeonSet/src/set/kContainerTools/ContainerType.cpp @@ -65,5 +65,4 @@ auto ContainerTypeUtils::isExpandable(ContainerType option) -> bool } } // namespace internal -} // namespace set -} // namespace Neon + diff --git a/libNeonSys/src/sys/Report.cpp b/libNeonSys/src/sys/Report.cpp index c1cfdbc8..8c702d1c 100644 --- a/libNeonSys/src/sys/Report.cpp +++ b/libNeonSys/src/sys/Report.cpp @@ -136,9 +136,6 @@ auto Report::device() -> void addSubdoc("CUDA", subdoc); } - addMember("Runtime Version", ver, &subdoc); - - addMember("CUDA API Version", CUDA_VERSION, &subdoc); addMember("num_gpus", num_gpus); From 090e57fd4e2be0eb163269783e28971bc87a0b8e Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Mon, 18 Jul 2022 19:36:08 +0200 Subject: [PATCH 08/67] Documentation --- .../include/Neon/domain/interface/GridBase.h | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/libNeonDomain/include/Neon/domain/interface/GridBase.h b/libNeonDomain/include/Neon/domain/interface/GridBase.h index 36ecd27e..0440c1bb 100644 --- a/libNeonDomain/include/Neon/domain/interface/GridBase.h +++ b/libNeonDomain/include/Neon/domain/interface/GridBase.h @@ -20,15 +20,6 @@ class GridBase public: GridBase(); - GridBase(const std::string& gridImplementationName, - const Neon::Backend& backend, - const Neon::index_3d& dim, - const Neon::domain::Stencil& stencil, - const Neon::set::DataSet& nPartitionElements /**< Number of element per partition */, - const Neon::index_3d& defaultBlockSize, - const Vec_3d& spacingData = Vec_3d(1, 1, 1) /*! Spacing, i.e. size of a voxel */, - const Vec_3d& origin = Vec_3d(0, 0, 0) /*! Origin */); - /** * Returns the size of the grid */ @@ -81,7 +72,6 @@ class GridBase /** * Creates a DataSet object compatible with the number of GPU used by the grid. - * TODO - refactor into a create method once all grids are ported */ template auto newDataSet() const @@ -123,30 +113,60 @@ class GridBase auto toString() const -> std::string; + /** + * Returns an UID for the grid + * @return + */ auto getGridUID() const -> size_t; + /** + * Add the grid information in a Report object + */ virtual auto toReport(Neon::Report& report, bool addBackendInfo = false) const -> void; + /** + * Returns the thread block size used by default by the grid + */ auto getDefaultBlock() const -> const Neon::index_3d&; protected: - auto init(const std::string& gridImplementationName, - const Neon::Backend& backend, - const Neon::index_3d& dimension, - const Neon::domain::Stencil& stencil, - const Neon::set::DataSet& nPartitionElements, - const Neon::index_3d& defaultBlockSize, - const Vec_3d& spacingData, - const Vec_3d& origin) -> void; + /** + * Protected constructor + */ + GridBase(const std::string& gridImplementationName, + const Neon::Backend& backend, + const Neon::index_3d& dim, + const Neon::domain::Stencil& stencil, + const Neon::set::DataSet& nPartitionElements /**< Number of element per partition */, + const Neon::index_3d& defaultBlockSize, + const Vec_3d& spacingData = Vec_3d(1, 1, 1) /*! Spacing, i.e. size of a voxel */, + const Vec_3d& origin = Vec_3d(0, 0, 0) /*! Origin */); + /** + * Protected initialization function used by derived classes to set some parameters. + */ + auto init(const std::string& gridImplementationName /**< Name of the implementation, for example dGrid eGrid etc */, + const Neon::Backend& backend /**< Backend used to create the grid */, + const Neon::index_3d& dimension /**< Dimension of the grid */, + const Neon::domain::Stencil& stencil /**< Union of all the stencil that will be used with the grid */, + const Neon::set::DataSet& nPartitionElements /**< Elements associated to each partition */, + const Neon::index_3d& defaultBlockSize /**< Default thread block size */, + const Vec_3d& spacingData /**< Grid spacing */, + const Vec_3d& origin /**< Position in space of the grid's origin */) -> void; + /** + * Protected method to set the default thread blocks size + */ auto setDefaultBlock(const Neon::index_3d&) -> void; + /** + * Protected method to set default thread block size by data view. + */ auto getDefaultLaunchParameters(Neon::DataView) -> Neon::set::LaunchParameters&; @@ -166,8 +186,8 @@ class GridBase Neon::index_3d dimension /**< Dimension of the grid */; Neon::domain::Stencil stencil /**< Stencil used for the grid initialization */; Neon::set::DataSet nPartitionElements /**< Number of elements per partition */; - Vec_3d spacing /*! Spacing, i.e. size of a voxel */; - Vec_3d origin /*! Origin */; + Vec_3d spacing /**< Spacing, i.e. size of a voxel */; + Vec_3d origin /**< Position in space of the grid's origin */; Defaults_t defaults; std::string gridImplementationName; }; From 182155b9ed4f27ec472b2023b331cac028a12ddc Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Mon, 18 Jul 2022 22:51:23 +0200 Subject: [PATCH 09/67] Imposing coding standards on the Container class. --- .../set/ContainerTools/HostManagedContainer.h | 22 +-- .../set/ContainerTools/HostManagedSyncType.h | 12 ++ libNeonSet/include/Neon/set/Containter.h | 155 ++++-------------- libNeonSet/include/Neon/set/Containter_imp.h | 87 ++++++++++ libNeonSet/src/set/Containter.cpp | 115 +++++++++++++ 5 files changed, 253 insertions(+), 138 deletions(-) create mode 100644 libNeonSet/include/Neon/set/ContainerTools/HostManagedSyncType.h create mode 100644 libNeonSet/include/Neon/set/Containter_imp.h create mode 100644 libNeonSet/src/set/Containter.cpp diff --git a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h index a471ef24..1a9926b2 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h @@ -1,17 +1,11 @@ #pragma once #include "Neon/set/ContainerTools/ContainerAPI.h" +#include "Neon/set/ContainerTools/HostManagedSyncType.h" #include "Neon/set/ContainerTools/Loader.h" namespace Neon::set::internal { -enum struct HostManagedSyncType -{ - intraGPU = 0, - multiGPU = 1, - none = 2 -}; - /** * This Container run operation on the host * In terms of interaction with streams it always implement a barrier on the associated stream @@ -36,12 +30,12 @@ struct HostManagedContainer : ContainerAPI * @param data * @param userLambda */ - HostManagedContainer(const std::string& name, - ContainerAPI::DataViewSupport dataViewSupport, - const DataContainerT& dataIteratorContainer, + HostManagedContainer(const std::string& name, + ContainerAPI::DataViewSupport dataViewSupport, + const DataContainerT& dataIteratorContainer, std::function loadingLambda, - HostManagedSyncType preSyncType, - HostManagedSyncType presSyncType) + HostManagedSyncType preSyncType, + HostManagedSyncType presSyncType) : mLoadingLambda(loadingLambda), mDataContainer(dataIteratorContainer) { @@ -77,7 +71,7 @@ struct HostManagedContainer : ContainerAPI auto parse() -> const std::vector& override { - auto parser = newParser(); + auto parser = newParser(); Neon::SetIdx setIdx(0); this->mLoadingLambda(setIdx, parser); return getTokens(); @@ -158,4 +152,4 @@ struct HostManagedContainer : ContainerAPI HostManagedSyncType mPostSyncType; }; -} // namespace Neon +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/ContainerTools/HostManagedSyncType.h b/libNeonSet/include/Neon/set/ContainerTools/HostManagedSyncType.h new file mode 100644 index 00000000..5d2b53a6 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/HostManagedSyncType.h @@ -0,0 +1,12 @@ +#pragma once + +namespace Neon::set::internal { + +enum struct HostManagedSyncType +{ + intraGPU = 0, + multiGPU = 1, + none = 2 +}; + +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 4687ec33..ed407d34 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -5,11 +5,9 @@ #include "functional" #include "type_traits" -#include "Neon/set/ContainerTools/DeviceContainer.h" -#include "Neon/set/ContainerTools/DeviceManagedContainer.h" -#include "Neon/set/ContainerTools/DeviceThenHostManagedContainer.h" -#include "Neon/set/ContainerTools/HostManagedContainer.h" -#include "Neon/set/ContainerTools/OldDeviceManagedContainer.h" +#include "Neon/set/ContainerTools/ContainerAPI.h" +#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/ContainerTools/HostManagedSyncType.h" namespace Neon::set { @@ -22,11 +20,8 @@ struct Container * Run a Neon Container on a given stream and with a given data view */ auto run(int streamIdx /**< Target stream */, - Neon::DataView dataView = Neon::DataView::STANDARD /**< Target data view ( STANDARD by default ) */ ) - -> void - { - mContainer->run(streamIdx, dataView); - } + Neon::DataView dataView = Neon::DataView::STANDARD /**< Target data view ( STANDARD by default ) */) + -> void; /** * Runs a Neon Container on a given stream and with a given data view @@ -34,37 +29,25 @@ struct Container auto run(Neon::SetIdx setIdx /**< Set index of a target device */, int streamIdx /**< Target stream */, Neon::DataView dataView = Neon::DataView::STANDARD /**< Target data view ( STANDARD by default ) */) - -> void - { - mContainer->run(setIdx, streamIdx, dataView); - } + -> void; /** * Returns the internal interface of a Neon Container. */ auto getContainerInterface() - -> Neon::set::internal::ContainerAPI& - { - return mContainer.operator*(); - } + -> Neon::set::internal::ContainerAPI&; /** * Returns the internal interface of a Neon Container. */ auto getContainerInterface() const - -> const Neon::set::internal::ContainerAPI& - { - return mContainer.operator*(); - } + -> const Neon::set::internal::ContainerAPI&; /** - * Returns the internal interface of a Neon Container. - */ + * Returns the internal interface of a Neon Container. + */ auto getContainerInterfaceShrPtr() - -> std::shared_ptr - { - return mContainer; - } + -> std::shared_ptr; /** * Factory function to create a Neon Container @@ -75,16 +58,8 @@ struct Container const DataContainerT& a /**< Multi device object that will be used for the creating of the Container */, const UserLoadingLambdaT& f /**< User's loading lambda for the new Container */, const index_3d& blockSize /**< Block size for the thread grid */, - std::function shMemSizeFun /**< User's function to implicitly compute the required shared memory */) -> Container - { - using LoadingLambda = typename std::invoke_result::type; - auto k = new Neon::set::internal::DeviceContainer(name, dataViewSupport, - a, f, - blockSize, shMemSizeFun); - - std::shared_ptr tmp(k); - return Container(tmp); - } + std::function shMemSizeFun /**< User's function to implicitly compute the required shared memory */) + -> Container; /** * Factory function to generate a kContainer object. @@ -100,15 +75,7 @@ struct Container Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, DataContainerT a, const UserLoadingLambdaT& f) - -> Container - { - using ManagedLaunch = typename std::invoke_result::type; - auto k = new Neon::set::internal::OldDeviceManagedContainer(name, dataViewSupport, - a, f); - - std::shared_ptr tmp(k); - return Container(tmp); - } + -> Container; template @@ -118,17 +85,7 @@ struct Container Neon::set::internal::HostManagedSyncType presSyncType, DataContainerT a, const UserLoadingLambdaT& f) - -> Container - { - using ManagedLaunch = typename std::invoke_result::type; - auto k = new Neon::set::internal::HostManagedContainer(name, dataViewSupport, - a, f, - preSyncType, - presSyncType); - - std::shared_ptr tmp(k); - return Container(tmp); - } + -> Container; template @@ -136,91 +93,41 @@ struct Container Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, DataContainerT a, const UserLoadingLambdaT& f) - -> Container - { - using ManagedLaunch = typename std::invoke_result::type; - auto k = new Neon::set::internal::DeviceManagedContainer(name, dataViewSupport, - a, f); - - std::shared_ptr tmp(k); - return Container(tmp); - } + -> Container; static auto factoryDeviceThenHostManaged(const std::string& name, Container& device, - Container& host) -> Container - { - auto k = new Neon::set::internal::DeviceThenHostManagedContainer(name, - device.getContainerInterfaceShrPtr(), - host.getContainerInterfaceShrPtr()); - - std::shared_ptr tmp(k); - return Container(tmp); - } + Container& host) + -> Container; auto getName() const - -> const std::string& - { - return mContainer->getName(); - } + -> const std::string&; auto getUid() const - -> uint64_t - { - const auto uid = (uint64_t)mContainer.get(); - return uid; - } + -> uint64_t; auto logTokens() - -> void - { - return mContainer->toLog(getUid()); - } + -> void; auto getHostContainer() const - -> Container - { - std::shared_ptr hostAPI = - mContainer->getHostContainer(); - return Container(hostAPI); - } - - virtual auto getDeviceContainer() const -> Container - { - std::shared_ptr deviceAPI = - mContainer->getDeviceContainer(); - return Container(deviceAPI); - } + -> Container; + + virtual auto getDeviceContainer() const -> Container; auto getDataViewSupport() const - -> Neon::set::internal::ContainerAPI::DataViewSupport - { - auto& api = this->getContainerInterface(); - auto const dwSupport = api.getDataViewSupport(); - return dwSupport; - } + -> Neon::set::internal::ContainerAPI::DataViewSupport; auto getContainerType() const - -> Neon::set::internal::ContainerType - { - auto& api = this->getContainerInterface(); - auto const type = api.getContainerType(); - return type; - } + -> Neon::set::internal::ContainerType; protected: std::shared_ptr mContainer; - Container(std::shared_ptr& container) - : mContainer(container) - { - // Empty - } - Container(std::shared_ptr&& container) - : mContainer(container) - { - // Empty - } + Container(std::shared_ptr& container); + + Container(std::shared_ptr&& container); }; } // namespace Neon::set + +#include "Neon/set/Containter_imp.h" \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h new file mode 100644 index 00000000..28fa51e1 --- /dev/null +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -0,0 +1,87 @@ +#pragma once + +#include "Neon/set/DevSet.h" +#include "Neon/set/dependencyTools/DataParsing.h" +#include "functional" +#include "type_traits" + +#include "Neon/set/ContainerTools/DeviceContainer.h" +#include "Neon/set/ContainerTools/DeviceManagedContainer.h" +#include "Neon/set/ContainerTools/DeviceThenHostManagedContainer.h" +#include "Neon/set/ContainerTools/HostManagedContainer.h" +#include "Neon/set/ContainerTools/OldDeviceManagedContainer.h" + +namespace Neon::set { + + +template +auto Container::factory(const std::string& name, + Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, + const DataContainerT& a, + const UserLoadingLambdaT& f, + const index_3d& blockSize, + std::function shMemSizeFun) -> Container +{ + using LoadingLambda = typename std::invoke_result::type; + auto k = new Neon::set::internal::DeviceContainer(name, dataViewSupport, + a, f, + blockSize, shMemSizeFun); + + std::shared_ptr tmp(k); + return Container(tmp); +} + +template +auto Container::factoryOldManaged(const std::string& name, + Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, + DataContainerT a, + const UserLoadingLambdaT& f) + -> Container +{ + using ManagedLaunch = typename std::invoke_result::type; + auto k = new Neon::set::internal::OldDeviceManagedContainer(name, dataViewSupport, + a, f); + + std::shared_ptr tmp(k); + return Container(tmp); +} + +template +auto Container::factoryHostManaged(const std::string& name, + Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, + Neon::set::internal::HostManagedSyncType preSyncType, + Neon::set::internal::HostManagedSyncType presSyncType, + DataContainerT a, + const UserLoadingLambdaT& f) + -> Container +{ + using ManagedLaunch = typename std::invoke_result::type; + auto k = new Neon::set::internal::HostManagedContainer(name, dataViewSupport, + a, f, + preSyncType, + presSyncType); + + std::shared_ptr tmp(k); + return Container(tmp); +} + +template +auto Container::factoryDeviceManaged(const std::string& name, + Neon::set::internal::ContainerAPI::DataViewSupport dataViewSupport, + DataContainerT a, + const UserLoadingLambdaT& f) + -> Container +{ + using ManagedLaunch = typename std::invoke_result::type; + auto k = new Neon::set::internal::DeviceManagedContainer(name, dataViewSupport, + a, f); + + std::shared_ptr tmp(k); + return Container(tmp); +} + + +} // namespace Neon::set diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp new file mode 100644 index 00000000..1a7f691e --- /dev/null +++ b/libNeonSet/src/set/Containter.cpp @@ -0,0 +1,115 @@ +#include "Neon/set/Containter.h" + +namespace Neon::set { + +auto Container::run(int streamIdx, + Neon::DataView dataView) + -> void +{ + mContainer->run(streamIdx, dataView); +} + + +auto Container::run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) + -> void +{ + mContainer->run(setIdx, streamIdx, dataView); +} + +auto Container::getContainerInterface() + -> Neon::set::internal::ContainerAPI& +{ + return mContainer.operator*(); +} + +auto Container::getContainerInterface() const + -> const Neon::set::internal::ContainerAPI& +{ + return mContainer.operator*(); +} + + +auto Container::getContainerInterfaceShrPtr() + -> std::shared_ptr +{ + return mContainer; +} + +auto Container::factoryDeviceThenHostManaged(const std::string& name, + Container& device, + Container& host) -> Container +{ + auto k = new Neon::set::internal::DeviceThenHostManagedContainer(name, + device.getContainerInterfaceShrPtr(), + host.getContainerInterfaceShrPtr()); + + std::shared_ptr tmp(k); + return Container(tmp); +} + +auto Container::getName() const + -> const std::string& +{ + return mContainer->getName(); +} + +auto Container::getUid() const + -> uint64_t +{ + const auto uid = (uint64_t)mContainer.get(); + return uid; +} + +auto Container::logTokens() + -> void +{ + return mContainer->toLog(getUid()); +} + +auto Container::getHostContainer() const + -> Container +{ + std::shared_ptr hostAPI = + mContainer->getHostContainer(); + return Container(hostAPI); +} + +auto Container::getDeviceContainer() const -> Container +{ + std::shared_ptr deviceAPI = + mContainer->getDeviceContainer(); + return Container(deviceAPI); +} + +auto Container::getDataViewSupport() const + -> Neon::set::internal::ContainerAPI::DataViewSupport +{ + auto& api = this->getContainerInterface(); + auto const dwSupport = api.getDataViewSupport(); + return dwSupport; +} + +auto Container::getContainerType() const + -> Neon::set::internal::ContainerType +{ + auto& api = this->getContainerInterface(); + auto const type = api.getContainerType(); + return type; +} + +Container::Container(std::shared_ptr& container) + : mContainer(container) +{ + // Empty +} + +Container::Container(std::shared_ptr&& container) + : mContainer(container) +{ + // Empty +} + + +} // namespace Neon::set From 0a944c3d6cc1778a8c27253c73633b05afd89f3e Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Tue, 19 Jul 2022 23:10:12 +0200 Subject: [PATCH 10/67] WIP: new container graph mechanism. --- .../types/{DataView.e.cpp => DataView.cpp} | 0 .../include/Neon/set/ContainerTools/Graph.h | 92 +++++++++++++ .../Neon/set/ContainerTools/GraphDependency.h | 21 +++ .../set/ContainerTools/GraphDependencyType.h | 52 ++++++++ .../Neon/set/ContainerTools/GraphNode.h | 47 +++++++ .../ContainerTools/GraphNodeOrganization.h | 33 +++++ .../set/ContainerTools/GraphNodeScheduling.h | 56 ++++++++ libNeonSet/src/set/kContainerTools/Graph.cpp | 122 ++++++++++++++++++ .../set/kContainerTools/GraphDependency.cpp | 26 ++++ .../kContainerTools/GraphDependencyType.cpp | 61 +++++++++ .../src/set/kContainerTools/GraphNode.cpp | 59 +++++++++ .../kContainerTools/GraphNodeOrganization.cpp | 35 +++++ .../kContainerTools/GraphNodeScheduling.cpp | 53 ++++++++ 13 files changed, 657 insertions(+) rename libNeonCore/src/core/types/{DataView.e.cpp => DataView.cpp} (100%) create mode 100644 libNeonSet/include/Neon/set/ContainerTools/Graph.h create mode 100644 libNeonSet/include/Neon/set/ContainerTools/GraphDependency.h create mode 100644 libNeonSet/include/Neon/set/ContainerTools/GraphDependencyType.h create mode 100644 libNeonSet/include/Neon/set/ContainerTools/GraphNode.h create mode 100644 libNeonSet/include/Neon/set/ContainerTools/GraphNodeOrganization.h create mode 100644 libNeonSet/include/Neon/set/ContainerTools/GraphNodeScheduling.h create mode 100644 libNeonSet/src/set/kContainerTools/Graph.cpp create mode 100644 libNeonSet/src/set/kContainerTools/GraphDependency.cpp create mode 100644 libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp create mode 100644 libNeonSet/src/set/kContainerTools/GraphNode.cpp create mode 100644 libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp create mode 100644 libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp diff --git a/libNeonCore/src/core/types/DataView.e.cpp b/libNeonCore/src/core/types/DataView.cpp similarity index 100% rename from libNeonCore/src/core/types/DataView.e.cpp rename to libNeonCore/src/core/types/DataView.cpp diff --git a/libNeonSet/include/Neon/set/ContainerTools/Graph.h b/libNeonSet/include/Neon/set/ContainerTools/Graph.h new file mode 100644 index 00000000..18d85f77 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/Graph.h @@ -0,0 +1,92 @@ +#pragma once + +#include "Neon/core/core.h" +#include "Neon/core/types/digraph.h" + +#include "Neon/set/ContainerTools/GraphDependency.h" +#include "Neon/set/ContainerTools/GraphNode.h" + +namespace Neon::set::container { + +struct Graph +{ + using Uid = GraphNodeOrganization::Uid; + using Index = GraphNodeOrganization::Index; + + public: + Graph(); + + /** + * Get a reference to the begin node + */ + auto getBeginNode() const -> const GraphNode&; + + /** + * Get a reference to the end node of the graph + */ + auto getEndNode() const -> const GraphNode&; + + /** + * add a node between the begin and end nodes + */ + auto addNode(Container& container) -> GraphNode&; + + /** + * Remove Node + */ + auto removeNode(GraphNode& gn) -> GraphNode; + + /** + * Add node between two other nodes + */ + auto addNodeInBetween(const GraphNode& nodeA, + Container& containerB, + const GraphNode& nodeC) -> GraphNode&; + + auto addNodeInBetween(const GraphNode& nodeA, + Container& containerB, + const GraphNode& nodeC, + GraphDependency& ab, + GraphDependency& bc) -> GraphNode&; + /** + * Add a dependency between two nodes of the graph + */ + auto addDependency(const GraphNode& source, + const GraphNode& destination, + GraphDependencyType graphDependencyType = GraphDependencyType::USER) -> GraphDependency&; + + /** + * Clone a node and return a reference to the new clone. + * The cloning process connects the clone the the same nodes of the original + * + * @param graphNode + * @return + */ + auto clone(const GraphNode& graphNode) -> GraphNode&; + + /** + * Returns all proceeding graph nodes. + * The begin node is excluded + */ + auto getProceedingGraphNodes() -> std::vector; + + /** + * Returns all subsequent graph nodes. + * The end node is excluded + */ + auto getSubsequentGraphNodes() -> std::vector; + + /** + * Execute the scheduling operation associated to the node + */ + auto execute() -> void; + + auto computeScheduling() -> void; + + private: + using RawGraph = DiGraph; + Uid mUidCounter; + RawGraph mRawGraph; +}; + +} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphDependency.h b/libNeonSet/include/Neon/set/ContainerTools/GraphDependency.h new file mode 100644 index 00000000..90a63b99 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/GraphDependency.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Neon/set/ContainerTools/GraphDependencyType.h" + +namespace Neon::set::container { + +struct GraphDependency +{ + public: + GraphDependency(); + GraphDependency(GraphDependencyType type); + + auto setType(GraphDependencyType type) -> void; + auto getType() -> GraphDependencyType; + + private: + GraphDependencyType mType; + // TODO - add information for data and Scheduling dependency +}; + +} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphDependencyType.h b/libNeonSet/include/Neon/set/ContainerTools/GraphDependencyType.h new file mode 100644 index 00000000..be5dee20 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/GraphDependencyType.h @@ -0,0 +1,52 @@ +#pragma once +#include +#include + +namespace Neon { + +enum struct GraphDependencyType +{ + DATA = 0 /** dependency generated by analyzing data dependency */, + SCHEDULING = 1 /** hints for scheduling **/, + USER = 2 /** Uer defined scheduling */ +}; + +/** + * Set of utilities for GraphDependencyType options. + */ +struct GraphDependencyTypeUtil +{ + /** + * Number of configurations for the enum + */ + static const int nConfig{static_cast(3)}; + + /** + * Convert enum value to string + * + * @param dataView + */ + static auto toString(GraphDependencyType dataView) -> std::string; + + /** + * Returns all valid configuration for GraphDependencyType + */ + static auto validOptions() -> std::array; + + /** + * Convert an integer to a GraphDependencyType + */ + static auto fromInt(int val) -> GraphDependencyType; + + /** + * Convert a GraphDependencyType to an integer + */ + static auto toInt(GraphDependencyType dataView) -> int; +}; + + +/** + * operator<< + */ +std::ostream& operator<<(std::ostream& os, Neon::GraphDependencyType const& m); +} // namespace Neon diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphNode.h b/libNeonSet/include/Neon/set/ContainerTools/GraphNode.h new file mode 100644 index 00000000..e43a54b1 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/GraphNode.h @@ -0,0 +1,47 @@ +#pragma once + +#include "Neon/set/ContainerTools/GraphNodeOrganization.h" +#include "Neon/set/ContainerTools/GraphNodeScheduling.h" + +#include "Neon/set/Containter.h" + +namespace Neon::set::container { + +struct GraphNode +{ + public: + GraphNode(); + GraphNode(const Container& container, + GraphNodeOrganization::Uid uid); + + /** + * Factory method to generate a begin node + */ + static auto getBeginNode() -> GraphNode; + + /** + * Factory method to generate a end node + */ + static auto getEndNode() -> GraphNode; + + /** + * Execute the scheduling operation associated to the node + */ + auto execute() -> void; + + auto getOrganization() -> GraphNodeOrganization&; + auto getOrganization() const -> const GraphNodeOrganization&; + + auto getScheduling() -> GraphNodeScheduling&; + auto getScheduling() const -> const GraphNodeScheduling&; + + auto getContianer() -> Container&; + auto getContianer() const -> const Container&; + + private: + Container mContainer /**< Any Neon container */; + GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; + GraphNodeOrganization mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; +}; + +} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphNodeOrganization.h b/libNeonSet/include/Neon/set/ContainerTools/GraphNodeOrganization.h new file mode 100644 index 00000000..1aaa2537 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/GraphNodeOrganization.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include "vector" + +namespace Neon::set::container { + +class GraphNodeOrganization +{ + public: + using Uid = uint32_t; + using Index = uint32_t; + + constexpr static Uid notSet = 0; + constexpr static Uid beginUid = 1; + constexpr static Uid endUid = 2; + constexpr static Uid firstInternal = 3; + + GraphNodeOrganization(); + GraphNodeOrganization(int uid); + + auto setUid(Uid uid) -> void; + auto setIndex(Index index) -> void; + + auto getUid() const -> Uid; + auto getIndex() const -> Index; + + private: + Uid mUid /** unique identifier for the node */; + Index mIndex /** relative index w.r.t the completed graph. This value may change during the life of the graph */; +}; + +} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphNodeScheduling.h b/libNeonSet/include/Neon/set/ContainerTools/GraphNodeScheduling.h new file mode 100644 index 00000000..df3b1773 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/GraphNodeScheduling.h @@ -0,0 +1,56 @@ +#pragma once + +#include "Neon/core/types/DataView.h" +#include "vector" + +namespace Neon::set::container { + +class GraphNodeScheduling +{ + + /** + * Get the stream to execute the Container + */ + auto getStream() const + -> int; + + /** + * Get the event to asynchronously signal that the execution of the Container is completed. + */ + auto getEvent() const + -> int; + + /** + * Get list of events to wait the completion of. + */ + auto getDependentEvents() const + -> const std::vector&; + + /** + * Set the stream for the Container execution + */ + auto setStream(int stream /**< stream for the Container execution */) -> void; + + /** + * Set the event to asynchronously signal the completion of the Container. + */ + auto setEvent(int event /**< Event to be used to signal the completion of the Container */) -> void; + + /** + * Set the list of events that needed to be waited for before running the Container. + */ + auto setDependentEvents(const std::vector&) -> void; + + auto setDataView(Neon::DataView dataView) -> void; + + public: + GraphNodeScheduling(); + + private: + int mStream /**< Stream for each operation for the node */; + int mEvent /**< Event to be used to signal the completion of the node container */; + std::vector mDependentEvents /**< Events to be waited for before running the Container */; + Neon::DataView mDataView; +}; + +} // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/Graph.cpp b/libNeonSet/src/set/kContainerTools/Graph.cpp new file mode 100644 index 00000000..0c613a8a --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/Graph.cpp @@ -0,0 +1,122 @@ +#include "Neon/set/ContainerTools/Graph.h" + +namespace Neon::set::container { + +Graph::Graph() +{ + auto begin = GraphNode::getBeginNode(); + auto end = GraphNode::getEndNode(); + mUidCounter = GraphNodeOrganization::firstInternal; + + mRawGraph.addVertex(begin.getOrganization().getUid(), begin); + mRawGraph.addVertex(end.getOrganization().getUid(), end); +} + +auto Graph::getBeginNode() const -> const GraphNode& +{ + return mRawGraph.getVertexProperty(GraphNodeOrganization::beginUid); +} + +auto Graph::getEndNode() const -> const GraphNode& +{ + return mRawGraph.getVertexProperty(GraphNodeOrganization::endUid); +} + +auto Graph::addNodeInBetween(const GraphNode& nodeA, + Container& containerB, + const GraphNode& nodeC) -> GraphNode& +{ + auto& nodeB = addNode(containerB); + + GraphDependency ab(GraphDependencyType::USER); + GraphDependency bc(GraphDependencyType::USER); + + mRawGraph.addEdge(nodeA.getOrganization().getUid(), + nodeB.getOrganization().getUid(), + ab); + + mRawGraph.addEdge(nodeB.getOrganization().getUid(), + nodeC.getOrganization().getUid(), + bc); + + return nodeB; +} + +auto Graph::addNodeInBetween(const GraphNode& nodeA, + Container& containerB, + const GraphNode& nodeC, + GraphDependency& ab, + GraphDependency& bc) -> GraphNode& +{ + auto& nodeB = addNodeInBetween(nodeA, containerB, nodeC); + + ab = mRawGraph.getEdgeProperty({nodeA.getOrganization().getUid(), + nodeB.getOrganization().getUid()}); + + + bc = mRawGraph.getEdgeProperty({nodeB.getOrganization().getUid(), + nodeC.getOrganization().getUid()}); + + return nodeB; +} + +auto Graph::addNode(Container& container) -> GraphNode& +{ + auto const& node = GraphNode(container, mUidCounter); + mRawGraph.addVertex(node.getOrganization().getUid(), node); + mUidCounter++; + return mRawGraph.getVertexProperty(node.getOrganization().getUid()); +} + +auto Graph::addDependency(const GraphNode& nodeA, + const GraphNode& nodeB, + GraphDependencyType graphDependencyType) -> GraphDependency& +{ + GraphDependency ab(graphDependencyType); + + mRawGraph.addEdge(nodeA.getOrganization().getUid(), + nodeB.getOrganization().getUid(), + ab); + + return mRawGraph.getEdgeProperty({nodeA.getOrganization().getUid(), + nodeB.getOrganization().getUid()}); +} +auto Graph::removeNode(GraphNode& gn) -> GraphNode +{ + auto uidB = gn.getOrganization().getUid(); + + std::vector a_toBeConnectedToEnd; + mRawGraph.forEachInEdge(uidB, [&](const RawGraph::Edge& edge) -> void { + auto uidA = edge.first; + int outEdgesFromA = mRawGraph.outEdgesCount(uidA); + if (outEdgesFromA == 1) { + a_toBeConnectedToEnd.push_back(uidA); + } + }); + + std::vector c_toBeConnectedToBegin; + mRawGraph.forEachOutEdge(uidB, [&](const RawGraph::Edge& edge) -> void { + auto uidC = edge.second; + int inEdgesIntoC = mRawGraph.outEdgesCount(uidC); + if (inEdgesIntoC == 1) { + a_toBeConnectedToEnd.push_back(uidC); + } + }); + + for (auto&& uidA : a_toBeConnectedToEnd) { + auto& nodeA = mRawGraph.getVertexProperty(uidA); + addDependency(nodeA, this->getEndNode()); + } + + for (auto&& uidC : c_toBeConnectedToBegin) { + auto& nodeC = mRawGraph.getVertexProperty(uidC); + addDependency(this->getBeginNode(), nodeC); + } + + GraphNode removed = mRawGraph.getVertexProperty(gn.getOrganization().getUid()); + removed.getOrganization().setUid(GraphNodeOrganization::notSet); + + return removed; +} + +} // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphDependency.cpp b/libNeonSet/src/set/kContainerTools/GraphDependency.cpp new file mode 100644 index 00000000..64e92901 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/GraphDependency.cpp @@ -0,0 +1,26 @@ +#pragma once + +#include "Neon/set/ContainerTools/GraphDependency.h" + +namespace Neon::set::container { + +GraphDependency::GraphDependency() +{ + mType = GraphDependencyType::NOTSET; +} + +auto GraphDependency::setType(GraphDependencyType type) -> void +{ + mType = type; +} + +auto GraphDependency::getType() -> GraphDependencyType +{ + return mType; +} +GraphDependency::GraphDependency(GraphDependencyType type) +{ + setType(type); +} + +} // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp b/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp new file mode 100644 index 00000000..4dc31819 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp @@ -0,0 +1,61 @@ +#include "Neon/set/ContainerTools/GraphDependencyType.h" +#include "Neon/core/core.h" + +namespace Neon { + + +auto GraphDependencyTypeUtil::validOptions() -> std::array +{ + std::array options = {GraphDependencyType::DATA, + GraphDependencyType::SCHEDULING, + GraphDependencyType::USER}; + return options; +} + +auto GraphDependencyTypeUtil::toString(GraphDependencyType e) -> std::string +{ + switch (e) { + case GraphDependencyType::DATA: { + return "DATA"; + } + case GraphDependencyType::SCHEDULING: { + return "SCHEDULING"; + } + case GraphDependencyType::USER: { + return "USER"; + } + default: { + NEON_THROW_UNSUPPORTED_OPTION("GraphDependencyTypeUtil"); + } + } +} + +auto GraphDependencyTypeUtil::fromInt(int val) -> GraphDependencyType +{ + switch (val) { + case static_cast(GraphDependencyType::DATA): { + return GraphDependencyType::DATA; + } + case static_cast(GraphDependencyType::SCHEDULING): { + return GraphDependencyType::SCHEDULING; + } + case static_cast(GraphDependencyType::USER): { + return GraphDependencyType::USER; + } + default: { + NEON_THROW_UNSUPPORTED_OPTION("GraphDependencyTypeUtil"); + } + } +} + +auto GraphDependencyTypeUtil::toInt(GraphDependencyType dataView) -> int +{ + return static_cast(dataView); +} + +} // namespace Neon + +std::ostream& operator<<(std::ostream& os, Neon::GraphDependencyType const& m) +{ + return os << std::string(Neon::GraphDependencyTypeUtil::toString(m)); +} diff --git a/libNeonSet/src/set/kContainerTools/GraphNode.cpp b/libNeonSet/src/set/kContainerTools/GraphNode.cpp new file mode 100644 index 00000000..250eb359 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/GraphNode.cpp @@ -0,0 +1,59 @@ +#include "Neon/set/ContainerTools/GraphNode.h" + +namespace Neon::set::container { + +GraphNode::GraphNode() +{ +} + +auto GraphNode::getBeginNode() -> GraphNode +{ + GraphNode node; + node.mGraphNodeOrganization.setUid(GraphNodeOrganization::beginUid); + return node; +} + +auto GraphNode::getEndNode() -> GraphNode +{ + GraphNode node; + node.mGraphNodeOrganization.setUid(GraphNodeOrganization::endUid); + return node; +} + +auto GraphNode::getOrganization() -> GraphNodeOrganization& +{ + return mGraphNodeOrganization; +} + +auto GraphNode::getOrganization() const -> const GraphNodeOrganization& +{ + return mGraphNodeOrganization; +} + +auto GraphNode::getScheduling() -> GraphNodeScheduling& +{ + return mGraphNodeScheduling; +} + +auto GraphNode::getScheduling() const -> const GraphNodeScheduling& +{ + return mGraphNodeScheduling; +} + +auto GraphNode::getContianer() -> Container& +{ + return mContainer; +} + +auto GraphNode::getContianer() const -> const Container& +{ + return mContainer; +} + +GraphNode::GraphNode(const Container& container, GraphNodeOrganization::Uid uid) +{ + mContainer = container; + mGraphNodeOrganization.setUid(uid); +} + +} // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp b/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp new file mode 100644 index 00000000..4ec1b781 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp @@ -0,0 +1,35 @@ +#include "Neon/set/ContainerTools/GraphNodeOrganization.h" + +namespace Neon::set::container { + +GraphNodeOrganization::GraphNodeOrganization() +{ + mUid = notSet; + mIndex = notSet; +} +GraphNodeOrganization::GraphNodeOrganization(int uid) +{ + mUid = uid; + mIndex = notSet; +} + +auto GraphNodeOrganization::setUid(Uid uid) -> void +{ + mUid = uid; +} +auto GraphNodeOrganization::setIndex(Index index) -> void +{ + mIndex = index; +} + +auto GraphNodeOrganization::getUid() const -> Uid +{ + return mUid; +} + +auto GraphNodeOrganization::getIndex() const -> Index +{ + return mIndex; +} + +} // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp b/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp new file mode 100644 index 00000000..81149f25 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp @@ -0,0 +1,53 @@ +#include "Neon/set/ContainerTools/GraphNodeScheduling.h" + +namespace Neon::set::container { + +GraphNodeScheduling::GraphNodeScheduling() +{ + mStream = -1; + mEvent = -1; + mDataView = Neon::DataView::STANDARD; +} + +auto GraphNodeScheduling::getStream() const + -> int +{ + return mStream; +} + +auto GraphNodeScheduling::getEvent() const + -> int +{ + return mEvent; +} + +auto GraphNodeScheduling::getDependentEvents() const + -> const std::vector& +{ + return mDependentEvents; +} + +auto GraphNodeScheduling::setStream(int stream) + -> void +{ + mStream = stream; +} + +auto GraphNodeScheduling::setEvent(int event) + -> void +{ + mEvent = event; +} + +auto GraphNodeScheduling::setDependentEvents(const std::vector& dependentEvents) + -> void +{ + mDependentEvents = dependentEvents; +} + +auto GraphNodeScheduling::setDataView(Neon::DataView dataView) -> void +{ + mDataView = dataView; +} + +} // namespace Neon::set::container From 3c7a25bb41d63a8836e1a2d8c693081fdced46a7 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Mon, 8 Aug 2022 21:37:24 +0200 Subject: [PATCH 11/67] WIP --- libNeonCore/include/Neon/core/types/digraph.h | 15 +- .../Neon/set/ContainerTools/ContainerAPI.h | 60 ++++++- ...ntainerType.h => ContainerExecutionType.h} | 14 +- .../ContainerTools/ContainerOperationType.h | 48 ++++++ .../set/ContainerTools/ContainerPatternType.h | 37 +++++ .../include/Neon/set/ContainerTools/Graph.h | 56 +++---- .../Neon/set/ContainerTools/GraphNode.h | 47 ------ .../GraphData.h} | 6 +- .../{ => graph}/GraphDependency.h | 2 +- .../{ => graph}/GraphDependencyType.h | 6 +- .../Neon/set/ContainerTools/graph/GraphNode.h | 77 +++++++++ .../{ => graph}/GraphNodeScheduling.h | 9 ++ .../set/ContainerTools/graph/GraphNodeType.h | 53 +++++++ .../ContainerOperationType.cpp | 56 +++++++ .../kContainerTools/ContainerPatternType.cpp | 75 +++++++++ .../src/set/kContainerTools/ContainerType.cpp | 2 +- libNeonSet/src/set/kContainerTools/Graph.cpp | 147 ++++++++++++------ .../set/kContainerTools/GraphDependency.cpp | 2 +- .../kContainerTools/GraphDependencyType.cpp | 2 +- .../src/set/kContainerTools/GraphNode.cpp | 54 ++++++- .../kContainerTools/GraphNodeOrganization.cpp | 14 +- .../kContainerTools/GraphNodeScheduling.cpp | 7 +- .../src/set/kContainerTools/GraphNodeType.cpp | 61 ++++++++ .../src/set/kContainerTools/containerAPI.cpp | 41 +++-- 24 files changed, 711 insertions(+), 180 deletions(-) rename libNeonSet/include/Neon/set/ContainerTools/{ContainerType.h => ContainerExecutionType.h} (71%) create mode 100644 libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h create mode 100644 libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h delete mode 100644 libNeonSet/include/Neon/set/ContainerTools/GraphNode.h rename libNeonSet/include/Neon/set/ContainerTools/{GraphNodeOrganization.h => graph/GraphData.h} (88%) rename libNeonSet/include/Neon/set/ContainerTools/{ => graph}/GraphDependency.h (87%) rename libNeonSet/include/Neon/set/ContainerTools/{ => graph}/GraphDependencyType.h (86%) create mode 100644 libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h rename libNeonSet/include/Neon/set/ContainerTools/{ => graph}/GraphNodeScheduling.h (88%) create mode 100644 libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h create mode 100644 libNeonSet/src/set/kContainerTools/ContainerOperationType.cpp create mode 100644 libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp create mode 100644 libNeonSet/src/set/kContainerTools/GraphNodeType.cpp diff --git a/libNeonCore/include/Neon/core/types/digraph.h b/libNeonCore/include/Neon/core/types/digraph.h index a82f5bc8..2e86f575 100644 --- a/libNeonCore/include/Neon/core/types/digraph.h +++ b/libNeonCore/include/Neon/core/types/digraph.h @@ -32,10 +32,10 @@ struct Empty /** * DiGraph is a directed graph datastructure implemented using an adjacency list. - * + * * Self loops can be represented. * Parallel loops cannot be represented. - * + * * @tparam VertexProp Type representing the properties to be stored per-vertex * @tparam EdgeProp Type representing the properties to be stored per-edge */ @@ -415,9 +415,9 @@ class DiGraph /** * Contract an edge by deleting the source vertex and connecting all its neighbors - * with the target vertex. The edge property of the removed vertex is set to all the + * with the target vertex. The edge property of the removed vertex is set to all the * new edges. - * + * * a--->c--->d * ^ * | @@ -449,9 +449,9 @@ class DiGraph /** * Contract an edge by deleting the source vertex and connecting all its neighbors - * with the target vertex The edge property of the removed vertex is set to all the + * with the target vertex The edge property of the removed vertex is set to all the * new edges. - * + * * a--->c--->d * ^ * | @@ -504,7 +504,8 @@ class DiGraph * @param v Vertex * @return Neighboring vertices of v */ - const std::set inNeighbors(size_t v) const + auto inNeighbors(size_t v) const + -> const std::set { std::set in; forEachInEdge(v, [&](const Edge& e) { diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h index 67fc7618..53584859 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h @@ -1,8 +1,11 @@ #pragma once +#include "Neon/set/ContainerTools/ContainerOperationType.h" +#include "Neon/set/ContainerTools/ContainerPatternType.h" + +#include "Neon/set/ContainerTools/ContainerExecutionType.h" #include "Neon/set/DevSet.h" #include "Neon/set/dependencyTools/DataParsing.h" -#include "Neon/set/ContainerTools/ContainerType.h" #include "functional" #include "type_traits" @@ -55,40 +58,79 @@ struct ContainerAPI -> void; /** - * + * Returns a name associated to the container */ auto getName() const -> const std::string&; - auto getContainerType() const - -> ContainerType; - auto getTokens() const -> const std::vector&; auto getTokenRef() -> std::vector&; + /** + * Get the execution type for the container + */ + auto getContainerExecutionType() -> ContainerExecutionType; + + /** + * Get the Operation type for the container + */ + auto getContainerOperationType() -> ContainerOperationType; + + /** + * Get the Pattern type for the container + */ + auto getContainerPatternType() -> ContainerPatternType; + auto getDataViewSupport() const -> DataViewSupport; /** * Log information on the parsed tokens. */ - auto toLog(uint64_t ContainerUid)->void; + auto toLog(uint64_t ContainerUid) -> void; protected: + /** + * Set the name for the container + */ auto setName(const std::string& name) -> void; + /** + * Set the launch parameters for the container + * @param dw + * @return + */ auto setLaunchParameters(Neon::DataView dw) -> Neon::set::LaunchParameters&; + /** + * Get the launch parameters for the container + */ auto getLaunchParameters(Neon::DataView dw) const -> const Neon::set::LaunchParameters&; - auto setContainerType(ContainerType containerType) -> void; + /** + * Set the execution type for the container + */ + auto setContainerExecutionType(ContainerExecutionType containerType) -> void; + + /** + * Set the Operation type for the container + */ + auto setContainerOperationType(ContainerOperationType containerType) -> void; + /** + * Set the Pattern type for the container + */ + auto setContainerPatternType(ContainerPatternType containerType) -> void; + + /** + * Set the DataView support for the container + */ auto setDataViewSupport(DataViewSupport dataViewSupport) -> void; @@ -96,7 +138,9 @@ struct ContainerAPI std::vector mParsed; std::string mName{"Anonymous"}; /**< Name of the Container */ std::array mLaunchParameters; - ContainerType mContainerType; + ContainerExecutionType mContainerExecutionType; + ContainerOperationType mContainerOperationType; + ContainerPatternType mContainerPatternType; DataViewSupport mDataViewSupport = DataViewSupport::on; }; diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h similarity index 71% rename from libNeonSet/include/Neon/set/ContainerTools/ContainerType.h rename to libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h index 54c4201c..a8a24cdd 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h @@ -11,7 +11,7 @@ namespace Neon::set::internal { -enum struct ContainerType +enum struct ContainerExecutionType { device = 0 /** the operation of the containers are only for the device (note: device can be CPU too) */, deviceManaged = 1 /** manage version of the device type of Container, i.e. the launch is managed by the container itself. Useful to wrap calls to cuBlas operation for example*/, @@ -20,15 +20,15 @@ enum struct ContainerType }; -struct ContainerTypeUtils +struct ContainerExecutionTypeUtils { static constexpr int nOptions = 3; - static auto toString(ContainerType option) -> std::string; - static auto fromString(const std::string& option) -> ContainerType; - static auto getOptions() -> std::array; - static auto isExpandable(ContainerType option) -> bool; + static auto toString(ContainerExecutionType option) -> std::string; + static auto fromString(const std::string& option) -> ContainerExecutionType; + static auto getOptions() -> std::array; + static auto isExpandable(ContainerExecutionType option) -> bool; }; -} // namespace Neon +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h new file mode 100644 index 00000000..14bad2fb --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h @@ -0,0 +1,48 @@ +#pragma once + +#include "Neon/set/DevSet.h" +#include "Neon/set/dependencyTools/DataParsing.h" +#include "functional" +#include "type_traits" + +/** + * Abstract interface to hide + */ + +namespace Neon::set::internal { + +enum struct ContainerOperationType +{ + compute = 0 /**< dependency generated by analyzing data dependency */, + halo = 1 /**< hints for scheduling **/, + sync = 2 /**< User defined scheduling */, + anchor = 3 /**< Anchor node: begin or end */ +}; + + +struct ContainerOperationTypeUtils +{ + static constexpr int nOptions = 4; + + /** + * Convert type to string + */ + static auto toString(ContainerOperationType option) -> std::string; + + /** + * Returns the type associated to a string + */ + static auto fromString(const std::string& option) -> ContainerOperationType; + + /** + * Return available options + */ + static auto getOptions() -> std::array; +}; + + +} // namespace Neon::set::internal +/** + * operator<< + */ +std::ostream& operator<<(std::ostream& os, Neon::set::internal::ContainerOperationType const& m); \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h new file mode 100644 index 00000000..0c9a1235 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Neon/set/DevSet.h" +#include "Neon/set/dependencyTools/DataParsing.h" +#include "functional" +#include "type_traits" + +/** + * Abstract interface to hide + */ + +namespace Neon::set::internal { + +enum struct ContainerPatternType +{ + map = 0, + stencil = 1, + reduction = 2, +}; + + +struct ContainerPatternTypeUtils +{ + static constexpr int nOptions = 4; + + static auto toString(ContainerPatternType option) -> std::string; + static auto fromString(const std::string& option) -> ContainerPatternType; + static auto getOptions() -> std::array; + static auto isExpandable(ContainerPatternType option) -> bool; +}; + + +} // namespace Neon::set::internal +/** + * operator<< + */ +std::ostream& operator<<(std::ostream& os, Neon::set::internal::ContainerPatternType const& m); \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/ContainerTools/Graph.h b/libNeonSet/include/Neon/set/ContainerTools/Graph.h index 18d85f77..9cd00742 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Graph.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Graph.h @@ -3,15 +3,15 @@ #include "Neon/core/core.h" #include "Neon/core/types/digraph.h" -#include "Neon/set/ContainerTools/GraphDependency.h" -#include "Neon/set/ContainerTools/GraphNode.h" +#include "Neon/set/ContainerTools/graph/GraphDependency.h" +#include "Neon/set/ContainerTools/graph/GraphNode.h" namespace Neon::set::container { struct Graph { - using Uid = GraphNodeOrganization::Uid; - using Index = GraphNodeOrganization::Index; + using Uid = GraphData::Uid; + using Index = GraphData::Index; public: Graph(); @@ -27,9 +27,9 @@ struct Graph auto getEndNode() const -> const GraphNode&; /** - * add a node between the begin and end nodes + * Adds a node between the begin and end nodes */ - auto addNode(Container& container) -> GraphNode&; + auto addNode(const Container& container) -> GraphNode&; /** * Remove Node @@ -37,44 +37,46 @@ struct Graph auto removeNode(GraphNode& gn) -> GraphNode; /** - * Add node between two other nodes + * Adds a dependency between two nodes of the graph */ - auto addNodeInBetween(const GraphNode& nodeA, - Container& containerB, - const GraphNode& nodeC) -> GraphNode&; - - auto addNodeInBetween(const GraphNode& nodeA, - Container& containerB, - const GraphNode& nodeC, - GraphDependency& ab, - GraphDependency& bc) -> GraphNode&; + auto addNodeInBetween(const GraphNode& nodeA, + Container& containerB, + const GraphNode& nodeC, + const GraphDependencyType ab = GraphDependencyType::USER, + const GraphDependencyType bc = GraphDependencyType::USER) -> GraphNode&; + /** - * Add a dependency between two nodes of the graph + * Adds a dependency between two node of the graph */ - auto addDependency(const GraphNode& source, - const GraphNode& destination, - GraphDependencyType graphDependencyType = GraphDependencyType::USER) -> GraphDependency&; + auto addDependency(const GraphNode& nodeA, + const GraphNode& nodeB, + GraphDependencyType type) -> GraphDependency&; + + /** + * Returns the dependency type between two nodes. + */ + auto getDependencyType(const GraphNode& nodeA, + const GraphNode& nodeB) -> GraphDependencyType; /** * Clone a node and return a reference to the new clone. * The cloning process connects the clone the the same nodes of the original - * - * @param graphNode - * @return */ - auto clone(const GraphNode& graphNode) -> GraphNode&; + auto cloneNode(const GraphNode& graphNode) + -> GraphNode&; /** * Returns all proceeding graph nodes. * The begin node is excluded */ - auto getProceedingGraphNodes() -> std::vector; + auto getProceedingGraphNodes(const GraphNode& graphNode) + -> std::vector; /** * Returns all subsequent graph nodes. * The end node is excluded */ - auto getSubsequentGraphNodes() -> std::vector; + auto getSubsequentGraphNodes(const GraphNode& graphNode) -> std::vector; /** * Execute the scheduling operation associated to the node @@ -83,6 +85,8 @@ struct Graph auto computeScheduling() -> void; + auto ioToDot(const std::string& fame) -> void; + private: using RawGraph = DiGraph; Uid mUidCounter; diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphNode.h b/libNeonSet/include/Neon/set/ContainerTools/GraphNode.h deleted file mode 100644 index e43a54b1..00000000 --- a/libNeonSet/include/Neon/set/ContainerTools/GraphNode.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "Neon/set/ContainerTools/GraphNodeOrganization.h" -#include "Neon/set/ContainerTools/GraphNodeScheduling.h" - -#include "Neon/set/Containter.h" - -namespace Neon::set::container { - -struct GraphNode -{ - public: - GraphNode(); - GraphNode(const Container& container, - GraphNodeOrganization::Uid uid); - - /** - * Factory method to generate a begin node - */ - static auto getBeginNode() -> GraphNode; - - /** - * Factory method to generate a end node - */ - static auto getEndNode() -> GraphNode; - - /** - * Execute the scheduling operation associated to the node - */ - auto execute() -> void; - - auto getOrganization() -> GraphNodeOrganization&; - auto getOrganization() const -> const GraphNodeOrganization&; - - auto getScheduling() -> GraphNodeScheduling&; - auto getScheduling() const -> const GraphNodeScheduling&; - - auto getContianer() -> Container&; - auto getContianer() const -> const Container&; - - private: - Container mContainer /**< Any Neon container */; - GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; - GraphNodeOrganization mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; -}; - -} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphNodeOrganization.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphData.h similarity index 88% rename from libNeonSet/include/Neon/set/ContainerTools/GraphNodeOrganization.h rename to libNeonSet/include/Neon/set/ContainerTools/graph/GraphData.h index 1aaa2537..65d7ac0b 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/GraphNodeOrganization.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphData.h @@ -5,7 +5,7 @@ namespace Neon::set::container { -class GraphNodeOrganization +class GraphData { public: using Uid = uint32_t; @@ -16,8 +16,8 @@ class GraphNodeOrganization constexpr static Uid endUid = 2; constexpr static Uid firstInternal = 3; - GraphNodeOrganization(); - GraphNodeOrganization(int uid); + GraphData(); + GraphData(int uid); auto setUid(Uid uid) -> void; auto setIndex(Index index) -> void; diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphDependency.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependency.h similarity index 87% rename from libNeonSet/include/Neon/set/ContainerTools/GraphDependency.h rename to libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependency.h index 90a63b99..c1b79501 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/GraphDependency.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependency.h @@ -1,6 +1,6 @@ #pragma once -#include "Neon/set/ContainerTools/GraphDependencyType.h" +#include "GraphDependencyType.h" namespace Neon::set::container { diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphDependencyType.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependencyType.h similarity index 86% rename from libNeonSet/include/Neon/set/ContainerTools/GraphDependencyType.h rename to libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependencyType.h index be5dee20..326ddcd7 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/GraphDependencyType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependencyType.h @@ -6,9 +6,9 @@ namespace Neon { enum struct GraphDependencyType { - DATA = 0 /** dependency generated by analyzing data dependency */, - SCHEDULING = 1 /** hints for scheduling **/, - USER = 2 /** Uer defined scheduling */ + data = 0 /**< dependency generated by analyzing data dependency */, + scheduling = 1 /**< hints for scheduling **/, + user = 2 /**< User defined scheduling */ }; /** diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h new file mode 100644 index 00000000..42df9ff6 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h @@ -0,0 +1,77 @@ +#pragma once + +#include "GraphData.h" +#include "GraphNodeScheduling.h" +#include "Neon/set/ContainerTools/graph/GraphNodeType.h" +#include "Neon/set/Containter.h" + +namespace Neon::set::container { + +struct GraphNode +{ + public: + GraphNode(); + + GraphNode(const Container& container, + GraphData::Uid uid, + GraphNodeType graphNodeType); + + /** + * Factory method to generate a begin node + */ + static auto newBeginNode() -> GraphNode; + + /** + * Factory method to generate a end node + */ + static auto newEndNode() -> GraphNode; + + /** + * Executes the scheduling operation associated to the node + */ + auto execute() -> void; + + /** + * Returns a reference to graph information related to this node. + * */ + auto getGraphData() -> GraphData&; + + /** + * Returns a reference to graph information related to this node. + * */ + auto getGraphData() const -> const GraphData&; + + /** + * Returns the scheduling information to run this node + */ + auto getScheduling() -> GraphNodeScheduling&; + + /** + * Returns the scheduling information to run this node + */ + auto getScheduling() const -> const GraphNodeScheduling&; + + /** + * Returns a reference to the container stored by this node. + */ + auto getContianer() -> Container&; + + /** + * Returns a reference to the container stored by this node. + */ + auto getContianer() const -> const Container&; + + auto toString() -> std::string; + + private: + auto helpGetDotProperties() -> std::string; + auto helpGetDotName() -> std::string; + auto helpGetDotInfo() -> std::string; + + Container mContainer /**< Any Neon container */; + GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; + GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; + GraphNodeType mGraphNodeType; +}; + +} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/GraphNodeScheduling.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h similarity index 88% rename from libNeonSet/include/Neon/set/ContainerTools/GraphNodeScheduling.h rename to libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h index df3b1773..dbcd72ad 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/GraphNodeScheduling.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h @@ -41,11 +41,20 @@ class GraphNodeScheduling */ auto setDependentEvents(const std::vector&) -> void; + /** + * Set the data view for the node + * @param dataView + */ auto setDataView(Neon::DataView dataView) -> void; public: GraphNodeScheduling(); + /** + * Returns data view associated to this node; + */ + auto getDataView() const -> Neon::DataView; + private: int mStream /**< Stream for each operation for the node */; int mEvent /**< Event to be used to signal the completion of the node container */; diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h new file mode 100644 index 00000000..a27116c0 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include + +namespace Neon { + +enum struct GraphNodeType +{ + Compute = 0 /**< dependency generated by analyzing data dependency */, + Halo = 1 /**< hints for scheduling **/, + Sync = 2 /**< User defined scheduling */, + Anchor = 3 /**< Anchor node: begin or end */ +}; + +/** + * Set of utilities for GraphNodeType options. + */ +struct GraphNodeTypeUtil +{ + /** + * Number of configurations for the enum + */ + static const int nConfig{static_cast(3)}; + + /** + * Convert enum value to string + * + * @param dataView + */ + static auto toString(GraphNodeType dataView) -> std::string; + + /** + * Returns all valid configuration for GraphNodeType + */ + static auto validOptions() -> std::array; + + /** + * Convert an integer to a GraphNodeType + */ + static auto fromInt(int val) -> GraphNodeType; + + /** + * Convert a GraphNodeType to an integer + */ + static auto toInt(GraphNodeType dataView) -> int; +}; + +} // namespace Neon + +/** + * operator<< + */ +std::ostream& operator<<(std::ostream& os, Neon::GraphNodeType const& m); \ No newline at end of file diff --git a/libNeonSet/src/set/kContainerTools/ContainerOperationType.cpp b/libNeonSet/src/set/kContainerTools/ContainerOperationType.cpp new file mode 100644 index 00000000..f9b5afc6 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/ContainerOperationType.cpp @@ -0,0 +1,56 @@ +#include "Neon/set/ContainerTools/ContainerOperationType.h" + +/** + * Abstract interface to hide + */ + +namespace Neon::set::internal { + +auto ContainerOperationTypeUtils::toString(ContainerOperationType option) -> std::string +{ + switch (option) { + case ContainerOperationType::compute: { + return "compute"; + } + case ContainerOperationType::halo: { + return "halo"; + } + case ContainerOperationType::sync: { + return "sync"; + } + case ContainerOperationType::anchor: { + return "anchor"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerOperationTypeUtils::fromString(const std::string& option) + -> ContainerOperationType +{ + auto const options = getOptions(); + + for (auto a : options) { + if (toString(a) == option) { + return a; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerOperationTypeUtils::getOptions() -> std::array +{ + std::array opts = {ContainerOperationType::compute, + ContainerOperationType::halo, + ContainerOperationType::sync, + ContainerOperationType::anchor}; + return opts; +} + +} // namespace Neon::set::internal + + +std::ostream& operator<<(std::ostream& os, Neon::set::internal::ContainerOperationType const& m) +{ + return os << std::string(Neon::set::internal::ContainerOperationTypeUtils::toString(m)); +} diff --git a/libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp b/libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp new file mode 100644 index 00000000..6c83a417 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp @@ -0,0 +1,75 @@ +#include "Neon/set/ContainerTools/ContainerPatternType.h" + +/** + * Abstract interface to hide + */ + +namespace Neon::set::internal { + +auto ContainerPatternTypeUtils::toString(ContainerPatternType option) -> std::string +{ + switch (option) { + case ContainerPatternType::compute: { + return "compute"; + } + case ContainerPatternType::halo: { + return "halo"; + } + case ContainerPatternType::sync: { + return "sync"; + } + case ContainerPatternType::anchor: { + return "anchor"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerPatternTypeUtils::fromString(const std::string& option) + -> ContainerPatternType +{ + auto const options = getOptions(); + + for (auto a : options) { + if (toString(a) == option) { + return a; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerPatternTypeUtils::getOptions() -> std::array +{ + std::array opts = {ContainerPatternType::compute, + ContainerPatternType::halo, + ContainerPatternType::sync, + ContainerPatternType::anchor}; + return opts; +} + +auto ContainerPatternTypeUtils::isExpandable(ContainerPatternType option) -> bool +{ + switch (option) { + case ContainerPatternType::compute: { + return false; + } + case ContainerPatternType::halo: { + return false; + } + case ContainerPatternType::sync: { + return false; + } + case ContainerPatternType::anchor: { + return true; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +} // namespace Neon::set::internal + + +std::ostream& operator<<(std::ostream& os, Neon::set::internal::ContainerPatternType const& m) +{ + return os << std::string(Neon::set::internal::ContainerPatternTypeUtils::toString(m)); +} diff --git a/libNeonSet/src/set/kContainerTools/ContainerType.cpp b/libNeonSet/src/set/kContainerTools/ContainerType.cpp index d03b6697..8a095fab 100644 --- a/libNeonSet/src/set/kContainerTools/ContainerType.cpp +++ b/libNeonSet/src/set/kContainerTools/ContainerType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/ContainerType.h" +#include "Neon/set/ContainerTools/ContainerExecutionType.h" /** * Abstract interface to hide diff --git a/libNeonSet/src/set/kContainerTools/Graph.cpp b/libNeonSet/src/set/kContainerTools/Graph.cpp index 0c613a8a..23ace60a 100644 --- a/libNeonSet/src/set/kContainerTools/Graph.cpp +++ b/libNeonSet/src/set/kContainerTools/Graph.cpp @@ -4,88 +4,72 @@ namespace Neon::set::container { Graph::Graph() { - auto begin = GraphNode::getBeginNode(); - auto end = GraphNode::getEndNode(); - mUidCounter = GraphNodeOrganization::firstInternal; + auto begin = GraphNode::newBeginNode(); + auto end = GraphNode::newEndNode(); + mUidCounter = GraphData::firstInternal; - mRawGraph.addVertex(begin.getOrganization().getUid(), begin); - mRawGraph.addVertex(end.getOrganization().getUid(), end); + mRawGraph.addVertex(begin.getGraphData().getUid(), begin); + mRawGraph.addVertex(end.getGraphData().getUid(), end); } auto Graph::getBeginNode() const -> const GraphNode& { - return mRawGraph.getVertexProperty(GraphNodeOrganization::beginUid); + return mRawGraph.getVertexProperty(GraphData::beginUid); } auto Graph::getEndNode() const -> const GraphNode& { - return mRawGraph.getVertexProperty(GraphNodeOrganization::endUid); + return mRawGraph.getVertexProperty(GraphData::endUid); } -auto Graph::addNodeInBetween(const GraphNode& nodeA, - Container& containerB, - const GraphNode& nodeC) -> GraphNode& -{ - auto& nodeB = addNode(containerB); - - GraphDependency ab(GraphDependencyType::USER); - GraphDependency bc(GraphDependencyType::USER); - - mRawGraph.addEdge(nodeA.getOrganization().getUid(), - nodeB.getOrganization().getUid(), - ab); - - mRawGraph.addEdge(nodeB.getOrganization().getUid(), - nodeC.getOrganization().getUid(), - bc); - - return nodeB; -} - -auto Graph::addNodeInBetween(const GraphNode& nodeA, - Container& containerB, - const GraphNode& nodeC, - GraphDependency& ab, - GraphDependency& bc) -> GraphNode& +auto Graph::addNodeInBetween(const GraphNode& nodeA, + Container& containerB, + const GraphNode& nodeC, + const GraphDependencyType ab, + const GraphDependencyType bc) -> GraphNode& { auto& nodeB = addNodeInBetween(nodeA, containerB, nodeC); - ab = mRawGraph.getEdgeProperty({nodeA.getOrganization().getUid(), - nodeB.getOrganization().getUid()}); + auto& abEdge = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid()}); + abEdge.setType(ab); + + auto& bcEdge = mRawGraph.getEdgeProperty({nodeB.getGraphData().getUid(), + nodeC.getGraphData().getUid()}); + bcEdge.setType(bc); - bc = mRawGraph.getEdgeProperty({nodeB.getOrganization().getUid(), - nodeC.getOrganization().getUid()}); return nodeB; } -auto Graph::addNode(Container& container) -> GraphNode& +auto Graph::addNode(const Container& container) -> GraphNode& { auto const& node = GraphNode(container, mUidCounter); - mRawGraph.addVertex(node.getOrganization().getUid(), node); + mRawGraph.addVertex(node.getGraphData().getUid(), node); mUidCounter++; - return mRawGraph.getVertexProperty(node.getOrganization().getUid()); + return mRawGraph.getVertexProperty(node.getGraphData().getUid()); } auto Graph::addDependency(const GraphNode& nodeA, const GraphNode& nodeB, - GraphDependencyType graphDependencyType) -> GraphDependency& + GraphDependencyType type) -> GraphDependency& { - GraphDependency ab(graphDependencyType); + GraphDependency ab(type); - mRawGraph.addEdge(nodeA.getOrganization().getUid(), - nodeB.getOrganization().getUid(), + mRawGraph.addEdge(nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid(), ab); - return mRawGraph.getEdgeProperty({nodeA.getOrganization().getUid(), - nodeB.getOrganization().getUid()}); + return mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid()}); } + auto Graph::removeNode(GraphNode& gn) -> GraphNode { - auto uidB = gn.getOrganization().getUid(); + auto uidB = gn.getGraphData().getUid(); - std::vector a_toBeConnectedToEnd; + std::vector a_toBeConnectedToEnd; mRawGraph.forEachInEdge(uidB, [&](const RawGraph::Edge& edge) -> void { auto uidA = edge.first; int outEdgesFromA = mRawGraph.outEdgesCount(uidA); @@ -94,7 +78,7 @@ auto Graph::removeNode(GraphNode& gn) -> GraphNode } }); - std::vector c_toBeConnectedToBegin; + std::vector c_toBeConnectedToBegin; mRawGraph.forEachOutEdge(uidB, [&](const RawGraph::Edge& edge) -> void { auto uidC = edge.second; int inEdgesIntoC = mRawGraph.outEdgesCount(uidC); @@ -113,10 +97,73 @@ auto Graph::removeNode(GraphNode& gn) -> GraphNode addDependency(this->getBeginNode(), nodeC); } - GraphNode removed = mRawGraph.getVertexProperty(gn.getOrganization().getUid()); - removed.getOrganization().setUid(GraphNodeOrganization::notSet); + GraphNode removed = mRawGraph.getVertexProperty(gn.getGraphData().getUid()); + removed.getGraphData().setUid(GraphData::notSet); return removed; } +auto Graph::getProceedingGraphNodes(const GraphNode& graphNode) + -> std::vector +{ + std::vector nodes; + + auto nodeUID = graphNode.getGraphData().getUid(); + auto nodeUidSet = mRawGraph.inNeighbors(nodeUID); + for (auto&& proceedingUid : nodeUidSet) { + auto& proceedingNode = mRawGraph.getVertexProperty(proceedingUid); + nodes.push_back(&proceedingNode); + } + + return nodes; +} + +auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode) -> std::vector +{ + std::vector nodes; + + auto nodeUID = graphNode.getGraphData().getUid(); + auto nodeUidSet = mRawGraph.outNeighbors(nodeUID); + for (auto&& subsequentUID : nodeUidSet) { + auto& subsequentNode = mRawGraph.getVertexProperty(subsequentUID); + nodes.push_back(&subsequentNode); + } + + return nodes; +} + +auto Graph::cloneNode(const GraphNode& graphNode) + -> GraphNode& +{ + auto proceedings = getProceedingGraphNodes(graphNode); + auto subsequents = getSubsequentGraphNodes(graphNode); + + auto& newNode = addNode(graphNode.getContianer()); + + for (const auto& proPtr : proceedings) { + auto dependencyType = getDependencyType(*proPtr, graphNode); + addDependency(*proPtr, newNode, dependencyType); + } + + for (const auto& post : subsequents) { + auto dependencyType = getDependencyType(graphNode, *post); + addDependency(newNode, *post, dependencyType); + } + + return newNode; +} + +auto Graph::getDependencyType(const GraphNode& nodeA, + const GraphNode& nodeB) + -> GraphDependencyType +{ + auto uidA = nodeA.getGraphData().getUid(); + auto uidB = nodeB.getGraphData().getUid(); + + auto edgePropetry = mRawGraph.getEdgeProperty({uidA, uidB}); + auto dependencyType = edgePropetry.getType(); + + return dependencyType; +} + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphDependency.cpp b/libNeonSet/src/set/kContainerTools/GraphDependency.cpp index 64e92901..41d929ff 100644 --- a/libNeonSet/src/set/kContainerTools/GraphDependency.cpp +++ b/libNeonSet/src/set/kContainerTools/GraphDependency.cpp @@ -1,6 +1,6 @@ #pragma once -#include "Neon/set/ContainerTools/GraphDependency.h" +#include "Neon/set/ContainerTools/graph/GraphDependency.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp b/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp index 4dc31819..85db65db 100644 --- a/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp +++ b/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/GraphDependencyType.h" +#include "Neon/set/ContainerTools/graph/GraphDependencyType.h" #include "Neon/core/core.h" namespace Neon { diff --git a/libNeonSet/src/set/kContainerTools/GraphNode.cpp b/libNeonSet/src/set/kContainerTools/GraphNode.cpp index 250eb359..1d1368ac 100644 --- a/libNeonSet/src/set/kContainerTools/GraphNode.cpp +++ b/libNeonSet/src/set/kContainerTools/GraphNode.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/GraphNode.h" +#include "Neon/set/ContainerTools/graph/GraphNode.h" namespace Neon::set::container { @@ -9,23 +9,23 @@ GraphNode::GraphNode() auto GraphNode::getBeginNode() -> GraphNode { GraphNode node; - node.mGraphNodeOrganization.setUid(GraphNodeOrganization::beginUid); + node.mGraphNodeOrganization.setUid(GraphData::beginUid); return node; } auto GraphNode::getEndNode() -> GraphNode { GraphNode node; - node.mGraphNodeOrganization.setUid(GraphNodeOrganization::endUid); + node.mGraphNodeOrganization.setUid(GraphData::endUid); return node; } -auto GraphNode::getOrganization() -> GraphNodeOrganization& +auto GraphNode::getGraphData() -> GraphData& { return mGraphNodeOrganization; } -auto GraphNode::getOrganization() const -> const GraphNodeOrganization& +auto GraphNode::getGraphData() const -> const GraphData& { return mGraphNodeOrganization; } @@ -50,10 +50,52 @@ auto GraphNode::getContianer() const -> const Container& return mContainer; } -GraphNode::GraphNode(const Container& container, GraphNodeOrganization::Uid uid) +GraphNode::GraphNode(const Container& container, GraphData::Uid uid) { mContainer = container; mGraphNodeOrganization.setUid(uid); } +auto GraphNode::toString() -> std::string +{ + return std::string(); +} + +auto GraphNode::helpGetDotProperties() -> std::string +{ + if (mGraphNodeType == GraphNodeType::Anchor) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } + if (mGraphNodeType == GraphNodeType::Compute) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } + if (mGraphNodeType == GraphNodeType::Halo) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } + if (mGraphNodeType == GraphNodeType::Sync) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } +} +auto GraphNode::helpGetDotName() -> std::string +{ + return getContianer().getName(); +} +auto GraphNode::helpGetDotInfo() -> std::string +{ + if (mGraphNodeType == GraphNodeType::Anchor) { + return std::string(); + } + if (mGraphNodeType == GraphNodeType::Compute) { + std::stringstream s; + s << "Uid = " << getContianer().getUid(); + s << "DataView = " << Neon::DataViewUtil::toString(getScheduling().getDataView()); + return s.str(); + } + if (mGraphNodeType == GraphNodeType::Halo) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } + if (mGraphNodeType == GraphNodeType::Sync) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp b/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp index 4ec1b781..ac324c04 100644 --- a/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp +++ b/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp @@ -1,33 +1,33 @@ -#include "Neon/set/ContainerTools/GraphNodeOrganization.h" +#include "Neon/set/ContainerTools/graph/GraphData.h" namespace Neon::set::container { -GraphNodeOrganization::GraphNodeOrganization() +GraphData::GraphData() { mUid = notSet; mIndex = notSet; } -GraphNodeOrganization::GraphNodeOrganization(int uid) +GraphData::GraphData(int uid) { mUid = uid; mIndex = notSet; } -auto GraphNodeOrganization::setUid(Uid uid) -> void +auto GraphData::setUid(Uid uid) -> void { mUid = uid; } -auto GraphNodeOrganization::setIndex(Index index) -> void +auto GraphData::setIndex(Index index) -> void { mIndex = index; } -auto GraphNodeOrganization::getUid() const -> Uid +auto GraphData::getUid() const -> Uid { return mUid; } -auto GraphNodeOrganization::getIndex() const -> Index +auto GraphData::getIndex() const -> Index { return mIndex; } diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp b/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp index 81149f25..86fb6956 100644 --- a/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp +++ b/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/GraphNodeScheduling.h" +#include "Neon/set/ContainerTools/graph/GraphNodeScheduling.h" namespace Neon::set::container { @@ -50,4 +50,9 @@ auto GraphNodeScheduling::setDataView(Neon::DataView dataView) -> void mDataView = dataView; } +auto GraphNodeScheduling::getDataView() const -> Neon::DataView +{ + return mDataView; +} + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeType.cpp b/libNeonSet/src/set/kContainerTools/GraphNodeType.cpp new file mode 100644 index 00000000..45a94f77 --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/GraphNodeType.cpp @@ -0,0 +1,61 @@ +#include "Neon/set/ContainerTools/graph/GraphNodeType.h" +#include "Neon/core/core.h" + +namespace Neon { + + +auto GraphNodeTypeUtil::validOptions() -> std::array +{ + std::array options = {GraphNodeType::Compute, + GraphNodeType::Halo, + GraphNodeType::Sync}; + return options; +} + +auto GraphNodeTypeUtil::toString(GraphNodeType e) -> std::string +{ + switch (e) { + case GraphNodeType::Compute: { + return "DATA"; + } + case GraphNodeType::Halo: { + return "SCHEDULING"; + } + case GraphNodeType::Sync: { + return "Sync"; + } + default: { + NEON_THROW_UNSUPPORTED_OPTION("GraphNodeTypeUtil"); + } + } +} + +auto GraphNodeTypeUtil::fromInt(int val) -> GraphNodeType +{ + switch (val) { + case static_cast(GraphNodeType::Compute): { + return GraphNodeType::Compute; + } + case static_cast(GraphNodeType::Halo): { + return GraphNodeType::Halo; + } + case static_cast(GraphNodeType::Sync): { + return GraphNodeType::Sync; + } + default: { + NEON_THROW_UNSUPPORTED_OPTION("GraphNodeTypeUtil"); + } + } +} + +auto GraphNodeTypeUtil::toInt(GraphNodeType dataView) -> int +{ + return static_cast(dataView); +} + +} // namespace Neon + +std::ostream& operator<<(std::ostream& os, Neon::GraphNodeType const& m) +{ + return os << std::string(Neon::GraphNodeTypeUtil::toString(m)); +} diff --git a/libNeonSet/src/set/kContainerTools/containerAPI.cpp b/libNeonSet/src/set/kContainerTools/containerAPI.cpp index 2a88d4ac..3ed1d05f 100644 --- a/libNeonSet/src/set/kContainerTools/containerAPI.cpp +++ b/libNeonSet/src/set/kContainerTools/containerAPI.cpp @@ -50,16 +50,6 @@ auto ContainerAPI::getLaunchParameters(Neon::DataView dw) const -> const Neon::s return mLaunchParameters[DataViewUtil::toInt(dw)]; } -auto ContainerAPI::setContainerType(ContainerType containerType) -> void -{ - mContainerType = containerType; -} - -auto ContainerAPI::getContainerType() const -> ContainerType -{ - return mContainerType; -} - auto ContainerAPI::getDataViewSupport() const -> ContainerAPI::DataViewSupport { return mDataViewSupport; @@ -82,4 +72,33 @@ auto ContainerAPI::toLog(uint64_t uid) -> void NEON_INFO("Container {}: tokens = [{}]", uid, listOfTokes.str()); } -} // namespace Neon +auto ContainerAPI::getContainerExecutionType() -> ContainerExecutionType +{ + return mContainerExecutionType; +} + +auto ContainerAPI::getContainerOperationType() -> ContainerOperationType +{ + return mContainerOperationType; +} + +auto ContainerAPI::getContainerPatternType() -> ContainerPatternType +{ + return mContainerPatternType; +} + +auto ContainerAPI::setContainerExecutionType(ContainerExecutionType containerType) -> void +{ + mContainerExecutionType = containerType; +} + +auto ContainerAPI::setContainerOperationType(ContainerOperationType containerType) -> void +{ + mContainerOperationType = containerType; +} +auto ContainerAPI::setContainerPatternType(ContainerPatternType containerType) -> void +{ + mContainerPatternType = containerType; +} + +} // namespace Neon::set::internal From 7942c0a7d301edea60430a09d37028966b5b36fb Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Tue, 9 Aug 2022 19:34:01 +0200 Subject: [PATCH 12/67] WIP --- .../Neon/set/ContainerTools/AnchorContainer.h | 53 ++++++ .../Neon/set/ContainerTools/ContainerAPI.h | 18 +- .../ContainerTools/ContainerExecutionType.h | 7 +- .../ContainerTools/ContainerOperationType.h | 10 +- .../set/ContainerTools/ContainerPatternType.h | 4 +- .../Neon/set/ContainerTools/DeviceContainer.h | 8 +- .../include/Neon/set/ContainerTools/Graph.h | 68 ++++++- .../Neon/set/ContainerTools/graph/GraphNode.h | 8 +- .../set/ContainerTools/graph/GraphNodeType.h | 53 ------ libNeonSet/include/Neon/set/Containter.h | 5 +- libNeonSet/src/set/Containter.cpp | 8 + .../set/kContainerTools/AnchorContainer.cpp | 40 ++++ libNeonSet/src/set/kContainerTools/Graph.cpp | 180 +++++++++++++++++- .../src/set/kContainerTools/GraphNode.cpp | 30 +-- .../src/set/kContainerTools/GraphNodeType.cpp | 61 ------ .../src/set/kContainerTools/containerAPI.cpp | 6 +- 16 files changed, 399 insertions(+), 160 deletions(-) create mode 100644 libNeonSet/include/Neon/set/ContainerTools/AnchorContainer.h delete mode 100644 libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h create mode 100644 libNeonSet/src/set/kContainerTools/AnchorContainer.cpp delete mode 100644 libNeonSet/src/set/kContainerTools/GraphNodeType.cpp diff --git a/libNeonSet/include/Neon/set/ContainerTools/AnchorContainer.h b/libNeonSet/include/Neon/set/ContainerTools/AnchorContainer.h new file mode 100644 index 00000000..95835449 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/AnchorContainer.h @@ -0,0 +1,53 @@ +#pragma once +#include "Neon/core/core.h" + +#include "Neon/set/ContainerTools/ContainerAPI.h" +#include "Neon/set/ContainerTools/Loader.h" + +namespace Neon { +namespace set { +namespace internal { + +/** + * Specialized implementation of KContainer_i + * + * + * @tparam DataIteratorContainerT + * @tparam UserComputeLambdaT + */ +struct AnchorContainer : ContainerAPI +{ + public: + virtual ~AnchorContainer() override = default; + + public: + AnchorContainer(const std::string& name); + + auto parse() -> const std::vector& override; + + auto getHostContainer() -> std::shared_ptr final; + + virtual auto getDeviceContainer() -> std::shared_ptr final; + + /** + * Run container over streams + * @param streamIdx + * @param dataView + */ + virtual auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + + /** + * Run container over streams + * @param streamIdx + * @param dataView + */ + virtual auto run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void override; + + private: + std::vector mEmtpy; + +}; + +} // namespace internal +} // namespace set +} // namespace Neon diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h index 53584859..6c87411e 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h @@ -72,17 +72,17 @@ struct ContainerAPI /** * Get the execution type for the container */ - auto getContainerExecutionType() -> ContainerExecutionType; + auto getContainerExecutionType() const -> Neon::set::ContainerExecutionType; /** * Get the Operation type for the container */ - auto getContainerOperationType() -> ContainerOperationType; + auto getContainerOperationType() const -> Neon::set::ContainerOperationType; /** * Get the Pattern type for the container */ - auto getContainerPatternType() -> ContainerPatternType; + auto getContainerPatternType() const -> Neon::set::ContainerPatternType; auto getDataViewSupport() const -> DataViewSupport; @@ -116,17 +116,17 @@ struct ContainerAPI /** * Set the execution type for the container */ - auto setContainerExecutionType(ContainerExecutionType containerType) -> void; + auto setContainerExecutionType(Neon::set::ContainerExecutionType containerType) -> void; /** * Set the Operation type for the container */ - auto setContainerOperationType(ContainerOperationType containerType) -> void; + auto setContainerOperationType(Neon::set::ContainerOperationType containerType) -> void; /** * Set the Pattern type for the container */ - auto setContainerPatternType(ContainerPatternType containerType) -> void; + auto setContainerPatternType(Neon::set::ContainerPatternType containerType) -> void; /** * Set the DataView support for the container @@ -138,9 +138,9 @@ struct ContainerAPI std::vector mParsed; std::string mName{"Anonymous"}; /**< Name of the Container */ std::array mLaunchParameters; - ContainerExecutionType mContainerExecutionType; - ContainerOperationType mContainerOperationType; - ContainerPatternType mContainerPatternType; + Neon::set::ContainerExecutionType mContainerExecutionType; + Neon::set::ContainerOperationType mContainerOperationType; + Neon::set::ContainerPatternType mContainerPatternType; DataViewSupport mDataViewSupport = DataViewSupport::on; }; diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h index a8a24cdd..0383f899 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h @@ -9,14 +9,15 @@ * Abstract interface to hide */ -namespace Neon::set::internal { +namespace Neon::set { enum struct ContainerExecutionType { device = 0 /** the operation of the containers are only for the device (note: device can be CPU too) */, deviceManaged = 1 /** manage version of the device type of Container, i.e. the launch is managed by the container itself. Useful to wrap calls to cuBlas operation for example*/, deviceThenHostManaged = 2, /** a container that stores operation on both device and host. For this type of Container a getHostContainer method is enabled to retrieved a container with the host code */ - hostManaged = 3 + hostManaged = 3, + none = 4 }; @@ -31,4 +32,4 @@ struct ContainerExecutionTypeUtils }; -} // namespace Neon::set::internal +} // namespace Neon::set diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h index 14bad2fb..f77d0fda 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h @@ -9,12 +9,12 @@ * Abstract interface to hide */ -namespace Neon::set::internal { +namespace Neon::set { enum struct ContainerOperationType { - compute = 0 /**< dependency generated by analyzing data dependency */, - halo = 1 /**< hints for scheduling **/, + compute = 0 /**< Dependency generated by analyzing data dependency */, + halo = 1 /**< Hints for scheduling **/, sync = 2 /**< User defined scheduling */, anchor = 3 /**< Anchor node: begin or end */ }; @@ -33,7 +33,7 @@ struct ContainerOperationTypeUtils * Returns the type associated to a string */ static auto fromString(const std::string& option) -> ContainerOperationType; - + /** * Return available options */ @@ -45,4 +45,4 @@ struct ContainerOperationTypeUtils /** * operator<< */ -std::ostream& operator<<(std::ostream& os, Neon::set::internal::ContainerOperationType const& m); \ No newline at end of file +std::ostream& operator<<(std::ostream& os, Neon::set::ContainerOperationType const& m); \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h index 0c9a1235..59d83986 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h @@ -9,7 +9,7 @@ * Abstract interface to hide */ -namespace Neon::set::internal { +namespace Neon::set { enum struct ContainerPatternType { @@ -34,4 +34,4 @@ struct ContainerPatternTypeUtils /** * operator<< */ -std::ostream& operator<<(std::ostream& os, Neon::set::internal::ContainerPatternType const& m); \ No newline at end of file +std::ostream& operator<<(std::ostream& os, Neon::set::container::ContainerPatternType const& m); \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h b/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h index 05808bc0..7730f605 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h @@ -33,7 +33,9 @@ struct DeviceContainer : ContainerAPI m_dataIteratorContainer(dataIteratorContainer) { setName(name); - setContainerType(ContainerType::device); + setContainerExecutionType(ContainerExecutionType::device); + setContainerOperationType(ContainerOperationType::compute); + setDataViewSupport(dataViewSupport); initLaunchParameters(dataIteratorContainer, blockSize, shMemSizeFun); @@ -101,7 +103,7 @@ struct DeviceContainer : ContainerAPI const Neon::Backend& bk = m_dataIteratorContainer.getBackend(); Neon::set::KernelConfig kernelConfig(dataView, bk, streamIdx, this->getLaunchParameters(dataView)); - if (ContainerType::device == this->getContainerType()) { + if (ContainerExecutionType::device == this->getContainerType()) { bk.devSet().template kernelLambdaWithIterator( kernelConfig, m_dataIteratorContainer, @@ -127,7 +129,7 @@ struct DeviceContainer : ContainerAPI const Neon::Backend& bk = m_dataIteratorContainer.getBackend(); Neon::set::KernelConfig kernelConfig(dataView, bk, streamIdx, this->getLaunchParameters(dataView)); - if (ContainerType::device == this->getContainerType()) { + if (ContainerExecutionType::device == this->getContainerType()) { bk.devSet().template kernelLambdaWithIterator( setIdx, kernelConfig, diff --git a/libNeonSet/include/Neon/set/ContainerTools/Graph.h b/libNeonSet/include/Neon/set/ContainerTools/Graph.h index 9cd00742..2e883bb8 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Graph.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Graph.h @@ -29,7 +29,8 @@ struct Graph /** * Adds a node between the begin and end nodes */ - auto addNode(const Container& container) -> GraphNode&; + auto addNode(const Container& container, + GraphNodeType graphNodeType) -> GraphNode&; /** * Remove Node @@ -42,8 +43,8 @@ struct Graph auto addNodeInBetween(const GraphNode& nodeA, Container& containerB, const GraphNode& nodeC, - const GraphDependencyType ab = GraphDependencyType::USER, - const GraphDependencyType bc = GraphDependencyType::USER) -> GraphNode&; + const GraphDependencyType ab = GraphDependencyType::user, + const GraphDependencyType bc = GraphDependencyType::user) -> GraphNode&; /** * Adds a dependency between two node of the graph @@ -87,10 +88,71 @@ struct Graph auto ioToDot(const std::string& fame) -> void; + private: + /** + * Invalidate all scheduling information that were computed + */ + auto helpInvalidateScheduling() -> void; + + /** + * Remove redundant dependencies + */ + auto helpRemoteRedundantDependencies() -> void; + + /* + * Compute BFS + */ + auto computeBFS(const std::vector& depednenciesToBeConsidered) -> void; + + /** + * Returns the out-neighbour of a target node + */ + auto helpGetOutNeighbors(GraphData::Uid, + bool fileterOutEnd = true, + const std::vector& dependencyTypes = {GraphDependencyType::user, + GraphDependencyType::data}) + -> std::set; + + /** + * Returns the in-neighbour of a target node + */ + auto helpGetInNeighbors(GraphData::Uid nodeUid, + bool fileterOutBegin = true, + const std::vector& dependencyTypes = {GraphDependencyType::user, + GraphDependencyType::data}) + -> std::set; + + /** + * Returns the out-edges of a target node + */ + auto helpGetOutEdges(GraphData::Uid, + bool filterOutEnd = true, + const std::vector& dependencyTypes = {GraphDependencyType::user, + GraphDependencyType::data}) + -> std::set>; + + /** + * Returns the in-edges of a target node + */ + auto helpGetInEdges(GraphData::Uid nodeUid, + bool filterOutBegin = true, + const std::vector& dependencyTypes = {GraphDependencyType::user, + GraphDependencyType::data}) + -> std::set>; + + /** + * Returns nodes Ids for a BFS visit + */ + auto helpGetBFS(bool filterOutBegin = false, + const std::vector& dependencyTypes = {GraphDependencyType::user, + GraphDependencyType::data}) + -> std::vector>; + using RawGraph = DiGraph; Uid mUidCounter; RawGraph mRawGraph; + bool mSchedulingStatusIsValid; }; } // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h index 42df9ff6..8d4299f0 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h @@ -54,15 +54,18 @@ struct GraphNode /** * Returns a reference to the container stored by this node. */ - auto getContianer() -> Container&; + auto getContainer() -> Container&; /** * Returns a reference to the container stored by this node. */ - auto getContianer() const -> const Container&; + auto getContainer() const -> const Container&; + + auto getContainerOperationType()const -> Neon::set::ContainerOperationType; auto toString() -> std::string; + private: auto helpGetDotProperties() -> std::string; auto helpGetDotName() -> std::string; @@ -71,7 +74,6 @@ struct GraphNode Container mContainer /**< Any Neon container */; GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; - GraphNodeType mGraphNodeType; }; } // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h deleted file mode 100644 index a27116c0..00000000 --- a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeType.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once -#include -#include - -namespace Neon { - -enum struct GraphNodeType -{ - Compute = 0 /**< dependency generated by analyzing data dependency */, - Halo = 1 /**< hints for scheduling **/, - Sync = 2 /**< User defined scheduling */, - Anchor = 3 /**< Anchor node: begin or end */ -}; - -/** - * Set of utilities for GraphNodeType options. - */ -struct GraphNodeTypeUtil -{ - /** - * Number of configurations for the enum - */ - static const int nConfig{static_cast(3)}; - - /** - * Convert enum value to string - * - * @param dataView - */ - static auto toString(GraphNodeType dataView) -> std::string; - - /** - * Returns all valid configuration for GraphNodeType - */ - static auto validOptions() -> std::array; - - /** - * Convert an integer to a GraphNodeType - */ - static auto fromInt(int val) -> GraphNodeType; - - /** - * Convert a GraphNodeType to an integer - */ - static auto toInt(GraphNodeType dataView) -> int; -}; - -} // namespace Neon - -/** - * operator<< - */ -std::ostream& operator<<(std::ostream& os, Neon::GraphNodeType const& m); \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index ed407d34..72cf0b06 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -6,8 +6,8 @@ #include "type_traits" #include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/Loader.h" #include "Neon/set/ContainerTools/HostManagedSyncType.h" +#include "Neon/set/ContainerTools/Loader.h" namespace Neon::set { @@ -100,6 +100,9 @@ struct Container Container& host) -> Container; + static auto factoryAnchor(const std::string& name /**< A user's string to identify the computation done by the Container. */) + -> Container; + auto getName() const -> const std::string&; diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index 1a7f691e..a1957068 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -1,4 +1,5 @@ #include "Neon/set/Containter.h" +#include "Neon/set/ContainerTools/AnchorContainer.h" namespace Neon::set { @@ -49,6 +50,13 @@ auto Container::factoryDeviceThenHostManaged(const std::string& name, return Container(tmp); } +auto Container::factoryAnchor(const std::string& name) -> Container +{ + auto k = new Neon::set::internal::AnchorContainer(name); + std::shared_ptr tmp(k); + return Container(); +} + auto Container::getName() const -> const std::string& { diff --git a/libNeonSet/src/set/kContainerTools/AnchorContainer.cpp b/libNeonSet/src/set/kContainerTools/AnchorContainer.cpp new file mode 100644 index 00000000..340341ef --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/AnchorContainer.cpp @@ -0,0 +1,40 @@ +#pragma once +#include "Neon/core/core.h" + +#include "Neon/set/ContainerTools/AnchorContainer.h" + +namespace Neon::set::internal { + +AnchorContainer::AnchorContainer(const std::string& name) +{ + setName(name); + setContainerExecutionType(ContainerExecutionType::none); + setContainerOperationType(ContainerOperationType::anchor); + setDataViewSupport(ContainerAPI::DataViewSupport::off); +} + + +auto AnchorContainer::parse() -> const std::vector& +{ + return mEmtpy; +} + +auto AnchorContainer::getHostContainer() -> std::shared_ptr +{ + NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); +} + +auto AnchorContainer::getDeviceContainer() -> std::shared_ptr +{ + NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); +} + +auto AnchorContainer::run(int streamIdx , Neon::DataView dataView ) -> void +{ +} + +auto AnchorContainer::run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void +{ +} + +} // namespace Neon::set::internal diff --git a/libNeonSet/src/set/kContainerTools/Graph.cpp b/libNeonSet/src/set/kContainerTools/Graph.cpp index 23ace60a..fd87a26b 100644 --- a/libNeonSet/src/set/kContainerTools/Graph.cpp +++ b/libNeonSet/src/set/kContainerTools/Graph.cpp @@ -10,6 +10,8 @@ Graph::Graph() mRawGraph.addVertex(begin.getGraphData().getUid(), begin); mRawGraph.addVertex(end.getGraphData().getUid(), end); + + helpInvalidateScheduling(); } auto Graph::getBeginNode() const -> const GraphNode& @@ -28,6 +30,8 @@ auto Graph::addNodeInBetween(const GraphNode& nodeA, const GraphDependencyType ab, const GraphDependencyType bc) -> GraphNode& { + helpInvalidateScheduling(); + auto& nodeB = addNodeInBetween(nodeA, containerB, nodeC); auto& abEdge = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), @@ -43,9 +47,12 @@ auto Graph::addNodeInBetween(const GraphNode& nodeA, return nodeB; } -auto Graph::addNode(const Container& container) -> GraphNode& +auto Graph::addNode(const Container& container, + GraphNodeType graphNodeType) -> GraphNode& { - auto const& node = GraphNode(container, mUidCounter); + helpInvalidateScheduling(); + + auto const& node = GraphNode(container, mUidCounter, graphNodeType); mRawGraph.addVertex(node.getGraphData().getUid(), node); mUidCounter++; return mRawGraph.getVertexProperty(node.getGraphData().getUid()); @@ -55,6 +62,8 @@ auto Graph::addDependency(const GraphNode& nodeA, const GraphNode& nodeB, GraphDependencyType type) -> GraphDependency& { + helpInvalidateScheduling(); + GraphDependency ab(type); mRawGraph.addEdge(nodeA.getGraphData().getUid(), @@ -67,6 +76,8 @@ auto Graph::addDependency(const GraphNode& nodeA, auto Graph::removeNode(GraphNode& gn) -> GraphNode { + helpInvalidateScheduling(); + auto uidB = gn.getGraphData().getUid(); std::vector a_toBeConnectedToEnd; @@ -135,6 +146,8 @@ auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode) -> std::vector GraphNode& { + helpInvalidateScheduling(); + auto proceedings = getProceedingGraphNodes(graphNode); auto subsequents = getSubsequentGraphNodes(graphNode); @@ -166,4 +179,167 @@ auto Graph::getDependencyType(const GraphNode& nodeA, return dependencyType; } +auto Graph::helpInvalidateScheduling() -> void +{ + mSchedulingStatusIsValid = false; +} + +auto Graph::helpRemoteRedundantDependencies() -> void +{ + // Vectors of edges to be removed + std::vector> edgesToBeRemoved; + mRawGraph.forEachVertex([&](size_t visitingNode) { + // In this body we are looping over all nodes + // For each node do: + + // Check node's children + const auto& children = helpGetOutNeighbors(visitingNode); + if (children.size() <= 1) { + // If no more than one, move to the next node + // Nothing to do for the visiting node as there are no redundant paths + // Let's move to another + return; + } + // Start checking for redundant paths + for (const auto& targetChild : children) { + if (helpGetInEdges(targetChild).size() <= 1) { + // This targetChild can only be reached by one father + // No redundant path here + continue; + } + bool foundRedundant = false; + // Checking all siblings' paths. + // We are looking for the targetChild in the path of any of its siblings. + // A BFS visit is used for the process. + for (const auto& targetSibling : children) { + if (targetSibling == targetChild) { + continue; + } + // first BFS frontier are the targetSibling's child + auto frontier = mRawGraph.outNeighbors(targetSibling); + while (frontier.size() != 0) { + auto nextFrontier = std::set(); + + for (const auto& nodeInFrontier : frontier) { + if (nodeInFrontier == targetChild) { + // We have found a redundant path + foundRedundant = true; + break; + } else { + // Let's continue by updating the frontier for the next iteration + for (auto nodeFrontierForNextIteration : helpGetOutNeighbors(nodeInFrontier)) { + nextFrontier.insert(nodeFrontierForNextIteration); + } + } + } + + if (foundRedundant) { + // A longer and altenrative path has been found. + break; + } + frontier = nextFrontier; + } + if (foundRedundant) + break; + } + if (foundRedundant) { + edgesToBeRemoved.push_back({visitingNode, targetChild}); + } + } + }); + for (const auto& toBeRemoved : edgesToBeRemoved) { + mRawGraph.removeEdge(toBeRemoved); + } +} + +auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, + bool filteredOut, + const std::vector& dependencyTypes) -> std::set +{ + std::set outNgh; + mRawGraph.forEachOutEdge( + nodeUid, + [&](std::pair edge) { + auto& edgeProp = mRawGraph.getEdgeProperty(edge); + for (auto& depType : dependencyTypes) { + if (depType == edgeProp.getType()) { + if (mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { + break; + } + outNgh.insert(edge.second); + } + } + }); + return outNgh; +} + +auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, bool filterOutBegin, const std::vector& dependencyTypes) -> std::set +{ + std::set inNgh; + mRawGraph.forEachInEdge( + nodeUid, + [&](std::pair edge) { + auto& edgeProp = mRawGraph.getEdgeProperty(edge); + for (auto& depType : dependencyTypes) { + if (depType == edgeProp.getType()) { + if (mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor && filterOutBegin) { + break; + } + inNgh.insert(edge.first); + } + } + }); + return inNgh; +} + +auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, + bool filterOutEnd, + const std::vector& dependencyTypes) -> std::set> +{ + std::set> outEdges; + mRawGraph.forEachOutEdge( + nodeUid, + [&](std::pair edge) { + auto& edgeProp = mRawGraph.getEdgeProperty(edge); + for (auto& depType : dependencyTypes) { + if (depType == edgeProp.getType()) { + if (mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor && filterOutEnd) { + break; + } + outEdges.insert(edge); + } + } + }); + return outEdges; +} + +auto Graph::helpGetInEdges(GraphData::Uid nodeUid, + bool filterOutBegin, + const std::vector& dependencyTypes) -> std::set> +{ + std::set> inEdges; + mRawGraph.forEachInEdge( + nodeUid, + [&](std::pair edge) { + auto& edgeProp = mRawGraph.getEdgeProperty(edge); + for (auto& depType : dependencyTypes) { + if (depType == edgeProp.getType()) { + if (mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor && filterOutBegin) { + break; + } + inEdges.insert(edge); + } + } + }); + return inEdges; +} + +auto Graph::helpGetBFS(bool filterOutBegin, const std::vector& dependencyTypes) -> std::vector> +{ + std::vector> bfs; + bfs.push_back(std::vector()); + int currentLevel = 0; +} + + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphNode.cpp b/libNeonSet/src/set/kContainerTools/GraphNode.cpp index 1d1368ac..377bacf9 100644 --- a/libNeonSet/src/set/kContainerTools/GraphNode.cpp +++ b/libNeonSet/src/set/kContainerTools/GraphNode.cpp @@ -40,12 +40,12 @@ auto GraphNode::getScheduling() const -> const GraphNodeScheduling& return mGraphNodeScheduling; } -auto GraphNode::getContianer() -> Container& +auto GraphNode::getContainer() -> Container& { return mContainer; } -auto GraphNode::getContianer() const -> const Container& +auto GraphNode::getContainer() const -> const Container& { return mContainer; } @@ -55,47 +55,53 @@ GraphNode::GraphNode(const Container& container, GraphData::Uid uid) mContainer = container; mGraphNodeOrganization.setUid(uid); } + auto GraphNode::toString() -> std::string { return std::string(); } + auto GraphNode::helpGetDotProperties() -> std::string { - if (mGraphNodeType == GraphNodeType::Anchor) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (mGraphNodeType == GraphNodeType::Compute) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (mGraphNodeType == GraphNodeType::Halo) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (mGraphNodeType == GraphNodeType::Sync) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } } auto GraphNode::helpGetDotName() -> std::string { - return getContianer().getName(); + return getContainer().getName(); } auto GraphNode::helpGetDotInfo() -> std::string { - if (mGraphNodeType == GraphNodeType::Anchor) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { return std::string(); } - if (mGraphNodeType == GraphNodeType::Compute) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { std::stringstream s; - s << "Uid = " << getContianer().getUid(); + s << "Uid = " << getContainer().getUid(); s << "DataView = " << Neon::DataViewUtil::toString(getScheduling().getDataView()); return s.str(); } - if (mGraphNodeType == GraphNodeType::Halo) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (mGraphNodeType == GraphNodeType::Sync) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } } +auto GraphNode::getContainerOperationType() const -> Neon::set::ContainerOperationType +{ + return getContainer().getContainerInterface().getContainerOperationType(); +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeType.cpp b/libNeonSet/src/set/kContainerTools/GraphNodeType.cpp deleted file mode 100644 index 45a94f77..00000000 --- a/libNeonSet/src/set/kContainerTools/GraphNodeType.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "Neon/set/ContainerTools/graph/GraphNodeType.h" -#include "Neon/core/core.h" - -namespace Neon { - - -auto GraphNodeTypeUtil::validOptions() -> std::array -{ - std::array options = {GraphNodeType::Compute, - GraphNodeType::Halo, - GraphNodeType::Sync}; - return options; -} - -auto GraphNodeTypeUtil::toString(GraphNodeType e) -> std::string -{ - switch (e) { - case GraphNodeType::Compute: { - return "DATA"; - } - case GraphNodeType::Halo: { - return "SCHEDULING"; - } - case GraphNodeType::Sync: { - return "Sync"; - } - default: { - NEON_THROW_UNSUPPORTED_OPTION("GraphNodeTypeUtil"); - } - } -} - -auto GraphNodeTypeUtil::fromInt(int val) -> GraphNodeType -{ - switch (val) { - case static_cast(GraphNodeType::Compute): { - return GraphNodeType::Compute; - } - case static_cast(GraphNodeType::Halo): { - return GraphNodeType::Halo; - } - case static_cast(GraphNodeType::Sync): { - return GraphNodeType::Sync; - } - default: { - NEON_THROW_UNSUPPORTED_OPTION("GraphNodeTypeUtil"); - } - } -} - -auto GraphNodeTypeUtil::toInt(GraphNodeType dataView) -> int -{ - return static_cast(dataView); -} - -} // namespace Neon - -std::ostream& operator<<(std::ostream& os, Neon::GraphNodeType const& m) -{ - return os << std::string(Neon::GraphNodeTypeUtil::toString(m)); -} diff --git a/libNeonSet/src/set/kContainerTools/containerAPI.cpp b/libNeonSet/src/set/kContainerTools/containerAPI.cpp index 3ed1d05f..fe128ab3 100644 --- a/libNeonSet/src/set/kContainerTools/containerAPI.cpp +++ b/libNeonSet/src/set/kContainerTools/containerAPI.cpp @@ -72,17 +72,17 @@ auto ContainerAPI::toLog(uint64_t uid) -> void NEON_INFO("Container {}: tokens = [{}]", uid, listOfTokes.str()); } -auto ContainerAPI::getContainerExecutionType() -> ContainerExecutionType +auto ContainerAPI::getContainerExecutionType() const -> ContainerExecutionType { return mContainerExecutionType; } -auto ContainerAPI::getContainerOperationType() -> ContainerOperationType +auto ContainerAPI::getContainerOperationType() const -> ContainerOperationType { return mContainerOperationType; } -auto ContainerAPI::getContainerPatternType() -> ContainerPatternType +auto ContainerAPI::getContainerPatternType() const -> ContainerPatternType { return mContainerPatternType; } From 23b2d3467bfaec1a304e888564bf58d8df0f44f5 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Wed, 10 Aug 2022 23:27:27 +0200 Subject: [PATCH 13/67] WIP --- .../include/Neon/set/ContainerTools/Bfs.h | 71 +++++++ .../include/Neon/set/ContainerTools/Bfs_imp.h | 43 +++++ .../include/Neon/set/ContainerTools/Graph.h | 42 +++- .../Neon/set/ContainerTools/graph/GraphNode.h | 3 +- .../graph/GraphNodeScheduling.h | 22 +-- libNeonSet/include/Neon/set/Containter.h | 2 + libNeonSet/src/set/kContainerTools/Bfs.cpp | 62 ++++++ libNeonSet/src/set/kContainerTools/Graph.cpp | 180 +++++++++++++++--- 8 files changed, 381 insertions(+), 44 deletions(-) create mode 100644 libNeonSet/include/Neon/set/ContainerTools/Bfs.h create mode 100644 libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h create mode 100644 libNeonSet/src/set/kContainerTools/Bfs.cpp diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs.h b/libNeonSet/include/Neon/set/ContainerTools/Bfs.h new file mode 100644 index 00000000..fe52a021 --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/Bfs.h @@ -0,0 +1,71 @@ +#pragma once + +#include "Neon/set/ContainerTools/graph/GraphData.h" + +namespace Neon::set::container { + +struct Graph; + +struct Bfs +{ + using Level = std::vector; + /** + * Returns the number of levels + */ + auto getNumberOfLevels() -> int; + + /** + * Returns a reference to a level and it's level index + */ + auto getNewLevel() -> std::pair; + + /** + * Returns a reference to a specific level + */ + auto getLevel(int levelId) const -> const Level&; + + /** + * Returns a reference to a specific level + */ + auto getLevel(int levelId) -> Level&; + + /** + * Returns max level width + */ + auto getMaxLevelWidth() const -> int; + + /** + * Returns max level width + */ + auto getLevelWidth(int levelIdx) const -> int; + + /** + * For Each iterator (read-only) + */ + template + auto forEachLevel(Fun fun) -> void; + + /** + * For Each iterator (read-only) + */ + template + auto forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) -> void; + + /** + * For Each iterator (read-only) + */ + template + auto forEachNodeByLevel(const Graph& graph, Fun fun) -> void; + + /** + * Clear the BFS status + */ + auto clear() -> void; + + private: + std::vector data; +}; + +} // namespace Neon::set::container + +#include "Neon/set/ContainerTools/Bfs_imp.h" diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h b/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h new file mode 100644 index 00000000..0aa9e76a --- /dev/null +++ b/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h @@ -0,0 +1,43 @@ +#pragma once + +#include "Neon/set/ContainerTools/Bfs.h" +#include "Neon/set/ContainerTools/Graph.h" + +namespace Neon::set::container { + +template +auto Bfs::forEachLevel(Fun fun) -> void +{ + int levelIdx = 0; + for (auto& level : data) { + fun(level, levelIdx); + levelIdx++; + } +} + +template +auto Bfs::forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) -> void +{ + for (auto& nodeIdx : data.at(levelIdx)) { + const auto& node = graph.helpGetGraphNode(nodeIdx); + fun(node); + } +} + +auto Bfs::clear() -> void +{ + data.clear(); +} +template +auto Bfs::forEachNodeByLevel(const Graph& graph, Fun fun) -> void +{ + forEachLevel([&graph, &fun](const Level& level, int levelIdx) { + for (const auto& nodeIdx : level) { + const auto& node = graph.helpGetGraphNode(nodeIdx); + fun(node, levelIdx); + } + }); +} + + +} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/Graph.h b/libNeonSet/include/Neon/set/ContainerTools/Graph.h index 2e883bb8..14fa2ce1 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Graph.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Graph.h @@ -3,15 +3,18 @@ #include "Neon/core/core.h" #include "Neon/core/types/digraph.h" +#include "Neon/set/ContainerTools/Bfs.h" #include "Neon/set/ContainerTools/graph/GraphDependency.h" #include "Neon/set/ContainerTools/graph/GraphNode.h" namespace Neon::set::container { +struct Bfs; struct Graph { using Uid = GraphData::Uid; using Index = GraphData::Index; + friend struct Bfs; public: Graph(); @@ -29,8 +32,7 @@ struct Graph /** * Adds a node between the begin and end nodes */ - auto addNode(const Container& container, - GraphNodeType graphNodeType) -> GraphNode&; + auto addNode(const Container& container) -> GraphNode&; /** * Remove Node @@ -84,12 +86,10 @@ struct Graph */ auto execute() -> void; - auto computeScheduling() -> void; - auto ioToDot(const std::string& fame) -> void; - private: + protected: /** * Invalidate all scheduling information that were computed */ @@ -100,7 +100,7 @@ struct Graph */ auto helpRemoteRedundantDependencies() -> void; - /* + /** * Compute BFS */ auto computeBFS(const std::vector& depednenciesToBeConsidered) -> void; @@ -144,15 +144,41 @@ struct Graph /** * Returns nodes Ids for a BFS visit */ - auto helpGetBFS(bool filterOutBegin = false, + auto helpGetBFS(bool filterOutBeginEnd = false, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) - -> std::vector>; + -> Bfs; + + /** + * Extract a graph node from its id + */ + auto helpGetGraphNode(GraphData::Uid) + -> GraphNode&; + + /** + * Extract a graph node from its id + */ + auto helpGetGraphNode(GraphData::Uid) const + -> const GraphNode&; + + /** + * + * Computes two elements: + * - order of execution + * - mapping between streams and graph nodes + */ + auto helpComputeScheduling(bool filterOutAnchors = true) -> void; + + auto helpComputeScheduling_01_mappingStreams(bool filterOutAnchors) -> void; + auto helpComputeScheduling_02_events() -> void; using RawGraph = DiGraph; + Uid mUidCounter; RawGraph mRawGraph; bool mSchedulingStatusIsValid; + Bfs mExecutionBfs; + int mMaxNumberStreams; }; } // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h index 8d4299f0..fe4af07e 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h @@ -13,8 +13,7 @@ struct GraphNode GraphNode(); GraphNode(const Container& container, - GraphData::Uid uid, - GraphNodeType graphNodeType); + GraphData::Uid uid); /** * Factory method to generate a begin node diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h index dbcd72ad..c6abd4a7 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h @@ -8,12 +8,6 @@ namespace Neon::set::container { class GraphNodeScheduling { - /** - * Get the stream to execute the Container - */ - auto getStream() const - -> int; - /** * Get the event to asynchronously signal that the execution of the Container is completed. */ @@ -26,11 +20,6 @@ class GraphNodeScheduling auto getDependentEvents() const -> const std::vector&; - /** - * Set the stream for the Container execution - */ - auto setStream(int stream /**< stream for the Container execution */) -> void; - /** * Set the event to asynchronously signal the completion of the Container. */ @@ -55,6 +44,17 @@ class GraphNodeScheduling */ auto getDataView() const -> Neon::DataView; + /** + * Get the stream to execute the Container + */ + auto getStream() const + -> int; + + /** + * Set the stream for the Container execution + */ + auto setStream(int stream /**< stream for the Container execution */) -> void; + private: int mStream /**< Stream for each operation for the node */; int mEvent /**< Event to be used to signal the completion of the node container */; diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 72cf0b06..21b97630 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -11,9 +11,11 @@ namespace Neon::set { + struct Container { public: + Container() = default; /** diff --git a/libNeonSet/src/set/kContainerTools/Bfs.cpp b/libNeonSet/src/set/kContainerTools/Bfs.cpp new file mode 100644 index 00000000..bf54202f --- /dev/null +++ b/libNeonSet/src/set/kContainerTools/Bfs.cpp @@ -0,0 +1,62 @@ +#pragma once + +#include "Neon/set/ContainerTools/Bfs.h" + +namespace Neon::set::container { + + +auto Bfs::getNumberOfLevels() -> int +{ + return int(data.size()); +} + +/** + * Returns a reference to a level and it's level index + */ +auto Bfs::getNewLevel() -> std::pair&, int> +{ + data.push_back(std::vector()); + int idx = int(data.size()) - 1; + return {data[idx], idx}; +} + +/** + * Returns a reference to a specific level + */ +auto Bfs::getLevel(int levelId) const + -> const std::vector& +{ + return data[levelId]; +} + +/** + * Returns a reference to a specific level + */ +auto Bfs::getLevel(int levelId) -> std::vector& +{ + return data[levelId]; +} + +/** + * Returns max level width + */ +auto Bfs::getMaxLevelWidth() const -> int +{ + int maxWidth = 0; + for (const auto& level : data) { + maxWidth = std::max(maxWidth, int(level.size())); + } + return maxWidth; +} + +/** + * Returns max level width + */ +auto Bfs::getLevelWidth(int levelIdx) const + -> int +{ + return int(data.at(levelIdx).size()); +} + + +} // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/Graph.cpp b/libNeonSet/src/set/kContainerTools/Graph.cpp index fd87a26b..ba35e6d7 100644 --- a/libNeonSet/src/set/kContainerTools/Graph.cpp +++ b/libNeonSet/src/set/kContainerTools/Graph.cpp @@ -32,27 +32,17 @@ auto Graph::addNodeInBetween(const GraphNode& nodeA, { helpInvalidateScheduling(); - auto& nodeB = addNodeInBetween(nodeA, containerB, nodeC); - - auto& abEdge = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), - nodeB.getGraphData().getUid()}); - abEdge.setType(ab); - - auto& bcEdge = mRawGraph.getEdgeProperty({nodeB.getGraphData().getUid(), - nodeC.getGraphData().getUid()}); - - bcEdge.setType(bc); - - + auto& nodeB = addNode(containerB); + addDependency(nodeA, nodeB, ab); + addDependency(nodeB, nodeC, bc); return nodeB; } -auto Graph::addNode(const Container& container, - GraphNodeType graphNodeType) -> GraphNode& +auto Graph::addNode(const Container& container) -> GraphNode& { helpInvalidateScheduling(); - auto const& node = GraphNode(container, mUidCounter, graphNodeType); + auto const& node = GraphNode(container, mUidCounter); mRawGraph.addVertex(node.getGraphData().getUid(), node); mUidCounter++; return mRawGraph.getVertexProperty(node.getGraphData().getUid()); @@ -100,12 +90,12 @@ auto Graph::removeNode(GraphNode& gn) -> GraphNode for (auto&& uidA : a_toBeConnectedToEnd) { auto& nodeA = mRawGraph.getVertexProperty(uidA); - addDependency(nodeA, this->getEndNode()); + addDependency(nodeA, this->getEndNode(), GraphDependencyType::data); } for (auto&& uidC : c_toBeConnectedToBegin) { auto& nodeC = mRawGraph.getVertexProperty(uidC); - addDependency(this->getBeginNode(), nodeC); + addDependency(this->getBeginNode(), nodeC, GraphDependencyType::data); } GraphNode removed = mRawGraph.getVertexProperty(gn.getGraphData().getUid()); @@ -151,7 +141,7 @@ auto Graph::cloneNode(const GraphNode& graphNode) auto proceedings = getProceedingGraphNodes(graphNode); auto subsequents = getSubsequentGraphNodes(graphNode); - auto& newNode = addNode(graphNode.getContianer()); + auto& newNode = addNode(graphNode.getContainer()); for (const auto& proPtr : proceedings) { auto dependencyType = getDependencyType(*proPtr, graphNode); @@ -182,6 +172,7 @@ auto Graph::getDependencyType(const GraphNode& nodeA, auto Graph::helpInvalidateScheduling() -> void { mSchedulingStatusIsValid = false; + mExecutionBfs.clear(); } auto Graph::helpRemoteRedundantDependencies() -> void @@ -263,7 +254,7 @@ auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, auto& edgeProp = mRawGraph.getEdgeProperty(edge); for (auto& depType : dependencyTypes) { if (depType == edgeProp.getType()) { - if (mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { + if (mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor && filteredOut) { break; } outNgh.insert(edge.second); @@ -334,12 +325,155 @@ auto Graph::helpGetInEdges(GraphData::Uid nodeUid, return inEdges; } -auto Graph::helpGetBFS(bool filterOutBegin, const std::vector& dependencyTypes) -> std::vector> +auto Graph::helpGetBFS(bool filterOutBeginEnd, + const std::vector& dependencyTypes) + -> Bfs { - std::vector> bfs; - bfs.push_back(std::vector()); - int currentLevel = 0; + using Frontier = std::unordered_map; + + Bfs bfs; + + Frontier a; + Frontier b; + + Frontier* currentFrontier = &a; + Frontier* nextFrontier = &b; + + + if (!filterOutBeginEnd) { + currentFrontier->insert({getBeginNode().getGraphData().getUid(), 0}); + } else { + auto beginNode = getBeginNode().getGraphData().getUid(); + auto outNgh = helpGetOutNeighbors(beginNode, filterOutBeginEnd, dependencyTypes); + for (const auto& ngh : outNgh) { + size_t stillUnsatisfiedDependencies = helpGetInEdges(ngh).size() - 1; + currentFrontier->insert({ngh, stillUnsatisfiedDependencies}); + } + } + + while (currentFrontier->size() != 0) { + auto [newLevel, newLevelIdx] = bfs.getNewLevel(); + nextFrontier->clear(); + + for (auto& currentFrontierNode : *currentFrontier) { + if (currentFrontierNode.second == 0) { + // All incoming dependencies have been resolved. + // The node is ready to be added to the current BFS level + newLevel.push_back(currentFrontierNode.first); + + // Adding the node's children to the next frontier + for (const auto& child : helpGetOutNeighbors(currentFrontierNode.first)) { + try { + nextFrontier->at(child)--; + } catch (...) { + nextFrontier->insert({child, helpGetInEdges(currentFrontierNode.first).size() - 1}); + } + } + } else { + nextFrontier->insert(currentFrontierNode); + } + } + std::swap(currentFrontier, nextFrontier); + } + + return bfs; } +auto Graph::helpComputeScheduling_01_mappingStreams(bool filterOutAnchors) -> void +{ + mSchedulingStatusIsValid = true; + mExecutionBfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); + + mMaxNumberStreams = mExecutionBfs.getMaxLevelWidth(); + int currentNode = 0; + // used stream -> true + // available -> false + std::vector streamsStatus(mMaxNumberStreams, false); + + auto bookFirstAvailableStream = [&]() { + for (int i = 0; i < int(streamsStatus.size()); i++) { + if (!streamsStatus[i]) { + streamsStatus[i] = true; + return i; + } + } + }; + + auto isStreamAvailable = [&](int streamId) -> bool { + return streamsStatus[streamId] == false; + }; + + auto bookStream = [&](int streamId) -> bool { + if (isStreamAvailable(streamId)) { + streamsStatus[streamId] = true; + return true; + } + return false; + }; + + // The stream mapping process is computer per level. + // On each level we have two steps + // a. map nodes with the streams of one of the proceeding nodes when possible + // b. map the remaining nodes by mapping the first available stream + mExecutionBfs.forEachLevel([&](Bfs::Level& level, + int levelIdx) { + std::vector delayedBooking; + + // Step a. + for (auto& nodeUid : level) { + auto node = mRawGraph.getVertexProperty(nodeUid); + + int associatedStream = [&]() -> int { + if (levelIdx == 0) { + return bookFirstAvailableStream(); + } + auto& preNodes = mRawGraph.inNeighbors(node.getGraphData().getUid()); + for (auto& preNodeIdx : preNodes) { + auto preNodeStream = mRawGraph.getVertexProperty(preNodeIdx).getScheduling().getStream(); + if (bookStream(preNodeStream)) { + return preNodeStream; + } + } + return -1; + }(); + + if (associatedStream == -1) { + // track nodes that need to go through step 2 + delayedBooking.push_back(&node); + } else { + node.getScheduling().setStream(associatedStream); + } + } + + // Step b. + for (auto nodePrt : delayedBooking) { + auto associatedStream = bookFirstAvailableStream(); + (*nodePrt).getScheduling().setStream(associatedStream); + } + + streamsStatus = std::vector(mMaxNumberStreams, false); + }); +} + +auto Graph::helpComputeScheduling(bool filterOutAnchors) -> void +{ + helpComputeScheduling_01_mappingStreams(filterOutAnchors); + helpComputeScheduling_02_events(); +} + +auto Graph::helpGetGraphNode(GraphData::Uid uid) -> GraphNode& +{ + return mRawGraph.getVertexProperty(uid); +} + +auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& +{ + return mRawGraph.getVertexProperty(uid); +} + +auto Graph::helpComputeScheduling_02_events() -> void +{ + NEON_DEV_UNDER_CONSTRUCTION(""); +} } // namespace Neon::set::container From 87ffb4c37085789b5cd11ad25e7d483c1c770d42 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Fri, 12 Aug 2022 19:21:46 +0200 Subject: [PATCH 14/67] WIP --- .../include/Neon/set/ContainerTools/Bfs.h | 6 +- .../include/Neon/set/ContainerTools/Bfs_imp.h | 7 +- .../include/Neon/set/ContainerTools/Graph.h | 15 +- .../graph/GraphNodeScheduling.h | 44 +++--- libNeonSet/src/set/kContainerTools/Graph.cpp | 131 ++++++++++++++++-- .../kContainerTools/GraphNodeScheduling.cpp | 22 +-- 6 files changed, 174 insertions(+), 51 deletions(-) diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs.h b/libNeonSet/include/Neon/set/ContainerTools/Bfs.h index fe52a021..3aebff04 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Bfs.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Bfs.h @@ -43,19 +43,19 @@ struct Bfs * For Each iterator (read-only) */ template - auto forEachLevel(Fun fun) -> void; + auto forEachLevel(Fun fun) const -> void; /** * For Each iterator (read-only) */ template - auto forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) -> void; + auto forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) const -> void; /** * For Each iterator (read-only) */ template - auto forEachNodeByLevel(const Graph& graph, Fun fun) -> void; + auto forEachNodeByLevel(const Graph& graph, Fun fun) const -> void; /** * Clear the BFS status diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h b/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h index 0aa9e76a..d34dcf36 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h @@ -6,7 +6,7 @@ namespace Neon::set::container { template -auto Bfs::forEachLevel(Fun fun) -> void +auto Bfs::forEachLevel(Fun fun) const -> void { int levelIdx = 0; for (auto& level : data) { @@ -16,7 +16,7 @@ auto Bfs::forEachLevel(Fun fun) -> void } template -auto Bfs::forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) -> void +auto Bfs::forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) const -> void { for (auto& nodeIdx : data.at(levelIdx)) { const auto& node = graph.helpGetGraphNode(nodeIdx); @@ -28,8 +28,9 @@ auto Bfs::clear() -> void { data.clear(); } + template -auto Bfs::forEachNodeByLevel(const Graph& graph, Fun fun) -> void +auto Bfs::forEachNodeByLevel(const Graph& graph, Fun fun) const -> void { forEachLevel([&graph, &fun](const Level& level, int levelIdx) { for (const auto& nodeIdx : level) { diff --git a/libNeonSet/include/Neon/set/ContainerTools/Graph.h b/libNeonSet/include/Neon/set/ContainerTools/Graph.h index 14fa2ce1..12b0e5e8 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Graph.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Graph.h @@ -169,8 +169,19 @@ struct Graph */ auto helpComputeScheduling(bool filterOutAnchors = true) -> void; - auto helpComputeScheduling_01_mappingStreams(bool filterOutAnchors) -> void; - auto helpComputeScheduling_02_events() -> void; + /** + * Resetting node's data related to scheduling + */ + auto helpComputeScheduling_00_resetData() -> void; + /** + * Maps node to streams + */ + auto helpComputeScheduling_01_mappingStreams(const Bfs& bfs, bool filterOutAnchors) -> void; + + /** + * Define events to be waited and fired from each node + */ + auto helpComputeScheduling_02_events(const Bfs& bfs) -> void; using RawGraph = DiGraph; diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h index c6abd4a7..caae61dc 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h @@ -7,28 +7,11 @@ namespace Neon::set::container { class GraphNodeScheduling { - - /** - * Get the event to asynchronously signal that the execution of the Container is completed. - */ - auto getEvent() const - -> int; - + public: /** * Get list of events to wait the completion of. */ - auto getDependentEvents() const - -> const std::vector&; - - /** - * Set the event to asynchronously signal the completion of the Container. - */ - auto setEvent(int event /**< Event to be used to signal the completion of the Container */) -> void; - - /** - * Set the list of events that needed to be waited for before running the Container. - */ - auto setDependentEvents(const std::vector&) -> void; + auto getDependentEvents() -> std::vector&; /** * Set the data view for the node @@ -36,7 +19,6 @@ class GraphNodeScheduling */ auto setDataView(Neon::DataView dataView) -> void; - public: GraphNodeScheduling(); /** @@ -55,11 +37,27 @@ class GraphNodeScheduling */ auto setStream(int stream /**< stream for the Container execution */) -> void; + /** + * Get the event to asynchronously signal that the execution of the Container is completed. + */ + auto getEvent() const + -> int; + + /** + * Set the event to asynchronously signal the completion of the Container. + */ + auto setEvent(int event /**< Event to be used to signal the completion of the Container */) -> void; + + /** + * Reset all scheduling data + */ + void reset(); + private: - int mStream /**< Stream for each operation for the node */; - int mEvent /**< Event to be used to signal the completion of the node container */; + int mStream{-1} /**< Stream for each operation for the node */; + int mEvent{-1} /**< Event to be used to signal the completion of the node container */; std::vector mDependentEvents /**< Events to be waited for before running the Container */; - Neon::DataView mDataView; + Neon::DataView mDataView{DataView::STANDARD}; }; } // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/Graph.cpp b/libNeonSet/src/set/kContainerTools/Graph.cpp index ba35e6d7..5a974b9e 100644 --- a/libNeonSet/src/set/kContainerTools/Graph.cpp +++ b/libNeonSet/src/set/kContainerTools/Graph.cpp @@ -379,12 +379,11 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd return bfs; } -auto Graph::helpComputeScheduling_01_mappingStreams(bool filterOutAnchors) -> void +auto Graph::helpComputeScheduling_01_mappingStreams(Bfs& bfs, bool filterOutAnchors) -> void { mSchedulingStatusIsValid = true; - mExecutionBfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); + mMaxNumberStreams = bfs.getMaxLevelWidth(); - mMaxNumberStreams = mExecutionBfs.getMaxLevelWidth(); int currentNode = 0; // used stream -> true // available -> false @@ -415,8 +414,8 @@ auto Graph::helpComputeScheduling_01_mappingStreams(bool filterOutAnchors) -> vo // On each level we have two steps // a. map nodes with the streams of one of the proceeding nodes when possible // b. map the remaining nodes by mapping the first available stream - mExecutionBfs.forEachLevel([&](Bfs::Level& level, - int levelIdx) { + bfs.forEachLevel([&](Bfs::Level& level, + int levelIdx) { std::vector delayedBooking; // Step a. @@ -457,8 +456,10 @@ auto Graph::helpComputeScheduling_01_mappingStreams(bool filterOutAnchors) -> vo auto Graph::helpComputeScheduling(bool filterOutAnchors) -> void { - helpComputeScheduling_01_mappingStreams(filterOutAnchors); - helpComputeScheduling_02_events(); + Bfs bfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); + helpComputeScheduling_00_resetData(bfs); + helpComputeScheduling_01_mappingStreams(bfs, filterOutAnchors); + helpComputeScheduling_02_events(bfs); } auto Graph::helpGetGraphNode(GraphData::Uid uid) -> GraphNode& @@ -471,9 +472,121 @@ auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& return mRawGraph.getVertexProperty(uid); } -auto Graph::helpComputeScheduling_02_events() -> void + +auto Graph::helpComputeScheduling_01_mappingStreams(const Bfs& bfs, bool filterOutAnchors) -> void { - NEON_DEV_UNDER_CONSTRUCTION(""); + mSchedulingStatusIsValid = true; + mMaxNumberStreams = bfs.getMaxLevelWidth(); + + int currentNode = 0; + // used stream -> true + // available -> false + std::vector streamsStatus(mMaxNumberStreams, false); + + auto bookFirstAvailableStream = [&]() { + for (int i = 0; i < int(streamsStatus.size()); i++) { + if (!streamsStatus[i]) { + streamsStatus[i] = true; + return i; + } + } + }; + + auto isStreamAvailable = [&](int streamId) -> bool { + return streamsStatus[streamId] == false; + }; + + auto bookStream = [&](int streamId) -> bool { + if (isStreamAvailable(streamId)) { + streamsStatus[streamId] = true; + return true; + } + return false; + }; + + // The stream mapping process is computer per level. + // On each level we have two steps + // a. map nodes with the streams of one of the proceeding nodes when possible + // b. map the remaining nodes by mapping the first available stream + bfs.forEachLevel([&](const Bfs::Level& level, + int levelIdx) { + std::vector delayedBooking; + + // Step a. + for (auto& nodeUid : level) { + auto node = mRawGraph.getVertexProperty(nodeUid); + + int associatedStream = [&]() -> int { + if (levelIdx == 0) { + return bookFirstAvailableStream(); + } + auto& preNodes = mRawGraph.inNeighbors(node.getGraphData().getUid()); + for (auto& preNodeIdx : preNodes) { + auto preNodeStream = mRawGraph.getVertexProperty(preNodeIdx).getScheduling().getStream(); + if (bookStream(preNodeStream)) { + return preNodeStream; + } + } + return -1; + }(); + + if (associatedStream == -1) { + // track nodes that need to go through step 2 + delayedBooking.push_back(&node); + } else { + node.getScheduling().setStream(associatedStream); + } + } + + // Step b. + for (auto nodePrt : delayedBooking) { + auto associatedStream = bookFirstAvailableStream(); + (*nodePrt).getScheduling().setStream(associatedStream); + } + + streamsStatus = std::vector(mMaxNumberStreams, false); + }); +} + +auto Graph::helpComputeScheduling_02_events(const Bfs& bfs) -> void +{ + int eventCount = 1; + + mExecutionBfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int levelId) { + int targetStreamId = targetNode.getScheduling().getStream(); + auto preNodeIds = mRawGraph.inNeighbors(targetNode.getGraphData().getUid()); + if (preNodeIds.size() == 0) { + // this is the first node, no need to have dependencies + return; + } + // Processing PreNodes on different streams than the node + std::vector preNodesOnDifferentStreams; + for (auto nodeId : preNodeIds) { + auto& preNode = mRawGraph.getVertexProperty(nodeId); + auto preNodeStream = preNode.getScheduling().getStream(); + if (preNodeStream == targetStreamId) { + continue; + } + // For pre-nodes on different streams we do the following + // a. check if the pre-node has an event associated, if not create one + // b. add the pre-node event to the list of the target node + + // a. + int preNodeEvent = -1; + if (preNode.getScheduling().getEvent() == -1) { + preNodeEvent = eventCount; + preNode.getScheduling().setEvent(preNodeEvent); + eventCount++; + } + targetNode.getScheduling().getDependentEvents().push_back(preNodeEvent); + } + }); +} +auto Graph::helpComputeScheduling_00_resetData() -> void +{ + mExecutionBfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int levelId) { + targetNode.getScheduling().reset(); + }); } } // namespace Neon::set::container diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp b/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp index 86fb6956..c786f796 100644 --- a/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp +++ b/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp @@ -4,9 +4,7 @@ namespace Neon::set::container { GraphNodeScheduling::GraphNodeScheduling() { - mStream = -1; - mEvent = -1; - mDataView = Neon::DataView::STANDARD; + reset(); } auto GraphNodeScheduling::getStream() const @@ -21,8 +19,8 @@ auto GraphNodeScheduling::getEvent() const return mEvent; } -auto GraphNodeScheduling::getDependentEvents() const - -> const std::vector& +auto GraphNodeScheduling::getDependentEvents() + -> std::vector& { return mDependentEvents; } @@ -39,12 +37,6 @@ auto GraphNodeScheduling::setEvent(int event) mEvent = event; } -auto GraphNodeScheduling::setDependentEvents(const std::vector& dependentEvents) - -> void -{ - mDependentEvents = dependentEvents; -} - auto GraphNodeScheduling::setDataView(Neon::DataView dataView) -> void { mDataView = dataView; @@ -55,4 +47,12 @@ auto GraphNodeScheduling::getDataView() const -> Neon::DataView return mDataView; } +auto GraphNodeScheduling::reset() -> void +{ + mStream = -1; + mEvent = -1; + mDataView = DataView::STANDARD; + mDependentEvents.clear(); +} + } // namespace Neon::set::container From 7d11d4d6b82ec9eb993e866981596e6539296eec Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Fri, 12 Aug 2022 21:08:37 +0200 Subject: [PATCH 15/67] WIP --- libNeonSet/src/set/kContainerTools/Graph.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libNeonSet/src/set/kContainerTools/Graph.cpp b/libNeonSet/src/set/kContainerTools/Graph.cpp index 5a974b9e..04e5b20c 100644 --- a/libNeonSet/src/set/kContainerTools/Graph.cpp +++ b/libNeonSet/src/set/kContainerTools/Graph.cpp @@ -457,9 +457,11 @@ auto Graph::helpComputeScheduling_01_mappingStreams(Bfs& bfs, bool filterOutAnch auto Graph::helpComputeScheduling(bool filterOutAnchors) -> void { Bfs bfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); - helpComputeScheduling_00_resetData(bfs); + helpComputeScheduling_00_resetData(); helpComputeScheduling_01_mappingStreams(bfs, filterOutAnchors); helpComputeScheduling_02_events(bfs); + + } auto Graph::helpGetGraphNode(GraphData::Uid uid) -> GraphNode& @@ -472,6 +474,12 @@ auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& return mRawGraph.getVertexProperty(uid); } +auto Graph::helpComputeScheduling_00_resetData() -> void +{ + mExecutionBfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int levelId) { + targetNode.getScheduling().reset(); + }); +} auto Graph::helpComputeScheduling_01_mappingStreams(const Bfs& bfs, bool filterOutAnchors) -> void { @@ -582,11 +590,6 @@ auto Graph::helpComputeScheduling_02_events(const Bfs& bfs) -> void } }); } -auto Graph::helpComputeScheduling_00_resetData() -> void -{ - mExecutionBfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int levelId) { - targetNode.getScheduling().reset(); - }); -} + } // namespace Neon::set::container From c05341e6793aa4898ad0397454872815ef1c47db Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Fri, 12 Aug 2022 22:55:22 +0200 Subject: [PATCH 16/67] WIP --- .../include/Neon/set/ContainerTools/Bfs.h | 6 +- .../include/Neon/set/ContainerTools/Bfs_imp.h | 11 +-- .../ContainerTools/ContainerExecutionType.h | 2 +- .../set/ContainerTools/ContainerPatternType.h | 5 +- .../Neon/set/ContainerTools/DeviceContainer.h | 4 +- .../ContainerTools/DeviceManagedContainer.h | 4 +- .../DeviceThenHostManagedContainer.h | 2 +- .../include/Neon/set/ContainerTools/Graph.h | 8 +- .../set/ContainerTools/HostManagedContainer.h | 4 +- .../OldDeviceManagedContainer.h | 2 +- .../Neon/set/ContainerTools/graph/GraphNode.h | 8 +- libNeonSet/include/Neon/set/Containter.h | 4 +- libNeonSet/src/set/Containter.cpp | 6 +- .../AnchorContainer.cpp | 5 +- .../{kContainerTools => container}/Bfs.cpp | 2 - .../ContainerAPI.cpp} | 0 .../set/container/ContainerExecutionType.cpp | 59 ++++++++++++ .../ContainerOperationType.cpp | 6 +- .../set/container/ContainerPatternType.cpp | 53 +++++++++++ .../{kContainerTools => container}/Graph.cpp | 95 ++----------------- .../GraphDependency.cpp | 3 - .../GraphDependencyType.cpp | 30 +++--- .../GraphNode.cpp | 7 +- .../GraphNodeOrganization.cpp | 0 .../GraphNodeScheduling.cpp | 0 .../kContainerTools/ContainerPatternType.cpp | 75 --------------- .../src/set/kContainerTools/ContainerType.cpp | 68 ------------- 27 files changed, 178 insertions(+), 291 deletions(-) rename libNeonSet/src/set/{kContainerTools => container}/AnchorContainer.cpp (82%) rename libNeonSet/src/set/{kContainerTools => container}/Bfs.cpp (98%) rename libNeonSet/src/set/{kContainerTools/containerAPI.cpp => container/ContainerAPI.cpp} (100%) create mode 100644 libNeonSet/src/set/container/ContainerExecutionType.cpp rename libNeonSet/src/set/{kContainerTools => container}/ContainerOperationType.cpp (86%) create mode 100644 libNeonSet/src/set/container/ContainerPatternType.cpp rename libNeonSet/src/set/{kContainerTools => container}/Graph.cpp (85%) rename libNeonSet/src/set/{kContainerTools => container}/GraphDependency.cpp (88%) rename libNeonSet/src/set/{kContainerTools => container}/GraphDependencyType.cpp (63%) rename libNeonSet/src/set/{kContainerTools => container}/GraphNode.cpp (94%) rename libNeonSet/src/set/{kContainerTools => container}/GraphNodeOrganization.cpp (100%) rename libNeonSet/src/set/{kContainerTools => container}/GraphNodeScheduling.cpp (100%) delete mode 100644 libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp delete mode 100644 libNeonSet/src/set/kContainerTools/ContainerType.cpp diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs.h b/libNeonSet/include/Neon/set/ContainerTools/Bfs.h index 3aebff04..15049c16 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Bfs.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Bfs.h @@ -43,19 +43,19 @@ struct Bfs * For Each iterator (read-only) */ template - auto forEachLevel(Fun fun) const -> void; + auto forEachLevel(Fun fun) -> void; /** * For Each iterator (read-only) */ template - auto forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) const -> void; + auto forEachNodeAtLevel(int levelIdx, Graph& graph, Fun fun) -> void; /** * For Each iterator (read-only) */ template - auto forEachNodeByLevel(const Graph& graph, Fun fun) const -> void; + auto forEachNodeByLevel(Graph& graph, Fun fun) -> void; /** * Clear the BFS status diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h b/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h index d34dcf36..1aaab83d 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h @@ -1,12 +1,11 @@ #pragma once -#include "Neon/set/ContainerTools/Bfs.h" #include "Neon/set/ContainerTools/Graph.h" namespace Neon::set::container { template -auto Bfs::forEachLevel(Fun fun) const -> void +auto Bfs::forEachLevel(Fun fun) -> void { int levelIdx = 0; for (auto& level : data) { @@ -16,10 +15,10 @@ auto Bfs::forEachLevel(Fun fun) const -> void } template -auto Bfs::forEachNodeAtLevel(int levelIdx, const Graph& graph, Fun fun) const -> void +auto Bfs::forEachNodeAtLevel(int levelIdx, Neon::set::container::Graph& graph, Fun fun) -> void { for (auto& nodeIdx : data.at(levelIdx)) { - const auto& node = graph.helpGetGraphNode(nodeIdx); + auto& node = graph.helpGetGraphNode(nodeIdx); fun(node); } } @@ -30,11 +29,11 @@ auto Bfs::clear() -> void } template -auto Bfs::forEachNodeByLevel(const Graph& graph, Fun fun) const -> void +auto Bfs::forEachNodeByLevel(Graph& graph, Fun fun) -> void { forEachLevel([&graph, &fun](const Level& level, int levelIdx) { for (const auto& nodeIdx : level) { - const auto& node = graph.helpGetGraphNode(nodeIdx); + auto& node = graph.helpGetGraphNode(nodeIdx); fun(node, levelIdx); } }); diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h index 0383f899..0036fad2 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h @@ -23,7 +23,7 @@ enum struct ContainerExecutionType struct ContainerExecutionTypeUtils { - static constexpr int nOptions = 3; + static constexpr int nOptions = 4; static auto toString(ContainerExecutionType option) -> std::string; static auto fromString(const std::string& option) -> ContainerExecutionType; diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h b/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h index 59d83986..09b6c955 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h +++ b/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h @@ -26,12 +26,11 @@ struct ContainerPatternTypeUtils static auto toString(ContainerPatternType option) -> std::string; static auto fromString(const std::string& option) -> ContainerPatternType; static auto getOptions() -> std::array; - static auto isExpandable(ContainerPatternType option) -> bool; }; -} // namespace Neon::set::internal +} // namespace Neon::set /** * operator<< */ -std::ostream& operator<<(std::ostream& os, Neon::set::container::ContainerPatternType const& m); \ No newline at end of file +std::ostream& operator<<(std::ostream& os, Neon::set::ContainerPatternType const& m); \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h b/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h index 7730f605..fbf866ac 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h @@ -103,7 +103,7 @@ struct DeviceContainer : ContainerAPI const Neon::Backend& bk = m_dataIteratorContainer.getBackend(); Neon::set::KernelConfig kernelConfig(dataView, bk, streamIdx, this->getLaunchParameters(dataView)); - if (ContainerExecutionType::device == this->getContainerType()) { + if (ContainerExecutionType::device == this->getContainerExecutionType()) { bk.devSet().template kernelLambdaWithIterator( kernelConfig, m_dataIteratorContainer, @@ -129,7 +129,7 @@ struct DeviceContainer : ContainerAPI const Neon::Backend& bk = m_dataIteratorContainer.getBackend(); Neon::set::KernelConfig kernelConfig(dataView, bk, streamIdx, this->getLaunchParameters(dataView)); - if (ContainerExecutionType::device == this->getContainerType()) { + if (ContainerExecutionType::device == this->getContainerExecutionType()) { bk.devSet().template kernelLambdaWithIterator( setIdx, kernelConfig, diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h index 5ffadbdd..9dfb2b90 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h @@ -31,7 +31,7 @@ struct DeviceManagedContainer : ContainerAPI : mLoadingLambda(loadingLambda), mDataContainer(dataIteratorContainer) { - setContainerType(ContainerType::deviceManaged); + setContainerExecutionType(ContainerExecutionType::deviceManaged); setDataViewSupport(dataViewSupport); setName(name); } @@ -97,7 +97,7 @@ struct DeviceManagedContainer : ContainerAPI int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override { - if (ContainerType::deviceManaged == this->getContainerType()) { + if (ContainerExecutionType::deviceManaged == this->getContainerType()) { const Neon::Backend& bk = mDataContainer.getBackend(); // We use device 0 as a dummy setIdx to create a loader. diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h index 82eacebb..6bdf3079 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h @@ -37,7 +37,7 @@ struct DeviceThenHostManagedContainer : ContainerAPI this->setDataViewSupport(DataViewSupport::off); - setContainerType(ContainerType::deviceThenHostManaged); + setContainerExecutionType(ContainerExecutionType::deviceThenHostManaged); setName(name); } diff --git a/libNeonSet/include/Neon/set/ContainerTools/Graph.h b/libNeonSet/include/Neon/set/ContainerTools/Graph.h index 12b0e5e8..3001b5f1 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Graph.h +++ b/libNeonSet/include/Neon/set/ContainerTools/Graph.h @@ -3,7 +3,6 @@ #include "Neon/core/core.h" #include "Neon/core/types/digraph.h" -#include "Neon/set/ContainerTools/Bfs.h" #include "Neon/set/ContainerTools/graph/GraphDependency.h" #include "Neon/set/ContainerTools/graph/GraphNode.h" @@ -172,23 +171,22 @@ struct Graph /** * Resetting node's data related to scheduling */ - auto helpComputeScheduling_00_resetData() -> void; + auto helpComputeScheduling_00_resetData(Bfs& bfs) -> void; /** * Maps node to streams */ - auto helpComputeScheduling_01_mappingStreams(const Bfs& bfs, bool filterOutAnchors) -> void; + auto helpComputeScheduling_01_mappingStreams(Bfs& bfs) -> void; /** * Define events to be waited and fired from each node */ - auto helpComputeScheduling_02_events(const Bfs& bfs) -> void; + auto helpComputeScheduling_02_events(Bfs& bfs) -> void; using RawGraph = DiGraph; Uid mUidCounter; RawGraph mRawGraph; bool mSchedulingStatusIsValid; - Bfs mExecutionBfs; int mMaxNumberStreams; }; diff --git a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h index 1a9926b2..edfca82f 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h @@ -39,7 +39,7 @@ struct HostManagedContainer : ContainerAPI : mLoadingLambda(loadingLambda), mDataContainer(dataIteratorContainer) { - setContainerType(ContainerType::hostManaged); + setContainerExecutionType(ContainerExecutionType::hostManaged); setDataViewSupport(dataViewSupport); setName(name); mPreSyncType = preSyncType; @@ -107,7 +107,7 @@ struct HostManagedContainer : ContainerAPI int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override { - if (ContainerType::deviceManaged == this->getContainerType()) { + if (ContainerExecutionType::deviceManaged == this->getContainerType()) { NEON_THROW_UNSUPPORTED_OPTION(""); } // REMEMBER that this is run in parallel withing omp diff --git a/libNeonSet/include/Neon/set/ContainerTools/OldDeviceManagedContainer.h b/libNeonSet/include/Neon/set/ContainerTools/OldDeviceManagedContainer.h index 40c5f771..314b05b6 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/OldDeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/ContainerTools/OldDeviceManagedContainer.h @@ -31,7 +31,7 @@ struct OldDeviceManagedContainer : ContainerAPI : mLoadingLambda(loadingLambda), mDataContainer(dataIteratorContainer) { - setContainerType(ContainerType::deviceManaged); + setContainerExecutionType(ContainerExecutionType::deviceManaged); setDataViewSupport(dataViewSupport); setName(name); } diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h index fe4af07e..19211d09 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h @@ -2,7 +2,6 @@ #include "GraphData.h" #include "GraphNodeScheduling.h" -#include "Neon/set/ContainerTools/graph/GraphNodeType.h" #include "Neon/set/Containter.h" namespace Neon::set::container { @@ -36,7 +35,7 @@ struct GraphNode auto getGraphData() -> GraphData&; /** - * Returns a reference to graph information related to this node. + * Returns a reference to some graph information related to this node. * */ auto getGraphData() const -> const GraphData&; @@ -60,7 +59,10 @@ struct GraphNode */ auto getContainer() const -> const Container&; - auto getContainerOperationType()const -> Neon::set::ContainerOperationType; + /** + * Returns the operation type of the container associated to this node + */ + auto getContainerOperationType() const -> Neon::set::ContainerOperationType; auto toString() -> std::string; diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 21b97630..a04e7dfd 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -122,8 +122,8 @@ struct Container auto getDataViewSupport() const -> Neon::set::internal::ContainerAPI::DataViewSupport; - auto getContainerType() const - -> Neon::set::internal::ContainerType; + auto getContainerExecutionType() const + -> Neon::set::ContainerExecutionType; protected: std::shared_ptr mContainer; diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index a1957068..640df642 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -99,11 +99,11 @@ auto Container::getDataViewSupport() const return dwSupport; } -auto Container::getContainerType() const - -> Neon::set::internal::ContainerType +auto Container::getContainerExecutionType() const + -> Neon::set::ContainerExecutionType { auto& api = this->getContainerInterface(); - auto const type = api.getContainerType(); + auto const type = api.getContainerExecutionType(); return type; } diff --git a/libNeonSet/src/set/kContainerTools/AnchorContainer.cpp b/libNeonSet/src/set/container/AnchorContainer.cpp similarity index 82% rename from libNeonSet/src/set/kContainerTools/AnchorContainer.cpp rename to libNeonSet/src/set/container/AnchorContainer.cpp index 340341ef..9dc95009 100644 --- a/libNeonSet/src/set/kContainerTools/AnchorContainer.cpp +++ b/libNeonSet/src/set/container/AnchorContainer.cpp @@ -1,4 +1,3 @@ -#pragma once #include "Neon/core/core.h" #include "Neon/set/ContainerTools/AnchorContainer.h" @@ -29,11 +28,11 @@ auto AnchorContainer::getDeviceContainer() -> std::shared_ptr NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); } -auto AnchorContainer::run(int streamIdx , Neon::DataView dataView ) -> void +auto AnchorContainer::run(int /*streamIdx*/ , Neon::DataView /*dataView*/ ) -> void { } -auto AnchorContainer::run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void +auto AnchorContainer::run(Neon::SetIdx /*setIdx*/, int /*streamIdx*/, Neon::DataView /*dataView*/) -> void { } diff --git a/libNeonSet/src/set/kContainerTools/Bfs.cpp b/libNeonSet/src/set/container/Bfs.cpp similarity index 98% rename from libNeonSet/src/set/kContainerTools/Bfs.cpp rename to libNeonSet/src/set/container/Bfs.cpp index bf54202f..9bb3a514 100644 --- a/libNeonSet/src/set/kContainerTools/Bfs.cpp +++ b/libNeonSet/src/set/container/Bfs.cpp @@ -1,5 +1,3 @@ -#pragma once - #include "Neon/set/ContainerTools/Bfs.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/kContainerTools/containerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp similarity index 100% rename from libNeonSet/src/set/kContainerTools/containerAPI.cpp rename to libNeonSet/src/set/container/ContainerAPI.cpp diff --git a/libNeonSet/src/set/container/ContainerExecutionType.cpp b/libNeonSet/src/set/container/ContainerExecutionType.cpp new file mode 100644 index 00000000..6f368505 --- /dev/null +++ b/libNeonSet/src/set/container/ContainerExecutionType.cpp @@ -0,0 +1,59 @@ +#include "Neon/set/ContainerTools/ContainerExecutionType.h" + +/** + * Abstract interface to hide + */ + +namespace Neon::set { + +auto ContainerExecutionTypeUtils::toString(ContainerExecutionType option) -> std::string +{ + switch (option) { + case ContainerExecutionType::device: { + return "device"; + } + case ContainerExecutionType::deviceManaged: { + return "deviceManaged"; + } + case ContainerExecutionType::hostManaged: { + return "hostManaged"; + } + case ContainerExecutionType::deviceThenHostManaged: { + return "deviceThenHostManaged"; + } + case ContainerExecutionType::none: { + return "none"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerExecutionTypeUtils::fromString(const std::string& option) + -> ContainerExecutionType +{ + auto const options = getOptions(); + + for (auto a : options) { + if (toString(a) == option) { + return a; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerExecutionTypeUtils::getOptions() -> std::array +{ + std::array opts = {ContainerExecutionType::device, + ContainerExecutionType::deviceManaged, + ContainerExecutionType::deviceThenHostManaged, + ContainerExecutionType::hostManaged}; + return opts; +} + +} // namespace Neon::set::internal + + +std::ostream& operator<<(std::ostream& os, Neon::set::ContainerExecutionType const& m) +{ + return os << std::string(Neon::set::ContainerExecutionTypeUtils::toString(m)); +} diff --git a/libNeonSet/src/set/kContainerTools/ContainerOperationType.cpp b/libNeonSet/src/set/container/ContainerOperationType.cpp similarity index 86% rename from libNeonSet/src/set/kContainerTools/ContainerOperationType.cpp rename to libNeonSet/src/set/container/ContainerOperationType.cpp index f9b5afc6..c4a9a724 100644 --- a/libNeonSet/src/set/kContainerTools/ContainerOperationType.cpp +++ b/libNeonSet/src/set/container/ContainerOperationType.cpp @@ -4,7 +4,7 @@ * Abstract interface to hide */ -namespace Neon::set::internal { +namespace Neon::set { auto ContainerOperationTypeUtils::toString(ContainerOperationType option) -> std::string { @@ -50,7 +50,7 @@ auto ContainerOperationTypeUtils::getOptions() -> std::array std::string +{ + switch (option) { + case ContainerPatternType::map: { + return "compute"; + } + case ContainerPatternType::stencil: { + return "halo"; + } + case ContainerPatternType::reduction: { + return "sync"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerPatternTypeUtils::fromString(const std::string& option) + -> ContainerPatternType +{ + auto const options = getOptions(); + + for (auto a : options) { + if (toString(a) == option) { + return a; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto ContainerPatternTypeUtils::getOptions() -> std::array +{ + std::array opts = {ContainerPatternType::map, + ContainerPatternType::stencil, + ContainerPatternType::reduction}; + return opts; +} + + +} // namespace Neon::set::internal + + +std::ostream& operator<<(std::ostream& os, Neon::set::ContainerPatternType const& m) +{ + return os << std::string(Neon::set::ContainerPatternTypeUtils::toString(m)); +} diff --git a/libNeonSet/src/set/kContainerTools/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp similarity index 85% rename from libNeonSet/src/set/kContainerTools/Graph.cpp rename to libNeonSet/src/set/container/Graph.cpp index 04e5b20c..ae357476 100644 --- a/libNeonSet/src/set/kContainerTools/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -1,4 +1,5 @@ #include "Neon/set/ContainerTools/Graph.h" +#include "Neon/set/ContainerTools/Bfs.h" namespace Neon::set::container { @@ -172,7 +173,6 @@ auto Graph::getDependencyType(const GraphNode& nodeA, auto Graph::helpInvalidateScheduling() -> void { mSchedulingStatusIsValid = false; - mExecutionBfs.clear(); } auto Graph::helpRemoteRedundantDependencies() -> void @@ -379,89 +379,12 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd return bfs; } -auto Graph::helpComputeScheduling_01_mappingStreams(Bfs& bfs, bool filterOutAnchors) -> void -{ - mSchedulingStatusIsValid = true; - mMaxNumberStreams = bfs.getMaxLevelWidth(); - - int currentNode = 0; - // used stream -> true - // available -> false - std::vector streamsStatus(mMaxNumberStreams, false); - - auto bookFirstAvailableStream = [&]() { - for (int i = 0; i < int(streamsStatus.size()); i++) { - if (!streamsStatus[i]) { - streamsStatus[i] = true; - return i; - } - } - }; - - auto isStreamAvailable = [&](int streamId) -> bool { - return streamsStatus[streamId] == false; - }; - - auto bookStream = [&](int streamId) -> bool { - if (isStreamAvailable(streamId)) { - streamsStatus[streamId] = true; - return true; - } - return false; - }; - - // The stream mapping process is computer per level. - // On each level we have two steps - // a. map nodes with the streams of one of the proceeding nodes when possible - // b. map the remaining nodes by mapping the first available stream - bfs.forEachLevel([&](Bfs::Level& level, - int levelIdx) { - std::vector delayedBooking; - - // Step a. - for (auto& nodeUid : level) { - auto node = mRawGraph.getVertexProperty(nodeUid); - - int associatedStream = [&]() -> int { - if (levelIdx == 0) { - return bookFirstAvailableStream(); - } - auto& preNodes = mRawGraph.inNeighbors(node.getGraphData().getUid()); - for (auto& preNodeIdx : preNodes) { - auto preNodeStream = mRawGraph.getVertexProperty(preNodeIdx).getScheduling().getStream(); - if (bookStream(preNodeStream)) { - return preNodeStream; - } - } - return -1; - }(); - - if (associatedStream == -1) { - // track nodes that need to go through step 2 - delayedBooking.push_back(&node); - } else { - node.getScheduling().setStream(associatedStream); - } - } - - // Step b. - for (auto nodePrt : delayedBooking) { - auto associatedStream = bookFirstAvailableStream(); - (*nodePrt).getScheduling().setStream(associatedStream); - } - - streamsStatus = std::vector(mMaxNumberStreams, false); - }); -} - auto Graph::helpComputeScheduling(bool filterOutAnchors) -> void { Bfs bfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); - helpComputeScheduling_00_resetData(); - helpComputeScheduling_01_mappingStreams(bfs, filterOutAnchors); + helpComputeScheduling_00_resetData(bfs); + helpComputeScheduling_01_mappingStreams(bfs); helpComputeScheduling_02_events(bfs); - - } auto Graph::helpGetGraphNode(GraphData::Uid uid) -> GraphNode& @@ -474,19 +397,18 @@ auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& return mRawGraph.getVertexProperty(uid); } -auto Graph::helpComputeScheduling_00_resetData() -> void +auto Graph::helpComputeScheduling_00_resetData(Bfs& bfs) -> void { - mExecutionBfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int levelId) { + bfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int /*levelId*/) { targetNode.getScheduling().reset(); }); } -auto Graph::helpComputeScheduling_01_mappingStreams(const Bfs& bfs, bool filterOutAnchors) -> void +auto Graph::helpComputeScheduling_01_mappingStreams(Bfs& bfs) -> void { mSchedulingStatusIsValid = true; mMaxNumberStreams = bfs.getMaxLevelWidth(); - int currentNode = 0; // used stream -> true // available -> false std::vector streamsStatus(mMaxNumberStreams, false); @@ -498,6 +420,7 @@ auto Graph::helpComputeScheduling_01_mappingStreams(const Bfs& bfs, bool filterO return i; } } + NEON_THROW_UNSUPPORTED_OPERATION(""); }; auto isStreamAvailable = [&](int streamId) -> bool { @@ -556,11 +479,11 @@ auto Graph::helpComputeScheduling_01_mappingStreams(const Bfs& bfs, bool filterO }); } -auto Graph::helpComputeScheduling_02_events(const Bfs& bfs) -> void +auto Graph::helpComputeScheduling_02_events(Bfs& bfs) -> void { int eventCount = 1; - mExecutionBfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int levelId) { + bfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int /*levelId*/) { int targetStreamId = targetNode.getScheduling().getStream(); auto preNodeIds = mRawGraph.inNeighbors(targetNode.getGraphData().getUid()); if (preNodeIds.size() == 0) { diff --git a/libNeonSet/src/set/kContainerTools/GraphDependency.cpp b/libNeonSet/src/set/container/GraphDependency.cpp similarity index 88% rename from libNeonSet/src/set/kContainerTools/GraphDependency.cpp rename to libNeonSet/src/set/container/GraphDependency.cpp index 41d929ff..895e8844 100644 --- a/libNeonSet/src/set/kContainerTools/GraphDependency.cpp +++ b/libNeonSet/src/set/container/GraphDependency.cpp @@ -1,12 +1,9 @@ -#pragma once - #include "Neon/set/ContainerTools/graph/GraphDependency.h" namespace Neon::set::container { GraphDependency::GraphDependency() { - mType = GraphDependencyType::NOTSET; } auto GraphDependency::setType(GraphDependencyType type) -> void diff --git a/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp b/libNeonSet/src/set/container/GraphDependencyType.cpp similarity index 63% rename from libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp rename to libNeonSet/src/set/container/GraphDependencyType.cpp index 85db65db..f98e0914 100644 --- a/libNeonSet/src/set/kContainerTools/GraphDependencyType.cpp +++ b/libNeonSet/src/set/container/GraphDependencyType.cpp @@ -6,23 +6,23 @@ namespace Neon { auto GraphDependencyTypeUtil::validOptions() -> std::array { - std::array options = {GraphDependencyType::DATA, - GraphDependencyType::SCHEDULING, - GraphDependencyType::USER}; + std::array options = {GraphDependencyType::data, + GraphDependencyType::scheduling, + GraphDependencyType::user}; return options; } auto GraphDependencyTypeUtil::toString(GraphDependencyType e) -> std::string { switch (e) { - case GraphDependencyType::DATA: { - return "DATA"; + case GraphDependencyType::data: { + return "data"; } - case GraphDependencyType::SCHEDULING: { - return "SCHEDULING"; + case GraphDependencyType::scheduling: { + return "scheduling"; } - case GraphDependencyType::USER: { - return "USER"; + case GraphDependencyType::user: { + return "user"; } default: { NEON_THROW_UNSUPPORTED_OPTION("GraphDependencyTypeUtil"); @@ -33,14 +33,14 @@ auto GraphDependencyTypeUtil::toString(GraphDependencyType e) -> std::string auto GraphDependencyTypeUtil::fromInt(int val) -> GraphDependencyType { switch (val) { - case static_cast(GraphDependencyType::DATA): { - return GraphDependencyType::DATA; + case static_cast(GraphDependencyType::data): { + return GraphDependencyType::data; } - case static_cast(GraphDependencyType::SCHEDULING): { - return GraphDependencyType::SCHEDULING; + case static_cast(GraphDependencyType::scheduling): { + return GraphDependencyType::scheduling; } - case static_cast(GraphDependencyType::USER): { - return GraphDependencyType::USER; + case static_cast(GraphDependencyType::user): { + return GraphDependencyType::user; } default: { NEON_THROW_UNSUPPORTED_OPTION("GraphDependencyTypeUtil"); diff --git a/libNeonSet/src/set/kContainerTools/GraphNode.cpp b/libNeonSet/src/set/container/GraphNode.cpp similarity index 94% rename from libNeonSet/src/set/kContainerTools/GraphNode.cpp rename to libNeonSet/src/set/container/GraphNode.cpp index 377bacf9..8ca78687 100644 --- a/libNeonSet/src/set/kContainerTools/GraphNode.cpp +++ b/libNeonSet/src/set/container/GraphNode.cpp @@ -6,14 +6,14 @@ GraphNode::GraphNode() { } -auto GraphNode::getBeginNode() -> GraphNode +auto GraphNode::newBeginNode() -> GraphNode { GraphNode node; node.mGraphNodeOrganization.setUid(GraphData::beginUid); return node; } -auto GraphNode::getEndNode() -> GraphNode +auto GraphNode::newEndNode() -> GraphNode { GraphNode node; node.mGraphNodeOrganization.setUid(GraphData::endUid); @@ -76,6 +76,7 @@ auto GraphNode::helpGetDotProperties() -> std::string if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } + NEON_DEV_UNDER_CONSTRUCTION(""); } auto GraphNode::helpGetDotName() -> std::string { @@ -98,6 +99,8 @@ auto GraphNode::helpGetDotInfo() -> std::string if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } + NEON_DEV_UNDER_CONSTRUCTION(""); + } auto GraphNode::getContainerOperationType() const -> Neon::set::ContainerOperationType { diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp b/libNeonSet/src/set/container/GraphNodeOrganization.cpp similarity index 100% rename from libNeonSet/src/set/kContainerTools/GraphNodeOrganization.cpp rename to libNeonSet/src/set/container/GraphNodeOrganization.cpp diff --git a/libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp b/libNeonSet/src/set/container/GraphNodeScheduling.cpp similarity index 100% rename from libNeonSet/src/set/kContainerTools/GraphNodeScheduling.cpp rename to libNeonSet/src/set/container/GraphNodeScheduling.cpp diff --git a/libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp b/libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp deleted file mode 100644 index 6c83a417..00000000 --- a/libNeonSet/src/set/kContainerTools/ContainerPatternType.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "Neon/set/ContainerTools/ContainerPatternType.h" - -/** - * Abstract interface to hide - */ - -namespace Neon::set::internal { - -auto ContainerPatternTypeUtils::toString(ContainerPatternType option) -> std::string -{ - switch (option) { - case ContainerPatternType::compute: { - return "compute"; - } - case ContainerPatternType::halo: { - return "halo"; - } - case ContainerPatternType::sync: { - return "sync"; - } - case ContainerPatternType::anchor: { - return "anchor"; - } - } - NEON_THROW_UNSUPPORTED_OPTION(""); -} - -auto ContainerPatternTypeUtils::fromString(const std::string& option) - -> ContainerPatternType -{ - auto const options = getOptions(); - - for (auto a : options) { - if (toString(a) == option) { - return a; - } - } - NEON_THROW_UNSUPPORTED_OPTION(""); -} - -auto ContainerPatternTypeUtils::getOptions() -> std::array -{ - std::array opts = {ContainerPatternType::compute, - ContainerPatternType::halo, - ContainerPatternType::sync, - ContainerPatternType::anchor}; - return opts; -} - -auto ContainerPatternTypeUtils::isExpandable(ContainerPatternType option) -> bool -{ - switch (option) { - case ContainerPatternType::compute: { - return false; - } - case ContainerPatternType::halo: { - return false; - } - case ContainerPatternType::sync: { - return false; - } - case ContainerPatternType::anchor: { - return true; - } - } - NEON_THROW_UNSUPPORTED_OPTION(""); -} - -} // namespace Neon::set::internal - - -std::ostream& operator<<(std::ostream& os, Neon::set::internal::ContainerPatternType const& m) -{ - return os << std::string(Neon::set::internal::ContainerPatternTypeUtils::toString(m)); -} diff --git a/libNeonSet/src/set/kContainerTools/ContainerType.cpp b/libNeonSet/src/set/kContainerTools/ContainerType.cpp deleted file mode 100644 index 8a095fab..00000000 --- a/libNeonSet/src/set/kContainerTools/ContainerType.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "Neon/set/ContainerTools/ContainerExecutionType.h" - -/** - * Abstract interface to hide - */ - -namespace Neon::set::internal { - -auto ContainerTypeUtils::toString(ContainerType option) -> std::string -{ - switch (option) { - case ContainerType::device: { - return "device"; - } - case ContainerType::deviceManaged: { - return "deviceManaged"; - } - case ContainerType::hostManaged: { - return "hostManaged"; - } - case ContainerType::deviceThenHostManaged: { - return "deviceThenHostManaged"; - } - } - NEON_THROW_UNSUPPORTED_OPTION(""); -} - -auto ContainerTypeUtils::fromString(const std::string& option) -> ContainerType -{ - auto const options = getOptions(); - - for (auto a : options) { - if (toString(a) == option) { - return a; - } - } - NEON_THROW_UNSUPPORTED_OPTION(""); -} - -auto ContainerTypeUtils::getOptions() -> std::array -{ - std::array opts = {ContainerType::device, - ContainerType::deviceManaged, - ContainerType::deviceThenHostManaged}; - return opts; -} - -auto ContainerTypeUtils::isExpandable(ContainerType option) -> bool -{ - switch (option) { - case ContainerType::device: { - return false; - } - case ContainerType::deviceManaged: { - return false; - } - case ContainerType::hostManaged: { - return false; - } - case ContainerType::deviceThenHostManaged: { - return true; - } - } - NEON_THROW_UNSUPPORTED_OPTION(""); -} - -} // namespace internal - From 78bb946e447237764b20818d3723269058602955 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Fri, 12 Aug 2022 23:07:18 +0200 Subject: [PATCH 17/67] WIP --- .../tests/unit/gUt_map/src/gUt_map_container.cu.h | 2 +- libNeonSet/include/Neon/set/Containter.h | 6 +++--- libNeonSet/include/Neon/set/Containter_imp.h | 10 +++++----- .../{ContainerTools => container}/AnchorContainer.h | 4 ++-- .../Neon/set/{ContainerTools => container}/Bfs.h | 4 ++-- .../Neon/set/{ContainerTools => container}/Bfs_imp.h | 2 +- .../set/{ContainerTools => container}/ContainerAPI.h | 6 +++--- .../ContainerExecutionType.h | 0 .../ContainerOperationType.h | 0 .../ContainerPatternType.h | 0 .../{ContainerTools => container}/DeviceContainer.h | 4 ++-- .../DeviceManagedContainer.h | 4 ++-- .../DeviceThenHostManagedContainer.h | 6 +++--- .../Neon/set/{ContainerTools => container}/Graph.h | 4 ++-- .../HostManagedContainer.h | 6 +++--- .../HostManagedSyncType.h | 0 .../Neon/set/{ContainerTools => container}/Loader.h | 2 +- .../OldDeviceManagedContainer.h | 4 ++-- .../{ContainerTools => container}/graph/GraphData.h | 0 .../graph/GraphDependency.h | 0 .../graph/GraphDependencyType.h | 0 .../{ContainerTools => container}/graph/GraphNode.h | 0 .../graph/GraphNodeScheduling.h | 0 libNeonSet/src/set/Containter.cpp | 2 +- libNeonSet/src/set/container/AnchorContainer.cpp | 2 +- libNeonSet/src/set/container/Bfs.cpp | 2 +- libNeonSet/src/set/container/ContainerAPI.cpp | 2 +- .../src/set/container/ContainerExecutionType.cpp | 2 +- .../src/set/container/ContainerOperationType.cpp | 2 +- libNeonSet/src/set/container/ContainerPatternType.cpp | 2 +- libNeonSet/src/set/container/Graph.cpp | 4 ++-- libNeonSet/src/set/container/GraphDependency.cpp | 2 +- libNeonSet/src/set/container/GraphDependencyType.cpp | 2 +- libNeonSet/src/set/container/GraphNode.cpp | 2 +- libNeonSet/src/set/container/GraphNodeOrganization.cpp | 2 +- libNeonSet/src/set/container/GraphNodeScheduling.cpp | 2 +- .../sUt_skeleton/src/sUt_skeleton.sequenceMapKernels.h | 2 +- .../src/sUt_skeleton.onStream.kernels.h | 2 +- libNeonSolver/src/linear/krylov/CGContainers.cu | 2 +- 39 files changed, 49 insertions(+), 49 deletions(-) rename libNeonSet/include/Neon/set/{ContainerTools => container}/AnchorContainer.h (92%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/Bfs.h (93%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/Bfs_imp.h (95%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/ContainerAPI.h (95%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/ContainerExecutionType.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/ContainerOperationType.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/ContainerPatternType.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/DeviceContainer.h (98%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/DeviceManagedContainer.h (97%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/DeviceThenHostManagedContainer.h (96%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/Graph.h (98%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/HostManagedContainer.h (97%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/HostManagedSyncType.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/Loader.h (99%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/OldDeviceManagedContainer.h (97%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/graph/GraphData.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/graph/GraphDependency.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/graph/GraphDependencyType.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/graph/GraphNode.h (100%) rename libNeonSet/include/Neon/set/{ContainerTools => container}/graph/GraphNodeScheduling.h (100%) diff --git a/libNeonDomain/tests/unit/gUt_map/src/gUt_map_container.cu.h b/libNeonDomain/tests/unit/gUt_map/src/gUt_map_container.cu.h index 08b4da01..3b32c7d7 100644 --- a/libNeonDomain/tests/unit/gUt_map/src/gUt_map_container.cu.h +++ b/libNeonDomain/tests/unit/gUt_map/src/gUt_map_container.cu.h @@ -1,7 +1,7 @@ #pragma once #include #include "Neon/domain/eGrid.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/Loader.h" #include "gUt_map.run.h" #include "gUt_map.storage.h" #include "gtest/gtest.h" diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index a04e7dfd..cfc8515a 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -5,9 +5,9 @@ #include "functional" #include "type_traits" -#include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/HostManagedSyncType.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/HostManagedSyncType.h" +#include "Neon/set/container/Loader.h" namespace Neon::set { diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h index 28fa51e1..e4cc92da 100644 --- a/libNeonSet/include/Neon/set/Containter_imp.h +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -5,11 +5,11 @@ #include "functional" #include "type_traits" -#include "Neon/set/ContainerTools/DeviceContainer.h" -#include "Neon/set/ContainerTools/DeviceManagedContainer.h" -#include "Neon/set/ContainerTools/DeviceThenHostManagedContainer.h" -#include "Neon/set/ContainerTools/HostManagedContainer.h" -#include "Neon/set/ContainerTools/OldDeviceManagedContainer.h" +#include "Neon/set/container/DeviceContainer.h" +#include "Neon/set/container/DeviceManagedContainer.h" +#include "Neon/set/container/DeviceThenHostManagedContainer.h" +#include "Neon/set/container/HostManagedContainer.h" +#include "Neon/set/container/OldDeviceManagedContainer.h" namespace Neon::set { diff --git a/libNeonSet/include/Neon/set/ContainerTools/AnchorContainer.h b/libNeonSet/include/Neon/set/container/AnchorContainer.h similarity index 92% rename from libNeonSet/include/Neon/set/ContainerTools/AnchorContainer.h rename to libNeonSet/include/Neon/set/container/AnchorContainer.h index 95835449..945885b3 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/AnchorContainer.h +++ b/libNeonSet/include/Neon/set/container/AnchorContainer.h @@ -1,8 +1,8 @@ #pragma once #include "Neon/core/core.h" -#include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" namespace Neon { namespace set { diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs.h b/libNeonSet/include/Neon/set/container/Bfs.h similarity index 93% rename from libNeonSet/include/Neon/set/ContainerTools/Bfs.h rename to libNeonSet/include/Neon/set/container/Bfs.h index 15049c16..11696ad6 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Bfs.h +++ b/libNeonSet/include/Neon/set/container/Bfs.h @@ -1,6 +1,6 @@ #pragma once -#include "Neon/set/ContainerTools/graph/GraphData.h" +#include "Neon/set/container/graph/GraphData.h" namespace Neon::set::container { @@ -68,4 +68,4 @@ struct Bfs } // namespace Neon::set::container -#include "Neon/set/ContainerTools/Bfs_imp.h" +#include "Neon/set/container/Bfs_imp.h" diff --git a/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h b/libNeonSet/include/Neon/set/container/Bfs_imp.h similarity index 95% rename from libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h rename to libNeonSet/include/Neon/set/container/Bfs_imp.h index 1aaab83d..d46388b0 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Bfs_imp.h +++ b/libNeonSet/include/Neon/set/container/Bfs_imp.h @@ -1,6 +1,6 @@ #pragma once -#include "Neon/set/ContainerTools/Graph.h" +#include "Neon/set/container/Graph.h" namespace Neon::set::container { diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h similarity index 95% rename from libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h rename to libNeonSet/include/Neon/set/container/ContainerAPI.h index 6c87411e..b34cd205 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -1,9 +1,9 @@ #pragma once -#include "Neon/set/ContainerTools/ContainerOperationType.h" -#include "Neon/set/ContainerTools/ContainerPatternType.h" +#include "Neon/set/container/ContainerOperationType.h" +#include "Neon/set/container/ContainerPatternType.h" -#include "Neon/set/ContainerTools/ContainerExecutionType.h" +#include "Neon/set/container/ContainerExecutionType.h" #include "Neon/set/DevSet.h" #include "Neon/set/dependencyTools/DataParsing.h" diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/ContainerExecutionType.h rename to libNeonSet/include/Neon/set/container/ContainerExecutionType.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h b/libNeonSet/include/Neon/set/container/ContainerOperationType.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/ContainerOperationType.h rename to libNeonSet/include/Neon/set/container/ContainerOperationType.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h b/libNeonSet/include/Neon/set/container/ContainerPatternType.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/ContainerPatternType.h rename to libNeonSet/include/Neon/set/container/ContainerPatternType.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h b/libNeonSet/include/Neon/set/container/DeviceContainer.h similarity index 98% rename from libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h rename to libNeonSet/include/Neon/set/container/DeviceContainer.h index fbf866ac..5a80bf30 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceContainer.h @@ -1,8 +1,8 @@ #pragma once #include "Neon/core/core.h" -#include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" namespace Neon { namespace set { diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h similarity index 97% rename from libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h rename to libNeonSet/include/Neon/set/container/DeviceManagedContainer.h index 9dfb2b90..ffb06a44 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h @@ -1,7 +1,7 @@ #pragma once -#include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" namespace Neon::set::internal { diff --git a/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h similarity index 96% rename from libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h rename to libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h index 6bdf3079..42b9aa6a 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/DeviceThenHostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h @@ -1,8 +1,8 @@ #pragma once -#include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/Loader.h" -#include "Neon/set/ContainerTools/OldDeviceManagedContainer.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" +#include "Neon/set/container/OldDeviceManagedContainer.h" namespace Neon::set::internal { diff --git a/libNeonSet/include/Neon/set/ContainerTools/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h similarity index 98% rename from libNeonSet/include/Neon/set/ContainerTools/Graph.h rename to libNeonSet/include/Neon/set/container/Graph.h index 3001b5f1..256f05c6 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -3,8 +3,8 @@ #include "Neon/core/core.h" #include "Neon/core/types/digraph.h" -#include "Neon/set/ContainerTools/graph/GraphDependency.h" -#include "Neon/set/ContainerTools/graph/GraphNode.h" +#include "Neon/set/container/graph/GraphDependency.h" +#include "Neon/set/container/graph/GraphNode.h" namespace Neon::set::container { struct Bfs; diff --git a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h b/libNeonSet/include/Neon/set/container/HostManagedContainer.h similarity index 97% rename from libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h rename to libNeonSet/include/Neon/set/container/HostManagedContainer.h index edfca82f..d745f85d 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/HostManagedContainer.h @@ -1,8 +1,8 @@ #pragma once -#include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/HostManagedSyncType.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/HostManagedSyncType.h" +#include "Neon/set/container/Loader.h" namespace Neon::set::internal { diff --git a/libNeonSet/include/Neon/set/ContainerTools/HostManagedSyncType.h b/libNeonSet/include/Neon/set/container/HostManagedSyncType.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/HostManagedSyncType.h rename to libNeonSet/include/Neon/set/container/HostManagedSyncType.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/Loader.h b/libNeonSet/include/Neon/set/container/Loader.h similarity index 99% rename from libNeonSet/include/Neon/set/ContainerTools/Loader.h rename to libNeonSet/include/Neon/set/container/Loader.h index 01cfbdfd..ff18e703 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/Loader.h +++ b/libNeonSet/include/Neon/set/container/Loader.h @@ -2,7 +2,7 @@ //#include #include "Neon/set/DevSet.h" #include "Neon/set/dependencyTools/DataParsing.h" -#include "Neon/set/ContainerTools/ContainerAPI.h" +#include "Neon/set/container/ContainerAPI.h" #include "type_traits" namespace Neon::set { diff --git a/libNeonSet/include/Neon/set/ContainerTools/OldDeviceManagedContainer.h b/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h similarity index 97% rename from libNeonSet/include/Neon/set/ContainerTools/OldDeviceManagedContainer.h rename to libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h index 314b05b6..ba653e0d 100644 --- a/libNeonSet/include/Neon/set/ContainerTools/OldDeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h @@ -1,7 +1,7 @@ #pragma once -#include "Neon/set/ContainerTools/ContainerAPI.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" namespace Neon::set::internal { diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphData.h b/libNeonSet/include/Neon/set/container/graph/GraphData.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/graph/GraphData.h rename to libNeonSet/include/Neon/set/container/graph/GraphData.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependency.h rename to libNeonSet/include/Neon/set/container/graph/GraphDependency.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependencyType.h b/libNeonSet/include/Neon/set/container/graph/GraphDependencyType.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/graph/GraphDependencyType.h rename to libNeonSet/include/Neon/set/container/graph/GraphDependencyType.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h b/libNeonSet/include/Neon/set/container/graph/GraphNode.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/graph/GraphNode.h rename to libNeonSet/include/Neon/set/container/graph/GraphNode.h diff --git a/libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h b/libNeonSet/include/Neon/set/container/graph/GraphNodeScheduling.h similarity index 100% rename from libNeonSet/include/Neon/set/ContainerTools/graph/GraphNodeScheduling.h rename to libNeonSet/include/Neon/set/container/graph/GraphNodeScheduling.h diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index 640df642..95e36e0e 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -1,5 +1,5 @@ #include "Neon/set/Containter.h" -#include "Neon/set/ContainerTools/AnchorContainer.h" +#include "Neon/set/container/AnchorContainer.h" namespace Neon::set { diff --git a/libNeonSet/src/set/container/AnchorContainer.cpp b/libNeonSet/src/set/container/AnchorContainer.cpp index 9dc95009..b100e679 100644 --- a/libNeonSet/src/set/container/AnchorContainer.cpp +++ b/libNeonSet/src/set/container/AnchorContainer.cpp @@ -1,6 +1,6 @@ #include "Neon/core/core.h" -#include "Neon/set/ContainerTools/AnchorContainer.h" +#include "Neon/set/container/AnchorContainer.h" namespace Neon::set::internal { diff --git a/libNeonSet/src/set/container/Bfs.cpp b/libNeonSet/src/set/container/Bfs.cpp index 9bb3a514..ba637b64 100644 --- a/libNeonSet/src/set/container/Bfs.cpp +++ b/libNeonSet/src/set/container/Bfs.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/Bfs.h" +#include "Neon/set/container/Bfs.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/container/ContainerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp index fe128ab3..d314cd1c 100644 --- a/libNeonSet/src/set/container/ContainerAPI.cpp +++ b/libNeonSet/src/set/container/ContainerAPI.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/ContainerAPI.h" +#include "Neon/set/container/ContainerAPI.h" /** diff --git a/libNeonSet/src/set/container/ContainerExecutionType.cpp b/libNeonSet/src/set/container/ContainerExecutionType.cpp index 6f368505..cafddf52 100644 --- a/libNeonSet/src/set/container/ContainerExecutionType.cpp +++ b/libNeonSet/src/set/container/ContainerExecutionType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/ContainerExecutionType.h" +#include "Neon/set/container/ContainerExecutionType.h" /** * Abstract interface to hide diff --git a/libNeonSet/src/set/container/ContainerOperationType.cpp b/libNeonSet/src/set/container/ContainerOperationType.cpp index c4a9a724..941c549f 100644 --- a/libNeonSet/src/set/container/ContainerOperationType.cpp +++ b/libNeonSet/src/set/container/ContainerOperationType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/ContainerOperationType.h" +#include "Neon/set/container/ContainerOperationType.h" /** * Abstract interface to hide diff --git a/libNeonSet/src/set/container/ContainerPatternType.cpp b/libNeonSet/src/set/container/ContainerPatternType.cpp index 33ab4495..f6cec6dc 100644 --- a/libNeonSet/src/set/container/ContainerPatternType.cpp +++ b/libNeonSet/src/set/container/ContainerPatternType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/ContainerPatternType.h" +#include "Neon/set/container/ContainerPatternType.h" /** * Abstract interface to hide diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index ae357476..7cabebe7 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -1,5 +1,5 @@ -#include "Neon/set/ContainerTools/Graph.h" -#include "Neon/set/ContainerTools/Bfs.h" +#include "Neon/set/container/Graph.h" +#include "Neon/set/container/Bfs.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/container/GraphDependency.cpp b/libNeonSet/src/set/container/GraphDependency.cpp index 895e8844..ef3f185d 100644 --- a/libNeonSet/src/set/container/GraphDependency.cpp +++ b/libNeonSet/src/set/container/GraphDependency.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/graph/GraphDependency.h" +#include "Neon/set/container/graph/GraphDependency.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/container/GraphDependencyType.cpp b/libNeonSet/src/set/container/GraphDependencyType.cpp index f98e0914..f525b8a2 100644 --- a/libNeonSet/src/set/container/GraphDependencyType.cpp +++ b/libNeonSet/src/set/container/GraphDependencyType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/graph/GraphDependencyType.h" +#include "Neon/set/container/graph/GraphDependencyType.h" #include "Neon/core/core.h" namespace Neon { diff --git a/libNeonSet/src/set/container/GraphNode.cpp b/libNeonSet/src/set/container/GraphNode.cpp index 8ca78687..8209105a 100644 --- a/libNeonSet/src/set/container/GraphNode.cpp +++ b/libNeonSet/src/set/container/GraphNode.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/graph/GraphNode.h" +#include "Neon/set/container/graph/GraphNode.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/container/GraphNodeOrganization.cpp b/libNeonSet/src/set/container/GraphNodeOrganization.cpp index ac324c04..3cac2bb2 100644 --- a/libNeonSet/src/set/container/GraphNodeOrganization.cpp +++ b/libNeonSet/src/set/container/GraphNodeOrganization.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/graph/GraphData.h" +#include "Neon/set/container/graph/GraphData.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/container/GraphNodeScheduling.cpp b/libNeonSet/src/set/container/GraphNodeScheduling.cpp index c786f796..d0fb662f 100644 --- a/libNeonSet/src/set/container/GraphNodeScheduling.cpp +++ b/libNeonSet/src/set/container/GraphNodeScheduling.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/ContainerTools/graph/GraphNodeScheduling.h" +#include "Neon/set/container/graph/GraphNodeScheduling.h" namespace Neon::set::container { diff --git a/libNeonSkeleton/tests/unit/sUt_skeleton/src/sUt_skeleton.sequenceMapKernels.h b/libNeonSkeleton/tests/unit/sUt_skeleton/src/sUt_skeleton.sequenceMapKernels.h index df7508eb..67c58114 100644 --- a/libNeonSkeleton/tests/unit/sUt_skeleton/src/sUt_skeleton.sequenceMapKernels.h +++ b/libNeonSkeleton/tests/unit/sUt_skeleton/src/sUt_skeleton.sequenceMapKernels.h @@ -5,7 +5,7 @@ #include "Neon/domain/dGrid.h" #include "Neon/domain/eGrid.h" #include "Neon/set/Containter.h" -#include "Neon/set/ContainerTools/ContainerAPI.h" +#include "Neon/set/container/ContainerAPI.h" #include "Neon/skeleton/Skeleton.h" #include "gtest/gtest.h" #include "sUt.runHelper.h" diff --git a/libNeonSkeleton/tests/unit/sUt_skeletonOnStreams/src/sUt_skeleton.onStream.kernels.h b/libNeonSkeleton/tests/unit/sUt_skeletonOnStreams/src/sUt_skeleton.onStream.kernels.h index f467b57d..2ef2d591 100644 --- a/libNeonSkeleton/tests/unit/sUt_skeletonOnStreams/src/sUt_skeleton.onStream.kernels.h +++ b/libNeonSkeleton/tests/unit/sUt_skeletonOnStreams/src/sUt_skeleton.onStream.kernels.h @@ -6,7 +6,7 @@ #include "Neon/domain/dGrid.h" #include "Neon/domain/eGrid.h" #include "Neon/set/Containter.h" -#include "Neon/set/ContainerTools/ContainerAPI.h" +#include "Neon/set/container/ContainerAPI.h" #include "Neon/skeleton/Skeleton.h" #include "gtest/gtest.h" #include "sUt.runHelper.h" diff --git a/libNeonSolver/src/linear/krylov/CGContainers.cu b/libNeonSolver/src/linear/krylov/CGContainers.cu index 30c5283b..a2a09a6c 100644 --- a/libNeonSolver/src/linear/krylov/CGContainers.cu +++ b/libNeonSolver/src/linear/krylov/CGContainers.cu @@ -2,7 +2,7 @@ #include "Neon/domain/dGrid.h" #include "Neon/domain/eGrid.h" #include "Neon/domain/bGrid.h" -#include "Neon/set/ContainerTools/Loader.h" +#include "Neon/set/container/Loader.h" #include "Neon/solver/linear/krylov/CGContainers.h" namespace Neon::solver { From fe27bd2bc7f72a99b0c315399e3818d9b01a9a64 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Fri, 12 Aug 2022 23:24:55 +0200 Subject: [PATCH 18/67] WIP --- libNeonSet/include/Neon/set/container/{ => graph}/Bfs.h | 2 +- libNeonSet/include/Neon/set/container/{ => graph}/Bfs_imp.h | 0 libNeonSet/src/set/container/Graph.cpp | 2 +- libNeonSet/src/set/container/{ => graph}/Bfs.cpp | 2 +- libNeonSet/src/set/container/{ => graph}/GraphDependency.cpp | 0 .../src/set/container/{ => graph}/GraphDependencyType.cpp | 0 libNeonSet/src/set/container/{ => graph}/GraphNode.cpp | 0 .../src/set/container/{ => graph}/GraphNodeOrganization.cpp | 0 .../src/set/container/{ => graph}/GraphNodeScheduling.cpp | 0 9 files changed, 3 insertions(+), 3 deletions(-) rename libNeonSet/include/Neon/set/container/{ => graph}/Bfs.h (97%) rename libNeonSet/include/Neon/set/container/{ => graph}/Bfs_imp.h (100%) rename libNeonSet/src/set/container/{ => graph}/Bfs.cpp (96%) rename libNeonSet/src/set/container/{ => graph}/GraphDependency.cpp (100%) rename libNeonSet/src/set/container/{ => graph}/GraphDependencyType.cpp (100%) rename libNeonSet/src/set/container/{ => graph}/GraphNode.cpp (100%) rename libNeonSet/src/set/container/{ => graph}/GraphNodeOrganization.cpp (100%) rename libNeonSet/src/set/container/{ => graph}/GraphNodeScheduling.cpp (100%) diff --git a/libNeonSet/include/Neon/set/container/Bfs.h b/libNeonSet/include/Neon/set/container/graph/Bfs.h similarity index 97% rename from libNeonSet/include/Neon/set/container/Bfs.h rename to libNeonSet/include/Neon/set/container/graph/Bfs.h index 11696ad6..e095e591 100644 --- a/libNeonSet/include/Neon/set/container/Bfs.h +++ b/libNeonSet/include/Neon/set/container/graph/Bfs.h @@ -68,4 +68,4 @@ struct Bfs } // namespace Neon::set::container -#include "Neon/set/container/Bfs_imp.h" +#include "Bfs_imp.h" diff --git a/libNeonSet/include/Neon/set/container/Bfs_imp.h b/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h similarity index 100% rename from libNeonSet/include/Neon/set/container/Bfs_imp.h rename to libNeonSet/include/Neon/set/container/graph/Bfs_imp.h diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 7cabebe7..4c64f706 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -1,5 +1,5 @@ #include "Neon/set/container/Graph.h" -#include "Neon/set/container/Bfs.h" +#include "Neon/set/container/graph/Bfs.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/container/Bfs.cpp b/libNeonSet/src/set/container/graph/Bfs.cpp similarity index 96% rename from libNeonSet/src/set/container/Bfs.cpp rename to libNeonSet/src/set/container/graph/Bfs.cpp index ba637b64..01720d54 100644 --- a/libNeonSet/src/set/container/Bfs.cpp +++ b/libNeonSet/src/set/container/graph/Bfs.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/container/Bfs.h" +#include "Neon/set/container/graph/Bfs.h" namespace Neon::set::container { diff --git a/libNeonSet/src/set/container/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp similarity index 100% rename from libNeonSet/src/set/container/GraphDependency.cpp rename to libNeonSet/src/set/container/graph/GraphDependency.cpp diff --git a/libNeonSet/src/set/container/GraphDependencyType.cpp b/libNeonSet/src/set/container/graph/GraphDependencyType.cpp similarity index 100% rename from libNeonSet/src/set/container/GraphDependencyType.cpp rename to libNeonSet/src/set/container/graph/GraphDependencyType.cpp diff --git a/libNeonSet/src/set/container/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp similarity index 100% rename from libNeonSet/src/set/container/GraphNode.cpp rename to libNeonSet/src/set/container/graph/GraphNode.cpp diff --git a/libNeonSet/src/set/container/GraphNodeOrganization.cpp b/libNeonSet/src/set/container/graph/GraphNodeOrganization.cpp similarity index 100% rename from libNeonSet/src/set/container/GraphNodeOrganization.cpp rename to libNeonSet/src/set/container/graph/GraphNodeOrganization.cpp diff --git a/libNeonSet/src/set/container/GraphNodeScheduling.cpp b/libNeonSet/src/set/container/graph/GraphNodeScheduling.cpp similarity index 100% rename from libNeonSet/src/set/container/GraphNodeScheduling.cpp rename to libNeonSet/src/set/container/graph/GraphNodeScheduling.cpp From f709e8bcc8b8ec9d292df6a7be16b9bffabe722e Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Fri, 12 Aug 2022 23:33:45 +0200 Subject: [PATCH 19/67] WIP --- libNeonSet/include/Neon/set/container/Graph.h | 18 ++++++---- .../set/container/graph/GraphDependency.h | 2 +- libNeonSet/src/set/container/Graph.cpp | 33 +++++++++++++++++-- .../set/container/graph/GraphDependency.cpp | 2 +- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 256f05c6..19fc29ad 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -41,11 +41,11 @@ struct Graph /** * Adds a dependency between two nodes of the graph */ - auto addNodeInBetween(const GraphNode& nodeA, - Container& containerB, - const GraphNode& nodeC, - const GraphDependencyType ab = GraphDependencyType::user, - const GraphDependencyType bc = GraphDependencyType::user) -> GraphNode&; + auto addNodeInBetween(const GraphNode& nodeA, + Container& containerB, + const GraphNode& nodeC, + GraphDependencyType ab = GraphDependencyType::user, + GraphDependencyType bc = GraphDependencyType::user) -> GraphNode&; /** * Adds a dependency between two node of the graph @@ -71,14 +71,18 @@ struct Graph * Returns all proceeding graph nodes. * The begin node is excluded */ - auto getProceedingGraphNodes(const GraphNode& graphNode) + auto getProceedingGraphNodes(const GraphNode& graphNode, + const std::vector& dependencyTypes = {GraphDependencyType::user, + GraphDependencyType::data}) -> std::vector; /** * Returns all subsequent graph nodes. * The end node is excluded */ - auto getSubsequentGraphNodes(const GraphNode& graphNode) -> std::vector; + auto getSubsequentGraphNodes(const GraphNode& graphNode, + const std::vector& dependencyTypes = {GraphDependencyType::user, + GraphDependencyType::data}) -> std::vector; /** * Execute the scheduling operation associated to the node diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index c1b79501..ddf21868 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -11,7 +11,7 @@ struct GraphDependency GraphDependency(GraphDependencyType type); auto setType(GraphDependencyType type) -> void; - auto getType() -> GraphDependencyType; + auto getType() const-> GraphDependencyType; private: GraphDependencyType mType; diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 4c64f706..7d853e15 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -105,7 +105,8 @@ auto Graph::removeNode(GraphNode& gn) -> GraphNode return removed; } -auto Graph::getProceedingGraphNodes(const GraphNode& graphNode) +auto Graph::getProceedingGraphNodes(const GraphNode& graphNode, + const std::vector& dependencyTypes) -> std::vector { std::vector nodes; @@ -113,6 +114,20 @@ auto Graph::getProceedingGraphNodes(const GraphNode& graphNode) auto nodeUID = graphNode.getGraphData().getUid(); auto nodeUidSet = mRawGraph.inNeighbors(nodeUID); for (auto&& proceedingUid : nodeUidSet) { + const auto& connection = mRawGraph.getEdgeProperty({proceedingUid, nodeUID}); + bool toBeReturned = false; + + for(auto& t : dependencyTypes){ + if(t == connection.getType() ){ + toBeReturned = true; + break ; + } + } + + if(!toBeReturned){ + continue ; + } + auto& proceedingNode = mRawGraph.getVertexProperty(proceedingUid); nodes.push_back(&proceedingNode); } @@ -120,13 +135,27 @@ auto Graph::getProceedingGraphNodes(const GraphNode& graphNode) return nodes; } -auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode) -> std::vector +auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, + const std::vector& dependencyTypes) -> std::vector { std::vector nodes; auto nodeUID = graphNode.getGraphData().getUid(); auto nodeUidSet = mRawGraph.outNeighbors(nodeUID); for (auto&& subsequentUID : nodeUidSet) { + const auto& connection = mRawGraph.getEdgeProperty({nodeUID, subsequentUID}); + bool toBeReturned = false; + + for(auto& t : dependencyTypes){ + if(t == connection.getType() ){ + toBeReturned = true; + break ; + } + } + + if(!toBeReturned){ + continue ; + } auto& subsequentNode = mRawGraph.getVertexProperty(subsequentUID); nodes.push_back(&subsequentNode); } diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index ef3f185d..8645fb83 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -11,7 +11,7 @@ auto GraphDependency::setType(GraphDependencyType type) -> void mType = type; } -auto GraphDependency::getType() -> GraphDependencyType +auto GraphDependency::getType() const -> GraphDependencyType { return mType; } From cf2dee414de27d67a9246a73812bfc16630c4d32 Mon Sep 17 00:00:00 2001 From: Massimiliano Date: Sat, 13 Aug 2022 01:17:31 +0200 Subject: [PATCH 20/67] WIP --- .../set/container/ContainerExecutionType.h | 5 +- .../set/container/graph/GraphDependency.h | 2 + .../Neon/set/container/graph/GraphNode.h | 2 + .../set/container/ContainerExecutionType.cpp | 8 ++-- libNeonSet/src/set/container/Graph.cpp | 47 +++++++++++++++++++ .../set/container/graph/GraphDependency.cpp | 7 ++- .../src/set/container/graph/GraphNode.cpp | 42 ++++++++++++++++- 7 files changed, 106 insertions(+), 7 deletions(-) diff --git a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h index 0036fad2..59de7508 100644 --- a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h +++ b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h @@ -31,5 +31,8 @@ struct ContainerExecutionTypeUtils static auto isExpandable(ContainerExecutionType option) -> bool; }; - +/** + * operator<< + */ +std::ostream& operator<<(std::ostream& os, Neon::set::ContainerExecutionType const& m); } // namespace Neon::set diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index ddf21868..58945e1b 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -6,6 +6,8 @@ namespace Neon::set::container { struct GraphDependency { + std::string getLabel(); + public: GraphDependency(); GraphDependency(GraphDependencyType type); diff --git a/libNeonSet/include/Neon/set/container/graph/GraphNode.h b/libNeonSet/include/Neon/set/container/graph/GraphNode.h index 19211d09..c6806947 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphNode.h @@ -8,6 +8,8 @@ namespace Neon::set::container { struct GraphNode { + std::string getLabel(); + public: GraphNode(); diff --git a/libNeonSet/src/set/container/ContainerExecutionType.cpp b/libNeonSet/src/set/container/ContainerExecutionType.cpp index cafddf52..c18f351d 100644 --- a/libNeonSet/src/set/container/ContainerExecutionType.cpp +++ b/libNeonSet/src/set/container/ContainerExecutionType.cpp @@ -50,10 +50,10 @@ auto ContainerExecutionTypeUtils::getOptions() -> std::array void } }); } +auto Graph::ioToDot(const std::string& /*fame*/) -> void +{ + auto vertexLabel = [&](size_t v) -> std::string { + auto& node = mRawGraph.getVertexProperty(v); + return node.getLabel(); + }; + + auto edgeLabel = [&](const std::pair& edge) + -> std::string { + auto& edgeMeta = mRawGraph.getEdgeProperty(edge); + return edgeMeta.getLabel(); + }; + +//// auto edgeLabelProperty = [&](const std::pair& edge) +//// -> std::string { +////// const auto& metaEdge = clone.getEdgeProperty(edge); +////// if (metaEdge.m_isSchedulingEdge) { +////// // return "style=dashed, color=\"#2A9D8F\""; +////// return "style=dashed, color=\"#F4A261\", penwidth=7"; +////// } +////// return "color=\"#d9d9d9\", penwidth=7"; +//// }; +// +// auto vertexLabelProperty = [&](const size_t& v) { +// if (v == m_finalNodeId() || (v == m_rootNodeId())) { +// return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; +// } +// const auto& metaNode = clone.getVertexProperty(v); +// if (metaNode.isHu()) { +// return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; +// } +// if (metaNode.isSync()) { +// return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; +// } +// +// if (metaNode.isMap()) { +// return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; +// } +// if (metaNode.isReduce()) { +// return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; +// } +// if (metaNode.isStencil()) { +// return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; +// } +// return ""; +// }; +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 8645fb83..0b3f3467 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -1,5 +1,5 @@ #include "Neon/set/container/graph/GraphDependency.h" - +#include namespace Neon::set::container { GraphDependency::GraphDependency() @@ -20,4 +20,9 @@ GraphDependency::GraphDependency(GraphDependencyType type) setType(type); } +auto GraphDependency::getLabel() -> std::string +{ + return GraphDependencyTypeUtil::toString(getType()) +} + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 8209105a..2edeac83 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -1,4 +1,5 @@ #include "Neon/set/container/graph/GraphNode.h" +#include "Neon/set/container/ContainerExecutionType.h" namespace Neon::set::container { @@ -100,11 +101,50 @@ auto GraphNode::helpGetDotInfo() -> std::string return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } NEON_DEV_UNDER_CONSTRUCTION(""); - } auto GraphNode::getContainerOperationType() const -> Neon::set::ContainerOperationType { return getContainer().getContainerInterface().getContainerOperationType(); } +auto GraphNode::getLabel() -> std::string +{ + if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { + if (this->getGraphData().beginUid == getGraphData().getUid()) { + return "Begin"; + } + if (this->getGraphData().endUid == getGraphData().getUid()) { + return "End"; + } + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { + std::stringstream s; + s << "Container " + " - Name: " + << getContainer().getName(); + s << " - UID: " << getContainer().getUid(); + s << " - Execution: " << getContainer().getContainerExecutionType(); + s << " - DataView: " << getScheduling().getDataView(); + return s.str(); + } + if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { + std::stringstream s; + s << "Halo Update " + " - Name: " + << getContainer().getName(); + s << " - UID: " << getContainer().getUid(); + return s.str(); + } + if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { + std::stringstream s; + s << "Sync " + " - Name: " + << getContainer().getName(); + s << " - UID: " << getContainer().getUid(); + return s.str(); + } + NEON_DEV_UNDER_CONSTRUCTION(""); + return std::string(); +} } // namespace Neon::set::container From 0796ddb4ef5a24fae928ee060ed71908dc02a9e4 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Mon, 22 Aug 2022 14:05:14 -0400 Subject: [PATCH 21/67] WIP --- libNeonCore/src/core/types/DataView.cpp | 8 +- libNeonDomain/tests/unit/CMakeLists.txt | 5 +- .../unit/setUt_containerGraph/CMakeLists.txt | 17 ++ .../src/setUt_containerGraph_kernels.h | 160 ++++++++++++++++++ .../src/setUt_containerGraph_main.cpp | 12 ++ .../src/setUt_containerGraph_mapStencilMap.cu | 127 ++++++++++++++ .../src/setUt_containerGraph_runHelper.h | 141 +++++++++++++++ libNeonSet/include/Neon/set/container/Graph.h | 2 +- .../Neon/set/container/graph/Bfs_imp.h | 4 - libNeonSet/src/set/Containter.cpp | 2 +- libNeonSet/src/set/container/Graph.cpp | 106 ++++++------ libNeonSet/src/set/container/graph/Bfs.cpp | 4 + .../set/container/graph/GraphDependency.cpp | 2 +- .../src/set/container/graph/GraphNode.cpp | 3 + 14 files changed, 531 insertions(+), 62 deletions(-) create mode 100644 libNeonDomain/tests/unit/setUt_containerGraph/CMakeLists.txt create mode 100644 libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h create mode 100644 libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp create mode 100644 libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu create mode 100644 libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h diff --git a/libNeonCore/src/core/types/DataView.cpp b/libNeonCore/src/core/types/DataView.cpp index d37f165d..050d92b3 100644 --- a/libNeonCore/src/core/types/DataView.cpp +++ b/libNeonCore/src/core/types/DataView.cpp @@ -22,7 +22,7 @@ auto DataViewUtil::toString(DataView e) -> std::string } case DataView::BOUNDARY: { return "BOUNDARY"; - } + } default: { NEON_THROW_UNSUPPORTED_OPTION("DataViewUtil"); } @@ -40,7 +40,7 @@ auto DataViewUtil::fromInt(int val) -> DataView } case static_cast(DataView::BOUNDARY): { return DataView::BOUNDARY; - } + } default: { NEON_THROW_UNSUPPORTED_OPTION("DataViewUtil"); } @@ -52,9 +52,9 @@ auto DataViewUtil::toInt(DataView dataView) -> int return static_cast(dataView); } -} // namespace Neon - std::ostream& operator<<(std::ostream& os, Neon::DataView const& m) { return os << std::string(Neon::DataViewUtil::toString(m)); } + +} // namespace Neon diff --git a/libNeonDomain/tests/unit/CMakeLists.txt b/libNeonDomain/tests/unit/CMakeLists.txt index 39a0c1d6..e1d90515 100644 --- a/libNeonDomain/tests/unit/CMakeLists.txt +++ b/libNeonDomain/tests/unit/CMakeLists.txt @@ -5,8 +5,9 @@ add_subdirectory("gUt_containers") add_subdirectory("gUt_dataView_patterns") add_subdirectory("gUt_map") add_subdirectory("gUt_patterns_container") -#add_subdirectory("gUt_periodic") add_subdirectory("domainUt_swap") add_subdirectory("gUt_tools") add_subdirectory("gUt_vtk") -add_subdirectory("gUt_bGrid") \ No newline at end of file +add_subdirectory("gUt_bGrid") + +add_subdirectory("setUt_containerGraph") diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/CMakeLists.txt b/libNeonDomain/tests/unit/setUt_containerGraph/CMakeLists.txt new file mode 100644 index 00000000..cac19ef1 --- /dev/null +++ b/libNeonDomain/tests/unit/setUt_containerGraph/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.19 FATAL_ERROR) +SET(APP "setUt_containerGraph") +file(GLOB_RECURSE SrcFiles src/*.*) + +add_executable(${APP} ${SrcFiles}) + +target_link_libraries(${APP} + PUBLIC libNeonSkeleton + PUBLIC gtest_main) + +set_target_properties(${APP} PROPERTIES + CUDA_SEPARABLE_COMPILATION ON + CUDA_RESOLVE_DEVICE_SYMBOLS ON) +set_target_properties(${APP} PROPERTIES FOLDER "libNeonSkeleton") +source_group(TREE ${CMAKE_CURRENT_LIST_DIR} PREFIX "${APP}" FILES ${SrcFiles}) + +add_test(NAME ${APP} COMMAND ${APP}) \ No newline at end of file diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h new file mode 100644 index 00000000..58a6553e --- /dev/null +++ b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h @@ -0,0 +1,160 @@ +#pragma once + +#include + +#include "Neon/domain/aGrid.h" +#include "Neon/domain/dGrid.h" +#include "Neon/domain/eGrid.h" +#include "Neon/set/Containter.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/skeleton/Skeleton.h" +#include "gtest/gtest.h" +#include "setUt_containerGraph_runHelper.h" + +namespace UserTools { +template +auto xpy(const Field& x, + Field& y) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + "xpy", [&](Neon::set::Loader & L) -> auto { + auto& xLocal = L.load(x); + auto& yLocal = L.load(y); + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { + for (int i = 0; i < yLocal.cardinality(); i++) { + yLocal(e, i) += xLocal(e, i); + } + }; + }); + return Kontainer; +} + +template +auto aInvXpY(const Neon::template PatternScalar& fR, + const Field& x, + Field& y) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + "AXPY", [&](Neon::set::Loader & L) -> auto { + auto& xLocal = L.load(x); + auto& yLocal = L.load(y); + auto fRLocal = L.load(fR); + const auto fRVal = fRLocal(); + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { + //printf("%d yLocal.cardinality()\n", yLocal.cardinality()); + + for (int i = 0; i < yLocal.cardinality(); i++) { + //printf("%d %d (%d) x\n", e, xLocal(e, i), i); + yLocal(e, i) += (1.0 / fRVal) * xLocal(e, i); + } + }; + }); + return Kontainer; +} + +template +auto axpy(const Neon::template PatternScalar& fR, + const Field& x, + Field& y) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + "AXPY", [&](Neon::set::Loader & L) -> auto { + auto& xLocal = L.load(x); + auto& yLocal = L.load(y); + auto fRLocal = L.load(fR); + const auto fRVal = fRLocal(); + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { + //printf("%d yLocal.cardinality()\n", yLocal.cardinality()); + + for (int i = 0; i < yLocal.cardinality(); i++) { + //printf("%d %d (%d) x\n", e, xLocal(e, i), i); + yLocal(e, i) += fRVal * xLocal(e, i); + } + }; + }); + return Kontainer; +} + +template +auto laplace(const Field& x, + Field& y, + size_t sharedMem = 0) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + "Laplace", [&](Neon::set::Loader & L) -> auto { + auto& xLocal = L.load(x, Neon::Compute::STENCIL); + auto& yLocal = L.load(y); + + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& cell) mutable { + using Type = typename Field::Type; + for (int card = 0; card < xLocal.cardinality(); card++) { + typename Field::Type res = 0; + + + auto checkNeighbor = [&res](Neon::domain::NghInfo& neighbor) { + if (neighbor.isValid) { + res += neighbor.value; + } + }; + + // Laplacian stencil operates on 6 neighbors (assuming 3D) + if constexpr (std::is_same::value) { + for (int8_t nghIdx = 0; nghIdx < 6; ++nghIdx) { + auto neighbor = xLocal.nghVal(cell, nghIdx, card, Type(0)); + checkNeighbor(neighbor); + } + } else { + typename Field::Partition::nghIdx_t ngh(0, 0, 0); + + //+x + ngh.x = 1; + ngh.y = 0; + ngh.z = 0; + auto neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //-x + ngh.x = -1; + ngh.y = 0; + ngh.z = 0; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //+y + ngh.x = 0; + ngh.y = 1; + ngh.z = 0; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //-y + ngh.x = 0; + ngh.y = -1; + ngh.z = 0; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //+z + ngh.x = 0; + ngh.y = 0; + ngh.z = 1; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //-z + ngh.x = 0; + ngh.y = 0; + ngh.z = -1; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + } + + + yLocal(cell, card) = -6 * res; + } + }; + }); + return Kontainer; +} + +} // namespace UserTools \ No newline at end of file diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp new file mode 100644 index 00000000..d7386cee --- /dev/null +++ b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp @@ -0,0 +1,12 @@ +#include "gtest/gtest.h" + +#include "Neon/Neon.h" + +#include + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + Neon::init(); + return RUN_ALL_TESTS(); +} diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu new file mode 100644 index 00000000..3b7c491c --- /dev/null +++ b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu @@ -0,0 +1,127 @@ +#include "Neon/core/types/chrono.h" + +#include "Neon/set/Containter.h" + +#include "Neon/domain/aGrid.h" +#include "Neon/domain/bGrid.h" +#include "Neon/domain/dGrid.h" +#include "Neon/domain/eGrid.h" +#include "Neon/domain/tools/Geometries.h" +#include "Neon/domain/tools/TestData.h" + +#include "Neon/skeleton/Options.h" +#include "Neon/skeleton/Skeleton.h" + +#include +#include + +#include "gtest/gtest.h" +#include "setUt_containerGraph_kernels.h" +#include "setUt_containerGraph_runHelper.h" + +#include "Neon/set/container/Graph.h" + +using namespace Neon::domain::tool::testing; +static const std::string testFilePrefix("setUt_containerGraph"); + +template +void ThreeIndependentMapsTest(TestData& data) +{ + using Type = typename TestData::Type; + + const std::string appName(testFilePrefix); + + const Type scalarVal = 2; + const int nIterations = 10; + + auto fR = data.getGrid().template newPatternScalar(); + fR() = scalarVal; + data.getBackend().syncAll(); + + data.resetValuesToRandom(1, 50); + Neon::Timer_sec timer; + + { // NEON + auto& X = data.getField(FieldNames::X); + auto& Y = data.getField(FieldNames::Y); + auto& Z = data.getField(FieldNames::Z); + auto& W = data.getField(FieldNames::W); + + std::vector ops{ + UserTools::axpy(fR, Y, X), + UserTools::laplace(X, Y), + UserTools::axpy(fR, Y, Y)}; + + Neon::set::container::Graph graph; + + graph.addNode(UserTools::axpy(fR, W, X)); + graph.addNode(UserTools::axpy(fR, W, Y)); + graph.addNode(UserTools::axpy(fR, W, Z)); + + graph.ioToDot(appName, "UserGraph"); + +// timer.start(); +// for (int i = 0; i < nIterations; i++) { +// skl.run(); +// } +// data.getBackend().syncAll(); +// timer.stop(); + } + + { // Golden data + auto time = timer.time(); + + Type dR = scalarVal; + auto& X = data.getIODomain(FieldNames::X); + auto& Y = data.getIODomain(FieldNames::Y); + + for (int i = 0; i < nIterations; i++) { + data.axpy(&dR, Y, X); + data.laplace(X, Y); + data.axpy(&dR, Y, Y); + } + } + bool isOk = data.compare(FieldNames::X); + isOk = isOk && data.compare(FieldNames::Y); + + /*{ // DEBUG + data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); + data.getField(FieldNames::X).ioToVtk("Field_X", "X"); + + data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); + data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); + }*/ + + ASSERT_TRUE(isOk); +} + +template +void ThreeIndependentMaps(TestData& data) +{ + ThreeIndependentMapsTest(data); +} + + +namespace { +int getNGpus() +{ + if (Neon::sys::globalSpace::gpuSysObjStorage.numDevs() > 0) { + int maxGPUs = Neon::set::DevSet::maxSet().setCardinality(); + if (maxGPUs > 1) { + return maxGPUs; + } else { + return 3; + } + } else { + return 0; + } +} +} // namespace + +TEST(MapStencilMap_NoOCC, eGrid) +{ + int nGpus = getNGpus(); + using Grid = Neon::domain::internal::eGrid::eGrid; + using Type = int32_t; + runAllTestConfiguration("eGrid_t", ThreeIndependentMaps, nGpus, 1); +} diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h new file mode 100644 index 00000000..abf192cc --- /dev/null +++ b/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h @@ -0,0 +1,141 @@ +#pragma once +#include +#include "gtest/gtest.h" + +#include "Neon/core/core.h" +#include "Neon/core/tools/io/ioToVti.h" +#include "Neon/core/types/DataUse.h" +#include "Neon/core/types/DeviceType.h" + +#include "Neon/domain/dGrid.h" +#include "Neon/domain/eGrid.h" +#include "Neon/domain/tools/Geometries.h" +#include "Neon/domain/tools/TestData.h" + +#include "gtest/gtest.h" + +using namespace Neon; +using namespace Neon::domain; + +using namespace Neon::domain::tool::testing; +using namespace Neon::domain::tool; + +template +void runAllTestConfiguration(const std::string& gname, + std::function&)> f, + int nGpus, + int minNumGpus) +{ + if (Neon::sys::globalSpace::gpuSysObjStorage.numDevs() > 0) { + std::vector nGpuTest; + for (int i = minNumGpus; i <= nGpus; i++) { + nGpuTest.push_back(i); + } + + std::vector cardinalityTest{1}; + + std::vector dimTest{{64, 16, 252}}; + std::vector runtimeE{Neon::Runtime::openmp, Neon::Runtime::stream}; + + std::vector geos; + + if constexpr (std::is_same_v) { + geos = std::vector{ + Geometry::FullDomain, + }; + } else { + geos = std::vector{ + Geometry::FullDomain, + Geometry::Sphere, + Geometry::HollowSphere, + + }; + } + + for (const auto& dim : dimTest) { + for (const auto& card : cardinalityTest) { + for (auto& geo : geos) { + for (const auto& ngpu : nGpuTest) { + for (const auto& runtime : runtimeE) { + int maxnGPUs = Neon::set::DevSet::maxSet().setCardinality(); + + std::vector ids; + for (int i = 0; i < ngpu; i++) { + ids.push_back(i % maxnGPUs); + } + + Neon::Backend backend(ids, runtime); + Neon::MemoryOptions memoryOptions = backend.getMemoryOptions(); + + TestData testData(backend, + dim, + card, + memoryOptions, + geo); + + NEON_INFO(testData.toString()); + + f(testData); + } + } + } + } + } + } +} + + +template +void runOneTestConfiguration(const std::string& gname, + std::function&)> f, + int nGpus, + int minNumGpus) +{ + + if (Neon::sys::globalSpace::gpuSysObjStorage.numDevs() > 0) { + std::vector nGpuTest; + for (int i = minNumGpus; i <= nGpus; i++) { + nGpuTest.push_back(i); + } + + std::vector cardinalityTest{1}; + + std::vector dimTest{{64, 16, 252}}; + std::vector runtimeE{ Neon::Runtime::stream}; + + std::vector geos; + geos = std::vector{ + Geometry::FullDomain, + }; + + for (const auto& dim : dimTest) { + for (const auto& card : cardinalityTest) { + for (auto& geo : geos) { + for (const auto& ngpu : nGpuTest) { + for (const auto& runtime : runtimeE) { + int maxnGPUs = Neon::set::DevSet::maxSet().setCardinality(); + + std::vector ids; + for (int i = 0; i < ngpu; i++) { + ids.push_back(i % maxnGPUs); + } + + Neon::Backend backend(ids, runtime); + Neon::MemoryOptions memoryOptions = backend.getMemoryOptions(); + + TestData testData(backend, + dim, + card, + memoryOptions, + geo); + + NEON_INFO(testData.toString()); + + f(testData); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 19fc29ad..a5d4863f 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -89,7 +89,7 @@ struct Graph */ auto execute() -> void; - auto ioToDot(const std::string& fame) -> void; + auto ioToDot(const std::string& fname, const std::string& graphName) -> void; protected: diff --git a/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h b/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h index d46388b0..d2025272 100644 --- a/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h +++ b/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h @@ -23,10 +23,6 @@ auto Bfs::forEachNodeAtLevel(int levelIdx, Neon::set::container::Graph& graph, F } } -auto Bfs::clear() -> void -{ - data.clear(); -} template auto Bfs::forEachNodeByLevel(Graph& graph, Fun fun) -> void diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index 95e36e0e..74d808f6 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -54,7 +54,7 @@ auto Container::factoryAnchor(const std::string& name) -> Container { auto k = new Neon::set::internal::AnchorContainer(name); std::shared_ptr tmp(k); - return Container(); + return Container(tmp); } auto Container::getName() const diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 17f40975..19eda67d 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -46,6 +46,10 @@ auto Graph::addNode(const Container& container) -> GraphNode& auto const& node = GraphNode(container, mUidCounter); mRawGraph.addVertex(node.getGraphData().getUid(), node); mUidCounter++; + + addDependency(getBeginNode(), node, GraphDependencyType::user); + addDependency(node, getEndNode(), GraphDependencyType::user); + return mRawGraph.getVertexProperty(node.getGraphData().getUid()); } @@ -115,17 +119,17 @@ auto Graph::getProceedingGraphNodes(const GraphNode& grap auto nodeUidSet = mRawGraph.inNeighbors(nodeUID); for (auto&& proceedingUid : nodeUidSet) { const auto& connection = mRawGraph.getEdgeProperty({proceedingUid, nodeUID}); - bool toBeReturned = false; + bool toBeReturned = false; - for(auto& t : dependencyTypes){ - if(t == connection.getType() ){ - toBeReturned = true; - break ; + for (auto& t : dependencyTypes) { + if (t == connection.getType()) { + toBeReturned = true; + break; } } - if(!toBeReturned){ - continue ; + if (!toBeReturned) { + continue; } auto& proceedingNode = mRawGraph.getVertexProperty(proceedingUid); @@ -135,7 +139,7 @@ auto Graph::getProceedingGraphNodes(const GraphNode& grap return nodes; } -auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, +auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, const std::vector& dependencyTypes) -> std::vector { std::vector nodes; @@ -144,17 +148,17 @@ auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, auto nodeUidSet = mRawGraph.outNeighbors(nodeUID); for (auto&& subsequentUID : nodeUidSet) { const auto& connection = mRawGraph.getEdgeProperty({nodeUID, subsequentUID}); - bool toBeReturned = false; + bool toBeReturned = false; - for(auto& t : dependencyTypes){ - if(t == connection.getType() ){ - toBeReturned = true; - break ; + for (auto& t : dependencyTypes) { + if (t == connection.getType()) { + toBeReturned = true; + break; } } - if(!toBeReturned){ - continue ; + if (!toBeReturned) { + continue; } auto& subsequentNode = mRawGraph.getVertexProperty(subsequentUID); nodes.push_back(&subsequentNode); @@ -542,7 +546,8 @@ auto Graph::helpComputeScheduling_02_events(Bfs& bfs) -> void } }); } -auto Graph::ioToDot(const std::string& /*fame*/) -> void + +auto Graph::ioToDot(const std::string& fname, const std::string& graphName) -> void { auto vertexLabel = [&](size_t v) -> std::string { auto& node = mRawGraph.getVertexProperty(v); @@ -555,39 +560,42 @@ auto Graph::ioToDot(const std::string& /*fame*/) -> void return edgeMeta.getLabel(); }; -//// auto edgeLabelProperty = [&](const std::pair& edge) -//// -> std::string { -////// const auto& metaEdge = clone.getEdgeProperty(edge); -////// if (metaEdge.m_isSchedulingEdge) { -////// // return "style=dashed, color=\"#2A9D8F\""; -////// return "style=dashed, color=\"#F4A261\", penwidth=7"; -////// } -////// return "color=\"#d9d9d9\", penwidth=7"; -//// }; -// -// auto vertexLabelProperty = [&](const size_t& v) { -// if (v == m_finalNodeId() || (v == m_rootNodeId())) { -// return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; -// } -// const auto& metaNode = clone.getVertexProperty(v); -// if (metaNode.isHu()) { -// return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; -// } -// if (metaNode.isSync()) { -// return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; -// } -// -// if (metaNode.isMap()) { -// return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; -// } -// if (metaNode.isReduce()) { -// return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; -// } -// if (metaNode.isStencil()) { -// return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; -// } -// return ""; -// }; + //// auto edgeLabelProperty = [&](const std::pair& edge) + //// -> std::string { + ////// const auto& metaEdge = clone.getEdgeProperty(edge); + ////// if (metaEdge.m_isSchedulingEdge) { + ////// // return "style=dashed, color=\"#2A9D8F\""; + ////// return "style=dashed, color=\"#F4A261\", penwidth=7"; + ////// } + ////// return "color=\"#d9d9d9\", penwidth=7"; + //// }; + // + // auto vertexLabelProperty = [&](const size_t& v) { + // if (v == m_finalNodeId() || (v == m_rootNodeId())) { + // return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; + // } + // const auto& metaNode = clone.getVertexProperty(v); + // if (metaNode.isHu()) { + // return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + // } + // if (metaNode.isSync()) { + // return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + // } + // + // if (metaNode.isMap()) { + // return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; + // } + // if (metaNode.isReduce()) { + // return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; + // } + // if (metaNode.isStencil()) { + // return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; + // } + // return ""; + // }; + mRawGraph.exportDotFile(fname + ".dot", graphName, vertexLabel, edgeLabel /*, + vertexLabelProperty, edgeLabelProperty*/ + ); } diff --git a/libNeonSet/src/set/container/graph/Bfs.cpp b/libNeonSet/src/set/container/graph/Bfs.cpp index 01720d54..12a64697 100644 --- a/libNeonSet/src/set/container/graph/Bfs.cpp +++ b/libNeonSet/src/set/container/graph/Bfs.cpp @@ -56,5 +56,9 @@ auto Bfs::getLevelWidth(int levelIdx) const return int(data.at(levelIdx).size()); } +auto Bfs::clear() -> void +{ + data.clear(); +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 0b3f3467..5bfcc022 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -22,7 +22,7 @@ GraphDependency::GraphDependency(GraphDependencyType type) auto GraphDependency::getLabel() -> std::string { - return GraphDependencyTypeUtil::toString(getType()) + return GraphDependencyTypeUtil::toString(getType()); } } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 2edeac83..711f7aa3 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -1,5 +1,6 @@ #include "Neon/set/container/graph/GraphNode.h" #include "Neon/set/container/ContainerExecutionType.h" +#include "Neon/set/container/AnchorContainer.h" namespace Neon::set::container { @@ -11,6 +12,7 @@ auto GraphNode::newBeginNode() -> GraphNode { GraphNode node; node.mGraphNodeOrganization.setUid(GraphData::beginUid); + node.mContainer = Neon::set::Container::factoryAnchor("Begin"); return node; } @@ -18,6 +20,7 @@ auto GraphNode::newEndNode() -> GraphNode { GraphNode node; node.mGraphNodeOrganization.setUid(GraphData::endUid); + node.mContainer = Neon::set::Container::factoryAnchor("End"); return node; } From 16f4e5d363e99ff506049c963c74b75331e06d32 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Mon, 22 Aug 2022 14:23:22 -0400 Subject: [PATCH 22/67] WIP --- libNeonDomain/tests/unit/CMakeLists.txt | 1 - libNeonSet/tests/unit/CMakeLists.txt | 3 ++- .../tests/unit/setUt_containerGraph/CMakeLists.txt | 5 ++++- .../setUt_containerGraph/src/setUt_containerGraph_kernels.h | 0 .../setUt_containerGraph/src/setUt_containerGraph_main.cpp | 0 .../src/setUt_containerGraph_mapStencilMap.cu | 0 .../src/setUt_containerGraph_runHelper.h | 0 7 files changed, 6 insertions(+), 3 deletions(-) rename {libNeonDomain => libNeonSet}/tests/unit/setUt_containerGraph/CMakeLists.txt (82%) rename {libNeonDomain => libNeonSet}/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h (100%) rename {libNeonDomain => libNeonSet}/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp (100%) rename {libNeonDomain => libNeonSet}/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu (100%) rename {libNeonDomain => libNeonSet}/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h (100%) diff --git a/libNeonDomain/tests/unit/CMakeLists.txt b/libNeonDomain/tests/unit/CMakeLists.txt index e1d90515..b58cbddb 100644 --- a/libNeonDomain/tests/unit/CMakeLists.txt +++ b/libNeonDomain/tests/unit/CMakeLists.txt @@ -10,4 +10,3 @@ add_subdirectory("gUt_tools") add_subdirectory("gUt_vtk") add_subdirectory("gUt_bGrid") -add_subdirectory("setUt_containerGraph") diff --git a/libNeonSet/tests/unit/CMakeLists.txt b/libNeonSet/tests/unit/CMakeLists.txt index 342a9d53..a5e3a095 100644 --- a/libNeonSet/tests/unit/CMakeLists.txt +++ b/libNeonSet/tests/unit/CMakeLists.txt @@ -4,4 +4,5 @@ add_subdirectory("setUt_gpuSet") add_subdirectory("setUt_gpuSetNvcc") add_subdirectory("setUt_memMirrorSet") add_subdirectory("setUt_patterns") -add_subdirectory("setUt_Replica") \ No newline at end of file +add_subdirectory("setUt_Replica") +add_subdirectory("setUt_containerGraph") diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/CMakeLists.txt b/libNeonSet/tests/unit/setUt_containerGraph/CMakeLists.txt similarity index 82% rename from libNeonDomain/tests/unit/setUt_containerGraph/CMakeLists.txt rename to libNeonSet/tests/unit/setUt_containerGraph/CMakeLists.txt index cac19ef1..0b439d70 100644 --- a/libNeonDomain/tests/unit/setUt_containerGraph/CMakeLists.txt +++ b/libNeonSet/tests/unit/setUt_containerGraph/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.19 FATAL_ERROR) SET(APP "setUt_containerGraph") file(GLOB_RECURSE SrcFiles src/*.*) +SET(APP, "setUt_containerGraph") add_executable(${APP} ${SrcFiles}) target_link_libraries(${APP} @@ -11,7 +12,9 @@ target_link_libraries(${APP} set_target_properties(${APP} PROPERTIES CUDA_SEPARABLE_COMPILATION ON CUDA_RESOLVE_DEVICE_SYMBOLS ON) -set_target_properties(${APP} PROPERTIES FOLDER "libNeonSkeleton") + +set_target_properties(${APP} PROPERTIES FOLDER "libNeonSet") + source_group(TREE ${CMAKE_CURRENT_LIST_DIR} PREFIX "${APP}" FILES ${SrcFiles}) add_test(NAME ${APP} COMMAND ${APP}) \ No newline at end of file diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h similarity index 100% rename from libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp similarity index 100% rename from libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_main.cpp diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu similarity index 100% rename from libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu diff --git a/libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h similarity index 100% rename from libNeonDomain/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h From 1583db75654b7aac993e82ef061e43baeee3c6e6 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Tue, 23 Aug 2022 09:03:06 -0400 Subject: [PATCH 23/67] WIP --- libNeonCore/include/Neon/core/types/digraph.h | 1 + .../include/Neon/set/container/ContainerAPI.h | 9 ++- .../Neon/set/container/DeviceContainer.h | 17 ++++-- .../set/container/DeviceManagedContainer.h | 14 ++++- libNeonSet/include/Neon/set/container/Graph.h | 2 +- .../Neon/set/container/HostManagedContainer.h | 2 + .../Neon/set/container/graph/GraphNode.h | 5 +- libNeonSet/src/set/container/ContainerAPI.cpp | 32 ++++++++-- libNeonSet/src/set/container/Graph.cpp | 57 ++++++------------ .../src/set/container/graph/GraphNode.cpp | 60 ++++++++++++++++--- .../src/setUt_containerGraph_mapStencilMap.cu | 22 +++---- 11 files changed, 147 insertions(+), 74 deletions(-) diff --git a/libNeonCore/include/Neon/core/types/digraph.h b/libNeonCore/include/Neon/core/types/digraph.h index 2e86f575..bc95e911 100644 --- a/libNeonCore/include/Neon/core/types/digraph.h +++ b/libNeonCore/include/Neon/core/types/digraph.h @@ -337,6 +337,7 @@ class DiGraph return mVprop.at(v); } + /** * Set the vertex property * diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index b34cd205..76ff45f7 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -3,8 +3,8 @@ #include "Neon/set/container/ContainerOperationType.h" #include "Neon/set/container/ContainerPatternType.h" -#include "Neon/set/container/ContainerExecutionType.h" #include "Neon/set/DevSet.h" +#include "Neon/set/container/ContainerExecutionType.h" #include "Neon/set/dependencyTools/DataParsing.h" #include "functional" @@ -123,16 +123,15 @@ struct ContainerAPI */ auto setContainerOperationType(Neon::set::ContainerOperationType containerType) -> void; - /** - * Set the Pattern type for the container - */ - auto setContainerPatternType(Neon::set::ContainerPatternType containerType) -> void; /** * Set the DataView support for the container */ auto setDataViewSupport(DataViewSupport dataViewSupport) -> void; + auto setContainerPattern(const std::vector& tokens) -> void; + + bool mParsingDataUpdated = false; private: std::vector mParsed; diff --git a/libNeonSet/include/Neon/set/container/DeviceContainer.h b/libNeonSet/include/Neon/set/container/DeviceContainer.h index 5a80bf30..c89b5852 100644 --- a/libNeonSet/include/Neon/set/container/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceContainer.h @@ -39,6 +39,8 @@ struct DeviceContainer : ContainerAPI setDataViewSupport(dataViewSupport); initLaunchParameters(dataIteratorContainer, blockSize, shMemSizeFun); + + this->parse(); } auto initLaunchParameters(const DataIteratorContainerT& dataIteratorContainer, @@ -78,12 +80,19 @@ struct DeviceContainer : ContainerAPI auto parse() -> const std::vector& override { - auto parser = newParser(); - this->m_loadingLambda(parser); + if (!this->mParsingDataUpdated) { + auto parser = newParser(); + this->m_loadingLambda(parser); + this->mParsingDataUpdated = true; + + this->setContainerPattern(this->getTokens()); + } return getTokens(); } - auto getHostContainer() -> std::shared_ptr final + + auto + getHostContainer() -> std::shared_ptr final { NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); } @@ -129,7 +138,7 @@ struct DeviceContainer : ContainerAPI const Neon::Backend& bk = m_dataIteratorContainer.getBackend(); Neon::set::KernelConfig kernelConfig(dataView, bk, streamIdx, this->getLaunchParameters(dataView)); - if (ContainerExecutionType::device == this->getContainerExecutionType()) { + if (ContainerExecutionType::device == this->getContainerExecutionType()) { bk.devSet().template kernelLambdaWithIterator( setIdx, kernelConfig, diff --git a/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h index ffb06a44..f8e9cdec 100644 --- a/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h @@ -34,6 +34,9 @@ struct DeviceManagedContainer : ContainerAPI setContainerExecutionType(ContainerExecutionType::deviceManaged); setDataViewSupport(dataViewSupport); setName(name); + + this->parse(); + } auto newLoader(Neon::DeviceType devE, @@ -62,8 +65,13 @@ struct DeviceManagedContainer : ContainerAPI auto parse() -> const std::vector& override { Neon::SetIdx setIdx(0); - auto parser = newParser(); - this->mLoadingLambda(setIdx, parser); + if (!this->mParsingDataUpdated) { + auto parser = newParser(); + this->m_loadingLambda(setIdx, parser); + this->mParsingDataUpdated = true; + + this->setContainerPattern(this->getTokens()); + } return getTokens(); } @@ -120,4 +128,4 @@ struct DeviceManagedContainer : ContainerAPI DataContainer mDataContainer; }; -} // namespace Neon +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index a5d4863f..48c46026 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -89,7 +89,7 @@ struct Graph */ auto execute() -> void; - auto ioToDot(const std::string& fname, const std::string& graphName) -> void; + auto ioToDot(const std::string& fname, const std::string& graphName, bool debug) -> void; protected: diff --git a/libNeonSet/include/Neon/set/container/HostManagedContainer.h b/libNeonSet/include/Neon/set/container/HostManagedContainer.h index d745f85d..20c1b306 100644 --- a/libNeonSet/include/Neon/set/container/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/HostManagedContainer.h @@ -44,6 +44,8 @@ struct HostManagedContainer : ContainerAPI setName(name); mPreSyncType = preSyncType; mPostSyncType = presSyncType; + + this->parse(); } auto newLoader(Neon::DeviceType devE, diff --git a/libNeonSet/include/Neon/set/container/graph/GraphNode.h b/libNeonSet/include/Neon/set/container/graph/GraphNode.h index c6806947..a0ad22d8 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphNode.h @@ -8,7 +8,9 @@ namespace Neon::set::container { struct GraphNode { - std::string getLabel(); + std::string getLabel(bool debug); + + std::string getLabelProperty(); public: GraphNode(); @@ -77,6 +79,7 @@ struct GraphNode Container mContainer /**< Any Neon container */; GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; + ContainerPatternType getContainerpatternType() const; }; } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/ContainerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp index d314cd1c..0ad988ee 100644 --- a/libNeonSet/src/set/container/ContainerAPI.cpp +++ b/libNeonSet/src/set/container/ContainerAPI.cpp @@ -28,6 +28,12 @@ auto ContainerAPI::getTokens() const return mParsed; } +//auto ContainerAPI::clearTokens() +// -> void +//{ +// mParsed.clear(); +//} + auto ContainerAPI::getTokenRef() -> std::vector& { @@ -60,6 +66,27 @@ auto ContainerAPI::setDataViewSupport(ContainerAPI::DataViewSupport dataViewSupp mDataViewSupport = dataViewSupport; } +auto ContainerAPI::setContainerPattern(const std::vector& tokens) -> void +{ + Neon::set::ContainerPatternType patternType = Neon::set::ContainerPatternType::map; + + for (const auto& token : tokens) { + if (token.compute() == Neon::Compute::STENCIL) { + if (patternType == Neon::set::ContainerPatternType::reduction) { + NEON_THROW_UNSUPPORTED_OPTION("Mixing reduction and stencil patterns is currently not supported"); + } + patternType = Neon::set::ContainerPatternType::stencil; + } + if (token.compute() == Neon::Compute::REDUCE) { + if (patternType == Neon::set::ContainerPatternType::stencil) { + NEON_THROW_UNSUPPORTED_OPTION("Mixing reduction and stencil patterns is currently not supported"); + } + patternType = Neon::set::ContainerPatternType::reduction; + } + } + this->mContainerPatternType = patternType; +} + auto ContainerAPI::toLog(uint64_t uid) -> void { std::stringstream listOfTokes; @@ -96,9 +123,6 @@ auto ContainerAPI::setContainerOperationType(ContainerOperationType containerTyp { mContainerOperationType = containerType; } -auto ContainerAPI::setContainerPatternType(ContainerPatternType containerType) -> void -{ - mContainerPatternType = containerType; -} + } // namespace Neon::set::internal diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 19eda67d..ae214630 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -547,11 +547,11 @@ auto Graph::helpComputeScheduling_02_events(Bfs& bfs) -> void }); } -auto Graph::ioToDot(const std::string& fname, const std::string& graphName) -> void +auto Graph::ioToDot(const std::string& fname, const std::string& graphName, bool debug) -> void { auto vertexLabel = [&](size_t v) -> std::string { auto& node = mRawGraph.getVertexProperty(v); - return node.getLabel(); + return node.getLabel(debug); }; auto edgeLabel = [&](const std::pair& edge) @@ -560,42 +560,23 @@ auto Graph::ioToDot(const std::string& fname, const std::string& graphName) -> v return edgeMeta.getLabel(); }; - //// auto edgeLabelProperty = [&](const std::pair& edge) - //// -> std::string { - ////// const auto& metaEdge = clone.getEdgeProperty(edge); - ////// if (metaEdge.m_isSchedulingEdge) { - ////// // return "style=dashed, color=\"#2A9D8F\""; - ////// return "style=dashed, color=\"#F4A261\", penwidth=7"; - ////// } - ////// return "color=\"#d9d9d9\", penwidth=7"; - //// }; - // - // auto vertexLabelProperty = [&](const size_t& v) { - // if (v == m_finalNodeId() || (v == m_rootNodeId())) { - // return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; - // } - // const auto& metaNode = clone.getVertexProperty(v); - // if (metaNode.isHu()) { - // return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - // } - // if (metaNode.isSync()) { - // return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - // } - // - // if (metaNode.isMap()) { - // return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; - // } - // if (metaNode.isReduce()) { - // return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; - // } - // if (metaNode.isStencil()) { - // return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; - // } - // return ""; - // }; - mRawGraph.exportDotFile(fname + ".dot", graphName, vertexLabel, edgeLabel /*, - vertexLabelProperty, edgeLabelProperty*/ - ); + auto edgeLabelProperty = [&](const std::pair& edge) + -> std::string { + auto& edgeMeta = mRawGraph.getEdgeProperty(edge); + + if (edgeMeta.getType() == GraphDependencyType::scheduling) { + // return "style=dashed, color=\"#2A9D8F\""; + return "style=dashed, color=\"#F4A261\", penwidth=7"; + } + return "color=\"#d9d9d9\", penwidth=7"; + }; + + auto vertexLabelProperty = [&](const size_t& v) { + auto& node = mRawGraph.getVertexProperty(v); + return node.getLabelProperty(); + }; + mRawGraph.exportDotFile(fname + ".dot", graphName, vertexLabel, edgeLabel, + vertexLabelProperty, edgeLabelProperty); } diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 711f7aa3..49b02d96 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -1,6 +1,6 @@ #include "Neon/set/container/graph/GraphNode.h" -#include "Neon/set/container/ContainerExecutionType.h" #include "Neon/set/container/AnchorContainer.h" +#include "Neon/set/container/ContainerExecutionType.h" namespace Neon::set::container { @@ -105,11 +105,18 @@ auto GraphNode::helpGetDotInfo() -> std::string } NEON_DEV_UNDER_CONSTRUCTION(""); } + auto GraphNode::getContainerOperationType() const -> Neon::set::ContainerOperationType { return getContainer().getContainerInterface().getContainerOperationType(); } -auto GraphNode::getLabel() -> std::string + +auto GraphNode::getContainerpatternType() const -> Neon::set::ContainerPatternType +{ + return getContainer().getContainerInterface().getContainerPatternType(); +} + +auto GraphNode::getLabel(bool debug) -> std::string { if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { if (this->getGraphData().beginUid == getGraphData().getUid()) { @@ -122,12 +129,14 @@ auto GraphNode::getLabel() -> std::string } if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { std::stringstream s; - s << "Container " - " - Name: " - << getContainer().getName(); - s << " - UID: " << getContainer().getUid(); - s << " - Execution: " << getContainer().getContainerExecutionType(); - s << " - DataView: " << getScheduling().getDataView(); + if (debug) { + s << "Container " << getContainer().getName(); + s << "\\l - UID: " << getContainer().getUid(); + s << "\\l - Execution: " << getContainer().getContainerExecutionType(); + s << "\\l - DataView: " << getScheduling().getDataView(); + } else { + s << getContainer().getName(); + } return s.str(); } if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { @@ -150,4 +159,39 @@ auto GraphNode::getLabel() -> std::string return std::string(); } + +auto GraphNode::getLabelProperty() -> std::string +{ + if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { + if (this->getGraphData().beginUid == getGraphData().getUid()) { + return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; + } + if (this->getGraphData().endUid == getGraphData().getUid()) { + return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; + } + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { + auto pattern = getContainerpatternType(); + if (pattern == Neon::set::ContainerPatternType::map) { + return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; + } + if (pattern == Neon::set::ContainerPatternType::stencil) { + return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; + } + if (pattern == Neon::set::ContainerPatternType::reduction) { + return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; + } + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } + if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; + } + NEON_DEV_UNDER_CONSTRUCTION(""); + return std::string(); +} + } // namespace Neon::set::container diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu index 3b7c491c..f583911c 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu @@ -58,14 +58,16 @@ void ThreeIndependentMapsTest(TestData& data) graph.addNode(UserTools::axpy(fR, W, Y)); graph.addNode(UserTools::axpy(fR, W, Z)); - graph.ioToDot(appName, "UserGraph"); - -// timer.start(); -// for (int i = 0; i < nIterations; i++) { -// skl.run(); -// } -// data.getBackend().syncAll(); -// timer.stop(); + graph.ioToDot(appName, "UserGraph", false); + graph.ioToDot(appName + "-debug", "UserGraph", true); + + + // timer.start(); + // for (int i = 0; i < nIterations; i++) { + // skl.run(); + // } + // data.getBackend().syncAll(); + // timer.stop(); } { // Golden data @@ -118,10 +120,10 @@ int getNGpus() } } // namespace -TEST(MapStencilMap_NoOCC, eGrid) +TEST(ThreeIndependentMaps, eGrid) { int nGpus = getNGpus(); using Grid = Neon::domain::internal::eGrid::eGrid; using Type = int32_t; - runAllTestConfiguration("eGrid_t", ThreeIndependentMaps, nGpus, 1); + runOneTestConfiguration("eGrid_t", ThreeIndependentMaps, 1, 1); } From bd57943868157378c5c1ece59b0a5b0270b748e6 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Tue, 23 Aug 2022 09:43:46 -0400 Subject: [PATCH 24/67] WIP --- libNeonSet/include/Neon/set/container/Graph.h | 4 +- libNeonSet/src/set/container/Graph.cpp | 13 +- .../src/set/container/graph/GraphNode.cpp | 15 ++- ...Ut_containerGraph_ThreeIndependentMaps.cu} | 11 +- .../setUt_containerGraph_ThreePipedMaps.cu | 124 ++++++++++++++++++ .../src/setUt_containerGraph_kernels.h | 19 +-- 6 files changed, 160 insertions(+), 26 deletions(-) rename libNeonSet/tests/unit/setUt_containerGraph/src/{setUt_containerGraph_mapStencilMap.cu => setUt_containerGraph_ThreeIndependentMaps.cu} (90%) create mode 100644 libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cu diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 48c46026..246643e9 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -42,7 +42,7 @@ struct Graph * Adds a dependency between two nodes of the graph */ auto addNodeInBetween(const GraphNode& nodeA, - Container& containerB, + Container containerB, const GraphNode& nodeC, GraphDependencyType ab = GraphDependencyType::user, GraphDependencyType bc = GraphDependencyType::user) -> GraphNode&; @@ -101,7 +101,7 @@ struct Graph /** * Remove redundant dependencies */ - auto helpRemoteRedundantDependencies() -> void; + auto helpRemoveRedundantDependencies() -> void; /** * Compute BFS diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index ae214630..6c4da878 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -26,7 +26,7 @@ auto Graph::getEndNode() const -> const GraphNode& } auto Graph::addNodeInBetween(const GraphNode& nodeA, - Container& containerB, + Container containerB, const GraphNode& nodeC, const GraphDependencyType ab, const GraphDependencyType bc) -> GraphNode& @@ -208,7 +208,7 @@ auto Graph::helpInvalidateScheduling() -> void mSchedulingStatusIsValid = false; } -auto Graph::helpRemoteRedundantDependencies() -> void +auto Graph::helpRemoveRedundantDependencies() -> void { // Vectors of edges to be removed std::vector> edgesToBeRemoved; @@ -217,7 +217,7 @@ auto Graph::helpRemoteRedundantDependencies() -> void // For each node do: // Check node's children - const auto& children = helpGetOutNeighbors(visitingNode); + const auto& children = helpGetOutNeighbors(visitingNode, false); if (children.size() <= 1) { // If no more than one, move to the next node // Nothing to do for the visiting node as there are no redundant paths @@ -226,7 +226,7 @@ auto Graph::helpRemoteRedundantDependencies() -> void } // Start checking for redundant paths for (const auto& targetChild : children) { - if (helpGetInEdges(targetChild).size() <= 1) { + if (helpGetInEdges(targetChild, false).size() <= 1) { // This targetChild can only be reached by one father // No redundant path here continue; @@ -287,7 +287,8 @@ auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, auto& edgeProp = mRawGraph.getEdgeProperty(edge); for (auto& depType : dependencyTypes) { if (depType == edgeProp.getType()) { - if (mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor && filteredOut) { + bool isAnchor = mRawGraph.getVertexProperty(edge.second).getContainerOperationType() == Neon::set::ContainerOperationType::anchor; + if (isAnchor && filteredOut) { break; } outNgh.insert(edge.second); @@ -549,6 +550,8 @@ auto Graph::helpComputeScheduling_02_events(Bfs& bfs) -> void auto Graph::ioToDot(const std::string& fname, const std::string& graphName, bool debug) -> void { + this->helpRemoveRedundantDependencies(); + auto vertexLabel = [&](size_t v) -> std::string { auto& node = mRawGraph.getVertexProperty(v); return node.getLabel(debug); diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 49b02d96..18292dac 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -120,10 +120,20 @@ auto GraphNode::getLabel(bool debug) -> std::string { if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { if (this->getGraphData().beginUid == getGraphData().getUid()) { - return "Begin"; + std::stringstream s; + s << "Begin "; + if (debug) { + s << "\\l - Graph Node id: " << this->getGraphData().getUid(); + } + return s.str(); } if (this->getGraphData().endUid == getGraphData().getUid()) { - return "End"; + std::stringstream s; + s << "End "; + if (debug) { + s << "\\l - Graph Node id: " << this->getGraphData().getUid(); + } + return s.str(); } NEON_THROW_UNSUPPORTED_OPERATION(""); } @@ -131,6 +141,7 @@ auto GraphNode::getLabel(bool debug) -> std::string std::stringstream s; if (debug) { s << "Container " << getContainer().getName(); + s << "\\l - Graph Node id: " << this->getGraphData().getUid(); s << "\\l - UID: " << getContainer().getUid(); s << "\\l - Execution: " << getContainer().getContainerExecutionType(); s << "\\l - DataView: " << getScheduling().getDataView(); diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cu similarity index 90% rename from libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cu index f583911c..2fbb707b 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_mapStencilMap.cu +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cu @@ -47,16 +47,11 @@ void ThreeIndependentMapsTest(TestData& data) auto& Z = data.getField(FieldNames::Z); auto& W = data.getField(FieldNames::W); - std::vector ops{ - UserTools::axpy(fR, Y, X), - UserTools::laplace(X, Y), - UserTools::axpy(fR, Y, Y)}; - Neon::set::container::Graph graph; - graph.addNode(UserTools::axpy(fR, W, X)); - graph.addNode(UserTools::axpy(fR, W, Y)); - graph.addNode(UserTools::axpy(fR, W, Z)); + graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); + graph.addNode(UserTools::axpy(fR, W, Y, "nodeB")); + graph.addNode(UserTools::axpy(fR, W, Z, "nodeC")); graph.ioToDot(appName, "UserGraph", false); graph.ioToDot(appName + "-debug", "UserGraph", true); diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cu new file mode 100644 index 00000000..e4fc7e3c --- /dev/null +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cu @@ -0,0 +1,124 @@ +#include "Neon/core/types/chrono.h" + +#include "Neon/set/Containter.h" + +#include "Neon/domain/aGrid.h" +#include "Neon/domain/bGrid.h" +#include "Neon/domain/dGrid.h" +#include "Neon/domain/eGrid.h" +#include "Neon/domain/tools/Geometries.h" +#include "Neon/domain/tools/TestData.h" + +#include "Neon/skeleton/Options.h" +#include "Neon/skeleton/Skeleton.h" + +#include +#include + +#include "gtest/gtest.h" +#include "setUt_containerGraph_kernels.h" +#include "setUt_containerGraph_runHelper.h" + +#include "Neon/set/container/Graph.h" + +using namespace Neon::domain::tool::testing; +static const std::string testFilePrefix("setUt_containerGraph"); + +template +void ThreePippedMapsTest(TestData& data) +{ + using Type = typename TestData::Type; + + const std::string appName(testFilePrefix); + + const Type scalarVal = 2; + const int nIterations = 10; + + auto fR = data.getGrid().template newPatternScalar(); + fR() = scalarVal; + data.getBackend().syncAll(); + + data.resetValuesToRandom(1, 50); + Neon::Timer_sec timer; + + { // NEON + auto& X = data.getField(FieldNames::X); + auto& Y = data.getField(FieldNames::Y); + auto& Z = data.getField(FieldNames::Z); + auto& W = data.getField(FieldNames::W); + + Neon::set::container::Graph graph; + + auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); + graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, "nodeB"), nodeC); + + graph.ioToDot(appName, "UserGraph", false); + graph.ioToDot(appName + "-debug", "UserGraph", true); + + + // timer.start(); + // for (int i = 0; i < nIterations; i++) { + // skl.run(); + // } + // data.getBackend().syncAll(); + // timer.stop(); + } + + { // Golden data + auto time = timer.time(); + + Type dR = scalarVal; + auto& X = data.getIODomain(FieldNames::X); + auto& Y = data.getIODomain(FieldNames::Y); + + for (int i = 0; i < nIterations; i++) { + data.axpy(&dR, Y, X); + data.laplace(X, Y); + data.axpy(&dR, Y, Y); + } + } + bool isOk = data.compare(FieldNames::X); + isOk = isOk && data.compare(FieldNames::Y); + + /*{ // DEBUG + data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); + data.getField(FieldNames::X).ioToVtk("Field_X", "X"); + + data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); + data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); + }*/ + + ASSERT_TRUE(isOk); +} + +template +void ThreePippedMaps(TestData& data) +{ + ThreePippedMapsTest(data); +} + + +namespace { +int getNGpus() +{ + if (Neon::sys::globalSpace::gpuSysObjStorage.numDevs() > 0) { + int maxGPUs = Neon::set::DevSet::maxSet().setCardinality(); + if (maxGPUs > 1) { + return maxGPUs; + } else { + return 3; + } + } else { + return 0; + } +} +} // namespace + +TEST(ThreePippedMaps, eGrid) +{ + int nGpus = getNGpus(); + using Grid = Neon::domain::internal::eGrid::eGrid; + using Type = int32_t; + runOneTestConfiguration("eGrid_t", ThreePippedMaps, 1, 1); +} diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h index 58a6553e..035b5488 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h @@ -17,7 +17,7 @@ auto xpy(const Field& x, Field& y) -> Neon::set::Container { auto Kontainer = x.getGrid().getContainer( - "xpy", [&](Neon::set::Loader & L) -> auto { + "xpy", [&](Neon::set::Loader & L) -> auto{ auto& xLocal = L.load(x); auto& yLocal = L.load(y); return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { @@ -35,16 +35,16 @@ auto aInvXpY(const Neon::template PatternScalar& fR, Field& y) -> Neon::set::Container { auto Kontainer = x.getGrid().getContainer( - "AXPY", [&](Neon::set::Loader & L) -> auto { + "AXPY", [&](Neon::set::Loader & L) -> auto{ auto& xLocal = L.load(x); auto& yLocal = L.load(y); auto fRLocal = L.load(fR); const auto fRVal = fRLocal(); return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { - //printf("%d yLocal.cardinality()\n", yLocal.cardinality()); + // printf("%d yLocal.cardinality()\n", yLocal.cardinality()); for (int i = 0; i < yLocal.cardinality(); i++) { - //printf("%d %d (%d) x\n", e, xLocal(e, i), i); + // printf("%d %d (%d) x\n", e, xLocal(e, i), i); yLocal(e, i) += (1.0 / fRVal) * xLocal(e, i); } }; @@ -55,19 +55,20 @@ auto aInvXpY(const Neon::template PatternScalar& fR, template auto axpy(const Neon::template PatternScalar& fR, const Field& x, - Field& y) -> Neon::set::Container + Field& y, + const std::string& name) -> Neon::set::Container { auto Kontainer = x.getGrid().getContainer( - "AXPY", [&](Neon::set::Loader & L) -> auto { + "AXPY" + name, [&](Neon::set::Loader & L) -> auto{ auto& xLocal = L.load(x); auto& yLocal = L.load(y); auto fRLocal = L.load(fR); const auto fRVal = fRLocal(); return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { - //printf("%d yLocal.cardinality()\n", yLocal.cardinality()); + // printf("%d yLocal.cardinality()\n", yLocal.cardinality()); for (int i = 0; i < yLocal.cardinality(); i++) { - //printf("%d %d (%d) x\n", e, xLocal(e, i), i); + // printf("%d %d (%d) x\n", e, xLocal(e, i), i); yLocal(e, i) += fRVal * xLocal(e, i); } }; @@ -81,7 +82,7 @@ auto laplace(const Field& x, size_t sharedMem = 0) -> Neon::set::Container { auto Kontainer = x.getGrid().getContainer( - "Laplace", [&](Neon::set::Loader & L) -> auto { + "Laplace", [&](Neon::set::Loader & L) -> auto{ auto& xLocal = L.load(x, Neon::Compute::STENCIL); auto& yLocal = L.load(y); From b62fb87568fd07b8cdd72b2ca3e8abe3fb3cbf8e Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Tue, 23 Aug 2022 21:48:25 -0400 Subject: [PATCH 25/67] WIP --- libNeonSet/include/Neon/set/Containter.h | 5 +- libNeonSet/include/Neon/set/Containter_imp.h | 2 + .../include/Neon/set/container/ContainerAPI.h | 9 +- .../set/container/ContainerExecutionType.h | 7 +- .../set/container/ContainerOperationType.h | 13 +- .../Neon/set/container/ContainerPatternType.h | 1 + libNeonSet/include/Neon/set/container/Graph.h | 37 +++-- .../Neon/set/container/GraphContainer.h | 54 +++++++ libNeonSet/src/set/Containter.cpp | 11 ++ libNeonSet/src/set/container/ContainerAPI.cpp | 18 ++- .../set/container/ContainerExecutionType.cpp | 16 +- .../set/container/ContainerOperationType.cpp | 4 + .../set/container/ContainerPatternType.cpp | 10 +- libNeonSet/src/set/container/Graph.cpp | 30 +++- .../src/set/container/GraphContainer.cpp | 78 ++++++++++ .../src/setUt_containerGraph_NestedGraphs.cu | 140 ++++++++++++++++++ 16 files changed, 405 insertions(+), 30 deletions(-) create mode 100644 libNeonSet/include/Neon/set/container/GraphContainer.h create mode 100644 libNeonSet/src/set/container/GraphContainer.cpp create mode 100644 libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cu diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index cfc8515a..b9114e14 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -15,7 +15,6 @@ namespace Neon::set { struct Container { public: - Container() = default; /** @@ -97,6 +96,10 @@ struct Container const UserLoadingLambdaT& f) -> Container; + static auto factoryGraph(const std::string& name, + const container::Graph& graph, + std::function loadingLambda) -> Container; + static auto factoryDeviceThenHostManaged(const std::string& name, Container& device, Container& host) diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h index e4cc92da..3c401836 100644 --- a/libNeonSet/include/Neon/set/Containter_imp.h +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -11,6 +11,8 @@ #include "Neon/set/container/HostManagedContainer.h" #include "Neon/set/container/OldDeviceManagedContainer.h" +#include "Neon/set/container/GraphContainer.h" + namespace Neon::set { diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index 76ff45f7..cc1a14fb 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -10,6 +10,9 @@ #include "functional" #include "type_traits" +namespace Neon::set::container { +struct Graph; +} namespace Neon::set::internal { @@ -23,7 +26,7 @@ struct ContainerAPI enum struct DataViewSupport { on, - off + off, }; /** @@ -44,6 +47,8 @@ struct ContainerAPI virtual auto getDeviceContainer() -> std::shared_ptr = 0; + virtual auto getGraph() -> const Neon::set::container::Graph&; + /** * Parse the input and output data for the kernel * @return @@ -133,6 +138,8 @@ struct ContainerAPI bool mParsingDataUpdated = false; + void setContainerPattern(ContainerPatternType patternType); + private: std::vector mParsed; std::string mName{"Anonymous"}; /**< Name of the Container */ diff --git a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h index 59de7508..2673c4e2 100644 --- a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h +++ b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h @@ -16,14 +16,15 @@ enum struct ContainerExecutionType device = 0 /** the operation of the containers are only for the device (note: device can be CPU too) */, deviceManaged = 1 /** manage version of the device type of Container, i.e. the launch is managed by the container itself. Useful to wrap calls to cuBlas operation for example*/, deviceThenHostManaged = 2, /** a container that stores operation on both device and host. For this type of Container a getHostContainer method is enabled to retrieved a container with the host code */ - hostManaged = 3, - none = 4 + hostManaged = 3 /** host managed container */, + graph = 4 /** A complex container */, + none = 5 }; struct ContainerExecutionTypeUtils { - static constexpr int nOptions = 4; + static constexpr int nOptions = 5; static auto toString(ContainerExecutionType option) -> std::string; static auto fromString(const std::string& option) -> ContainerExecutionType; diff --git a/libNeonSet/include/Neon/set/container/ContainerOperationType.h b/libNeonSet/include/Neon/set/container/ContainerOperationType.h index f77d0fda..09dd0fc8 100644 --- a/libNeonSet/include/Neon/set/container/ContainerOperationType.h +++ b/libNeonSet/include/Neon/set/container/ContainerOperationType.h @@ -13,16 +13,17 @@ namespace Neon::set { enum struct ContainerOperationType { - compute = 0 /**< Dependency generated by analyzing data dependency */, - halo = 1 /**< Hints for scheduling **/, - sync = 2 /**< User defined scheduling */, - anchor = 3 /**< Anchor node: begin or end */ + compute = 0 /**< Compute container, can be on host or device */, + graph = 1 /**< A graph based container */, + halo = 2 /**< Halo update container **/, + sync = 3 /**< Synchronization Container */, + anchor = 4 /**< Synchronization Container: begin or end */ }; struct ContainerOperationTypeUtils { - static constexpr int nOptions = 4; + static constexpr int nOptions = 5; /** * Convert type to string @@ -41,7 +42,7 @@ struct ContainerOperationTypeUtils }; -} // namespace Neon::set::internal +} // namespace Neon::set /** * operator<< */ diff --git a/libNeonSet/include/Neon/set/container/ContainerPatternType.h b/libNeonSet/include/Neon/set/container/ContainerPatternType.h index 09b6c955..4cd90e46 100644 --- a/libNeonSet/include/Neon/set/container/ContainerPatternType.h +++ b/libNeonSet/include/Neon/set/container/ContainerPatternType.h @@ -16,6 +16,7 @@ enum struct ContainerPatternType map = 0, stencil = 1, reduction = 2, + complex = 3, }; diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 246643e9..f0d7a062 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -17,26 +17,31 @@ struct Graph public: Graph(); + explicit Graph(Neon::Backend& bk); /** * Get a reference to the begin node */ - auto getBeginNode() const -> const GraphNode&; + auto getBeginNode() const + -> const Neon::set::container::GraphNode&; /** * Get a reference to the end node of the graph */ - auto getEndNode() const -> const GraphNode&; + auto getEndNode() const + -> const GraphNode&; /** * Adds a node between the begin and end nodes */ - auto addNode(const Container& container) -> GraphNode&; + auto addNode(const Container& container) + -> GraphNode&; /** * Remove Node */ - auto removeNode(GraphNode& gn) -> GraphNode; + auto removeNode(GraphNode& gn) + -> GraphNode; /** * Adds a dependency between two nodes of the graph @@ -45,20 +50,23 @@ struct Graph Container containerB, const GraphNode& nodeC, GraphDependencyType ab = GraphDependencyType::user, - GraphDependencyType bc = GraphDependencyType::user) -> GraphNode&; + GraphDependencyType bc = GraphDependencyType::user) + -> GraphNode&; /** * Adds a dependency between two node of the graph */ auto addDependency(const GraphNode& nodeA, const GraphNode& nodeB, - GraphDependencyType type) -> GraphDependency&; + GraphDependencyType type) + -> GraphDependency&; /** * Returns the dependency type between two nodes. */ auto getDependencyType(const GraphNode& nodeA, - const GraphNode& nodeB) -> GraphDependencyType; + const GraphNode& nodeB) + -> GraphDependencyType; /** * Clone a node and return a reference to the new clone. @@ -87,10 +95,18 @@ struct Graph /** * Execute the scheduling operation associated to the node */ - auto execute() -> void; + auto run(int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD); - auto ioToDot(const std::string& fname, const std::string& graphName, bool debug) -> void; + auto run(Neon::SetIdx setIdx, + int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD); + auto ioToDot(const std::string& fname, + const std::string& graphName, + bool debug) -> void; + + auto getBackend() const -> const Neon::Backend&; protected: /** @@ -192,6 +208,9 @@ struct Graph RawGraph mRawGraph; bool mSchedulingStatusIsValid; int mMaxNumberStreams; + + Backend mBackend; + bool mBackendIsSet = false; }; } // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h new file mode 100644 index 00000000..d9fc7956 --- /dev/null +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" + +namespace Neon::set::internal { +struct Graph; +/** + * Specialized implementation of KContainer_i + * + * + * @tparam DataContainer + * @tparam ComputeLambdaT + */ +struct GraphContainer : ContainerAPI +{ + public: + ~GraphContainer() override = default; + + /** + * User facing API to define a kernel + * @param data + * @param userLambda + */ + GraphContainer(const std::string& name, + const Neon::set::container::Graph& containerGraph, + std::function loadingLambda); + + auto newParser() -> Loader; + + auto parse() -> const std::vector& override; + + auto getGraph() -> const Neon::set::container::Graph& override; + + auto getHostContainer() -> std::shared_ptr override; + + auto getDeviceContainer() -> std::shared_ptr override; + /** + * Run container over streams + * @param streamIdx + * @param dataView + */ + auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + + auto run(Neon::SetIdx setIdx, + int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + + private: + std::function mLoadingLambda; + std::shared_ptr mGraph; +}; + +} // namespace Neon::set::internal diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index 74d808f6..a8e198cb 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -57,6 +57,7 @@ auto Container::factoryAnchor(const std::string& name) -> Container return Container(tmp); } + auto Container::getName() const -> const std::string& { @@ -119,5 +120,15 @@ Container::Container(std::shared_ptr&& contai // Empty } +auto Container::factoryGraph(const std::string& name, + const container::Graph& graph, + std::function loadingLambda) -> Container +{ + auto k = new Neon::set::internal::GraphContainer(name, graph, loadingLambda); + + std::shared_ptr tmp(k); + return Container(tmp); +} + } // namespace Neon::set diff --git a/libNeonSet/src/set/container/ContainerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp index 0ad988ee..dd514063 100644 --- a/libNeonSet/src/set/container/ContainerAPI.cpp +++ b/libNeonSet/src/set/container/ContainerAPI.cpp @@ -28,11 +28,11 @@ auto ContainerAPI::getTokens() const return mParsed; } -//auto ContainerAPI::clearTokens() -// -> void +// auto ContainerAPI::clearTokens() +// -> void //{ -// mParsed.clear(); -//} +// mParsed.clear(); +// } auto ContainerAPI::getTokenRef() -> std::vector& @@ -66,6 +66,11 @@ auto ContainerAPI::setDataViewSupport(ContainerAPI::DataViewSupport dataViewSupp mDataViewSupport = dataViewSupport; } +auto ContainerAPI::setContainerPattern(Neon::set::ContainerPatternType patternType) -> void +{ + this->mContainerPatternType = patternType; +} + auto ContainerAPI::setContainerPattern(const std::vector& tokens) -> void { Neon::set::ContainerPatternType patternType = Neon::set::ContainerPatternType::map; @@ -124,5 +129,10 @@ auto ContainerAPI::setContainerOperationType(ContainerOperationType containerTyp mContainerOperationType = containerType; } +auto ContainerAPI::getGraph() -> const Neon::set::container::Graph& +{ + NEON_THROW_UNSUPPORTED_OPERATION(); +} + } // namespace Neon::set::internal diff --git a/libNeonSet/src/set/container/ContainerExecutionType.cpp b/libNeonSet/src/set/container/ContainerExecutionType.cpp index c18f351d..60e701b1 100644 --- a/libNeonSet/src/set/container/ContainerExecutionType.cpp +++ b/libNeonSet/src/set/container/ContainerExecutionType.cpp @@ -21,6 +21,9 @@ auto ContainerExecutionTypeUtils::toString(ContainerExecutionType option) -> std case ContainerExecutionType::deviceThenHostManaged: { return "deviceThenHostManaged"; } + case ContainerExecutionType::graph: { + return "graph"; + } case ContainerExecutionType::none: { return "none"; } @@ -46,14 +49,23 @@ auto ContainerExecutionTypeUtils::getOptions() -> std::array opts = {ContainerExecutionType::device, ContainerExecutionType::deviceManaged, ContainerExecutionType::deviceThenHostManaged, - ContainerExecutionType::hostManaged}; + ContainerExecutionType::hostManaged, + ContainerExecutionType::graph}; return opts; } +auto ContainerExecutionTypeUtils::isExpandable(ContainerExecutionType option) -> bool +{ + if (option == ContainerExecutionType::graph || + option == ContainerExecutionType::deviceThenHostManaged) { + return true; + } + return false; +} + std::ostream& operator<<(std::ostream& os, Neon::set::ContainerExecutionType const& m) { return os << Neon::set::ContainerExecutionTypeUtils::toString(m); } } // namespace Neon::set - diff --git a/libNeonSet/src/set/container/ContainerOperationType.cpp b/libNeonSet/src/set/container/ContainerOperationType.cpp index 941c549f..5bb54670 100644 --- a/libNeonSet/src/set/container/ContainerOperationType.cpp +++ b/libNeonSet/src/set/container/ContainerOperationType.cpp @@ -12,6 +12,9 @@ auto ContainerOperationTypeUtils::toString(ContainerOperationType option) -> std case ContainerOperationType::compute: { return "compute"; } + case ContainerOperationType::graph: { + return "graph"; + } case ContainerOperationType::halo: { return "halo"; } @@ -41,6 +44,7 @@ auto ContainerOperationTypeUtils::fromString(const std::string& option) auto ContainerOperationTypeUtils::getOptions() -> std::array { std::array opts = {ContainerOperationType::compute, + ContainerOperationType::graph, ContainerOperationType::halo, ContainerOperationType::sync, ContainerOperationType::anchor}; diff --git a/libNeonSet/src/set/container/ContainerPatternType.cpp b/libNeonSet/src/set/container/ContainerPatternType.cpp index f6cec6dc..c256b681 100644 --- a/libNeonSet/src/set/container/ContainerPatternType.cpp +++ b/libNeonSet/src/set/container/ContainerPatternType.cpp @@ -18,6 +18,9 @@ auto ContainerPatternTypeUtils::toString(ContainerPatternType option) -> std::st case ContainerPatternType::reduction: { return "sync"; } + case ContainerPatternType::complex: { + return "complex"; + } } NEON_THROW_UNSUPPORTED_OPTION(""); } @@ -38,13 +41,14 @@ auto ContainerPatternTypeUtils::fromString(const std::string& option) auto ContainerPatternTypeUtils::getOptions() -> std::array { std::array opts = {ContainerPatternType::map, - ContainerPatternType::stencil, - ContainerPatternType::reduction}; + ContainerPatternType::stencil, + ContainerPatternType::reduction, + ContainerPatternType::complex}; return opts; } -} // namespace Neon::set::internal +} // namespace Neon::set std::ostream& operator<<(std::ostream& os, Neon::set::ContainerPatternType const& m) diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 6c4da878..ba72eb81 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -548,7 +548,9 @@ auto Graph::helpComputeScheduling_02_events(Bfs& bfs) -> void }); } -auto Graph::ioToDot(const std::string& fname, const std::string& graphName, bool debug) -> void +auto Graph::ioToDot(const std::string& fname, + const std::string& graphName, + bool debug) -> void { this->helpRemoveRedundantDependencies(); @@ -582,5 +584,31 @@ auto Graph::ioToDot(const std::string& fname, const std::string& graphName, bool vertexLabelProperty, edgeLabelProperty); } +Graph::Graph(Backend& bk) +{ + mBackend = bk; + mBackendIsSet = true; +} + +auto Graph::getBackend() const -> const Neon::Backend& +{ + if (mBackendIsSet) { + return mBackend; + } + NeonException ex("Graph"); + ex << "A backend was not set."; + NEON_THROW(ex); +} + +auto Graph::run(Neon::SetIdx /*setIdx*/, int /*streamIdx*/, Neon::DataView /*dataView*/) +{ + NEON_DEV_UNDER_CONSTRUCTION(""); +} + +auto Graph::run(int /*streamIdx*/, Neon::DataView /*dataView*/) +{ + NEON_DEV_UNDER_CONSTRUCTION(""); +} + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp new file mode 100644 index 00000000..d7ed566e --- /dev/null +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -0,0 +1,78 @@ +#include "Neon/set/container/GraphContainer.h" +#include "Neon/set/container/Graph.h" + +namespace Neon::set::internal { + +GraphContainer::GraphContainer(const std::string& name, + const Neon::set::container::Graph& containerGraph, + std::function loadingLambda) + : mLoadingLambda(loadingLambda) +{ + mGraph = std::make_shared(containerGraph); + setContainerExecutionType(ContainerExecutionType::graph); + setDataViewSupport(DataViewSupport::off); + setName(name); + + this->parse(); +} + +auto GraphContainer::newParser() -> Loader +{ + auto parser = Loader(*this, + Neon::DeviceType::CPU, + Neon::SetIdx(0), + Neon::DataView::STANDARD, + Neon::set::internal::LoadingMode_e::PARSE_AND_EXTRACT_LAMBDA); + return parser; +} + +auto GraphContainer::parse() -> const std::vector& +{ + Neon::SetIdx setIdx(0); + if (!this->mParsingDataUpdated) { + auto parser = newParser(); + this->mLoadingLambda(setIdx, parser); + this->mParsingDataUpdated = true; + + setContainerPattern(ContainerPatternType::complex); + } + return getTokens(); +} + +auto GraphContainer::getGraph() -> const Neon::set::container::Graph& +{ + return *mGraph; +} + +auto GraphContainer::getHostContainer() -> std::shared_ptr +{ + NEON_THROW_UNSUPPORTED_OPTION("A managed Container Container is not associated with any host operation."); +} + +auto GraphContainer::getDeviceContainer() -> std::shared_ptr +{ + NEON_THROW_UNSUPPORTED_OPTION("A managed Container Container is not associated with any host operation."); +} + +/** + * Run container over streams + * @param streamIdx + * @param dataView + */ +auto GraphContainer::run(int /*streamIdx*/, + Neon::DataView /*dataView*/) -> void +{ + /// mGraph->run(streamIdx, dataView); +} + +auto GraphContainer::run(Neon::SetIdx /*setIdx*/, + int /*streamIdx*/, + Neon::DataView /*dataView*/) -> void +{ + // if (ContainerExecutionType::graph == this->getContainerType()) { + // mGraph->run(setIdx, streamIdx, dataView); + // } + // NEON_THROW_UNSUPPORTED_OPTION(""); +} + +} // namespace Neon::set::internal diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cu new file mode 100644 index 00000000..ad4a2dd9 --- /dev/null +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cu @@ -0,0 +1,140 @@ +#include "Neon/core/types/chrono.h" + +#include "Neon/set/Containter.h" + +#include "Neon/domain/aGrid.h" +#include "Neon/domain/bGrid.h" +#include "Neon/domain/dGrid.h" +#include "Neon/domain/eGrid.h" +#include "Neon/domain/tools/Geometries.h" +#include "Neon/domain/tools/TestData.h" + +#include "Neon/skeleton/Options.h" +#include "Neon/skeleton/Skeleton.h" + +#include +#include + +#include "gtest/gtest.h" +#include "setUt_containerGraph_kernels.h" +#include "setUt_containerGraph_runHelper.h" + +#include "Neon/set/container/Graph.h" + +using namespace Neon::domain::tool::testing; +static const std::string testFilePrefix("setUt_containerGraph_nestedGraph"); + +template +void NestedGraphsTest(TestData& data) +{ + using Type = typename TestData::Type; + + const std::string appName(testFilePrefix); + + const Type scalarVal = 2; + const int nIterations = 10; + + auto fR = data.getGrid().template newPatternScalar(); + fR() = scalarVal; + data.getBackend().syncAll(); + + data.resetValuesToRandom(1, 50); + Neon::Timer_sec timer; + + { // NEON + auto& X = data.getField(FieldNames::X); + auto& Y = data.getField(FieldNames::Y); + auto& Z = data.getField(FieldNames::Z); + auto& W = data.getField(FieldNames::W); + + auto generateInnerGraph = [&]() -> Neon::set::Container { + Neon::set::container::Graph graph; + + auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); + graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, "nodeB"), nodeC); + + graph.ioToDot(appName, "UserGraph", false); + graph.ioToDot(appName + "-debug", "UserGraph", true); + + auto container = Neon::set::Container::factoryGraph("Inner", graph, [](Neon::SetIdx, Neon::set::Loader&) {}); + return container; + }; + + Neon::set::container::Graph graph; + auto nodeA = generateInnerGraph(); + auto nodeB = generateInnerGraph(); + auto nodeC = generateInnerGraph(); + + graph.addNode(nodeA); + graph.addNode(nodeB); + graph.addNode(nodeC); + + + graph.ioToDot(appName, "UserGraph", false); + graph.ioToDot(appName + "-debug", "UserGraph", true); + // timer.start(); + // for (int i = 0; i < nIterations; i++) { + // skl.run(); + // } + // data.getBackend().syncAll(); + // timer.stop(); + } + + { // Golden data + auto time = timer.time(); + + Type dR = scalarVal; + auto& X = data.getIODomain(FieldNames::X); + auto& Y = data.getIODomain(FieldNames::Y); + + for (int i = 0; i < nIterations; i++) { + data.axpy(&dR, Y, X); + data.laplace(X, Y); + data.axpy(&dR, Y, Y); + } + } + bool isOk = data.compare(FieldNames::X); + isOk = isOk && data.compare(FieldNames::Y); + + /*{ // DEBUG + data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); + data.getField(FieldNames::X).ioToVtk("Field_X", "X"); + + data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); + data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); + }*/ + + ASSERT_TRUE(isOk); +} + +template +void NestedGraphs(TestData& data) +{ + NestedGraphsTest(data); +} + + +namespace { +int getNGpus() +{ + if (Neon::sys::globalSpace::gpuSysObjStorage.numDevs() > 0) { + int maxGPUs = Neon::set::DevSet::maxSet().setCardinality(); + if (maxGPUs > 1) { + return maxGPUs; + } else { + return 3; + } + } else { + return 0; + } +} +} // namespace + +TEST(NestedGraphs, eGrid) +{ + int nGpus = getNGpus(); + using Grid = Neon::domain::internal::eGrid::eGrid; + using Type = int32_t; + runOneTestConfiguration("eGrid_t", NestedGraphs, 1, 1); +} From 150a0456cc59c57e9f7db95ef697217ea00a0dc3 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Mon, 29 Aug 2022 19:14:15 -0400 Subject: [PATCH 26/67] WIP --- .../include/Neon/set/container/ContainerAPI.h | 126 +++++++++++++----- .../set/container/ContainerOperationType.h | 7 +- .../Neon/set/container/ContainerPatternType.h | 6 +- .../Neon/set/container/DeviceContainer.h | 4 +- libNeonSet/include/Neon/set/container/Graph.h | 34 ++++- .../include/Neon/set/container/graph/Bfs.h | 1 - libNeonSet/src/set/container/ContainerAPI.cpp | 105 +++++++++++---- .../set/container/ContainerOperationType.cpp | 7 +- .../set/container/ContainerPatternType.cpp | 6 +- libNeonSet/src/set/container/Graph.cpp | 55 +++++++- .../src/set/container/GraphContainer.cpp | 16 +-- 11 files changed, 268 insertions(+), 99 deletions(-) diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index cc1a14fb..28805856 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -10,6 +10,10 @@ #include "functional" #include "type_traits" +namespace Neon::set { +struct Loader; +} + namespace Neon::set::container { struct Graph; } @@ -23,6 +27,8 @@ namespace Neon::set::internal { struct ContainerAPI { public: + friend Neon::set::Loader; + enum struct DataViewSupport { on, @@ -30,65 +36,87 @@ struct ContainerAPI }; /** - * virtual default destructor + * virtual default destructor. */ virtual ~ContainerAPI() = default; /** - * Run the container over streams - * @param streamIdx - * @param dataView + * Run this Container over a stream. */ - virtual auto run(int streamIdx, Neon::DataView dataView = Neon::DataView::STANDARD) -> void = 0; + virtual auto run(int streamIdx, Neon::DataView dataView = Neon::DataView::STANDARD) + -> void = 0; - virtual auto run(Neon::SetIdx idx, int streamIdx, Neon::DataView dataView) -> void = 0; - - virtual auto getHostContainer() -> std::shared_ptr = 0; + /** + * Run this Container over a stream. + */ + virtual auto run(Neon::SetIdx idx, int streamIdx, Neon::DataView dataView) + -> void = 0; - virtual auto getDeviceContainer() -> std::shared_ptr = 0; + /** + * Returns a pointer to the internal host container. + */ + virtual auto getHostContainer() + -> std::shared_ptr; - virtual auto getGraph() -> const Neon::set::container::Graph&; + /** + * Returns a pointer to the internal device container. + */ + virtual auto getDeviceContainer() + -> std::shared_ptr; /** - * Parse the input and output data for the kernel - * @return + * Returns a handle to the internal graph of Containers. */ - virtual auto parse() -> const std::vector& = 0; + virtual auto getGraph() + -> const Neon::set::container::Graph&; /** - * - * @param dataParsing + * Parse the input and output data for the kernel. + * @return */ - auto addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) - -> void; + virtual auto parse() + -> const std::vector& = 0; + /** - * Returns a name associated to the container + * Returns a name associated to the container. */ auto getName() const -> const std::string&; + /** + * Returns a list of tokens as result of parsing the Container loading lambda. + */ auto getTokens() const -> const std::vector&; + /** + * Returns a list of tokens as result of parsing the Container loading lambda. + */ auto getTokenRef() -> std::vector&; /** - * Get the execution type for the container + * Get the execution type for the Container. */ - auto getContainerExecutionType() const -> Neon::set::ContainerExecutionType; + auto getContainerExecutionType() const + -> Neon::set::ContainerExecutionType; /** - * Get the Operation type for the container + * Get the Operation type for the Container. */ - auto getContainerOperationType() const -> Neon::set::ContainerOperationType; + auto getContainerOperationType() const + -> Neon::set::ContainerOperationType; /** - * Get the Pattern type for the container + * Get the Pattern type for the Container */ - auto getContainerPatternType() const -> Neon::set::ContainerPatternType; + auto getContainerPatternType() const + -> Neon::set::ContainerPatternType; + /** + * Returns information about DataView support for this Container. + */ auto getDataViewSupport() const -> DataViewSupport; @@ -98,6 +126,12 @@ struct ContainerAPI auto toLog(uint64_t ContainerUid) -> void; protected: + /** + * Add a new token + */ + auto addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) + -> void; + /** * Set the name for the container */ @@ -106,8 +140,6 @@ struct ContainerAPI /** * Set the launch parameters for the container - * @param dw - * @return */ auto setLaunchParameters(Neon::DataView dw) -> Neon::set::LaunchParameters&; @@ -118,31 +150,57 @@ struct ContainerAPI auto getLaunchParameters(Neon::DataView dw) const -> const Neon::set::LaunchParameters&; + /** + * Generate a string that will be printed in case or exceptions + * @return + */ + auto helpGetNameForError() + -> std::string; + /** * Set the execution type for the container */ - auto setContainerExecutionType(Neon::set::ContainerExecutionType containerType) -> void; + auto setContainerExecutionType(Neon::set::ContainerExecutionType containerType) + -> void; /** * Set the Operation type for the container */ - auto setContainerOperationType(Neon::set::ContainerOperationType containerType) -> void; - + auto setContainerOperationType(Neon::set::ContainerOperationType containerType) + -> void; /** * Set the DataView support for the container */ - auto setDataViewSupport(DataViewSupport dataViewSupport) -> void; + auto setDataViewSupport(DataViewSupport dataViewSupport) + -> void; - auto setContainerPattern(const std::vector& tokens) -> void; + /** + * Set the patter for this Container based on a list of tokens. + * @param tokens + */ + auto setContainerPattern(const std::vector& tokens) + -> void; - bool mParsingDataUpdated = false; + /** + * Set the patter for this Container + * @param tokens + */ + auto setContainerPattern(ContainerPatternType patternType) + -> void; - void setContainerPattern(ContainerPatternType patternType); + auto isParsingDataUpdated() + -> bool; + + auto setParsingDataUpdated(bool) + -> void; private: - std::vector mParsed; + using TokenList = std::vector; + std::string mName{"Anonymous"}; /**< Name of the Container */ + bool mParsingDataUpdated = false; + TokenList mParsed; std::array mLaunchParameters; Neon::set::ContainerExecutionType mContainerExecutionType; Neon::set::ContainerOperationType mContainerOperationType; diff --git a/libNeonSet/include/Neon/set/container/ContainerOperationType.h b/libNeonSet/include/Neon/set/container/ContainerOperationType.h index 09dd0fc8..edf9b061 100644 --- a/libNeonSet/include/Neon/set/container/ContainerOperationType.h +++ b/libNeonSet/include/Neon/set/container/ContainerOperationType.h @@ -41,9 +41,10 @@ struct ContainerOperationTypeUtils static auto getOptions() -> std::array; }; - -} // namespace Neon::set /** * operator<< */ -std::ostream& operator<<(std::ostream& os, Neon::set::ContainerOperationType const& m); \ No newline at end of file +std::ostream& operator<<(std::ostream& os, Neon::set::ContainerOperationType const& m); + +} // namespace Neon::set + diff --git a/libNeonSet/include/Neon/set/container/ContainerPatternType.h b/libNeonSet/include/Neon/set/container/ContainerPatternType.h index 4cd90e46..93b16a21 100644 --- a/libNeonSet/include/Neon/set/container/ContainerPatternType.h +++ b/libNeonSet/include/Neon/set/container/ContainerPatternType.h @@ -29,9 +29,9 @@ struct ContainerPatternTypeUtils static auto getOptions() -> std::array; }; - -} // namespace Neon::set /** * operator<< */ -std::ostream& operator<<(std::ostream& os, Neon::set::ContainerPatternType const& m); \ No newline at end of file +std::ostream& operator<<(std::ostream& os, Neon::set::ContainerPatternType const& m); + +} // namespace Neon::set diff --git a/libNeonSet/include/Neon/set/container/DeviceContainer.h b/libNeonSet/include/Neon/set/container/DeviceContainer.h index c89b5852..28b90294 100644 --- a/libNeonSet/include/Neon/set/container/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceContainer.h @@ -80,10 +80,10 @@ struct DeviceContainer : ContainerAPI auto parse() -> const std::vector& override { - if (!this->mParsingDataUpdated) { + if (!this->isParsingDataUpdated()) { auto parser = newParser(); this->m_loadingLambda(parser); - this->mParsingDataUpdated = true; + this->setParsingDataUpdated(true); this->setContainerPattern(this->getTokens()); } diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index f0d7a062..7ca93f8a 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -3,11 +3,11 @@ #include "Neon/core/core.h" #include "Neon/core/types/digraph.h" +#include "Neon/set/container/graph/Bfs.h" #include "Neon/set/container/graph/GraphDependency.h" #include "Neon/set/container/graph/GraphNode.h" namespace Neon::set::container { -struct Bfs; struct Graph { @@ -96,11 +96,13 @@ struct Graph * Execute the scheduling operation associated to the node */ auto run(int streamIdx = 0, - Neon::DataView dataView = Neon::DataView::STANDARD); + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void; auto run(Neon::SetIdx setIdx, int streamIdx = 0, - Neon::DataView dataView = Neon::DataView::STANDARD); + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void; auto ioToDot(const std::string& fname, const std::string& graphName, @@ -186,21 +188,36 @@ struct Graph * - order of execution * - mapping between streams and graph nodes */ - auto helpComputeScheduling(bool filterOutAnchors = true) -> void; + auto helpComputeScheduling(bool filterOutAnchors = true) + -> void; + + /** + * Execute + */ + auto helpExecute(bool filterOutAnchors = true) + -> void; + + auto helpExecute(Neon::SetIdx setIdx, + bool filterOutAnchors = true) + -> void; + /** * Resetting node's data related to scheduling */ - auto helpComputeScheduling_00_resetData(Bfs& bfs) -> void; + auto helpComputeScheduling_00_resetData(Bfs& bfs) + -> void; /** * Maps node to streams */ - auto helpComputeScheduling_01_mappingStreams(Bfs& bfs) -> void; + auto helpComputeScheduling_01_mappingStreams(Bfs& bfs) + -> void; /** * Define events to be waited and fired from each node */ - auto helpComputeScheduling_02_events(Bfs& bfs) -> void; + auto helpComputeScheduling_02_events(Bfs& bfs) + -> void; using RawGraph = DiGraph; @@ -208,9 +225,12 @@ struct Graph RawGraph mRawGraph; bool mSchedulingStatusIsValid; int mMaxNumberStreams; + Bfs mBfs; Backend mBackend; bool mBackendIsSet = false; }; } // namespace Neon::set::container + +#include "Neon/set/container/graph/Bfs_imp.h" diff --git a/libNeonSet/include/Neon/set/container/graph/Bfs.h b/libNeonSet/include/Neon/set/container/graph/Bfs.h index e095e591..0208af63 100644 --- a/libNeonSet/include/Neon/set/container/graph/Bfs.h +++ b/libNeonSet/include/Neon/set/container/graph/Bfs.h @@ -68,4 +68,3 @@ struct Bfs } // namespace Neon::set::container -#include "Bfs_imp.h" diff --git a/libNeonSet/src/set/container/ContainerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp index dd514063..c7e07f8d 100644 --- a/libNeonSet/src/set/container/ContainerAPI.cpp +++ b/libNeonSet/src/set/container/ContainerAPI.cpp @@ -1,21 +1,14 @@ #include "Neon/set/container/ContainerAPI.h" - -/** - * Abstract interface to hide - */ - namespace Neon::set::internal { -auto ContainerAPI::addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) -> void +auto ContainerAPI::addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) + -> void { mParsed.push_back(dataParsing); } -/** - * - */ auto ContainerAPI::getName() const -> const std::string& { @@ -28,12 +21,6 @@ auto ContainerAPI::getTokens() const return mParsed; } -// auto ContainerAPI::clearTokens() -// -> void -//{ -// mParsed.clear(); -// } - auto ContainerAPI::getTokenRef() -> std::vector& { @@ -46,12 +33,14 @@ auto ContainerAPI::setName(const std::string& name) mName = name; } -auto ContainerAPI::setLaunchParameters(Neon::DataView dw) -> Neon::set::LaunchParameters& +auto ContainerAPI::setLaunchParameters(Neon::DataView dw) + -> Neon::set::LaunchParameters& { return mLaunchParameters[DataViewUtil::toInt(dw)]; } -auto ContainerAPI::getLaunchParameters(Neon::DataView dw) const -> const Neon::set::LaunchParameters& +auto ContainerAPI::getLaunchParameters(Neon::DataView dw) const + -> const Neon::set::LaunchParameters& { return mLaunchParameters[DataViewUtil::toInt(dw)]; } @@ -61,17 +50,20 @@ auto ContainerAPI::getDataViewSupport() const -> ContainerAPI::DataViewSupport return mDataViewSupport; } -auto ContainerAPI::setDataViewSupport(ContainerAPI::DataViewSupport dataViewSupport) -> void +auto ContainerAPI::setDataViewSupport(ContainerAPI::DataViewSupport dataViewSupport) + -> void { mDataViewSupport = dataViewSupport; } -auto ContainerAPI::setContainerPattern(Neon::set::ContainerPatternType patternType) -> void +auto ContainerAPI::setContainerPattern(Neon::set::ContainerPatternType patternType) + -> void { this->mContainerPatternType = patternType; } -auto ContainerAPI::setContainerPattern(const std::vector& tokens) -> void +auto ContainerAPI::setContainerPattern(const std::vector& tokens) + -> void { Neon::set::ContainerPatternType patternType = Neon::set::ContainerPatternType::map; @@ -92,7 +84,8 @@ auto ContainerAPI::setContainerPattern(const std::vectormContainerPatternType = patternType; } -auto ContainerAPI::toLog(uint64_t uid) -> void +auto ContainerAPI::toLog(uint64_t uid) + -> void { std::stringstream listOfTokes; for (auto& token : mParsed) { @@ -104,35 +97,91 @@ auto ContainerAPI::toLog(uint64_t uid) -> void NEON_INFO("Container {}: tokens = [{}]", uid, listOfTokes.str()); } -auto ContainerAPI::getContainerExecutionType() const -> ContainerExecutionType +auto ContainerAPI::getContainerExecutionType() + const + -> ContainerExecutionType { return mContainerExecutionType; } -auto ContainerAPI::getContainerOperationType() const -> ContainerOperationType +auto ContainerAPI::getContainerOperationType() + const + -> ContainerOperationType { return mContainerOperationType; } -auto ContainerAPI::getContainerPatternType() const -> ContainerPatternType +auto ContainerAPI::getContainerPatternType() + const + -> ContainerPatternType { return mContainerPatternType; } -auto ContainerAPI::setContainerExecutionType(ContainerExecutionType containerType) -> void +auto ContainerAPI::setContainerExecutionType(ContainerExecutionType containerType) + -> void { mContainerExecutionType = containerType; } -auto ContainerAPI::setContainerOperationType(ContainerOperationType containerType) -> void +auto ContainerAPI::setContainerOperationType(ContainerOperationType containerType) + -> void { mContainerOperationType = containerType; } -auto ContainerAPI::getGraph() -> const Neon::set::container::Graph& +auto ContainerAPI::getGraph() + -> const Neon::set::container::Graph& +{ + std::string description = helpGetNameForError(); + Neon::NeonException exp("ContainerAPI"); + exp << description << " " + << "getGraph" + << " is not supported."; + NEON_THROW(exp); +} + +auto ContainerAPI::getHostContainer() + -> std::shared_ptr +{ + std::string description = helpGetNameForError(); + Neon::NeonException exp("ContainerAPI"); + exp << description << " " + << "getHostContainer" + << " is not supported."; + NEON_THROW(exp); +} + +auto ContainerAPI::helpGetNameForError() + -> std::string +{ + std::stringstream s; + s << getName() + << "[" << getContainerExecutionType() + << " - " << getContainerOperationType() + << " - " << getContainerPatternType(); + + return s.str(); +} + +auto ContainerAPI::getDeviceContainer() + -> std::shared_ptr { - NEON_THROW_UNSUPPORTED_OPERATION(); + std::string description = helpGetNameForError(); + Neon::NeonException exp("ContainerAPI"); + exp << description << " " + << "getDeviceContainer" + << " is not supported."; + NEON_THROW(exp); } +auto ContainerAPI::isParsingDataUpdated() -> bool +{ + return mParsingDataUpdated; +} +auto ContainerAPI::setParsingDataUpdated(bool status) -> void +{ + mParsingDataUpdated = status; +} } // namespace Neon::set::internal diff --git a/libNeonSet/src/set/container/ContainerOperationType.cpp b/libNeonSet/src/set/container/ContainerOperationType.cpp index 5bb54670..2f9d00ed 100644 --- a/libNeonSet/src/set/container/ContainerOperationType.cpp +++ b/libNeonSet/src/set/container/ContainerOperationType.cpp @@ -51,10 +51,11 @@ auto ContainerOperationTypeUtils::getOptions() -> std::array std::array void { - Bfs bfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); - helpComputeScheduling_00_resetData(bfs); - helpComputeScheduling_01_mappingStreams(bfs); - helpComputeScheduling_02_events(bfs); + mBfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); + helpComputeScheduling_00_resetData(mBfs); + helpComputeScheduling_01_mappingStreams(mBfs); + helpComputeScheduling_02_events(mBfs); } auto Graph::helpGetGraphNode(GraphData::Uid uid) -> GraphNode& @@ -600,12 +601,54 @@ auto Graph::getBackend() const -> const Neon::Backend& NEON_THROW(ex); } -auto Graph::run(Neon::SetIdx /*setIdx*/, int /*streamIdx*/, Neon::DataView /*dataView*/) +auto Graph::run(Neon::SetIdx /*setIdx*/, + int streamIdx, + Neon::DataView dataView) + -> void { + if (dataView != Neon::DataView::STANDARD) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + if (streamIdx != 0) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + if (!mSchedulingStatusIsValid) { + helpComputeScheduling(false); + } NEON_DEV_UNDER_CONSTRUCTION(""); } -auto Graph::run(int /*streamIdx*/, Neon::DataView /*dataView*/) +auto Graph::run(int /*streamIdx*/, + Neon::DataView /*dataView*/) + -> void +{ + NEON_DEV_UNDER_CONSTRUCTION(""); +} + +auto Graph::helpExecute(Neon::SetIdx setIdx, + bool /*filterOutAnchors*/) -> void +{ + int levels = mBfs.getNumberOfLevels(); + for (int i = 0; i < levels; i++) { + mBfs.forEachNodeAtLevel(i, *this, [&](Neon::set::container::GraphNode& graphNode) { + auto& scheduling = graphNode.getScheduling(); + auto& container = graphNode.getContainer(); + const auto& waitingEvents = scheduling.getDependentEvents(); + const auto& signalEvents = scheduling.getEvent(); + const auto& stream = scheduling.getStream(); + + for (auto toBeWaited : waitingEvents) { + mBackend.waitEventOnStream(setIdx, toBeWaited, stream); + } + container.run(setIdx, stream, scheduling.getDataView()); + + if (signalEvents >= 0) { + mBackend.pushEventOnStream(setIdx, signalEvents, stream); + } + }); + } +} +auto Graph::helpExecute(bool /*filterOutAnchors*/) -> void { NEON_DEV_UNDER_CONSTRUCTION(""); } diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index d7ed566e..3c7a8aa3 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -29,10 +29,10 @@ auto GraphContainer::newParser() -> Loader auto GraphContainer::parse() -> const std::vector& { Neon::SetIdx setIdx(0); - if (!this->mParsingDataUpdated) { + if (!this->isParsingDataUpdated()) { auto parser = newParser(); this->mLoadingLambda(setIdx, parser); - this->mParsingDataUpdated = true; + this->setParsingDataUpdated(true); setContainerPattern(ContainerPatternType::complex); } @@ -65,14 +65,14 @@ auto GraphContainer::run(int /*streamIdx*/, /// mGraph->run(streamIdx, dataView); } -auto GraphContainer::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, +auto GraphContainer::run(Neon::SetIdx /*setIdx*/, + int /*streamIdx*/, Neon::DataView /*dataView*/) -> void { - // if (ContainerExecutionType::graph == this->getContainerType()) { - // mGraph->run(setIdx, streamIdx, dataView); - // } - // NEON_THROW_UNSUPPORTED_OPTION(""); +// if (ContainerExecutionType::graph == this->getContainerExecutionType()) { +// mGraph->run(setIdx, streamIdx, dataView); +// } +// NEON_THROW_UNSUPPORTED_OPTION(""); } } // namespace Neon::set::internal From 601915ffd121e9742e49710f0453cdd302e4374f Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Tue, 30 Aug 2022 15:16:30 -0400 Subject: [PATCH 27/67] WIP --- .../include/Neon/domain/tools/TestData.h | 24 +-- libNeonSet/include/Neon/set/container/Graph.h | 45 +++-- libNeonSet/src/set/container/Graph.cpp | 177 +++++++++++++----- .../src/set/container/GraphContainer.cpp | 1 + .../src/set/container/graph/GraphNode.cpp | 83 ++++++-- .../unit/setUt_containerGraph/CMakeLists.txt | 6 + ... => setUt_containerGraph_NestedGraphs.cpp} | 24 +-- .../src/setUt_containerGraph_runHelper.h | 2 +- 8 files changed, 266 insertions(+), 96 deletions(-) rename libNeonSet/tests/unit/setUt_containerGraph/src/{setUt_containerGraph_NestedGraphs.cu => setUt_containerGraph_NestedGraphs.cpp} (85%) diff --git a/libNeonDomain/include/Neon/domain/tools/TestData.h b/libNeonDomain/include/Neon/domain/tools/TestData.h index 6344bed2..f2d1a534 100644 --- a/libNeonDomain/include/Neon/domain/tools/TestData.h +++ b/libNeonDomain/include/Neon/domain/tools/TestData.h @@ -300,10 +300,10 @@ template auto TestData::axpy(const Type* alpha, IODomain& A, IODomain& B) -> void { - this->template forEachActiveIODomain([&](const Neon::index_3d& idx, - int cardinality, - Type& a, - Type& b) { + this->template forEachActiveIODomain([&](const Neon::index_3d& /*idx*/, + int /*cardinality*/, + Type& a, + Type& b) { b += (*alpha) * a; }, A, B); @@ -318,8 +318,8 @@ auto TestData::laplace(IODomain& A, NEON_IO IODomain& B) } this->template forEachActiveIODomain([&](const Neon::index_3d& idx, int cardinality, - Type& a, - Type& b) { + Type& /*a*/, + Type& b) { // Laplacian stencil operates on 6 neighbors (assuming 3D) T res = 0; bool isValid = false; @@ -347,8 +347,8 @@ auto TestData::compare(FieldNames name, T tollerance) -> bool bool isTheSame = false; if constexpr (std::is_integral_v) { bool foundAnIssue = false; - this->compare(name, [&](const Neon::index_3d& idx, - int cardinality, + this->compare(name, [&](const Neon::index_3d& /*idx*/, + int /*cardinality*/, const T& golden, const T& computed) { if (golden != computed) { @@ -356,9 +356,9 @@ auto TestData::compare(FieldNames name, T tollerance) -> bool #pragma omp critical { foundAnIssue = true; - //std::stringstream s; - //s << idx.to_string() << " " << golden << " " << computed << std::endl; - //NEON_INFO(s.str()); + // std::stringstream s; + // s << idx.to_string() << " " << golden << " " << computed << std::endl; + // NEON_INFO(s.str()); } } } @@ -375,7 +375,7 @@ auto TestData::compare(FieldNames name, T tollerance) -> bool T maxAbs = std::max(goldenABS, computedABS); auto relativeDiff = (maxAbs == 0.0 ? 0.0 : std::abs(golden - computed) / maxAbs); - foundAnIssue = relativeDiff >= 0.00001; + foundAnIssue = relativeDiff >= tollerance; }); isTheSame = !foundAnIssue; } diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 7ca93f8a..330524a2 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -17,7 +17,7 @@ struct Graph public: Graph(); - explicit Graph(Neon::Backend& bk); + explicit Graph(const Backend& bk); /** * Get a reference to the begin node @@ -91,7 +91,8 @@ struct Graph auto getSubsequentGraphNodes(const GraphNode& graphNode, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) -> std::vector; - + auto runtimePreSet(int anchorStream) + -> void; /** * Execute the scheduling operation associated to the node */ @@ -110,6 +111,8 @@ struct Graph auto getBackend() const -> const Neon::Backend&; + + protected: /** * Invalidate all scheduling information that were computed @@ -188,37 +191,50 @@ struct Graph * - order of execution * - mapping between streams and graph nodes */ - auto helpComputeScheduling(bool filterOutAnchors = true) + auto helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> void; /** * Execute */ - auto helpExecute(bool filterOutAnchors = true) + auto helpExecute(int anchorStream) -> void; - auto helpExecute(Neon::SetIdx setIdx, - bool filterOutAnchors = true) + auto helpExecute(Neon::SetIdx setIdx, int anchorStream) -> void; - - /** * Resetting node's data related to scheduling */ - auto helpComputeScheduling_00_resetData(Bfs& bfs) + auto helpComputeScheduling_00_resetData() -> void; + /** - * Maps node to streams + * Resetting node's data related to scheduling */ - auto helpComputeScheduling_01_mappingStreams(Bfs& bfs) - -> void; + auto helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) + -> Bfs; + + /** + * Maps node to streams. + * Returns the max stream Id used by the scheduling + */ + auto helpComputeScheduling_02_mappingStreams(Bfs& bfs, bool filterOutAnchors, int anchorStream) + -> int; /** * Define events to be waited and fired from each node + * Returns the max event Id used by the scheduling. */ - auto helpComputeScheduling_02_events(Bfs& bfs) + auto helpComputeScheduling_03_events(Bfs& bfs) + -> int; + + /** + * Booking the required resources from the backend. + */ + auto helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) -> void; + using RawGraph = DiGraph; Uid mUidCounter; @@ -229,6 +245,9 @@ struct Graph Backend mBackend; bool mBackendIsSet = false; + + bool mFilterOutAnchorsPreSet = false; + int mAnchorStreamPreSet = 0; }; } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 3d54c2b8..3c95d65e 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -1,7 +1,7 @@ #include "Neon/set/container/Graph.h" +#include #include "Neon/set/container/graph/Bfs.h" - namespace Neon::set::container { Graph::Graph() @@ -397,11 +397,17 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd newLevel.push_back(currentFrontierNode.first); // Adding the node's children to the next frontier - for (const auto& child : helpGetOutNeighbors(currentFrontierNode.first)) { - try { - nextFrontier->at(child)--; - } catch (...) { - nextFrontier->insert({child, helpGetInEdges(currentFrontierNode.first).size() - 1}); + auto currentFrontierNodeChildren = helpGetOutNeighbors(currentFrontierNode.first, filterOutBeginEnd); + for (const auto& child : currentFrontierNodeChildren) { + auto it = std::find_if(nextFrontier->begin(), nextFrontier->end(), + [&child](auto& entry) { + return (entry.first == child); + }); + if (it != nextFrontier->end()) { + it->second--; + } else { + auto numChildDependencies = helpGetInEdges(child, filterOutBeginEnd).size(); + nextFrontier->insert({child, numChildDependencies - 1}); } } } else { @@ -414,12 +420,19 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd return bfs; } -auto Graph::helpComputeScheduling(bool filterOutAnchors) -> void +auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> void +{ + helpComputeScheduling_00_resetData(); + mBfs = helpComputeScheduling_01_generatingBFS(filterOutAnchors); + int maxStreamId = helpComputeScheduling_02_mappingStreams(mBfs, filterOutAnchors, anchorStream); + int maxEventId = helpComputeScheduling_03_events(mBfs); + helpComputeScheduling_04_ensureResources(maxStreamId, maxEventId); +} + +auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) -> Bfs { - mBfs = helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); - helpComputeScheduling_00_resetData(mBfs); - helpComputeScheduling_01_mappingStreams(mBfs); - helpComputeScheduling_02_events(mBfs); + return helpGetBFS(filterOutAnchors, {GraphDependencyType::data, + GraphDependencyType::user}); } auto Graph::helpGetGraphNode(GraphData::Uid uid) -> GraphNode& @@ -432,39 +445,49 @@ auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& return mRawGraph.getVertexProperty(uid); } -auto Graph::helpComputeScheduling_00_resetData(Bfs& bfs) -> void +auto Graph::helpComputeScheduling_00_resetData() -> void { - bfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int /*levelId*/) { + mRawGraph.forEachVertex([&](const int& graphNodeId) { + auto& targetNode = mRawGraph.getVertexProperty(graphNodeId); targetNode.getScheduling().reset(); }); } -auto Graph::helpComputeScheduling_01_mappingStreams(Bfs& bfs) -> void +auto Graph::helpComputeScheduling_02_mappingStreams(Bfs& bfs, + bool filterOutAnchors, + int anchorStream) + -> int { mSchedulingStatusIsValid = true; mMaxNumberStreams = bfs.getMaxLevelWidth(); // used stream -> true // available -> false - std::vector streamsStatus(mMaxNumberStreams, false); + constexpr bool usedStream = true; + constexpr bool availableStream = false; + + std::vector streamsStatus(mMaxNumberStreams, + availableStream); auto bookFirstAvailableStream = [&]() { for (int i = 0; i < int(streamsStatus.size()); i++) { - if (!streamsStatus[i]) { - streamsStatus[i] = true; + if (availableStream == streamsStatus[i]) { + streamsStatus[i] = usedStream; return i; } } NEON_THROW_UNSUPPORTED_OPERATION(""); }; - auto isStreamAvailable = [&](int streamId) -> bool { - return streamsStatus[streamId] == false; + auto isStreamAvailable = [&](int streamId) + -> bool { + return streamsStatus[streamId] == availableStream; }; - auto bookStream = [&](int streamId) -> bool { + auto bookStream = [&](int streamId) + -> bool { if (isStreamAvailable(streamId)) { - streamsStatus[streamId] = true; + streamsStatus[streamId] = usedStream; return true; } return false; @@ -478,9 +501,22 @@ auto Graph::helpComputeScheduling_01_mappingStreams(Bfs& bfs) -> void int levelIdx) { std::vector delayedBooking; + if (!filterOutAnchors && levelIdx == 0 && anchorStream > -1) { + // If anchors are represented than + // the first level contains only the begin node + bool checkA = getBeginNode().getGraphData().getUid() == level[0]; + bool checkB = level.size() == 1; + if (!checkA || !checkB) { + Neon::NeonException ex(""); + ex << "Inconsistent status of the container graph."; + NEON_THROW(ex); + } + mRawGraph.getVertexProperty(level[0]).getScheduling().setStream(anchorStream); + return; + } // Step a. for (auto& nodeUid : level) { - auto node = mRawGraph.getVertexProperty(nodeUid); + auto& node = mRawGraph.getVertexProperty(nodeUid); int associatedStream = [&]() -> int { if (levelIdx == 0) { @@ -512,11 +548,20 @@ auto Graph::helpComputeScheduling_01_mappingStreams(Bfs& bfs) -> void streamsStatus = std::vector(mMaxNumberStreams, false); }); + + if (!filterOutAnchors && anchorStream > -1) { + auto endNodeId = getEndNode().getGraphData().getUid(); + auto& endNode = mRawGraph.getVertexProperty(endNodeId); + endNode.getScheduling().setStream(anchorStream); + } + + this->ioToDot("tge","tge", true); + return mMaxNumberStreams - 1; } -auto Graph::helpComputeScheduling_02_events(Bfs& bfs) -> void +auto Graph::helpComputeScheduling_03_events(Bfs& bfs) -> int { - int eventCount = 1; + int eventCount = 0; bfs.forEachNodeByLevel(*this, [&](GraphNode& targetNode, int /*levelId*/) { int targetStreamId = targetNode.getScheduling().getStream(); @@ -538,15 +583,26 @@ auto Graph::helpComputeScheduling_02_events(Bfs& bfs) -> void // b. add the pre-node event to the list of the target node // a. - int preNodeEvent = -1; - if (preNode.getScheduling().getEvent() == -1) { + int preNodeEvent = preNode.getScheduling().getEvent(); + if (preNodeEvent == -1) { preNodeEvent = eventCount; preNode.getScheduling().setEvent(preNodeEvent); eventCount++; } + // b. targetNode.getScheduling().getDependentEvents().push_back(preNodeEvent); } }); + + return eventCount - 1; +} + +auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) + -> void +{ + auto bk = getBackend(); + bk.setAvailableStreamSet(maxStreamId + 1); + bk.setAvailableUserEvents(maxEventId + 1); } auto Graph::ioToDot(const std::string& fname, @@ -585,10 +641,19 @@ auto Graph::ioToDot(const std::string& fname, vertexLabelProperty, edgeLabelProperty); } -Graph::Graph(Backend& bk) +Graph::Graph(const Backend& bk) { mBackend = bk; mBackendIsSet = true; + + auto begin = GraphNode::newBeginNode(); + auto end = GraphNode::newEndNode(); + mUidCounter = GraphData::firstInternal; + + mRawGraph.addVertex(begin.getGraphData().getUid(), begin); + mRawGraph.addVertex(end.getGraphData().getUid(), end); + + helpInvalidateScheduling(); } auto Graph::getBackend() const -> const Neon::Backend& @@ -602,32 +667,33 @@ auto Graph::getBackend() const -> const Neon::Backend& } auto Graph::run(Neon::SetIdx /*setIdx*/, - int streamIdx, - Neon::DataView dataView) + int /*streamIdx*/, + Neon::DataView /*dataView*/) -> void { - if (dataView != Neon::DataView::STANDARD) { - NEON_THROW_UNSUPPORTED_OPERATION(""); - } - if (streamIdx != 0) { - NEON_THROW_UNSUPPORTED_OPERATION(""); - } - if (!mSchedulingStatusIsValid) { - helpComputeScheduling(false); - } - NEON_DEV_UNDER_CONSTRUCTION(""); + NEON_THROW_UNSUPPORTED_OPERATION(""); } -auto Graph::run(int /*streamIdx*/, - Neon::DataView /*dataView*/) +auto Graph::run(int streamIdx, + Neon::DataView dataView) -> void { - NEON_DEV_UNDER_CONSTRUCTION(""); + if (dataView != Neon::DataView::STANDARD) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + this->runtimePreSet(streamIdx); + this->helpExecute(streamIdx); } auto Graph::helpExecute(Neon::SetIdx setIdx, - bool /*filterOutAnchors*/) -> void + int anchorStream) -> void { + if (anchorStream > -1 && (anchorStream != mAnchorStreamPreSet || mFilterOutAnchorsPreSet == true)) { + Neon::NeonException ex(""); + ex << "Execution parameters are inconsistent with the preset ones."; + NEON_THROW(ex); + } + int levels = mBfs.getNumberOfLevels(); for (int i = 0; i < levels; i++) { mBfs.forEachNodeAtLevel(i, *this, [&](Neon::set::container::GraphNode& graphNode) { @@ -648,9 +714,30 @@ auto Graph::helpExecute(Neon::SetIdx setIdx, }); } } -auto Graph::helpExecute(bool /*filterOutAnchors*/) -> void + +auto Graph::helpExecute(int anchorStream) + -> void +{ + if (anchorStream > -1 && (anchorStream != mAnchorStreamPreSet || mFilterOutAnchorsPreSet == true)) { + Neon::NeonException ex(""); + ex << "Execution parameters are inconsistent with the preset ones."; + NEON_THROW(ex); + } + + int ndevs = getBackend().devSet().setCardinality(); + { +#pragma omp parallel for num_threads(ndevs) + for (int setIdx = 0; setIdx < ndevs; setIdx++) { + helpExecute(setIdx, anchorStream); + } + } +} + +auto Graph::runtimePreSet(int anchorStream) -> void { - NEON_DEV_UNDER_CONSTRUCTION(""); + helpComputeScheduling(false, anchorStream); + mAnchorStreamPreSet = anchorStream; + mFilterOutAnchorsPreSet = false; } diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index 3c7a8aa3..ea020cb9 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -10,6 +10,7 @@ GraphContainer::GraphContainer(const std::string& name, { mGraph = std::make_shared(containerGraph); setContainerExecutionType(ContainerExecutionType::graph); + setContainerOperationType(ContainerOperationType::graph); setDataViewSupport(DataViewSupport::off); setName(name); diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 18292dac..56d9df62 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -118,12 +118,51 @@ auto GraphNode::getContainerpatternType() const -> Neon::set::ContainerPatternTy auto GraphNode::getLabel(bool debug) -> std::string { - if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { + auto containerOperationType = getContainerOperationType(); + + auto printNodeInformation = [this]() { + std::stringstream s; + + auto printPositiveOrNone = [](int val) { + if (val >= 0) { + return std::to_string(val); + } + return std::string("None"); + }; + auto printNonEptyListOrNone = [](const std::vector& ids) { + if (ids.size() == 0) { + return std::string("None"); + } + std::stringstream tmp; + for (size_t i = 0; i < ids.size(); i++) { + if (i != 0) { + tmp << " "; + } + tmp << ids[i]; + } + return tmp.str(); + }; + + s << "\\l - UID: " << getContainer().getUid(); + s << "\\l - Execution: " << getContainer().getContainerExecutionType(); + s << "\\lGraphData "; + s << "\\l - Graph Node id: " << this->getGraphData().getUid(); + + s << "\\lScheduling " << getContainer().getName(); + s << "\\l - DataView: " << getScheduling().getDataView(); + s << "\\l - Stream : " << getScheduling().getStream(); + s << "\\l - Wait : " << printNonEptyListOrNone(getScheduling().getDependentEvents()); + s << "\\l - Signal : " << printPositiveOrNone(getScheduling().getEvent()); + s << "\\l ---- "; + + return s.str(); + }; + if (containerOperationType == Neon::set::ContainerOperationType::anchor) { if (this->getGraphData().beginUid == getGraphData().getUid()) { std::stringstream s; s << "Begin "; if (debug) { - s << "\\l - Graph Node id: " << this->getGraphData().getUid(); + s << printNodeInformation(); } return s.str(); } @@ -131,26 +170,23 @@ auto GraphNode::getLabel(bool debug) -> std::string std::stringstream s; s << "End "; if (debug) { - s << "\\l - Graph Node id: " << this->getGraphData().getUid(); + s << printNodeInformation(); } return s.str(); } NEON_THROW_UNSUPPORTED_OPERATION(""); } - if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { + if (containerOperationType == Neon::set::ContainerOperationType::compute) { std::stringstream s; if (debug) { s << "Container " << getContainer().getName(); - s << "\\l - Graph Node id: " << this->getGraphData().getUid(); - s << "\\l - UID: " << getContainer().getUid(); - s << "\\l - Execution: " << getContainer().getContainerExecutionType(); - s << "\\l - DataView: " << getScheduling().getDataView(); + s << printNodeInformation(); } else { s << getContainer().getName(); } return s.str(); } - if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { + if (containerOperationType == Neon::set::ContainerOperationType::halo) { std::stringstream s; s << "Halo Update " " - Name: " @@ -158,7 +194,7 @@ auto GraphNode::getLabel(bool debug) -> std::string s << " - UID: " << getContainer().getUid(); return s.str(); } - if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { + if (containerOperationType == Neon::set::ContainerOperationType::sync) { std::stringstream s; s << "Sync " " - Name: " @@ -166,6 +202,16 @@ auto GraphNode::getLabel(bool debug) -> std::string s << " - UID: " << getContainer().getUid(); return s.str(); } + if (containerOperationType == Neon::set::ContainerOperationType::graph) { + std::stringstream s; + if (debug) { + s << "Graph " << getContainer().getName(); + s << printNodeInformation(); + } else { + s << getContainer().getName(); + } + return s.str(); + } NEON_DEV_UNDER_CONSTRUCTION(""); return std::string(); } @@ -173,7 +219,8 @@ auto GraphNode::getLabel(bool debug) -> std::string auto GraphNode::getLabelProperty() -> std::string { - if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { + auto containerOperationType = getContainerOperationType(); + if (containerOperationType == Neon::set::ContainerOperationType::anchor) { if (this->getGraphData().beginUid == getGraphData().getUid()) { return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; } @@ -182,7 +229,7 @@ auto GraphNode::getLabelProperty() -> std::string } NEON_THROW_UNSUPPORTED_OPERATION(""); } - if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { + if (containerOperationType == Neon::set::ContainerOperationType::compute) { auto pattern = getContainerpatternType(); if (pattern == Neon::set::ContainerPatternType::map) { return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; @@ -193,14 +240,22 @@ auto GraphNode::getLabelProperty() -> std::string if (pattern == Neon::set::ContainerPatternType::reduction) { return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; } + if (pattern == Neon::set::ContainerPatternType::complex) { + return R"(style=filled, fillcolor="#ff33f6", color="#ff33f6")"; + } NEON_THROW_UNSUPPORTED_OPERATION(""); } - if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { + + if (containerOperationType == Neon::set::ContainerOperationType::halo) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { + + if (containerOperationType == Neon::set::ContainerOperationType::sync) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } + if (containerOperationType == Neon::set::ContainerOperationType::graph) { + return R"(shape=octagon, style="rounded,filled", fillcolor="#ff33f6", color="#ff33f6")"; + } NEON_DEV_UNDER_CONSTRUCTION(""); return std::string(); } diff --git a/libNeonSet/tests/unit/setUt_containerGraph/CMakeLists.txt b/libNeonSet/tests/unit/setUt_containerGraph/CMakeLists.txt index 0b439d70..340003ad 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/CMakeLists.txt +++ b/libNeonSet/tests/unit/setUt_containerGraph/CMakeLists.txt @@ -1,10 +1,16 @@ cmake_minimum_required(VERSION 3.19 FATAL_ERROR) + SET(APP "setUt_containerGraph") file(GLOB_RECURSE SrcFiles src/*.*) SET(APP, "setUt_containerGraph") add_executable(${APP} ${SrcFiles}) +target_compile_options(${APP} INTERFACE + $<$:${NeonCXXFlags}> + $<$:${NeonCUDAFlags}> + ) + target_link_libraries(${APP} PUBLIC libNeonSkeleton PUBLIC gtest_main) diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp similarity index 85% rename from libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cu rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp index ad4a2dd9..ee96a4a4 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cu +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp @@ -43,36 +43,39 @@ void NestedGraphsTest(TestData& data) { // NEON auto& X = data.getField(FieldNames::X); + auto& Y = data.getField(FieldNames::Y); auto& Z = data.getField(FieldNames::Z); + auto& W = data.getField(FieldNames::W); - auto generateInnerGraph = [&]() -> Neon::set::Container { + auto generateInnerGraph = [&](std::string name) -> Neon::set::Container { Neon::set::container::Graph graph; auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, "nodeB"), nodeC); - graph.ioToDot(appName, "UserGraph", false); - graph.ioToDot(appName + "-debug", "UserGraph", true); +// graph.ioToDot(appName, "UserGraph", false); +// graph.ioToDot(appName + "-debug", "UserGraph", true); - auto container = Neon::set::Container::factoryGraph("Inner", graph, [](Neon::SetIdx, Neon::set::Loader&) {}); + auto container = Neon::set::Container::factoryGraph(name + "Inner", graph, [](Neon::SetIdx, Neon::set::Loader&) {}); return container; }; - Neon::set::container::Graph graph; - auto nodeA = generateInnerGraph(); - auto nodeB = generateInnerGraph(); - auto nodeC = generateInnerGraph(); + Neon::set::container::Graph graph(data.getBackend()); + auto nodeA = generateInnerGraph("K"); + auto nodeB = generateInnerGraph("L"); + auto nodeC = generateInnerGraph("M"); graph.addNode(nodeA); graph.addNode(nodeB); graph.addNode(nodeC); - + graph.runtimePreSet(0); graph.ioToDot(appName, "UserGraph", false); graph.ioToDot(appName + "-debug", "UserGraph", true); + // timer.start(); // for (int i = 0; i < nIterations; i++) { // skl.run(); @@ -82,7 +85,7 @@ void NestedGraphsTest(TestData& data) } { // Golden data - auto time = timer.time(); + //auto time = timer.time(); Type dR = scalarVal; auto& X = data.getIODomain(FieldNames::X); @@ -133,7 +136,6 @@ int getNGpus() TEST(NestedGraphs, eGrid) { - int nGpus = getNGpus(); using Grid = Neon::domain::internal::eGrid::eGrid; using Type = int32_t; runOneTestConfiguration("eGrid_t", NestedGraphs, 1, 1); diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h index abf192cc..9bb230c7 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_runHelper.h @@ -86,7 +86,7 @@ void runAllTestConfiguration(const std::string& gname, template -void runOneTestConfiguration(const std::string& gname, +void runOneTestConfiguration(const std::string& , std::function&)> f, int nGpus, int minNumGpus) From 1a67851540e1375a93744584f406b8f3d32c918e Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Wed, 31 Aug 2022 09:18:43 -0400 Subject: [PATCH 28/67] WIP --- libNeonCore/include/Neon/core/types/digraph.h | 27 +++ libNeonSet/include/Neon/set/container/Graph.h | 14 +- libNeonSet/src/set/container/Graph.cpp | 180 +++++++++++++++--- .../src/set/container/graph/GraphNode.cpp | 9 +- .../src/setUt_containerGraph_NestedGraphs.cpp | 32 +++- .../src/setUt_containerGraph_kernels.h | 2 +- 6 files changed, 224 insertions(+), 40 deletions(-) diff --git a/libNeonCore/include/Neon/core/types/digraph.h b/libNeonCore/include/Neon/core/types/digraph.h index bc95e911..8f125e13 100644 --- a/libNeonCore/include/Neon/core/types/digraph.h +++ b/libNeonCore/include/Neon/core/types/digraph.h @@ -187,6 +187,18 @@ class DiGraph } } + /** + * Run a function on each vertex in the graph + * + * @param fn Function that takes in a vertex and does something + */ + void forEachVertex(std::function fn) const + { + for (auto& kv : mAdj) { + fn(kv.first); + } + } + /** * Returns a copy of incoming edges from a vertex as pairs of vertex ids * @@ -313,6 +325,21 @@ class DiGraph } } + /** + * Run a function on each edge + * + * @param fn Function that takes in an edge and does something + */ + void forEachEdge(std::function fn) const + { + for (auto i : mAdj) { + size_t src = i.first; + for (size_t tgt : i.second) { + fn({src, tgt}); + } + } + } + /** * Get a const-ref to the vertex property * diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 330524a2..ad2ff79a 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -38,10 +38,17 @@ struct Graph -> GraphNode&; /** - * Remove Node + * Remove node by maintaining the dependencies between + * proceeding and following nodes */ auto removeNode(GraphNode& gn) - -> GraphNode; + -> Neon::set::Container; + + /** + * Remove a node and its dependencies + */ + auto removeNodeAndItsDependencies(GraphNode& gn) + -> Neon::set::Container; /** * Adds a dependency between two nodes of the graph @@ -111,7 +118,8 @@ struct Graph auto getBackend() const -> const Neon::Backend&; - + auto expandSubGraphs() + -> void; protected: /** diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 3c95d65e..01dd4b3d 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -58,6 +58,9 @@ auto Graph::addDependency(const GraphNode& nodeA, const GraphNode& nodeB, GraphDependencyType type) -> GraphDependency& { + if (nodeA.getGraphData().getUid() == nodeB.getGraphData().getUid()) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } helpInvalidateScheduling(); GraphDependency ab(type); @@ -70,44 +73,89 @@ auto Graph::addDependency(const GraphNode& nodeA, nodeB.getGraphData().getUid()}); } -auto Graph::removeNode(GraphNode& gn) -> GraphNode +auto Graph::removeNode(GraphNode& gn) -> Container { helpInvalidateScheduling(); auto uidB = gn.getGraphData().getUid(); - std::vector a_toBeConnectedToEnd; - mRawGraph.forEachInEdge(uidB, [&](const RawGraph::Edge& edge) -> void { - auto uidA = edge.first; - int outEdgesFromA = mRawGraph.outEdgesCount(uidA); - if (outEdgesFromA == 1) { - a_toBeConnectedToEnd.push_back(uidA); + if (uidB == getBeginNode().getGraphData().getUid() || + uidB == getEndNode().getGraphData().getUid()) { + NeonException ex(""); + ex << "Begin or end nodes can not be removed"; + NEON_THROW(ex); + } + + // a. get all in and our edges + // b. connect each in node all the out nodes + + auto inNodes = mRawGraph.inNeighbors(uidB); + auto outNodes = mRawGraph.outNeighbors(uidB); + + for (auto inNodeId : inNodes) { + for (auto outNodeId : outNodes) { + auto& inNode = mRawGraph.getVertexProperty(inNodeId); + auto& outNode = mRawGraph.getVertexProperty(outNodeId); + auto& inNodeDepWithTarget = mRawGraph.getEdgeProperty({inNodeId, uidB}); + this->addDependency(inNode, outNode, inNodeDepWithTarget.getType()); } - }); + } + + for (auto inNodeId : inNodes) { + mRawGraph.removeEdge({inNodeId, uidB}); + } + for (auto outNodeId : outNodes) { + mRawGraph.removeEdge({uidB, outNodeId}); + } + + mRawGraph.removeVertex(uidB); + gn.getGraphData().setUid(-1); + + return gn.getContainer(); +} + +auto Graph::removeNodeAndItsDependencies(GraphNode& gn) + -> Container +{ + auto uidB = gn.getGraphData().getUid(); + + if (uidB == getBeginNode().getGraphData().getUid() || + uidB == getEndNode().getGraphData().getUid()) { + NeonException ex(""); + ex << "Begin or end nodes can not be removed"; + NEON_THROW(ex); + } - std::vector c_toBeConnectedToBegin; - mRawGraph.forEachOutEdge(uidB, [&](const RawGraph::Edge& edge) -> void { - auto uidC = edge.second; - int inEdgesIntoC = mRawGraph.outEdgesCount(uidC); - if (inEdgesIntoC == 1) { - a_toBeConnectedToEnd.push_back(uidC); + helpInvalidateScheduling(); + + auto inNodes = mRawGraph.inNeighbors(uidB); + auto outNodes = mRawGraph.outNeighbors(uidB); + + for (auto inNodeId : inNodes) { + auto& inNode = mRawGraph.getVertexProperty(inNodeId); + if (inNodeId != getBeginNode().getGraphData().getUid()) { + this->addDependency(getBeginNode(), inNode, GraphDependencyType::data); } - }); + } - for (auto&& uidA : a_toBeConnectedToEnd) { - auto& nodeA = mRawGraph.getVertexProperty(uidA); - addDependency(nodeA, this->getEndNode(), GraphDependencyType::data); + for (auto outNodeId : outNodes) { + auto& outNode = mRawGraph.getVertexProperty(outNodeId); + if (outNodeId != getEndNode().getGraphData().getUid()) { + this->addDependency(outNode, getBeginNode(), GraphDependencyType::data); + } } - for (auto&& uidC : c_toBeConnectedToBegin) { - auto& nodeC = mRawGraph.getVertexProperty(uidC); - addDependency(this->getBeginNode(), nodeC, GraphDependencyType::data); + for (auto inNodeId : inNodes) { + mRawGraph.removeEdge({inNodeId, uidB}); + } + for (auto outNodeId : outNodes) { + mRawGraph.removeEdge({uidB, outNodeId}); } - GraphNode removed = mRawGraph.getVertexProperty(gn.getGraphData().getUid()); - removed.getGraphData().setUid(GraphData::notSet); + mRawGraph.removeVertex(uidB); + gn.getGraphData().setUid(-1); - return removed; + return gn.getContainer(); } auto Graph::getProceedingGraphNodes(const GraphNode& graphNode, @@ -555,7 +603,7 @@ auto Graph::helpComputeScheduling_02_mappingStreams(Bfs& bfs, endNode.getScheduling().setStream(anchorStream); } - this->ioToDot("tge","tge", true); + this->ioToDot("tge", "tge", true); return mMaxNumberStreams - 1; } @@ -739,6 +787,88 @@ auto Graph::runtimePreSet(int anchorStream) -> void mAnchorStreamPreSet = anchorStream; mFilterOutAnchorsPreSet = false; } +auto Graph::expandSubGraphs() -> void +{ + bool atLeastOneWasFound = false; + + auto searchForSubGraph = [&]() -> std::tuple { + bool found = false; + size_t target = 0; + mRawGraph.forEachVertex([&](size_t id) { + auto& node = mRawGraph.getVertexProperty(id); + if (node.getContainer().getContainerExecutionType() == ContainerExecutionType::graph) { + target = id; + found = true; + atLeastOneWasFound = true; + } + }); + return {target, found}; + }; + int i = -1; + while (true) { + i++; + auto [newTargetId, validTarget] = searchForSubGraph(); + if (!validTarget) { + if (atLeastOneWasFound) { + helpInvalidateScheduling(); + this->helpRemoveRedundantDependencies(); + // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); + } + return; + } + // this->ioToDot(std::to_string(i) + "_t_00", "kllkj", true); + + auto& newTarget = mRawGraph.getVertexProperty(newTargetId); + const auto& subGraph = newTarget.getContainer().getContainerInterface().getGraph(); + + std::unordered_map fromOldToNew; + + // Cloning the subGraph nodes into the graph + subGraph.mRawGraph.forEachVertex([&](size_t id) { + const auto& oldNode = subGraph.mRawGraph.getVertexProperty(id); + const auto& newNode = this->addNode(oldNode.getContainer()); + fromOldToNew.insert(std::pair(oldNode.getGraphData().getUid(), + newNode.getGraphData().getUid())); + }); + ///this->ioToDot(std::to_string(i) + "_t_01", "kllkj", true); + + // Cloning the subGraph edges into the graph + subGraph.mRawGraph.forEachEdge([&](std::pair edge) { + const auto& oldDep = subGraph.mRawGraph.getEdgeProperty(edge); + size_t newA = fromOldToNew.at(edge.first); + size_t newB = fromOldToNew.at(edge.second); + + const auto& nodeA = mRawGraph.getVertexProperty(newA); + const auto& nodeB = mRawGraph.getVertexProperty(newB); + + this->addDependency(nodeA, nodeB, oldDep.getType()); + }); + //this->ioToDot(std::to_string(i) + "_t_02", "kllkj", true); + + { // Removing the cloned begin and end from the subGraph + auto oldBeginId = subGraph.getBeginNode().getGraphData().getUid(); + auto oldEndId = subGraph.getEndNode().getGraphData().getUid(); + + auto toBeRemovedBeginId = fromOldToNew.at(oldBeginId); + auto toBeRemovedEndId = fromOldToNew.at(oldEndId); + + auto& toBeRemovedBeginNode = mRawGraph.getVertexProperty(toBeRemovedBeginId); + auto& toBeRemovedEndNode = mRawGraph.getVertexProperty(toBeRemovedEndId); + + this->removeNode(toBeRemovedBeginNode); + this->removeNode(toBeRemovedEndNode); + } + // this->ioToDot(std::to_string(i) + "_t_03", "kllkj", true); + + { // Removing subGraph and depedencies + + this->removeNodeAndItsDependencies(newTarget); + std::cout << "removing " << newTarget.getContainer().getName() << std::endl; + } + //this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); + } + +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 56d9df62..220b426d 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -174,6 +174,12 @@ auto GraphNode::getLabel(bool debug) -> std::string } return s.str(); } + std::stringstream s; + s << "Sporious Anchor "; + if (debug) { + s << printNodeInformation(); + } + return s.str(); NEON_THROW_UNSUPPORTED_OPERATION(""); } if (containerOperationType == Neon::set::ContainerOperationType::compute) { @@ -227,7 +233,8 @@ auto GraphNode::getLabelProperty() -> std::string if (this->getGraphData().endUid == getGraphData().getUid()) { return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; } - NEON_THROW_UNSUPPORTED_OPERATION(""); + //NEON_THROW_UNSUPPORTED_OPERATION(""); + return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; } if (containerOperationType == Neon::set::ContainerOperationType::compute) { auto pattern = getContainerpatternType(); diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp index ee96a4a4..8f2dcaec 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp @@ -52,29 +52,41 @@ void NestedGraphsTest(TestData& data) auto generateInnerGraph = [&](std::string name) -> Neon::set::Container { Neon::set::container::Graph graph; - auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); - auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); - graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, "nodeB"), nodeC); + auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, name+"-StageA")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, name+"-StageC")); + graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, name+"-StageB"), nodeC); // graph.ioToDot(appName, "UserGraph", false); // graph.ioToDot(appName + "-debug", "UserGraph", true); - auto container = Neon::set::Container::factoryGraph(name + "Inner", graph, [](Neon::SetIdx, Neon::set::Loader&) {}); + auto container = Neon::set::Container::factoryGraph(name, graph, [](Neon::SetIdx, Neon::set::Loader&) {}); return container; }; Neon::set::container::Graph graph(data.getBackend()); - auto nodeA = generateInnerGraph("K"); - auto nodeB = generateInnerGraph("L"); - auto nodeC = generateInnerGraph("M"); + auto nodeA = generateInnerGraph("GraphK"); + auto nodeB = generateInnerGraph("GraphL"); + auto nodeC = generateInnerGraph("GraphM"); graph.addNode(nodeA); graph.addNode(nodeB); graph.addNode(nodeC); - graph.runtimePreSet(0); - graph.ioToDot(appName, "UserGraph", false); - graph.ioToDot(appName + "-debug", "UserGraph", true); + { + auto fname = appName + "_withSubGraph"; + graph.runtimePreSet(0); + graph.ioToDot(fname, "UserGraph", false); + graph.ioToDot(fname + "-debug", "UserGraph", true); + } + + { + auto fname = appName + "_expandSubGraphs"; + + graph.expandSubGraphs(); + graph.runtimePreSet(0); + graph.ioToDot(fname, "UserGraph", false); + graph.ioToDot(fname + "-debug", "UserGraph", true); + } // timer.start(); // for (int i = 0; i < nIterations; i++) { diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h index 035b5488..de12b2c1 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h @@ -59,7 +59,7 @@ auto axpy(const Neon::template PatternScalar& fR, const std::string& name) -> Neon::set::Container { auto Kontainer = x.getGrid().getContainer( - "AXPY" + name, [&](Neon::set::Loader & L) -> auto{ + name + "-AXPY", [&](Neon::set::Loader & L) -> auto{ auto& xLocal = L.load(x); auto& yLocal = L.load(y); auto fRLocal = L.load(fR); From cc478a86b720e5b3f201fd78a85d124033d845a8 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Thu, 1 Sep 2022 21:33:22 -0400 Subject: [PATCH 29/67] WIP --- .../include/Neon/domain/tools/IODomain.h | 10 +- libNeonSet/include/Neon/set/container/Graph.h | 2 + .../Neon/set/container/GraphContainer.h | 2 +- libNeonSet/src/set/container/Graph.cpp | 11 ++ .../src/set/container/GraphContainer.cpp | 18 +- ...t_containerGraph_ThreeIndependentMaps.cpp} | 37 ++-- ...> setUt_containerGraph_ThreePipedMaps.cpp} | 0 .../src/setUt_containerGraph_kernels.cu | 158 ++++++++++++++++++ .../src/setUt_containerGraph_kernels.h | 138 ++------------- 9 files changed, 221 insertions(+), 155 deletions(-) rename libNeonSet/tests/unit/setUt_containerGraph/src/{setUt_containerGraph_ThreeIndependentMaps.cu => setUt_containerGraph_ThreeIndependentMaps.cpp} (77%) rename libNeonSet/tests/unit/setUt_containerGraph/src/{setUt_containerGraph_ThreePipedMaps.cu => setUt_containerGraph_ThreePipedMaps.cpp} (100%) create mode 100644 libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.cu diff --git a/libNeonDomain/include/Neon/domain/tools/IODomain.h b/libNeonDomain/include/Neon/domain/tools/IODomain.h index c9ebc15c..84782b96 100644 --- a/libNeonDomain/include/Neon/domain/tools/IODomain.h +++ b/libNeonDomain/include/Neon/domain/tools/IODomain.h @@ -248,7 +248,7 @@ auto IODomain::resetValuesToMasked(ExportType offset, template auto IODomain::resetValuesToConst(ExportType offset) -> void { - mField.forEach([&](const Integer_3d& idx, int c, ExportType& val) { + mField.forEach([&](const Integer_3d&, int, ExportType& val) { val = offset; }); } @@ -363,9 +363,9 @@ auto IODomain::maxDiff(const IODomain& idx, - int c, - const ExportType& valA, - const ExportType& valB) { + int c, + const ExportType& valA, + const ExportType& valB) { const auto newDiff = std::abs(valA - valB); const int threadId = omp_get_thread_num(); if (newDiff > std::get<0>(max_diff[threadId])) { @@ -375,7 +375,7 @@ auto IODomain::maxDiff(const IODomain(md) = c; } }, - b); + b); int target = 0; for (auto i = 1; i < nThreads; i++) { diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index ad2ff79a..71956308 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -127,6 +127,8 @@ struct Graph */ auto helpInvalidateScheduling() -> void; + auto helpCheckBackendStatus() -> void; + /** * Remove redundant dependencies */ diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index d9fc7956..b53b2628 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -48,7 +48,7 @@ struct GraphContainer : ContainerAPI private: std::function mLoadingLambda; - std::shared_ptr mGraph; + std::shared_ptr mGraph; }; } // namespace Neon::set::internal diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 01dd4b3d..027ec2bb 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -32,6 +32,7 @@ auto Graph::addNodeInBetween(const GraphNode& nodeA, const GraphDependencyType ab, const GraphDependencyType bc) -> GraphNode& { + helpCheckBackendStatus(); helpInvalidateScheduling(); auto& nodeB = addNode(containerB); @@ -42,6 +43,7 @@ auto Graph::addNodeInBetween(const GraphNode& nodeA, auto Graph::addNode(const Container& container) -> GraphNode& { + helpCheckBackendStatus(); helpInvalidateScheduling(); auto const& node = GraphNode(container, mUidCounter); @@ -58,6 +60,7 @@ auto Graph::addDependency(const GraphNode& nodeA, const GraphNode& nodeB, GraphDependencyType type) -> GraphDependency& { + helpCheckBackendStatus(); if (nodeA.getGraphData().getUid() == nodeB.getGraphData().getUid()) { NEON_THROW_UNSUPPORTED_OPERATION(""); } @@ -869,6 +872,14 @@ auto Graph::expandSubGraphs() -> void } } +auto Graph::helpCheckBackendStatus() -> void +{ + if(!mBackendIsSet){ + NeonException exception("Container Graph"); + exception << "A backend was not registered with the Graph"; + NEON_THROW(exception); + } +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index ea020cb9..bd4aa473 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -60,20 +60,20 @@ auto GraphContainer::getDeviceContainer() -> std::shared_ptr void +auto GraphContainer::run(int streamIdx, + Neon::DataView dataView) -> void { - /// mGraph->run(streamIdx, dataView); + mGraph->run(streamIdx, dataView); } -auto GraphContainer::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, +auto GraphContainer::run(Neon::SetIdx /*setIdx*/, + int /*streamIdx*/, Neon::DataView /*dataView*/) -> void { -// if (ContainerExecutionType::graph == this->getContainerExecutionType()) { -// mGraph->run(setIdx, streamIdx, dataView); -// } -// NEON_THROW_UNSUPPORTED_OPTION(""); + // if (ContainerExecutionType::graph == this->getContainerExecutionType()) { + // mGraph->run(setIdx, streamIdx, dataView); + // } + // NEON_THROW_UNSUPPORTED_OPTION(""); } } // namespace Neon::set::internal diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cpp similarity index 77% rename from libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cu rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cpp index 2fbb707b..9c5882bc 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cu +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreeIndependentMaps.cpp @@ -38,7 +38,8 @@ void ThreeIndependentMapsTest(TestData& data) fR() = scalarVal; data.getBackend().syncAll(); - data.resetValuesToRandom(1, 50); + //data.resetValuesToRandom(1, 50); + data.resetValuesToConst(1, 50); Neon::Timer_sec timer; { // NEON @@ -47,7 +48,7 @@ void ThreeIndependentMapsTest(TestData& data) auto& Z = data.getField(FieldNames::Z); auto& W = data.getField(FieldNames::W); - Neon::set::container::Graph graph; + Neon::set::container::Graph graph(data.getBackend()); graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); graph.addNode(UserTools::axpy(fR, W, Y, "nodeB")); @@ -56,38 +57,45 @@ void ThreeIndependentMapsTest(TestData& data) graph.ioToDot(appName, "UserGraph", false); graph.ioToDot(appName + "-debug", "UserGraph", true); + Neon::set::Container exec = Neon::set::Container::factoryGraph("Test", graph, [&](Neon::SetIdx, + Neon::set::Loader& loader) { + loader.load(X); + loader.load(Y); + loader.load(Z); + }); - // timer.start(); - // for (int i = 0; i < nIterations; i++) { - // skl.run(); - // } - // data.getBackend().syncAll(); - // timer.stop(); + timer.start(); + for (int i = 0; i < nIterations; i++) { + exec.run(0); + } + data.getBackend().syncAll(); + timer.stop(); } { // Golden data - auto time = timer.time(); Type dR = scalarVal; auto& X = data.getIODomain(FieldNames::X); auto& Y = data.getIODomain(FieldNames::Y); + auto& Z = data.getIODomain(FieldNames::Z); + auto& W = data.getIODomain(FieldNames::W); for (int i = 0; i < nIterations; i++) { - data.axpy(&dR, Y, X); - data.laplace(X, Y); - data.axpy(&dR, Y, Y); + data.axpy(&dR, W, X); + data.axpy(&dR, W, Y); + data.axpy(&dR, W, Z); } } bool isOk = data.compare(FieldNames::X); isOk = isOk && data.compare(FieldNames::Y); - /*{ // DEBUG + { // DEBUG data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); data.getField(FieldNames::X).ioToVtk("Field_X", "X"); data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); - }*/ + } ASSERT_TRUE(isOk); } @@ -117,7 +125,6 @@ int getNGpus() TEST(ThreeIndependentMaps, eGrid) { - int nGpus = getNGpus(); using Grid = Neon::domain::internal::eGrid::eGrid; using Type = int32_t; runOneTestConfiguration("eGrid_t", ThreeIndependentMaps, 1, 1); diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp similarity index 100% rename from libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cu rename to libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.cu b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.cu new file mode 100644 index 00000000..d8057a7c --- /dev/null +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.cu @@ -0,0 +1,158 @@ +#include "setUt_containerGraph_kernels.h" + +namespace UserTools { +template +auto xpy(const Field& x, + Field& y) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + "xpy", [&](Neon::set::Loader & L) -> auto{ + auto& xLocal = L.load(x); + auto& yLocal = L.load(y); + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { + for (int i = 0; i < yLocal.cardinality(); i++) { + yLocal(e, i) += xLocal(e, i); + } + }; + }); + return Kontainer; +} + +template +auto aInvXpY(const Neon::template PatternScalar& fR, + const Field& x, + Field& y) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + "AXPY", [&](Neon::set::Loader & L) -> auto{ + auto& xLocal = L.load(x); + auto& yLocal = L.load(y); + auto fRLocal = L.load(fR); + const auto fRVal = fRLocal(); + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { + // printf("%d yLocal.cardinality()\n", yLocal.cardinality()); + + for (int i = 0; i < yLocal.cardinality(); i++) { + // printf("%d %d (%d) x\n", e, xLocal(e, i), i); + yLocal(e, i) += (1.0 / fRVal) * xLocal(e, i); + } + }; + }); + return Kontainer; +} + +template +auto axpy(const Neon::template PatternScalar& fR, + const Field& x, + Field& y, + const std::string& name) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + name + "-AXPY", [&](Neon::set::Loader & L) -> auto{ + auto& xLocal = L.load(x); + auto& yLocal = L.load(y); + auto fRLocal = L.load(fR); + const auto fRVal = fRLocal(); + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { + // printf("%d yLocal.cardinality()\n", yLocal.cardinality()); + + for (int i = 0; i < yLocal.cardinality(); i++) { + // printf("%d %d (%d) x\n", e, xLocal(e, i), i); + yLocal(e, i) += fRVal * xLocal(e, i); + } + }; + }); + return Kontainer; +} + +template +auto laplace(const Field& x, + Field& y, + size_t sharedMem ) -> Neon::set::Container +{ + auto Kontainer = x.getGrid().getContainer( + "Laplace", [&](Neon::set::Loader & L) -> auto{ + auto& xLocal = L.load(x, Neon::Compute::STENCIL); + auto& yLocal = L.load(y); + + return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& cell) mutable { + using Type = typename Field::Type; + for (int card = 0; card < xLocal.cardinality(); card++) { + typename Field::Type res = 0; + + + auto checkNeighbor = [&res](Neon::domain::NghInfo& neighbor) { + if (neighbor.isValid) { + res += neighbor.value; + } + }; + + // Laplacian stencil operates on 6 neighbors (assuming 3D) + if constexpr (std::is_same::value) { + for (int8_t nghIdx = 0; nghIdx < 6; ++nghIdx) { + auto neighbor = xLocal.nghVal(cell, nghIdx, card, Type(0)); + checkNeighbor(neighbor); + } + } else { + typename Field::Partition::nghIdx_t ngh(0, 0, 0); + + //+x + ngh.x = 1; + ngh.y = 0; + ngh.z = 0; + auto neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //-x + ngh.x = -1; + ngh.y = 0; + ngh.z = 0; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //+y + ngh.x = 0; + ngh.y = 1; + ngh.z = 0; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //-y + ngh.x = 0; + ngh.y = -1; + ngh.z = 0; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //+z + ngh.x = 0; + ngh.y = 0; + ngh.z = 1; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + + //-z + ngh.x = 0; + ngh.y = 0; + ngh.z = -1; + neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); + checkNeighbor(neighbor); + } + + + yLocal(cell, card) = -6 * res; + } + }; + }); + return Kontainer; +} + + +template auto xpy(const eField32_t& x, eField32_t& y) -> Neon::set::Container; + +template auto axpy(const Neon::template PatternScalar& fR, + const eField32_t& x, + eField32_t& y, + const std::string& name) -> Neon::set::Container; + +} // namespace UserTools \ No newline at end of file diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h index de12b2c1..891ff153 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_kernels.h @@ -14,148 +14,36 @@ namespace UserTools { template auto xpy(const Field& x, - Field& y) -> Neon::set::Container -{ - auto Kontainer = x.getGrid().getContainer( - "xpy", [&](Neon::set::Loader & L) -> auto{ - auto& xLocal = L.load(x); - auto& yLocal = L.load(y); - return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { - for (int i = 0; i < yLocal.cardinality(); i++) { - yLocal(e, i) += xLocal(e, i); - } - }; - }); - return Kontainer; -} + Field& y) -> Neon::set::Container; template auto aInvXpY(const Neon::template PatternScalar& fR, const Field& x, - Field& y) -> Neon::set::Container -{ - auto Kontainer = x.getGrid().getContainer( - "AXPY", [&](Neon::set::Loader & L) -> auto{ - auto& xLocal = L.load(x); - auto& yLocal = L.load(y); - auto fRLocal = L.load(fR); - const auto fRVal = fRLocal(); - return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { - // printf("%d yLocal.cardinality()\n", yLocal.cardinality()); - - for (int i = 0; i < yLocal.cardinality(); i++) { - // printf("%d %d (%d) x\n", e, xLocal(e, i), i); - yLocal(e, i) += (1.0 / fRVal) * xLocal(e, i); - } - }; - }); - return Kontainer; -} + Field& y) -> Neon::set::Container; template auto axpy(const Neon::template PatternScalar& fR, const Field& x, Field& y, - const std::string& name) -> Neon::set::Container -{ - auto Kontainer = x.getGrid().getContainer( - name + "-AXPY", [&](Neon::set::Loader & L) -> auto{ - auto& xLocal = L.load(x); - auto& yLocal = L.load(y); - auto fRLocal = L.load(fR); - const auto fRVal = fRLocal(); - return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& e) mutable { - // printf("%d yLocal.cardinality()\n", yLocal.cardinality()); - - for (int i = 0; i < yLocal.cardinality(); i++) { - // printf("%d %d (%d) x\n", e, xLocal(e, i), i); - yLocal(e, i) += fRVal * xLocal(e, i); - } - }; - }); - return Kontainer; -} + const std::string& name) -> Neon::set::Container; template auto laplace(const Field& x, Field& y, - size_t sharedMem = 0) -> Neon::set::Container -{ - auto Kontainer = x.getGrid().getContainer( - "Laplace", [&](Neon::set::Loader & L) -> auto{ - auto& xLocal = L.load(x, Neon::Compute::STENCIL); - auto& yLocal = L.load(y); - - return [=] NEON_CUDA_HOST_DEVICE(const typename Field::Cell& cell) mutable { - using Type = typename Field::Type; - for (int card = 0; card < xLocal.cardinality(); card++) { - typename Field::Type res = 0; - - - auto checkNeighbor = [&res](Neon::domain::NghInfo& neighbor) { - if (neighbor.isValid) { - res += neighbor.value; - } - }; - - // Laplacian stencil operates on 6 neighbors (assuming 3D) - if constexpr (std::is_same::value) { - for (int8_t nghIdx = 0; nghIdx < 6; ++nghIdx) { - auto neighbor = xLocal.nghVal(cell, nghIdx, card, Type(0)); - checkNeighbor(neighbor); - } - } else { - typename Field::Partition::nghIdx_t ngh(0, 0, 0); - - //+x - ngh.x = 1; - ngh.y = 0; - ngh.z = 0; - auto neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); - checkNeighbor(neighbor); - - //-x - ngh.x = -1; - ngh.y = 0; - ngh.z = 0; - neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); - checkNeighbor(neighbor); - - //+y - ngh.x = 0; - ngh.y = 1; - ngh.z = 0; - neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); - checkNeighbor(neighbor); + size_t sharedMem = 0) -> Neon::set::Container; - //-y - ngh.x = 0; - ngh.y = -1; - ngh.z = 0; - neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); - checkNeighbor(neighbor); - //+z - ngh.x = 0; - ngh.y = 0; - ngh.z = 1; - neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); - checkNeighbor(neighbor); +using eField32_t = Neon::domain::internal::eGrid::eGrid::Field; - //-z - ngh.x = 0; - ngh.y = 0; - ngh.z = -1; - neighbor = xLocal.nghVal(cell, ngh, card, Type(0)); - checkNeighbor(neighbor); - } +extern template auto xpy(const eField32_t& x, eField32_t& y) -> Neon::set::Container; +extern template auto axpy(const Neon::template PatternScalar& fR, + const eField32_t& x, + eField32_t& y, + const std::string& name) -> Neon::set::Container; - yLocal(cell, card) = -6 * res; - } - }; - }); - return Kontainer; -} +extern template auto laplace(const eField32_t& x, + eField32_t& y, + size_t sharedMem) -> Neon::set::Container; } // namespace UserTools \ No newline at end of file From 08a3a40fd4c90293e0bd2e54e47599456cbbcc45 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Mon, 12 Sep 2022 13:36:29 -0400 Subject: [PATCH 30/67] New container graph completed, including unit tests. --- .../include/Neon/domain/tools/TestData.h | 3 +- libNeonSet/include/Neon/set/container/Graph.h | 59 +++++++++++--- .../Neon/set/container/GraphContainer.h | 4 +- libNeonSet/src/set/container/Graph.cpp | 79 ++++++++++++------- .../src/set/container/GraphContainer.cpp | 11 +-- .../src/setUt_containerGraph_NestedGraphs.cpp | 57 ++++--------- .../setUt_containerGraph_ThreePipedMaps.cpp | 43 +++++----- 7 files changed, 143 insertions(+), 113 deletions(-) diff --git a/libNeonDomain/include/Neon/domain/tools/TestData.h b/libNeonDomain/include/Neon/domain/tools/TestData.h index f2d1a534..54fff3bc 100644 --- a/libNeonDomain/include/Neon/domain/tools/TestData.h +++ b/libNeonDomain/include/Neon/domain/tools/TestData.h @@ -342,7 +342,8 @@ auto TestData::laplace(IODomain& A, NEON_IO IODomain& B) } template -auto TestData::compare(FieldNames name, T tollerance) -> bool +auto TestData::compare(FieldNames name, + [[maybe_unused]] T tollerance) -> bool { bool isTheSame = false; if constexpr (std::is_integral_v) { diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 71956308..5403fd02 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -9,6 +9,14 @@ namespace Neon::set::container { +/** + * Abstraction for a graph of containers. + * Each graph node represents a Neon container, + * directed edges of the graph are dependencies between the containers. + * Dependencies my be data driven or user provided. + * + * + */ struct Graph { using Uid = GraphData::Uid; @@ -98,15 +106,24 @@ struct Graph auto getSubsequentGraphNodes(const GraphNode& graphNode, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) -> std::vector; + /** + * Set the stream to run the graph. + * We provide a preset function so that some initialization + * could be only once, before executing the run method. + */ auto runtimePreSet(int anchorStream) -> void; + /** - * Execute the scheduling operation associated to the node + * Execute the graph on all devices */ auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void; + /** + * Run the graph on a target device. + */ auto run(Neon::SetIdx setIdx, int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) @@ -116,21 +133,34 @@ struct Graph const std::string& graphName, bool debug) -> void; + /** + * Returns a reference for the used backend. + */ auto getBackend() const -> const Neon::Backend&; + /** + * Recursively iterate through the graph nodes + * to expand any graph type of node. + */ auto expandSubGraphs() -> void; + auto getNumberOfNodes() + ->int; + protected: /** * Invalidate all scheduling information that were computed */ auto helpInvalidateScheduling() -> void; + /** + * Helper - it checks the initialization of the backend. + */ auto helpCheckBackendStatus() -> void; /** - * Remove redundant dependencies + * Helper - it removes redundant dependencies */ auto helpRemoveRedundantDependencies() -> void; @@ -205,41 +235,44 @@ struct Graph -> void; /** - * Execute + * Helper - it executes the graph on all devices */ auto helpExecute(int anchorStream) -> void; + /** + * Helper - it executes the graph on a target device + */ auto helpExecute(Neon::SetIdx setIdx, int anchorStream) -> void; /** - * Resetting node's data related to scheduling + * Helper - It resets node scheduling data */ auto helpComputeScheduling_00_resetData() -> void; /** - * Resetting node's data related to scheduling + * Helper - it generates a BFS visit structure for the graph */ auto helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) -> Bfs; /** - * Maps node to streams. + * Helper - it maps node to streams. * Returns the max stream Id used by the scheduling */ auto helpComputeScheduling_02_mappingStreams(Bfs& bfs, bool filterOutAnchors, int anchorStream) -> int; /** - * Define events to be waited and fired from each node + * Helper - it defines events to be waited and fired from each node * Returns the max event Id used by the scheduling. */ auto helpComputeScheduling_03_events(Bfs& bfs) -> int; /** - * Booking the required resources from the backend. + * Helper - it Books the required resources from the backend. */ auto helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) -> void; @@ -247,13 +280,13 @@ struct Graph using RawGraph = DiGraph; - Uid mUidCounter; - RawGraph mRawGraph; + Uid mUidCounter /**< internal counter to create node uids */; + RawGraph mRawGraph /**< raw graph structure */; bool mSchedulingStatusIsValid; - int mMaxNumberStreams; - Bfs mBfs; + int mMaxNumberStreams /**< Max number of streams used in the scheduling phase */; + Bfs mBfs /**< Structure for the BFS visit. */; - Backend mBackend; + Backend mBackend /**< Backend used to create streams and events */; bool mBackendIsSet = false; bool mFilterOutAnchorsPreSet = false; diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index b53b2628..3630ce1a 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -40,7 +40,9 @@ struct GraphContainer : ContainerAPI * @param streamIdx * @param dataView */ - auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + auto run(int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void override; auto run(Neon::SetIdx setIdx, int streamIdx = 0, diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 027ec2bb..74a92820 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -192,7 +192,8 @@ auto Graph::getProceedingGraphNodes(const GraphNode& grap } auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, - const std::vector& dependencyTypes) -> std::vector + const std::vector& dependencyTypes) + -> std::vector { std::vector nodes; @@ -255,12 +256,14 @@ auto Graph::getDependencyType(const GraphNode& nodeA, return dependencyType; } -auto Graph::helpInvalidateScheduling() -> void +auto Graph::helpInvalidateScheduling() + -> void { mSchedulingStatusIsValid = false; } -auto Graph::helpRemoveRedundantDependencies() -> void +auto Graph::helpRemoveRedundantDependencies() + -> void { // Vectors of edges to be removed std::vector> edgesToBeRemoved; @@ -330,7 +333,8 @@ auto Graph::helpRemoveRedundantDependencies() -> void auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, bool filteredOut, - const std::vector& dependencyTypes) -> std::set + const std::vector& dependencyTypes) + -> std::set { std::set outNgh; mRawGraph.forEachOutEdge( @@ -350,7 +354,10 @@ auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, return outNgh; } -auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, bool filterOutBegin, const std::vector& dependencyTypes) -> std::set +auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, + bool filterOutBegin, + const std::vector& dependencyTypes) + -> std::set { std::set inNgh; mRawGraph.forEachInEdge( @@ -371,7 +378,8 @@ auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, bool filterOutBegin, cons auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, bool filterOutEnd, - const std::vector& dependencyTypes) -> std::set> + const std::vector& dependencyTypes) + -> std::set> { std::set> outEdges; mRawGraph.forEachOutEdge( @@ -392,7 +400,8 @@ auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, auto Graph::helpGetInEdges(GraphData::Uid nodeUid, bool filterOutBegin, - const std::vector& dependencyTypes) -> std::set> + const std::vector& dependencyTypes) + -> std::set> { std::set> inEdges; mRawGraph.forEachInEdge( @@ -471,7 +480,8 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd return bfs; } -auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> void +auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) + -> void { helpComputeScheduling_00_resetData(); mBfs = helpComputeScheduling_01_generatingBFS(filterOutAnchors); @@ -480,7 +490,8 @@ auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> vo helpComputeScheduling_04_ensureResources(maxStreamId, maxEventId); } -auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) -> Bfs +auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) + -> Bfs { return helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); @@ -610,7 +621,8 @@ auto Graph::helpComputeScheduling_02_mappingStreams(Bfs& bfs, return mMaxNumberStreams - 1; } -auto Graph::helpComputeScheduling_03_events(Bfs& bfs) -> int +auto Graph::helpComputeScheduling_03_events(Bfs& bfs) + -> int { int eventCount = 0; @@ -648,7 +660,8 @@ auto Graph::helpComputeScheduling_03_events(Bfs& bfs) -> int return eventCount - 1; } -auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) +auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, + int maxEventId) -> void { auto bk = getBackend(); @@ -707,7 +720,8 @@ Graph::Graph(const Backend& bk) helpInvalidateScheduling(); } -auto Graph::getBackend() const -> const Neon::Backend& +auto Graph::getBackend() const + -> const Neon::Backend& { if (mBackendIsSet) { return mBackend; @@ -717,12 +731,17 @@ auto Graph::getBackend() const -> const Neon::Backend& NEON_THROW(ex); } -auto Graph::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, - Neon::DataView /*dataView*/) +auto Graph::run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void { - NEON_THROW_UNSUPPORTED_OPERATION(""); + if (dataView != Neon::DataView::STANDARD) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + + this->runtimePreSet(streamIdx); + this->helpExecute(setIdx, streamIdx); } auto Graph::run(int streamIdx, @@ -732,12 +751,14 @@ auto Graph::run(int streamIdx, if (dataView != Neon::DataView::STANDARD) { NEON_THROW_UNSUPPORTED_OPERATION(""); } + this->runtimePreSet(streamIdx); this->helpExecute(streamIdx); } auto Graph::helpExecute(Neon::SetIdx setIdx, - int anchorStream) -> void + int anchorStream) + -> void { if (anchorStream > -1 && (anchorStream != mAnchorStreamPreSet || mFilterOutAnchorsPreSet == true)) { Neon::NeonException ex(""); @@ -815,11 +836,11 @@ auto Graph::expandSubGraphs() -> void if (atLeastOneWasFound) { helpInvalidateScheduling(); this->helpRemoveRedundantDependencies(); - // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); } return; } - // this->ioToDot(std::to_string(i) + "_t_00", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_00", "kllkj", true); auto& newTarget = mRawGraph.getVertexProperty(newTargetId); const auto& subGraph = newTarget.getContainer().getContainerInterface().getGraph(); @@ -833,7 +854,7 @@ auto Graph::expandSubGraphs() -> void fromOldToNew.insert(std::pair(oldNode.getGraphData().getUid(), newNode.getGraphData().getUid())); }); - ///this->ioToDot(std::to_string(i) + "_t_01", "kllkj", true); + /// this->ioToDot(std::to_string(i) + "_t_01", "kllkj", true); // Cloning the subGraph edges into the graph subGraph.mRawGraph.forEachEdge([&](std::pair edge) { @@ -846,7 +867,7 @@ auto Graph::expandSubGraphs() -> void this->addDependency(nodeA, nodeB, oldDep.getType()); }); - //this->ioToDot(std::to_string(i) + "_t_02", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_02", "kllkj", true); { // Removing the cloned begin and end from the subGraph auto oldBeginId = subGraph.getBeginNode().getGraphData().getUid(); @@ -861,25 +882,29 @@ auto Graph::expandSubGraphs() -> void this->removeNode(toBeRemovedBeginNode); this->removeNode(toBeRemovedEndNode); } - // this->ioToDot(std::to_string(i) + "_t_03", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_03", "kllkj", true); { // Removing subGraph and depedencies this->removeNodeAndItsDependencies(newTarget); - std::cout << "removing " << newTarget.getContainer().getName() << std::endl; } - //this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); } - } -auto Graph::helpCheckBackendStatus() -> void +auto Graph::helpCheckBackendStatus() + -> void { - if(!mBackendIsSet){ + if (!mBackendIsSet) { NeonException exception("Container Graph"); exception << "A backend was not registered with the Graph"; NEON_THROW(exception); } } +auto Graph::getNumberOfNodes() -> int +{ + // We remove 2 because of the head and tail holders. + return mRawGraph.numVertices() - 2; +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index bd4aa473..e266ccb3 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -66,14 +66,11 @@ auto GraphContainer::run(int streamIdx, mGraph->run(streamIdx, dataView); } -auto GraphContainer::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, - Neon::DataView /*dataView*/) -> void +auto GraphContainer::run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void { - // if (ContainerExecutionType::graph == this->getContainerExecutionType()) { - // mGraph->run(setIdx, streamIdx, dataView); - // } - // NEON_THROW_UNSUPPORTED_OPTION(""); + mGraph->run(setIdx, streamIdx, dataView); } } // namespace Neon::set::internal diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp index 8f2dcaec..19a26bdf 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp @@ -20,6 +20,7 @@ #include "setUt_containerGraph_runHelper.h" #include "Neon/set/container/Graph.h" +#define DEBUG_MODE 0 using namespace Neon::domain::tool::testing; static const std::string testFilePrefix("setUt_containerGraph_nestedGraph"); @@ -32,7 +33,6 @@ void NestedGraphsTest(TestData& data) const std::string appName(testFilePrefix); const Type scalarVal = 2; - const int nIterations = 10; auto fR = data.getGrid().template newPatternScalar(); fR() = scalarVal; @@ -43,21 +43,21 @@ void NestedGraphsTest(TestData& data) { // NEON auto& X = data.getField(FieldNames::X); - auto& Y = data.getField(FieldNames::Y); auto& Z = data.getField(FieldNames::Z); - auto& W = data.getField(FieldNames::W); auto generateInnerGraph = [&](std::string name) -> Neon::set::Container { - Neon::set::container::Graph graph; + Neon::set::container::Graph graph(data.getBackend()); - auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, name+"-StageA")); - auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, name+"-StageC")); - graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, name+"-StageB"), nodeC); + auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, name + "-StageA")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, name + "-StageC")); + graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, name + "-StageB"), nodeC); -// graph.ioToDot(appName, "UserGraph", false); -// graph.ioToDot(appName + "-debug", "UserGraph", true); +#if (DEBUG_MODE == 1) + graph.ioToDot(appName, "UserGraph", false); + graph.ioToDot(appName + "-debug", "UserGraph", true); +#endif auto container = Neon::set::Container::factoryGraph(name, graph, [](Neon::SetIdx, Neon::set::Loader&) {}); return container; @@ -73,14 +73,14 @@ void NestedGraphsTest(TestData& data) graph.addNode(nodeC); { - auto fname = appName + "_withSubGraph"; + auto fname = appName + "_withSubGraph"; graph.runtimePreSet(0); graph.ioToDot(fname, "UserGraph", false); graph.ioToDot(fname + "-debug", "UserGraph", true); } { - auto fname = appName + "_expandSubGraphs"; + auto fname = appName + "_expandSubGraphs"; graph.expandSubGraphs(); graph.runtimePreSet(0); @@ -88,39 +88,8 @@ void NestedGraphsTest(TestData& data) graph.ioToDot(fname + "-debug", "UserGraph", true); } - // timer.start(); - // for (int i = 0; i < nIterations; i++) { - // skl.run(); - // } - // data.getBackend().syncAll(); - // timer.stop(); + ASSERT_EQ(graph.getNumberOfNodes(), 9); } - - { // Golden data - //auto time = timer.time(); - - Type dR = scalarVal; - auto& X = data.getIODomain(FieldNames::X); - auto& Y = data.getIODomain(FieldNames::Y); - - for (int i = 0; i < nIterations; i++) { - data.axpy(&dR, Y, X); - data.laplace(X, Y); - data.axpy(&dR, Y, Y); - } - } - bool isOk = data.compare(FieldNames::X); - isOk = isOk && data.compare(FieldNames::Y); - - /*{ // DEBUG - data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); - data.getField(FieldNames::X).ioToVtk("Field_X", "X"); - - data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); - data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); - }*/ - - ASSERT_TRUE(isOk); } template @@ -152,3 +121,5 @@ TEST(NestedGraphs, eGrid) using Type = int32_t; runOneTestConfiguration("eGrid_t", NestedGraphs, 1, 1); } + +#undef DEBUG_MODE \ No newline at end of file diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp index e4fc7e3c..2459f203 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp @@ -21,6 +21,8 @@ #include "Neon/set/container/Graph.h" +#define DEBUG_MODE 0 + using namespace Neon::domain::tool::testing; static const std::string testFilePrefix("setUt_containerGraph"); @@ -32,7 +34,7 @@ void ThreePippedMapsTest(TestData& data) const std::string appName(testFilePrefix); const Type scalarVal = 2; - const int nIterations = 10; + const int nIterations = 3; auto fR = data.getGrid().template newPatternScalar(); fR() = scalarVal; @@ -47,47 +49,45 @@ void ThreePippedMapsTest(TestData& data) auto& Z = data.getField(FieldNames::Z); auto& W = data.getField(FieldNames::W); - Neon::set::container::Graph graph; + Neon::set::container::Graph graph(data.getBackend()); auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); - auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, "nodeB"), nodeC); graph.ioToDot(appName, "UserGraph", false); graph.ioToDot(appName + "-debug", "UserGraph", true); + graph.runtimePreSet(0); - // timer.start(); - // for (int i = 0; i < nIterations; i++) { - // skl.run(); - // } - // data.getBackend().syncAll(); - // timer.stop(); + for (int i = 0; i < nIterations; i++) { + graph.run(0); + } } { // Golden data - auto time = timer.time(); - Type dR = scalarVal; auto& X = data.getIODomain(FieldNames::X); auto& Y = data.getIODomain(FieldNames::Y); + auto& Z = data.getIODomain(FieldNames::Z); + auto& W = data.getIODomain(FieldNames::W); for (int i = 0; i < nIterations; i++) { - data.axpy(&dR, Y, X); - data.laplace(X, Y); - data.axpy(&dR, Y, Y); + data.axpy(&dR, W, X); + data.axpy(&dR, W, Y); + data.axpy(&dR, W, Z); } } bool isOk = data.compare(FieldNames::X); isOk = isOk && data.compare(FieldNames::Y); - /*{ // DEBUG - data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); - data.getField(FieldNames::X).ioToVtk("Field_X", "X"); +#if (DEBUG_MODE == 1) + data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); + data.getField(FieldNames::X).ioToVtk("Field_X", "X"); - data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); - data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); - }*/ + data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); + data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); +#endif ASSERT_TRUE(isOk); } @@ -117,8 +117,9 @@ int getNGpus() TEST(ThreePippedMaps, eGrid) { - int nGpus = getNGpus(); using Grid = Neon::domain::internal::eGrid::eGrid; using Type = int32_t; runOneTestConfiguration("eGrid_t", ThreePippedMaps, 1, 1); } + +#undef DEBUG_MODE \ No newline at end of file From 04295df0dd2e564b9237c5476cfa223672b4f797 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Sat, 17 Sep 2022 19:20:38 -0400 Subject: [PATCH 31/67] WIP --- .../include/Neon/set/dependency/Alias.h | 17 + .../Neon/set/dependency/DataDependencyType.h | 29 + .../include/Neon/set/dependency/Token.h | 76 ++ .../include/Neon/set/dependencyTools/Alias.h | 27 - .../Neon/set/dependencyTools/DataParsing.h | 52 - .../include/Neon/set/dependencyTools/enum.h | 74 -- .../{DataParsing.cpp => Token.cpp} | 14 +- libNeonSet/src/set/depencencyTools/enum.cpp | 74 -- .../Neon/skeleton/internal/StreamScheduler.h | 175 --- .../skeleton/internal/dependencyTools/Alias.h | 29 - .../{Dependency.h => DataDependency.h} | 26 +- .../skeleton/internal/multiGpuGraph/Edge.h | 135 -- .../internal/multiGpuGraph/MetaNode.h | 143 -- .../skeleton/internal/multiGpuGraph/edge.cpp | 86 -- .../skeleton/internal/multiGpuGraph/node.cpp | 279 ---- .../src/skeleton/internal/streamScheduler.cpp | 1146 ----------------- 16 files changed, 144 insertions(+), 2238 deletions(-) create mode 100644 libNeonSet/include/Neon/set/dependency/Alias.h create mode 100644 libNeonSet/include/Neon/set/dependency/DataDependencyType.h create mode 100644 libNeonSet/include/Neon/set/dependency/Token.h delete mode 100644 libNeonSet/include/Neon/set/dependencyTools/Alias.h delete mode 100644 libNeonSet/include/Neon/set/dependencyTools/DataParsing.h delete mode 100644 libNeonSet/include/Neon/set/dependencyTools/enum.h rename libNeonSet/src/set/depencencyTools/{DataParsing.cpp => Token.cpp} (86%) delete mode 100644 libNeonSet/src/set/depencencyTools/enum.cpp delete mode 100644 libNeonSkeleton/include/Neon/skeleton/internal/StreamScheduler.h delete mode 100644 libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/Alias.h rename libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/{Dependency.h => DataDependency.h} (51%) delete mode 100644 libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/Edge.h delete mode 100644 libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/MetaNode.h delete mode 100644 libNeonSkeleton/src/skeleton/internal/multiGpuGraph/edge.cpp delete mode 100644 libNeonSkeleton/src/skeleton/internal/multiGpuGraph/node.cpp delete mode 100644 libNeonSkeleton/src/skeleton/internal/streamScheduler.cpp diff --git a/libNeonSet/include/Neon/set/dependency/Alias.h b/libNeonSet/include/Neon/set/dependency/Alias.h new file mode 100644 index 00000000..30009520 --- /dev/null +++ b/libNeonSet/include/Neon/set/dependency/Alias.h @@ -0,0 +1,17 @@ +#pragma once +#include "Neon/set/Backend.h" + +namespace Neon::internal::dataDependency { + +/** + * Unique identifier for a kernel parameter + */ +using DataUId = int64_t; + +/** + * Unique identifier for a kernel parameter + */ +using DataIdx = int64_t; + + +} // namespace Neon::dataDependency diff --git a/libNeonSet/include/Neon/set/dependency/DataDependencyType.h b/libNeonSet/include/Neon/set/dependency/DataDependencyType.h new file mode 100644 index 00000000..d043fce3 --- /dev/null +++ b/libNeonSet/include/Neon/set/dependency/DataDependencyType.h @@ -0,0 +1,29 @@ +#pragma once +#include "Neon/set/Backend.h" + +namespace Neon::internal::dataDependency { + +/** + * Classical definition of dependency types. + */ +enum struct DataDependencyType +{ + RAW /**< Read after write */, + WAR /**< Write after read */, + RAR /**< Read after read. This is not actually a true dependency */, + WAW /**< This configuration may indicate something wrong in the user graph */, + NONE /**< Not defined */ +}; + +struct DataDependencyTypeUtils +{ + /** + * Returns a string for the selected allocator + * + * @param allocator + * @return + */ + static auto toString(DataDependencyType type) -> std::string; +}; + +} diff --git a/libNeonSet/include/Neon/set/dependency/Token.h b/libNeonSet/include/Neon/set/dependency/Token.h new file mode 100644 index 00000000..fd460ed8 --- /dev/null +++ b/libNeonSet/include/Neon/set/dependency/Token.h @@ -0,0 +1,76 @@ +#pragma once +#include "Neon/set/Backend.h" +#include "Neon/set/HuOptions.h" +#include "Neon/set/dependencyTools/AccessType.h" +#include "Neon/set/dependencyTools/Alias.h" +#include "Neon/set/dependencyTools/ComputeType.h" + +namespace Neon::internal::dataDependency { + +/** + * Stores type of operations on data for each kernels while user code is "parsed" + * It is used to construct the user kernel dependency graph + */ +struct Token +{ + public: + Token() = delete; + + /** + * Unique constructor + */ + Token(DataUId m_uid, + AccessType m_access, + Neon::Compute m_compute); + + /** + * Method to update a token + */ + auto update(DataUId m_uid, + AccessType m_access, + Neon::Compute m_compute) -> void; + + /** + * It returns the multi-GPU data uid + */ + auto uid() const -> DataUId; + + /** + * It returns the type of data access + */ + auto access() const -> AccessType; + + /** + * Returns the compute pattern + */ + auto compute() const -> Neon::Compute; + + /** + * Converts the token into a string + */ + auto toString() const -> std::string; + + /** + * It sets the halo update container associated to the multi-GPU data. + * @param hu + * @param huPerDevice + */ + auto setHaloUpdate(std::function hu, + std::function huPerDevice) -> void; + + auto getHaloUpdate() const -> const std::function&; + + auto getHaloUpdatePerDevice() const -> const std::function&; + + auto mergeAccess(AccessType) -> void; + + + private: + DataUId mUid; + AccessType mAccess; + Compute mCompute; + std::function mHu; + std::function mHuPerDevice; +}; + +} // namespace dependencyTools diff --git a/libNeonSet/include/Neon/set/dependencyTools/Alias.h b/libNeonSet/include/Neon/set/dependencyTools/Alias.h deleted file mode 100644 index 5cfcfae6..00000000 --- a/libNeonSet/include/Neon/set/dependencyTools/Alias.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include "Neon/set/Backend.h" - -namespace Neon { -namespace set { -namespace internal { -namespace dependencyTools { - -/** - * Unique identifier for a kernel parameter - */ -using DataUId_t = int64_t; - -/** - * Unique identifier for a kernel parameter - */ -using DataIdx_t = int64_t; - -/** - * Index of a KernelContainer - */ -using KernelContainerIdx_t = int64_t; - -} // namespace dependencyTools -} // namespace internal -} // namespace set -} // namespace Neon \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/dependencyTools/DataParsing.h b/libNeonSet/include/Neon/set/dependencyTools/DataParsing.h deleted file mode 100644 index f6c64749..00000000 --- a/libNeonSet/include/Neon/set/dependencyTools/DataParsing.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#include "Neon/set/Backend.h" -#include "Neon/set/HuOptions.h" -#include "Neon/set/dependencyTools/Alias.h" -#include "Neon/set/dependencyTools/enum.h" - -namespace Neon { -namespace set { -namespace internal { -namespace dependencyTools { - -/** - * Stores type of operations on data for each kernels while user code is "parsed" - * It is used to construct the user kernel dependency graph - */ -struct DataToken -{ - private: - DataUId_t m_uid; - Access_e m_access; - Compute m_compute; - std::function m_hu; - std::function m_huPerDevice; - - public: - DataToken() = delete; - - DataToken(DataUId_t m_uid, - Access_et::e m_access, - Neon::Compute m_compute); - - auto update(DataUId_t m_uid, - Access_et::e m_access, - Neon::Compute m_compute) -> void; - auto uid() const -> DataUId_t; - auto access() const -> Access_et::e; - auto compute() const -> Neon::Compute; - auto toString() const -> std::string; - - auto setHaloUpdate(std::function hu, - std::function huPerDevice) -> void; - - auto getHaloUpdate() const -> const std::function&; - auto getHaloUpdatePerDevice() const -> const std::function&; - - auto mergeAccess( Access_et::e)->void ; -}; - -} // namespace dependencyTools -} // namespace internal -} // namespace set -} // namespace Neon \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/dependencyTools/enum.h b/libNeonSet/include/Neon/set/dependencyTools/enum.h deleted file mode 100644 index a80bf07b..00000000 --- a/libNeonSet/include/Neon/set/dependencyTools/enum.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once -#include "Neon/set/Backend.h" - -namespace Neon { -namespace set { -namespace internal { -namespace dependencyTools { - -/** - * Define type of operation for a kernel parameter: Read or write. - * Write includes also complex operation where the parameter is both read and written. - */ -struct Access_et -{ - Access_et() = delete; - Access_et(const Access_et&) = delete; - - enum e - { - READ /**< The field or kernel parameter is in read only mode */, - WRITE /**< The field or kernel parameter is in write mode (this include read and write) */, - NONE /**< Not defined */ - }; - static auto toString(e val) -> std::string; - static auto merge(e valA, e valB) -> e; - -}; -using Access_e = Access_et::e; - -/** - * Classical definition of dependency types. - */ -struct Dependencies_et -{ - Dependencies_et() = delete; - Dependencies_et(const Dependencies_et&) = delete; - - enum e - { - RAW /**< Read after write */, - WAR /**< Write after read */, - RAR /**< Read after read. This is not actually a true dependency */, - WAW /**< This configuration may indicate something wrong in the user graph */, - NONE /**< Not defined */ - }; - static auto toString(e val) -> std::string; -}; -using Dependencies_e = Dependencies_et::e; -} // namespace dependencyTools -} // namespace internal -} // namespace set - -/** - * Enumeration for the supported type of computation by the skeleton - * */ -enum struct Compute -{ - MAP /**< Map operation */, - STENCIL /**< Stencil operation */, - REDUCE /**< Reduction operation */ -}; - -struct ComputeUtils -{ - /** - * Returns a string for the selected allocator - * - * @param allocator - * @return - */ - static auto toString(Compute allocator) -> const char*; -}; - -} // namespace Neon \ No newline at end of file diff --git a/libNeonSet/src/set/depencencyTools/DataParsing.cpp b/libNeonSet/src/set/depencencyTools/Token.cpp similarity index 86% rename from libNeonSet/src/set/depencencyTools/DataParsing.cpp rename to libNeonSet/src/set/depencencyTools/Token.cpp index 375f72c6..e7604b95 100644 --- a/libNeonSet/src/set/depencencyTools/DataParsing.cpp +++ b/libNeonSet/src/set/depencencyTools/Token.cpp @@ -13,12 +13,12 @@ DataToken::DataToken(DataUId_t uid, update(uid, access, compute); setHaloUpdate( [&](Neon::set::HuOptions&) -> void { - NeonException exp("DataToken_t"); + NeonException exp("DataToken"); exp << "This is not a stencil token and this is not a valid operation"; NEON_THROW(exp); }, [&](Neon::SetIdx, Neon::set::HuOptions&) -> void { - NeonException exp("DataToken_t"); + NeonException exp("DataToken"); exp << "This is not a stencil token and this is not a valid operation"; NEON_THROW(exp); }); @@ -33,11 +33,11 @@ auto DataToken::update(DataUId_t uid, m_compute = compute; setHaloUpdate( [&](Neon::set::HuOptions&) -> void { - NeonException exp("DataToken_t"); + NeonException exp("DataToken"); exp << "This is not a stencil token and this is not a valid operation"; NEON_THROW(exp); }, [&](Neon::SetIdx, Neon::set::HuOptions&) -> void { - NeonException exp("DataToken_t"); + NeonException exp("DataToken"); exp << "This is not a stencil token and this is not a valid operation"; NEON_THROW(exp); }); @@ -59,7 +59,7 @@ auto DataToken::uid() const -> DataUId_t auto DataToken::toString() const -> std::string { return " uid " + std::to_string(m_uid) + - " [Op " + Access_et::toString(m_access) + + " [Op " + AccessType::toString(m_access) + " Model " + Neon::ComputeUtils::toString(m_compute) + "]"; } @@ -82,9 +82,9 @@ auto DataToken::getHaloUpdatePerDevice() const { return m_huPerDevice; } -auto DataToken::mergeAccess(Access_et::e tomerge) -> void +auto DataToken::mergeAccess(AccessType::e tomerge) -> void { - m_access = Access_et::merge(m_access, tomerge); + m_access = AccessType::merge(m_access, tomerge); } } // namespace dependencyTools } // namespace internal diff --git a/libNeonSet/src/set/depencencyTools/enum.cpp b/libNeonSet/src/set/depencencyTools/enum.cpp deleted file mode 100644 index 8085649d..00000000 --- a/libNeonSet/src/set/depencencyTools/enum.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "Neon/set/dependencyTools/enum.h" - -namespace Neon { -namespace set { -namespace internal { -namespace dependencyTools { - - -auto Access_et::toString(e val) -> std::string -{ - switch (val) { - case READ: { - return "READ"; - } - case WRITE: { - return "WRITE"; - } - case NONE: { - return "NONE"; - } - } - NEON_THROW_UNSUPPORTED_OPTION(); -} - -auto Access_et::merge(e valA, e valB) -> e { - if(valA == e::WRITE) return e::WRITE; - if(valB == e::WRITE) return e::WRITE; - if(valA == e::READ) return e::READ; - if(valB == e::READ) return e::READ; - return e::NONE; -} - -auto Dependencies_et::toString(e val) -> std::string -{ - switch (val) { - case RAW: { - return "RAW"; - } - case WAR: { - return "WAR"; - } - case RAR: { - return "RAR"; - } - case WAW: { - return "WAW"; - } - case NONE: { - return "NONE"; - } - } - NEON_THROW_UNSUPPORTED_OPTION(); -} -} // namespace dependencyTools -} // namespace internal -} // namespace set - -auto ComputeUtils::toString(Compute val) -> const char* -{ - switch (val) { - case Compute::MAP: { - return "MAP"; - } - case Compute::STENCIL: { - return "STENCIL"; - } - case Compute::REDUCE: { - return "REDUCE"; - } - } - NEON_THROW_UNSUPPORTED_OPTION(); -} - -} // namespace Neon \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/StreamScheduler.h b/libNeonSkeleton/include/Neon/skeleton/internal/StreamScheduler.h deleted file mode 100644 index 9cc90758..00000000 --- a/libNeonSkeleton/include/Neon/skeleton/internal/StreamScheduler.h +++ /dev/null @@ -1,175 +0,0 @@ -#pragma once -#include -#include "Neon/skeleton/internal/MultiGpuGraph.h" - -namespace Neon::skeleton::internal { - -class StreamScheduler -{ - public: - using DiGraph = MultiGpuGraph::DiGraph; - - using Level = std::vector; - struct MetaNodeExtended - { - struct SchedulingInfo - { - SchedulingInfo(); - SchedulingInfo(size_t nodeId, size_t extendedNodeIdx, ContainerIdx cIdx); - NodeId nodeId; - MetaNodeExtendedIdx metaNodeExtendedIdx; - ContainerIdx containerIdx; - StreamIdx streamIdx = {-1}; - std::unordered_set waitEventIdxList; - EventIdx setEventIdx = {-1}; - EventIdx barrierLR = {-1}; - bool isHaloUpdateNode = false; - int schedulingOrder{-1}; - }; - - int blockingDependencies{-1}; - SchedulingInfo schedulingInfo; - }; - - - auto io2Dot(const std::string& nodeId, const std::string& graphName) -> void; - auto io2DotOrder(const std::string& nodeId, const std::string& graphName) -> void; - - private: - struct Storage - { - public: - std::vector m_levels; - std::vector m_streamFlags; - MultiGpuGraph& m_graph; - bool m_initDone = {false}; - Neon::Backend m_bk; - std::vector m_executionOrder; - std::vector m_linearization; - - Storage(Neon::Backend& bk, MultiGpuGraph& graph) - : m_graph(graph), m_bk(bk) - { - } - std::vector m_metaNodeExtendedList; - bool useFullBarrierOnAllStreamsAtTheEnd = true; - bool canEndNodeLastBarrierBeOptimizedOut = false; - }; - - std::shared_ptr m_storage; - - public: - auto init(Neon::Backend& bk, MultiGpuGraph& multiGpuGraph) -> void; - - /** - * Returns number of levels - * @return - */ - auto nLevels() -> int; - - /** - * - * @return - */ - auto addNewLevel() -> LevelIdx; - - auto getLevel(int levelIdx) -> Level&; - - auto resetLevels() -> void; - - /** - * - */ - auto getStreamFlags() -> std::vector&; - - /** - * Counting the number of streams required - * @return - */ - auto initStreamFlags() -> int; - - /** - * - * @return - */ - auto resetStreamFlags() -> void; - - /** - * - * @param containerIdx - * @return - */ - auto registerNodeToLastLevel(size_t nodeId) -> void; - - /** - * Creating the level for the scheduling - */ - auto initCreateLevels() -> void; - /** - * Schedule a stream for each node - */ - auto initScheduleStreams() -> void; - - /** - * Schedule required events for each node - */ - auto initScheduleEvents() -> void; - - /** - * Create a linearizex indexing - */ - auto initLinearisationList() -> void; - - /** - * Remove redundant synchronizations - */ - auto initCleanRedundantSync() -> void; - - /** - * Remove redundant events - */ - auto initCleanRedundantEvents() -> void; - - /** - * Define the execution order for each task - */ - auto initExecutionOrder() -> void; - - /** - * Execute the graph - */ - auto run(const Neon::skeleton::Options& options) -> void; - - private: - auto h_getMetaNodeExtended(NodeId id) -> MetaNodeExtended&; - auto h_getMetaNodeExtended(MetaNode& id) -> MetaNodeExtended&; - auto h_getMetaNode(NodeId id) -> MetaNode&; - - auto helpRunOmpAtGraphLevel() -> void; - auto helpRunOmpAtNodeLevel() -> void; - - template - auto h_dissolveDataDependencies(Graph& graph, NodeId nodeId) -> void - { - // helper function to update the dependency count of child nodes - auto outNeighbours = graph.outNeighbors(nodeId); - for (const auto& ngh : outNeighbours) { - auto& metaNodeExtended = h_getMetaNodeExtended(ngh); - // std::cout << "Node " << nodeId << " dissolve " << ngh << " from " << metaNodeExtended.blockingDependencies << " to " << metaNodeExtended.blockingDependencies - 1 << std::endl; - metaNodeExtended.blockingDependencies--; - } - // for (auto huNode : h_getMetaNodeExtended(nodeId).childHaloNodes) { - // h_dissolveDataDependencies(huNode); - // } - }; - - auto helpRun(NodeId nodeId, StreamIdx streamIdx) -> void; - auto helpRun(Neon::SetIdx setIdx, NodeId nodeId, StreamIdx streamIdx) -> void; - auto helpNvtxName(NodeId nodeId) -> std::string; - auto helpWaitForEventCompletion(StreamIdx streamIdx, EventIdx eventIdx) -> void; - auto helpWaitForEventCompletion(Neon::SetIdx setIdx, StreamIdx streamIdx, EventIdx eventIdx) -> void; - auto helpEnqueueEvent(StreamIdx streamIdx, EventIdx eventIdx) -> void; - auto helpEnqueueEvent(Neon::SetIdx setIdx, StreamIdx streamIdx, EventIdx eventIdx) -> void; -}; - -} // namespace Neon::skeleton::internal diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/Alias.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/Alias.h deleted file mode 100644 index 2893e2d6..00000000 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/Alias.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "Neon/set/Backend.h" -#include "Neon/set/dependencyTools/Alias.h" -#include "Neon/set/dependencyTools/DataParsing.h" -#include "Neon/set/dependencyTools/enum.h" - -namespace Neon::skeleton::internal { - -/** - * Index of a KernelContainer - */ -using ContainerIdx = int64_t; -using DataUId_t = Neon::set::internal::dependencyTools::DataUId_t; -using DataIdx_t = Neon::set::internal::dependencyTools::DataIdx_t; - -using Dependencies_e = Neon::set::internal::dependencyTools::Dependencies_e; -using Dependencies_et = Neon::set::internal::dependencyTools::Dependencies_et; - -using Access_e = Neon::set::internal::dependencyTools::Access_e; -using Access_et = Neon::set::internal::dependencyTools::Access_et; - -using DataToken_t = Neon::set::internal::dependencyTools::DataToken; - - -using NodeId = size_t; /** id for DiGraph */ -using MetaNodeExtendedIdx = size_t; /** index for the extended node information */ -using LevelIdx = int; /** level index */ - -} // namespace Neon \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/Dependency.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h similarity index 51% rename from libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/Dependency.h rename to libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h index 6cb08e41..96b98bb6 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/Dependency.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h @@ -1,7 +1,8 @@ #pragma once #include "Neon/set/Backend.h" -#include "Neon/set/dependencyTools/enum.h" -#include "Neon/skeleton/internal//dependencyTools/Alias.h" +#include "Neon/set/container/Graph.h" +#include "Neon/set/dependency/Alias.h" +#include "Neon/set/dependency/DataDependencyType.h" namespace Neon::skeleton::internal { @@ -9,10 +10,10 @@ namespace Neon::skeleton::internal { struct Dependency { private: - ContainerIdx m_t0 = 0; - ContainerIdx m_t1 = 0; - Dependencies_e m_type = Dependencies_e::NONE; - DataUId_t m_uid = 0; + Neon::set::container::GraphData::Uid mT0 = 0; + Neon::set::container::GraphData::Uid mT1 = 0; + Neon::internal::dataDependency::DataDependencyType mType = Neon::internal::dataDependency::DataDependencyType::NONE; + Neon::internal::dataDependency::DataUId mDataUid = 0; public: /** @@ -29,7 +30,10 @@ struct Dependency * @param A * @param B */ - Dependency(ContainerIdx t1, Dependencies_e type, DataUId_t m_uid, ContainerIdx t0); + Dependency(Neon::set::container::GraphData::Uid t1, + Neon::internal::dataDependency::DataDependencyType type, + Neon::internal::dataDependency::DataUId m_uid, + Neon::set::container::GraphData::Uid t0); /** * true the object has been initialized with a valid dependency @@ -47,19 +51,19 @@ struct Dependency * Returns the dependency type * @return */ - auto type() -> Dependencies_e; + auto type() -> Neon::internal::dataDependency::DataDependencyType; /** * Returns the "before" kernel id * @return */ - auto t0() -> ContainerIdx; + auto t0() -> Neon::set::container::GraphData::Uid; /** * Returns the "after" kernel id * @return */ - auto t1() -> ContainerIdx; + auto t1() -> Neon::set::container::GraphData::Uid; /** * Static method to build an empty dependency @@ -68,4 +72,4 @@ struct Dependency static Dependency getEmpty(); }; -} \ No newline at end of file +} // namespace Neon::skeleton::internal \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/Edge.h b/libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/Edge.h deleted file mode 100644 index a9c5048c..00000000 --- a/libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/Edge.h +++ /dev/null @@ -1,135 +0,0 @@ -#pragma once -#include "Neon/set/dependencyTools/DataParsing.h" -#include "Neon/skeleton/internal/dependencyTools/Alias.h" - -namespace Neon { -namespace skeleton { -namespace internal { - -/** - * Information stored for each Edge in the user graph - */ -struct Edge -{ - struct Info - { - Info(DataToken_t t, - Dependencies_e d, - bool haloUp = false) - : token(t), dependency(d), haloUpdate(haloUp) - { - if (haloUp && token.compute() != Neon::Compute::STENCIL) { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } - - DataToken_t token; - // This flag is true when a stencil dependency does need - // halo update as the previous map is running on internals - bool flag_discardStencilDep = {false}; - Dependencies_e dependency; - bool haloUpdate = false; - - /** - * Returns true if this is a stencil edge - * @return - */ - bool isStencil() const - { - return (token.compute() == Neon::Compute::STENCIL) && !flag_discardStencilDep; - } - - /** - * Returns true if this is halo edge - * @return - */ - bool isHu() const - { - return haloUpdate; - } - - auto toString() const -> std::string - { - using namespace set::internal::dependencyTools; - if (!haloUpdate) { - // return " UID " + std::to_string(token.uid()) + - return "- Type: " + Dependencies_et::toString(dependency) + "\\l"; //"- UID: " + std::to_string(token.uid()) + "\\l"; - // "\\l-Operation: " + Access_et::toString(token.access()) + - // "\\l-Pattern: " + Compute_et::toString(token.compute())+ - - } else { - // return " UID " + std::to_string(token.uid()) + - return "- Type: " + Dependencies_et::toString(dependency) + " HU\\l"; - // "\\l-Operation: " + Access_et::toString(token.access()) + - // "\\l-Pattern: " + Compute_et::toString(token.compute())+ - // " HU\\l"; - } - } - }; - - size_t m_edgeId; - std::vector m_dependencies; - bool m_isSchedulingEdge = false; - /** - * Private constructor. - * Only the container method can be used to create Edge elements. - * - * @param edgeId - * @param op - * @param uid - */ - Edge(size_t edgeId, - const DataToken_t& dataToken, - Dependencies_e dependency, - bool haloUp = false); - - Edge(size_t edgeId, - bool isSchedulingEdge); - - public: - Edge() = default; - - /** - * Factory method to create an Edge object. - * This methos is not thread safe - * - * @param op - * @return - */ - static auto - factory(const DataToken_t& dataToken, - Dependencies_e dependency, - bool haloUp = false) -> Edge; - - static auto - factorySchedulingEdge() -> Edge; - - auto clone() const -> Edge; - - auto edgeId() const -> size_t; - - auto - nDependencies() - const -> size_t; - - auto - info() - const -> const std::vector&; - - auto - infoMutable() - -> std::vector&; - - - auto - append(const DataToken_t& dataToken, - Dependencies_e dType) -> void; - - auto - toString() - const -> std::string; -}; - -} // namespace internal -} // namespace skeleton -} // namespace Neon \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/MetaNode.h b/libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/MetaNode.h deleted file mode 100644 index 4b6b1055..00000000 --- a/libNeonSkeleton/include/Neon/skeleton/internal/multiGpuGraph/MetaNode.h +++ /dev/null @@ -1,143 +0,0 @@ -#pragma once -#include "Neon/domain/internal/haloUpdateType.h" -#include "Neon/set/DevSet.h" -#include "Neon/skeleton/internal/dependencyTools/Alias.h" -namespace Neon { -namespace skeleton { -namespace internal { - -struct MetaNodeType_te -{ - MetaNodeType_te() = delete; - MetaNodeType_te(const MetaNodeType_te&) = delete; - enum e - { - SYNC_LEFT_RIGHT, - BARRIER, - HALO_UPDATE, - CONTAINER, - HELPER, - UNDEFINED - }; - - static auto - toString(MetaNodeType_te::e type) -> std::string; -}; -using MetaNodeType_e = MetaNodeType_te::e; - - -struct MetaNode -{ - private: - MetaNode(size_t nodeId, - const std::string& name, - MetaNodeType_e nodeType, - ContainerIdx kernelContainerIdx, - const Neon::DataView& dataView = Neon::DataView::STANDARD); - - private: - size_t m_nodeId; - std::string m_name; - MetaNodeType_e m_nodeType; - ContainerIdx m_kernelContainerIdx; - Neon::DataView m_dataView{Neon::DataView::STANDARD}; - Neon::Compute m_compute{Neon::Compute::MAP}; - - Neon::set::TransferMode m_transferMode{Neon::set::TransferMode::get}; - Neon::set::MultiDeviceObjectUid m_uid; - - size_t m_linearContinuousIndex = 0; /** this index is created when any change to the graph has been completed. - * It provides a way to associate data to nodes by the means of vectors - */ - - bool m_hasCoherentInput = false; - - std::function m_hu; - std::function m_huPerDevice; - - struct cudaGraphHandles_t - { - std::vector> m_data; - int m_first = 3; - int m_last = 3; - - auto init(MetaNodeType_e m_nodeType, int numDevices) -> void; - auto first() -> Neon::set::DataSet&; - auto last() -> Neon::set::DataSet&; - - } m_cudaGraphHandles; - - public: - /** - * - * @return - */ - static auto - factory(MetaNodeType_e nodeType, - const std::string& name, - ContainerIdx kernelContainerIdx, - const Neon::DataView& dataView = Neon::DataView::STANDARD) -> MetaNode; - - /** - * Create a clone of the node. - * The new node will have a different id - * @return - */ - auto clone() const -> MetaNode; - - static auto - haloUpdateFactory(Neon::set::TransferMode, - const Neon::set::MultiDeviceObjectUid& dataUids, - std::function hu, - const std::function& huPerDevice) -> MetaNode; - - static auto - syncLeftRightFactory(const Neon::set::MultiDeviceObjectUid& dataUids) -> MetaNode; - - auto - nodeId() const -> NodeId; - - - auto - name() const -> const std::string&; - - auto setAsCoherent() -> void; - - auto nodeType() const -> MetaNodeType_e; - - auto getContainerId() const -> ContainerIdx; - - auto toString() const -> std::string; - - auto setDataView(const Neon::DataView&) -> void; - - auto getDataView() const -> Neon::DataView; - - auto setCompute(const Neon::Compute&) -> void; - - auto getCompute() const -> Neon::Compute; - - auto isStencil() const -> bool; - - auto isReduce() const -> bool; - - auto isMap() const -> bool; - - auto isSync() const -> bool; - - auto isHu() const -> bool; - - auto hu(Neon::set::HuOptions& opt) -> void; - - auto hu(Neon::SetIdx setIdx, Neon::set::HuOptions& opt) -> void; - - auto transferMode() const -> Neon::set::TransferMode; - - auto setLinearContinuousIndex(size_t id) -> void; - - auto getLinearContinuousIndex() const -> size_t; -}; - -} // namespace internal -} // namespace skeleton -} // namespace Neon \ No newline at end of file diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph/edge.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph/edge.cpp deleted file mode 100644 index f12c1580..00000000 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph/edge.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "Neon/skeleton/internal/multiGpuGraph/Edge.h" - -#include -namespace Neon { -namespace skeleton { -namespace internal { - - -std::atomic edgeCounter_g{0}; - -Edge::Edge(size_t edgeId, - const DataToken_t& dataToken, - Dependencies_e dependency, - bool haloUp) - : m_edgeId(edgeId) -{ - m_dependencies.emplace_back(dataToken, dependency, haloUp); -} - -Edge::Edge(size_t edgeId, - bool isSchedulingEdge) - : m_edgeId(edgeId), m_isSchedulingEdge(isSchedulingEdge) -{ - if(isSchedulingEdge == false){ - NEON_THROW_UNSUPPORTED_OPTION(""); - } -} - -auto Edge::factory(const DataToken_t& dataToken, - Dependencies_e type, - bool haloUp) -> Edge -{ - size_t id = (edgeCounter_g++); - Edge edge(id, dataToken, type, haloUp); - return edge; -} - -auto Edge::factorySchedulingEdge() -> Edge -{ - size_t id = (edgeCounter_g++); - Edge edge(id, true); - return edge; -} - -auto Edge::edgeId() const -> size_t -{ - return m_edgeId; -} -auto Edge::nDependencies() const -> size_t -{ - return m_dependencies.size(); -} - -auto Edge::info() const -> const std::vector& -{ - return m_dependencies; -} -auto Edge::infoMutable() -> std::vector& -{ - return m_dependencies; -} - -auto Edge::append(const DataToken_t& dataToken, - Dependencies_e dType) -> void -{ - m_dependencies.push_back({dataToken, dType}); -} -auto Edge::toString() const -> std::string -{ - std::string intro = "Dependencies: \\l"; // + std::to_string(nDependencies()); - for (auto& i : info()) { - intro = intro + i.toString(); - } - return intro; -} -auto Edge::clone() const -> Edge -{ - size_t id = (edgeCounter_g++); - Edge clone(*this); - clone.m_edgeId = id; - return clone; -} - -} // namespace internal -} // namespace skeleton -} // namespace Neon \ No newline at end of file diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph/node.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph/node.cpp deleted file mode 100644 index be7731f8..00000000 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph/node.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include "Neon/skeleton/internal/multiGpuGraph/MetaNode.h" - -namespace Neon { -namespace skeleton { -namespace internal { - -std::atomic nodeCounter_g{0}; - -auto MetaNodeType_te::toString(MetaNodeType_te::e type) -> std::string -{ - switch (type) { - case SYNC_LEFT_RIGHT: { - return "SYNC_LEFT_RIGHT"; - } - case BARRIER: { - return "BARRIER"; - } - case HALO_UPDATE: { - return "HALO_UPDATE"; - } - case CONTAINER: { - return "KERNEL_CONTAINER"; - } - case HELPER: { - return "HELPER"; - } - case UNDEFINED: { - return "UNDEFINED"; - } - default: { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } -} - -namespace depTools = Neon::set::internal::dependencyTools; -MetaNode::MetaNode(size_t nodeId, - const std::string& name, - MetaNodeType_e nodeType, - depTools::KernelContainerIdx_t kernelContainerIdx, - const Neon::DataView& dataView) - : m_nodeId(nodeId), - m_name(name), - m_nodeType(nodeType), - m_kernelContainerIdx(kernelContainerIdx), - m_dataView(dataView) -{ -} - -auto MetaNode::factory(MetaNodeType_e nodeType, - const std::string& name, - depTools::KernelContainerIdx_t kernelContainerIdx, - const Neon::DataView& dataView) -> MetaNode -{ - MetaNode node(++nodeCounter_g, name, nodeType, kernelContainerIdx, dataView); - return node; -} - -auto MetaNode::nodeId() - const -> NodeId -{ - return m_nodeId; -} - -auto MetaNode::name() - const -> const std::string& -{ - return m_name; -} - -auto MetaNode::nodeType() - const -> MetaNodeType_e -{ - return m_nodeType; -} - -auto MetaNode::getContainerId() - const -> depTools::KernelContainerIdx_t -{ - return m_kernelContainerIdx; -} - -auto MetaNode::toString() const -> std::string -{ - switch (m_nodeType) { - case MetaNodeType_e::SYNC_LEFT_RIGHT: { - std::string res = //"Node ID " + std::to_string(nodeId()) + - std::string("Left-Right Sync\n\n"); - // std::string ret = "LR_SYNC"; - // ret += " " + std::to_string(m_uid); - // ret += " DEBUG " + std::to_string(m_nodeId); - return res; - } - case MetaNodeType_e::BARRIER: { - return "BARRIER"; - } - - case MetaNodeType_e::HALO_UPDATE: { - std::string res = //"Node ID " + std::to_string(nodeId()) + - std::string("Halo Update") + - "\n\nTransferMode: " + Neon::set::TransferModeUtils::toString(m_transferMode) + "\\l"; - // std::string ret = "HU " + - // Neon::set::Transfer_t::toString(m_transferMode) + - // " " + std::to_string(m_uid); - // ret += " DEBUG " + std::to_string(m_nodeId); - - return res; - } - case MetaNodeType_e::CONTAINER: { - std::string res = "" + name() + - //"\n\nNode ID " + std::to_string(nodeId()) + - "\\n\\nPattern: " + Neon::ComputeUtils::toString(m_compute) + - "\\lDataView: " + Neon::DataViewUtil::toString(m_dataView) + "\\l"; - // if (isStencil() && m_hasCoherentInput) { - // res += "\\l coherent"; - // } - // if (isStencil() && !m_hasCoherentInput) { - // res += "\\l NOT coherent"; - // } - // res += "\\l"; - // res += " DEBUG " + std::to_string(m_nodeId); - - return res; - } - case MetaNodeType_e::HELPER: { - return "HELPER"; - } - case MetaNodeType_e::UNDEFINED: { - return "UNDEFINED"; - } - default: { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } -} // namespace userGraph - -auto MetaNode::setDataView(const Neon::DataView& dv) -> void -{ - m_dataView = dv; -} - -auto MetaNode::getDataView() const -> Neon::DataView -{ - return m_dataView; -} - -auto MetaNode::setCompute(const Neon::Compute& c) -> void -{ - m_compute = c; -} - -auto MetaNode::getCompute() const -> Neon::Compute -{ - return m_compute; -} - -auto MetaNode::haloUpdateFactory(Neon::set::TransferMode tm, - const Neon::set::MultiDeviceObjectUid& dataUids, - std::function hu, - const std::function& huPerDevice) -> MetaNode -{ - MetaNode node(++nodeCounter_g, "HaloUpdate", MetaNodeType_e::HALO_UPDATE, -1); - node.m_transferMode = tm; - node.m_uid = dataUids; - node.m_hu = hu; - node.m_huPerDevice = huPerDevice; - return node; -} - -auto MetaNode::syncLeftRightFactory(const Neon::set::MultiDeviceObjectUid& dataUids) -> MetaNode -{ - MetaNode node(++nodeCounter_g, "syncLeftRigh", MetaNodeType_e::SYNC_LEFT_RIGHT, -1); - node.m_uid = dataUids; - return node; -} - -auto MetaNode::setAsCoherent() -> void -{ - m_hasCoherentInput = true; -} -auto MetaNode::isStencil() const -> bool -{ - return m_nodeType == MetaNodeType_e::CONTAINER && m_compute == Neon::Compute::STENCIL; -} -auto MetaNode::isMap() const -> bool -{ - return m_nodeType == MetaNodeType_e::CONTAINER && m_compute == Neon::Compute::MAP; -} - -auto MetaNode::isSync() const -> bool -{ - return m_nodeType == MetaNodeType_e::SYNC_LEFT_RIGHT; -} - -auto MetaNode::isHu() const -> bool -{ - return m_nodeType == MetaNodeType_e::HALO_UPDATE; -} - -auto MetaNode::isReduce() const -> bool -{ - return m_nodeType == MetaNodeType_e::CONTAINER && m_compute == Neon::Compute::REDUCE; -} - -auto MetaNode::clone() const -> MetaNode -{ - MetaNode clone(*this); - clone.m_nodeId = ++nodeCounter_g; - return clone; -} - -auto MetaNode::cudaGraphHandles_t::init(MetaNodeType_e nodeType, int numDevices) -> void -{ - m_data = std::vector>(2); - - m_data[0] = Neon::set::DataSet(numDevices); - m_data[1] = Neon::set::DataSet(numDevices); - - switch (nodeType) { - case MetaNodeType_e::CONTAINER: - case MetaNodeType_e::HELPER: - // Node that is papped to only one CUDA graph node - m_first = 0; - m_last = 0; - return; - case MetaNodeType_e::HALO_UPDATE: - case MetaNodeType_e::SYNC_LEFT_RIGHT: - // Node that is papped to a sequence of nodes. - // We track only the first and the last. - // first() is used to creates dependencies BEFORE this node - // last() is used to create dependencies AFTER this node - m_first = 0; - m_last = 1; - return; - default: { - return; - } - } -} - -auto MetaNode::cudaGraphHandles_t::first() -> Neon::set::DataSet& -{ - return m_data.at(m_first); -} - -auto MetaNode::cudaGraphHandles_t::last() -> Neon::set::DataSet& -{ - return m_data.at(m_last); -} - - -auto MetaNode::hu(Neon::set::HuOptions& opt) -> void -{ - m_hu(opt); -} - -auto MetaNode::hu(Neon::SetIdx setIdx, Neon::set::HuOptions& opt) -> void -{ - m_huPerDevice(setIdx, opt); -} - -auto MetaNode::transferMode() const - -> Neon::set::TransferMode -{ - return m_transferMode; -} - -auto MetaNode::setLinearContinuousIndex(size_t id) -> void -{ - m_linearContinuousIndex = id; -} -auto MetaNode::getLinearContinuousIndex() const -> size_t -{ - return m_linearContinuousIndex; -} - -} // namespace internal -} // namespace skeleton -} // namespace Neon \ No newline at end of file diff --git a/libNeonSkeleton/src/skeleton/internal/streamScheduler.cpp b/libNeonSkeleton/src/skeleton/internal/streamScheduler.cpp deleted file mode 100644 index dfbb868b..00000000 --- a/libNeonSkeleton/src/skeleton/internal/streamScheduler.cpp +++ /dev/null @@ -1,1146 +0,0 @@ -#include "Neon/skeleton/internal/StreamScheduler.h" -#include -#include "Neon/set/syncrhonizations/event_LR_barrier.h" - -namespace Neon::skeleton::internal { - -#ifdef NEON_USE_NVTX -#include -#endif - -StreamScheduler::MetaNodeExtended::SchedulingInfo::SchedulingInfo(size_t nodeId_, - size_t extendedNodeIdx_, - ContainerIdx cIdx) -{ - nodeId = nodeId_; - metaNodeExtendedIdx = extendedNodeIdx_; - containerIdx = cIdx; -} - -StreamScheduler::MetaNodeExtended::SchedulingInfo::SchedulingInfo() -{ - nodeId = 0; - metaNodeExtendedIdx = 0; - containerIdx = 0; - streamIdx = -1; - setEventIdx = -1; -} - -auto StreamScheduler::init(Neon::Backend& bk, MultiGpuGraph& multiGpuGraph) -> void -{ - m_storage = std::make_shared(bk, multiGpuGraph); - m_storage->m_metaNodeExtendedList = std::vector( - multiGpuGraph.getLinearContinuousIndexingCounter()); - - initCleanRedundantSync(); - initCreateLevels(); - initScheduleStreams(); - initScheduleEvents(); - initCleanRedundantEvents(); - initLinearisationList(); - initExecutionOrder(); -} - -auto StreamScheduler::initCleanRedundantSync() -> void -{ - if (m_storage->useFullBarrierOnAllStreamsAtTheEnd) { - { // Removing events from root nodes as we have a full barrier at the end - NodeId root = m_storage->m_graph.rootNodeId(); - auto& diGraph = m_storage->m_graph.getDiGraph(); - std::set rootChildList = diGraph.outNeighbors(root); - - for (auto& rootChild : rootChildList) { - const auto& rootChildMeta = h_getMetaNode(rootChild); - if (rootChildMeta.isSync()) { - auto& schedulingrGraph = m_storage->m_graph.getSchedulingDiGraph(); - if (diGraph.outNeighbors(rootChild).size() != 1) { - continue; - } - NodeId huNode = *diGraph.outNeighbors(rootChild).begin(); - const auto& huMeta = diGraph.getVertexProperty(huNode); - if (!huMeta.isHu()) { - continue; - } - // we are in a sutuation of a SYNC follow by a HALO Up. - if (schedulingrGraph.hasVertex(rootChild)) { - if (!schedulingrGraph.hasVertex(huNode)) { - schedulingrGraph.addVertex(huNode); - } - const auto& inSchedulingEdges = schedulingrGraph.inEdges(rootChild); - for (auto& inSchedulingEdge : inSchedulingEdges) { - schedulingrGraph.addEdge(inSchedulingEdge.first, huNode); - } - schedulingrGraph.removeVertex(rootChild); - } - for (auto& neighbour : diGraph.neighbors(rootChild)) { - diGraph.addEdge(root, neighbour); - } - diGraph.removeVertex(rootChild); - } - } - } - } -} - -auto StreamScheduler::initCleanRedundantEvents() -> void -{ - if (m_storage->useFullBarrierOnAllStreamsAtTheEnd) { - { // Removing events from root nodes as we have a full barrier at the end - NodeId root = m_storage->m_graph.rootNodeId(); - auto& metaNodeExtendedRoot = h_getMetaNodeExtended(root); - metaNodeExtendedRoot.schedulingInfo.setEventIdx = -1; - - auto& diGraph = m_storage->m_graph.getDiGraph(); - std::set rootChildList = diGraph.outNeighbors(root); - - for (auto& rootChild : rootChildList) { - auto& metaNodeExtended = h_getMetaNodeExtended(rootChild); - metaNodeExtended.schedulingInfo.waitEventIdxList = std::unordered_set(); - } - } - } - - // Checking if we can remove the last sync all - NodeId endNode = m_storage->m_graph.finalNodeId(); - auto& diGraph = m_storage->m_graph.getDiGraph(); - std::set endNodeChildList = diGraph.inNeighbors(endNode); - if (endNodeChildList.size() == 1) { - bool allReduceNodes = true; - for (auto& endNodeChild : endNodeChildList) { - const auto& metaNode = m_storage->m_graph.getDiGraph().getVertexProperty(endNodeChild); - if (!metaNode.isReduce()) { - allReduceNodes = false; - } else { - auto& metaNodeExtendedChild = h_getMetaNodeExtended(endNodeChild); - metaNodeExtendedChild.schedulingInfo.setEventIdx = -1; - } - } - if (allReduceNodes) { - m_storage->canEndNodeLastBarrierBeOptimizedOut = true; - } - } -} - - -/** - * Returns number of levels - * @return - */ -auto StreamScheduler::nLevels() -> int -{ - return static_cast(m_storage->m_levels.size()); -} - -/** - * - * @return - */ -auto StreamScheduler::addNewLevel() -> LevelIdx -{ - m_storage->m_levels.emplace_back(); - return LevelIdx(m_storage->m_levels.size() - 1); -} - -auto StreamScheduler::getLevel(int levelIdx) -> Level& -{ - return m_storage->m_levels.at(levelIdx); -} - -auto StreamScheduler::resetLevels() -> void -{ - m_storage->m_levels.clear(); -} - -/** - * - */ -auto StreamScheduler::getStreamFlags() -> std::vector& -{ - return m_storage->m_streamFlags; -} - -/** - * - * @return - */ -auto StreamScheduler::resetStreamFlags() -> void -{ - for (auto& flag : m_storage->m_streamFlags) { - flag = 0; - } -} - -auto StreamScheduler::h_getMetaNodeExtended(size_t id) -> MetaNodeExtended& -{ - auto& meta = m_storage->m_graph.getDiGraph().getVertexProperty(id); - return m_storage->m_metaNodeExtendedList.at(meta.getLinearContinuousIndex()); -}; - -auto StreamScheduler::h_getMetaNode(NodeId id) -> MetaNode& -{ - auto& meta = m_storage->m_graph.getDiGraph().getVertexProperty(id); - return meta; -}; - -auto StreamScheduler::h_getMetaNodeExtended(MetaNode& id) -> MetaNodeExtended& -{ - return m_storage->m_metaNodeExtendedList.at(id.getLinearContinuousIndex()); -} - -/** - * - * @param nodeId - */ -auto StreamScheduler::registerNodeToLastLevel(NodeId nodeId) -> void -{ - const size_t levelTarget = m_storage->m_levels.size() - 1; - this->m_storage->m_levels.at(levelTarget).push_back(nodeId); -} - -auto StreamScheduler::initCreateLevels() -> void -{ - auto& diGraph = m_storage->m_graph.getDiGraph(); - - // Set the dependency counter of each node - diGraph.forEachVertex([&](NodeId nodeId) { - auto& metaNodeExtended = h_getMetaNodeExtended(nodeId); - const int nDependencies = int(diGraph.inEdgesCount(nodeId)); - metaNodeExtended.blockingDependencies = nDependencies; - }); - - std::unordered_set frontier; - const NodeId beginning = m_storage->m_graph.rootNodeId(); - frontier.insert(beginning); - // h_dissolveDataDependencies(beginning); - - // Walking the graph following a BFS with constraints - int level = -1; - while (!frontier.empty()) { - addNewLevel(); - level++; - // printf("Level %d \n", level); - std::unordered_set nextFrontier; - std::unordered_set nodeToApplyDissolveTo; - for (auto& frontierNodeId : frontier) { - { // 2. If the node has still some dependencies that are not satisfy, - // don't process the node now ad add it to the next frontier - // printf("frontierNodeId %ld \n", frontierNodeId); - auto& frontierMetaNode = h_getMetaNode(frontierNodeId); - auto frontierMetaNodeExtended = h_getMetaNodeExtended(frontierMetaNode); - if (frontierMetaNodeExtended.blockingDependencies != 0) { - // There are some data dependencies still active before processing this node - // Moving the node to the next frontier. - nextFrontier.insert(frontierNodeId); - // std:: cout<< "frontierMetaNode " << frontierNodeId <<" postpone" < childList = diGraph.outNeighbors(frontierNodeId); - for (auto& child : childList) { - nextFrontier.insert(child); - } - } - { // 4. Upgrade information in the metaNodeExtended - auto& metaNode = h_getMetaNode(frontierNodeId); - auto& metaNodeExtended = h_getMetaNodeExtended(frontierNodeId); - metaNodeExtended.schedulingInfo = MetaNodeExtended::SchedulingInfo(frontierNodeId, - metaNode.getLinearContinuousIndex(), - metaNode.getContainerId()); - } - { // 5. Register the target frontier node to the last level - registerNodeToLastLevel(frontierNodeId); - nodeToApplyDissolveTo.insert(frontierNodeId); - } - } - - // Update all the dependencies - for (auto& frontierNode : nodeToApplyDissolveTo) { - h_dissolveDataDependencies(diGraph, frontierNode); - } - // h_print_depcountALL(); - frontier = nextFrontier; - } -} - -auto StreamScheduler::initStreamFlags() -> int -{ - int maxNstream = 0; - for (int i = 0; i < nLevels(); i++) { - Level& level = getLevel(i); - maxNstream = int(level.size()) > maxNstream ? int(level.size()) : maxNstream; - } - m_storage->m_streamFlags = std::vector(maxNstream, 0); - m_storage->m_bk.setAvailableStreamSet(maxNstream); - return maxNstream; -} - -auto StreamScheduler::initScheduleStreams() -> void -{ - auto& diGraph = m_storage->m_graph.getDiGraph(); - - NodeId startNodeId = m_storage->m_graph.rootNodeId(); - NodeId endNodeId = m_storage->m_graph.finalNodeId(); - - auto h_setStream = [this](NodeId nodeId, int streamId) { - auto& metaNode = h_getMetaNodeExtended(nodeId); - metaNode.schedulingInfo.streamIdx = streamId; - }; - - initStreamFlags(); - auto& streamFlags = getStreamFlags(); - - for (int i = 0; i < nLevels(); i++) { - resetStreamFlags(); - Level& level = getLevel(i); - std::vector leftToMatch; - // - for (auto it = level.begin(), end = level.end(); it != end; ++it) { - NodeId nodeId = *it; - - if (nodeId == endNodeId || nodeId == startNodeId) { - h_setStream(nodeId, 0); - continue; - } - - if (h_getMetaNodeExtended(nodeId).schedulingInfo.isHaloUpdateNode) { - // Halo nodes are associated to the same stream as the parent node - continue; - } - auto parents = diGraph.inNeighbors(nodeId); - bool matchDone = false; - // Try to match the stream id with one of the parent nodes - for (auto& parent : parents) { - const auto& parentMetaNodeExtended = h_getMetaNodeExtended(parent); - int parentStreamId = parentMetaNodeExtended.schedulingInfo.streamIdx; - - // checking if at this level the stream of the parent is still available - const bool available = (streamFlags[parentStreamId] == 0); - if (available) { - streamFlags[parentStreamId] = 1; - h_setStream(nodeId, parentStreamId); - matchDone = true; - break; - } - } - if (matchDone) - continue; - // nodes left to match - // no halo node is added to this vector - leftToMatch.push_back(nodeId); - } - for (auto& toMatch : leftToMatch) { - bool matchFound = false; - for (int streamIdx = 0; streamIdx < static_cast(streamFlags.size()); streamIdx++) { - const bool available = streamFlags[streamIdx] == 0; - if (available) { - streamFlags[streamIdx] = 1; - h_setStream(toMatch, streamIdx); - matchFound = true; - break; - } - } - if (!matchFound) { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } - } -} - -auto StreamScheduler::initScheduleEvents() -> void -{ - int eventCounter = 0; - - auto h_waitEvent = [this, &eventCounter](NodeId nodeId) -> EventIdx { - auto& metaNode = h_getMetaNodeExtended(nodeId); - if (metaNode.schedulingInfo.setEventIdx == -1) { - metaNode.schedulingInfo.setEventIdx = eventCounter; - eventCounter++; - } - return metaNode.schedulingInfo.setEventIdx; - }; - - auto h_barrierLREvent = [&eventCounter](MetaNodeExtended& metaNodeExtended) -> void { - if (metaNodeExtended.schedulingInfo.barrierLR == -1) { - metaNodeExtended.schedulingInfo.barrierLR = eventCounter; - eventCounter++; - } - }; - - auto h_setEvent = [this](NodeId nodeId, EventIdx eventIdx) -> void { - auto& metaNode = h_getMetaNodeExtended(nodeId); - metaNode.schedulingInfo.waitEventIdxList.insert(eventIdx); - }; - - auto h_addEventsIfNeeded = [this, &h_waitEvent, &h_setEvent, &h_barrierLREvent](NodeId nodeId) -> void { - const auto& diGraph = m_storage->m_graph.getDiGraph(); - auto& metaNodeExtended = h_getMetaNodeExtended(nodeId); - const Neon::StreamIdx nodeStreamIdx = metaNodeExtended.schedulingInfo.streamIdx; - auto& parentNodeIdSet = diGraph.inNeighbors(nodeId); - - for (auto& parentNodeId : parentNodeIdSet) { - auto parentMetaNode = h_getMetaNodeExtended(parentNodeId); - const Neon::StreamIdx parentStreamIdx = parentMetaNode.schedulingInfo.streamIdx; - if (parentStreamIdx != nodeStreamIdx) { - EventIdx eventIdx = h_waitEvent(parentNodeId); - h_setEvent(nodeId, eventIdx); - } - } - { // If the hode is a LR barrier, then we need to book an extra event - auto nodeMeta = h_getMetaNode(nodeId); - if (nodeMeta.nodeType() == MetaNodeType_te::SYNC_LEFT_RIGHT) { - h_barrierLREvent(metaNodeExtended); - } - if (nodeMeta.nodeType() == MetaNodeType_te::BARRIER) { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } - }; - - for (int i = 0; i < nLevels(); i++) { - Level& level = getLevel(i); - for (auto it = level.begin(), end = level.end(); it != end; ++it) { - NodeId nodeId = *it; - h_addEventsIfNeeded(nodeId); - } - } - - m_storage->m_bk.setAvailableUserEvents(eventCounter); -} - -auto StreamScheduler::initLinearisationList() -> void -{ - - std::vector& linear = m_storage->m_linearization; - for (int i = 0; i < nLevels(); i++) { - Level& level = getLevel(i); - for (auto it = level.begin(), end = level.end(); it != end; ++it) { - NodeId nodeId = *it; - MetaNodeExtended& metaNodeExtended = h_getMetaNodeExtended(nodeId); - int schedulingOrder = int(linear.size()); - metaNodeExtended.schedulingInfo.schedulingOrder = schedulingOrder; - linear.push_back(nodeId); - } - } -} - -#if 0 - auto StreamScheduler::initExecutionOrder() -> void - { - // Extract a linear indexing of all the nodes - const std::vector& linear = m_storage->m_linearization; - // Aliasing m_executionOrder with variable order - std::vector& order = m_storage->m_executionOrder; - - // A bool map to track nodes that were already processed - std::vector alreadyProceed(linear.size(), false); - - // Aliasing: the scheduling graph from m_graph - const auto& schedulingGraph = m_storage->m_graph.getSchedulingDiGraph(); - - // Lambda to extract all nodes that come before nodeId - // in the SCHEDULING graph - auto findSchedulingExecutionDep = [schedulingGraph](NodeId nodeId) -> std::set { - if (schedulingGraph.hasVertex(nodeId)) { - const auto& inNhg = schedulingGraph.inNeighbors(nodeId); - return inNhg; - } - return std::set(); - }; - - // Looping over all the nodes based on a linearized index. - // There is no specific order in the indexing - for (size_t i = 0; i < linear.size(); i++) { - NodeId nodeId = linear[i]; - MetaNode metaNode = h_getMetaNode(nodeId); - if (alreadyProceed[metaNode.getLinearContinuousIndex()]) { - continue; - } - const auto& SchedulingDeps = findSchedulingExecutionDep(nodeId); - for (const auto& schedulingDepNode : SchedulingDeps) { - const auto& depMeta = h_getMetaNode(schedulingDepNode); - if (!alreadyProceed[depMeta.getLinearContinuousIndex()]) { - order.push_back(schedulingDepNode); - alreadyProceed[depMeta.getLinearContinuousIndex()] = true; - } - } - order.push_back(nodeId); - alreadyProceed[metaNode.getLinearContinuousIndex()] = true; - } - - if (linear.size() != order.size()) { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - - for (size_t i = 0; i < order.size(); i++) { - NodeId nodeId = order[i]; - MetaNodeExtended& metaNodeExtended = h_getMetaNodeExtended(nodeId); - metaNodeExtended.schedulingInfo.schedulingOrder = static_cast(i); - } - } -#else - - -auto StreamScheduler::initExecutionOrder() -> void -{ - // Extract a linear indexing of all the nodes - // const std::vector& linear = m_storage->m_linearization; - // Aliasing m_executionOrder with variable order - std::vector& order = m_storage->m_executionOrder; - - - auto dataAndSchedulingGraph = m_storage->m_graph.getDiGraph(); - { - const auto& schedulingGraph = m_storage->m_graph.getSchedulingDiGraph(); - for (auto& edge : schedulingGraph.edges()) { - if (!dataAndSchedulingGraph.hasEdge(edge)) { - dataAndSchedulingGraph.addEdge(edge.first, edge.second); - } - } - } - - // Set the dependency counter of each node - dataAndSchedulingGraph.forEachVertex([&](NodeId nodeId) { - auto& metaNodeExtended = h_getMetaNodeExtended(nodeId); - const int nDependencies = int(dataAndSchedulingGraph.inEdgesCount(nodeId)); - metaNodeExtended.blockingDependencies = nDependencies; - }); - - std::unordered_set frontier; - const NodeId beginning = m_storage->m_graph.rootNodeId(); - frontier.insert(beginning); - - // Reseting Levels; - resetLevels(); - - // Walking the graph following a BFS with constraints - int level = -1; - while (!frontier.empty()) { - addNewLevel(); - level++; - // printf("Level %d \n", level); - std::unordered_set nextFrontier; - std::unordered_set nodeToApplyDissolveTo; - for (auto& frontierNodeId : frontier) { - { // 2. If the node has still some dependencies that are not satisfy, - // don't process the node now ad add it to the next frontier - // printf("frontierNodeId %ld \n", frontierNodeId); - auto& frontierMetaNode = h_getMetaNode(frontierNodeId); - auto frontierMetaNodeExtended = h_getMetaNodeExtended(frontierMetaNode); - if (frontierMetaNodeExtended.blockingDependencies != 0) { - // There are some data dependencies still active before processing this node - // Moving the node to the next frontier. - nextFrontier.insert(frontierNodeId); - // std:: cout<< "frontierMetaNode " << frontierNodeId <<" postpone" < childList = dataAndSchedulingGraph.outNeighbors(frontierNodeId); - for (auto& child : childList) { - nextFrontier.insert(child); - } - } - { // 5. Register the target frontier node to the last level - registerNodeToLastLevel(frontierNodeId); - nodeToApplyDissolveTo.insert(frontierNodeId); - } - } - - // Update all the dependencies - for (auto& frontierNode : nodeToApplyDissolveTo) { - h_dissolveDataDependencies(dataAndSchedulingGraph, frontierNode); - } - // h_print_depcountALL(); - frontier = nextFrontier; - } - for (int i = 0; i < nLevels(); i++) { - Level& lev = getLevel(i); - for (auto it = lev.begin(), end = lev.end(); it != end; ++it) { - NodeId nodeId = *it; - order.push_back(nodeId); - } - } -} - -#endif - - -auto StreamScheduler::helpRunOmpAtNodeLevel() -> void -{ - for (auto& nodeId : m_storage->m_executionOrder) { -#ifdef NEON_USE_NVTX - const auto nvtxName = helpNvtxName(nodeId); - nvtxRangePush(nvtxName.c_str()); -#endif - MetaNodeExtended metaNodeExtended = h_getMetaNodeExtended(nodeId); - const Neon::StreamIdx streamIdx = metaNodeExtended.schedulingInfo.streamIdx; - const EventIdx eventIdx = metaNodeExtended.schedulingInfo.setEventIdx; - for (const auto& eventToBeWaited : metaNodeExtended.schedulingInfo.waitEventIdxList) { - if (nodeId == m_storage->m_graph.finalNodeId()) { - continue; - } - helpWaitForEventCompletion(streamIdx, eventToBeWaited); - } - - helpRun(nodeId, streamIdx); - if (eventIdx != -1 && nodeId != m_storage->m_graph.finalNodeId()) { - helpEnqueueEvent(streamIdx, eventIdx); - } - if (nodeId == m_storage->m_graph.finalNodeId()) { - if (!m_storage->canEndNodeLastBarrierBeOptimizedOut) { - m_storage->m_bk.syncAll(); - } - } -#ifdef NEON_USE_NVTX - nvtxRangePop(); -#endif - } -} - -auto StreamScheduler::helpRunOmpAtGraphLevel() -> void -{ - const int nNodes = int(m_storage->m_executionOrder.size()); - - for (int setIdx = 0; setIdx < m_storage->m_bk.devSet().setCardinality(); setIdx++) { - for (int a = 0; a < nNodes; a++) { - auto& nodeId = m_storage->m_executionOrder[a]; - -#ifdef NEON_USE_NVTX - const auto nvtxName = helpNvtxName(nodeId); - nvtxRangePush(nvtxName.c_str()); -#endif - MetaNodeExtended metaNodeExtended = h_getMetaNodeExtended(nodeId); - const Neon::StreamIdx streamIdx = metaNodeExtended.schedulingInfo.streamIdx; - const EventIdx eventIdx = metaNodeExtended.schedulingInfo.setEventIdx; - for (const auto& eventToBeWaited : metaNodeExtended.schedulingInfo.waitEventIdxList) { - if (nodeId == m_storage->m_graph.finalNodeId()) { - continue; - } - helpWaitForEventCompletion(setIdx, streamIdx, eventToBeWaited); - } - - helpRun(setIdx, nodeId, streamIdx); - if (eventIdx != -1 && nodeId != m_storage->m_graph.finalNodeId()) { - helpEnqueueEvent(setIdx, streamIdx, eventIdx); - } - if (nodeId == m_storage->m_graph.finalNodeId()) { - if (!m_storage->canEndNodeLastBarrierBeOptimizedOut) { - m_storage->m_bk.syncAll(); - } - } -#ifdef NEON_USE_NVTX - nvtxRangePop(); -#endif - } - } -} -auto StreamScheduler::run(const Neon::skeleton::Options& options) -> void -{ - if (Neon::skeleton::Executor::ompAtNodeLevel == options.executor()) { -#ifdef NEON_USE_NVTX - nvtxRangePush("Skeleton Iteration - ompAtNodeLevel"); -#endif - helpRunOmpAtNodeLevel(); -#ifdef NEON_USE_NVTX - nvtxRangePop(); -#endif - return; - } - - if (Neon::skeleton::Executor::ompAtGraphLevel == options.executor()) { -#ifdef NEON_USE_NVTX - nvtxRangePush("Skeleton Iteration - ompAtGraphLevel"); -#endif - helpRunOmpAtGraphLevel(); -#ifdef NEON_USE_NVTX - nvtxRangePop(); -#endif - return; - } - NEON_THROW_UNSUPPORTED_OPTION("No supported Executor option."); -} - -auto StreamScheduler::helpRun(NodeId nodeId, Neon::StreamIdx streamIdx) -> void -{ - MetaNode& metaNode = h_getMetaNode(nodeId); - - - switch (metaNode.nodeType()) { - case MetaNodeType_te::CONTAINER: { - - ContainerIdx containerIdx = metaNode.getContainerId(); - auto& container = m_storage->m_graph.getContainer(containerIdx); - container.run(streamIdx, metaNode.getDataView()); - return; - } - case MetaNodeType_te::SYNC_LEFT_RIGHT: { - // Neon::set::Event_LR_barrier::sync(m_storage->m_bk, streamIdx, h_getMetaNodeExtended(nodeId).schedulingInfo.barrierLR); - m_storage->m_bk.sync(streamIdx); - return; - } - case MetaNodeType_te::HALO_UPDATE: { - const bool startWithBarrier = false; - Neon::set::HuOptions huOptions(metaNode.transferMode(), startWithBarrier, streamIdx); - metaNode.hu(huOptions); - return; - } - case MetaNodeType_te::HELPER: { - return; - } - case MetaNodeType_te::BARRIER: - case MetaNodeType_te::UNDEFINED: { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } -} - -auto StreamScheduler::helpRun(Neon::SetIdx setIdx, NodeId nodeId, Neon::StreamIdx streamIdx) -> void -{ - MetaNode& metaNode = h_getMetaNode(nodeId); - - - switch (metaNode.nodeType()) { - case MetaNodeType_te::CONTAINER: { - - ContainerIdx containerIdx = metaNode.getContainerId(); - auto& container = m_storage->m_graph.getContainer(containerIdx); - container.run(setIdx, streamIdx, metaNode.getDataView()); - return; - } - case MetaNodeType_te::SYNC_LEFT_RIGHT: { - // Neon::set::Event_LR_barrier::sync(m_storage->m_bk, streamIdx, h_getMetaNodeExtended(nodeId).schedulingInfo.barrierLR); - m_storage->m_bk.sync(setIdx, streamIdx); - return; - } - case MetaNodeType_te::HALO_UPDATE: { - const bool startWithBarrier = false; - Neon::set::HuOptions huOptions(metaNode.transferMode(), startWithBarrier, streamIdx); - metaNode.hu(setIdx, huOptions); - return; - } - case MetaNodeType_te::HELPER: { - return; - } - case MetaNodeType_te::BARRIER: - case MetaNodeType_te::UNDEFINED: { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } -} - -auto StreamScheduler::helpNvtxName(NodeId nodeId) -> std::string -{ - MetaNode& metaNode = h_getMetaNode(nodeId); - switch (metaNode.nodeType()) { - case MetaNodeType_te::CONTAINER: { - - ContainerIdx containerIdx = metaNode.getContainerId(); - auto& container = m_storage->m_graph.getContainer(containerIdx); - std::string name = container.getName() + "_" + Neon::DataViewUtil::toString(metaNode.getDataView()); - return name; - } - case MetaNodeType_te::SYNC_LEFT_RIGHT: { - // Neon::set::Event_LR_barrier::sync(m_storage->m_bk, streamIdx, h_getMetaNodeExtended(nodeId).schedulingInfo.barrierLR); - return "LeftRightSync"; - } - case MetaNodeType_te::HALO_UPDATE: { - return "Halo Update"; - } - case MetaNodeType_te::HELPER: { - return "HELPER"; - } - case MetaNodeType_te::BARRIER: - case MetaNodeType_te::UNDEFINED: - default: { - NEON_THROW_UNSUPPORTED_OPTION(""); - } - } -} - - -auto StreamScheduler::helpWaitForEventCompletion(StreamIdx streamIdx, Neon::EventIdx eventIdx) -> void -{ - auto& bk = m_storage->m_bk; - bk.waitEventOnStream(eventIdx, streamIdx); -} - -auto StreamScheduler::helpEnqueueEvent(StreamIdx streamIdx, Neon::EventIdx eventIdx) -> void -{ - auto& bk = m_storage->m_bk; - bk.pushEventOnStream(eventIdx, streamIdx); -} - -auto StreamScheduler::helpWaitForEventCompletion(Neon::SetIdx setIdx, StreamIdx streamIdx, Neon::EventIdx eventIdx) -> void -{ - auto& bk = m_storage->m_bk; - bk.waitEventOnStream(setIdx, eventIdx, streamIdx); -} - -auto StreamScheduler::helpEnqueueEvent(Neon::SetIdx setIdx, StreamIdx streamIdx, Neon::EventIdx eventIdx) -> void -{ - auto& bk = m_storage->m_bk; - bk.pushEventOnStream(setIdx, eventIdx, streamIdx); -} - -#if 0 - auto StreamScheduler::io2Dot(const std::string& fname, const std::string& graphName) -> void - { - auto clone = m_storage->m_graph.getDiGraph(); - m_storage->m_graph.getSchedulingDiGraph().forEachEdge([&](const MultiGpuGraph::DiGraphScheduling::Edge& edge) { - auto edgeMeta = Edge_t::factorySchedulingEdge(); - clone.addEdge(edge.first, edge.second, edgeMeta); - }); - - auto& mGpuGraph = m_storage->m_graph; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto vertexLabel = [&](NodeId nodeId) -> std::string { - auto& metaNodeExtended = h_getMetaNodeExtended(nodeId); - - auto h_intro = [&]() -> std::string { - return std::string("Scheduling info: \\l- Scheduling ID ") + std::to_string(metaNodeExtended.schedulingInfo.schedulingOrder) + "\\l"; - }; - - auto h_eventWaitString = [&]() -> std::string { - std::string ret; - if (metaNodeExtended.schedulingInfo.waitEventIdxList.size() == 0) { - ret += "- No waiting\\l"; - } else { - ret += "- Waiting events:"; - for (auto& e : metaNodeExtended.schedulingInfo.waitEventIdxList) { - ret += " " + std::to_string(e); - } - ret += "\\l"; - } - return ret; - }; - - auto h_streamString = [&]() -> std::string { - return "- Stream " + std::to_string(metaNodeExtended.schedulingInfo.streamIdx) + "\\l"; - }; - - [[maybe_unused]] auto h_barrierString = [&]() -> std::string { - if (metaNodeExtended.schedulingInfo.barrierLR != -1) { - return "- LR Event " + std::to_string(metaNodeExtended.schedulingInfo.barrierLR) + "\\l"; - ; - } - return ""; - }; - - auto h_eventRegisterString = [&]() -> std::string { - if (metaNodeExtended.schedulingInfo.setEventIdx != -1) { - return "- Registering Event " + std::to_string(metaNodeExtended.schedulingInfo.setEventIdx) + "\\l"; - ; - } - return ""; - }; - - if (nodeId == mGpuGraph.finalNodeId()) { - return std::string("END (") + std::to_string(nodeId) + ")\n\n" + h_intro() + h_eventWaitString() + h_streamString() + "\\l"; - } - if (nodeId == mGpuGraph.rootNodeId()) { - return std::string("START(") + std::to_string(nodeId) + ")\n\n" + h_intro() + h_eventWaitString() + h_streamString() + h_eventRegisterString() + "\\l"; - } - - - return clone.getVertexProperty(nodeId).toString() + h_intro() + h_eventWaitString() + h_streamString() + h_eventRegisterString() + "\\l"; - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto edgeLabel = [&](const std::pair& edge) - -> std::string { - const auto& metaEdge = clone.getEdgeProperty(edge); - if (metaEdge.m_isSchedulingEdge) { - return ""; - } - //if (property.nDependencies() > 0) { - auto& metaNodeExtendedStart = h_getMetaNodeExtended(edge.first); - auto& metaNodeExtendedEnd = h_getMetaNodeExtended(edge.second); - if (metaNodeExtendedStart.schedulingInfo.streamIdx != metaNodeExtendedEnd.schedulingInfo.streamIdx) { - // bool found = false; - for (auto& e : metaNodeExtendedEnd.schedulingInfo.waitEventIdxList) { - if (e == metaNodeExtendedStart.schedulingInfo.setEventIdx) { - // found = true; - } - } - // if (!found) { - // NEON_THROW_UNSUPPORTED_OPTION(""); - // } - if (metaEdge.nDependencies() > 0) { - return metaEdge.toString() + - "Synchronizations:\\l- Stream " + - std::to_string(metaNodeExtendedStart.schedulingInfo.streamIdx) + - "\\l- Event " + std::to_string(metaNodeExtendedStart.schedulingInfo.setEventIdx) + "\\l"; - } else { - return "Synchronization:\\l- Stream " + - std::to_string(metaNodeExtendedStart.schedulingInfo.streamIdx) + - "\\l- Event " + std::to_string(metaNodeExtendedStart.schedulingInfo.setEventIdx) + "\\l"; - } - } - //return property.toString() + "\\l"; - // } - return ""; - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto edgeLabelProperty = [&](const std::pair& edge) - -> std::string { - const auto& metaEdge = clone.getEdgeProperty(edge); - if (metaEdge.m_isSchedulingEdge) { - // return "style=dashed, color=\"#2A9D8F\""; - return "style=dashed, color=\"#F4A261\", penwidth=7"; - } - return "color=\"#d9d9d9\", penwidth=7"; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto vertexLabelProperty = [&](const size_t& v) { - if (v == mGpuGraph.finalNodeId() || (v == mGpuGraph.rootNodeId())) { - return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; - } - const auto& metaNode = clone.getVertexProperty(v); - if (metaNode.isHu()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - if (metaNode.isSync()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - - if (metaNode.isMap()) { - return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; - } - if (metaNode.isReduce()) { - return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; - } - if (metaNode.isStencil()) { - return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; - } - return ""; - }; - - //////////////////////////////////////////////////////////////////////////// - clone.exportDotFile(fname, graphName, vertexLabel, edgeLabel, - vertexLabelProperty, edgeLabelProperty); - } -#else - -auto StreamScheduler::io2Dot(const std::string& fname, const std::string& graphName) -> void -{ - auto clone = m_storage->m_graph.getDiGraph(); - m_storage->m_graph.getSchedulingDiGraph().forEachEdge([&](const MultiGpuGraph::DiGraphScheduling::Edge& edge) { - auto edgeMeta = Edge::factorySchedulingEdge(); - clone.addEdge(edge.first, edge.second, edgeMeta); - }); - - auto& mGpuGraph = m_storage->m_graph; - - auto vertexLabel = [&](NodeId nodeId) -> std::string { - auto& metaNodeExtended = h_getMetaNodeExtended(nodeId); - - auto h_intro = [&]() -> std::string { - return std::string("Scheduling info: \\l- Taks idx ") + - std::to_string(metaNodeExtended.schedulingInfo.schedulingOrder) + "\\l"; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_eventWaitString = [&]() -> std::string { - std::string ret; - if (metaNodeExtended.schedulingInfo.waitEventIdxList.size() == 0) { - ret += "- Waiting events: []\\l"; - } else { - ret += "- Waiting events: ["; - for (auto& e : metaNodeExtended.schedulingInfo.waitEventIdxList) { - ret += " " + std::to_string(e); - } - ret += "]\\l"; - } - return ret; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_streamString = [&]() -> std::string { - return "- Stream idx: " + std::to_string(metaNodeExtended.schedulingInfo.streamIdx) + "\\l"; - }; - - [[maybe_unused]] auto h_barrierString = [&]() -> std::string { - if (metaNodeExtended.schedulingInfo.barrierLR != -1) { - return "- LR Event " + std::to_string(metaNodeExtended.schedulingInfo.barrierLR) + "\\l"; - ; - } - return ""; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_eventRegisterString = [&]() -> std::string { - if (metaNodeExtended.schedulingInfo.setEventIdx != -1) { - return "- Completion Event idx: " + std::to_string(metaNodeExtended.schedulingInfo.setEventIdx) + - "\\l"; - } else { - return "- Completion Event idx: None"; - } - }; - - if (nodeId == mGpuGraph.finalNodeId()) { - return std::string("END \n") + h_intro() + h_streamString() + h_eventWaitString() + - h_eventRegisterString() + "\\l"; - } - if (nodeId == mGpuGraph.rootNodeId()) { - return std::string("START \n") + h_intro() + h_streamString() + h_eventWaitString() + - h_eventRegisterString() + "\\l"; - } - return clone.getVertexProperty(nodeId).toString() + h_intro() + h_streamString() + h_eventWaitString() + - h_eventRegisterString() + "\\l"; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto edgeLabel = [&](const std::pair&) - -> std::string { - return ""; - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto edgeLabelProperty = [&](const std::pair& edge) - -> std::string { - const auto& metaEdge = clone.getEdgeProperty(edge); - if (metaEdge.m_isSchedulingEdge) { - // return "style=dashed, color=\"#2A9D8F\""; - return "style=dashed, color=\"#F4A261\", penwidth=7"; - } - return "color=\"#d9d9d9\", penwidth=7"; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto vertexLabelProperty = [&](const size_t& v) { - if (v == mGpuGraph.finalNodeId() || (v == mGpuGraph.rootNodeId())) { - return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; - } - const auto& metaNode = clone.getVertexProperty(v); - if (metaNode.isHu()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - if (metaNode.isSync()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - - if (metaNode.isMap()) { - return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; - } - if (metaNode.isReduce()) { - return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; - } - if (metaNode.isStencil()) { - return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; - } - return ""; - }; - - //////////////////////////////////////////////////////////////////////////// - clone.exportDotFile(fname, graphName, vertexLabel, edgeLabel, - vertexLabelProperty, edgeLabelProperty); -} - -#endif - -auto StreamScheduler::io2DotOrder(const std::string& fname, const std::string& graphName) -> void -{ - MultiGpuGraph::DiGraphScheduling orderGraph; - for (int i = 0; i < int(m_storage->m_executionOrder.size()); i++) { - orderGraph.addVertex(m_storage->m_executionOrder[i]); - if (i > 0) { - orderGraph.addEdge(m_storage->m_executionOrder[i - 1], m_storage->m_executionOrder[i]); - } - } - - - auto& mGpuGraph = m_storage->m_graph; - - auto vertexLabel = [&](NodeId nodeId) -> std::string { - auto& metaNodeExtended = h_getMetaNodeExtended(nodeId); - - auto h_intro = [&]() -> std::string { - return std::string("Scheduling info: \\l- Taks idx ") + - std::to_string(metaNodeExtended.schedulingInfo.schedulingOrder) + "\\l"; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_eventWaitString = [&]() -> std::string { - std::string ret; - if (metaNodeExtended.schedulingInfo.waitEventIdxList.size() == 0) { - ret += "- Waiting events: []\\l"; - } else { - ret += "- Waiting events: ["; - for (auto& e : metaNodeExtended.schedulingInfo.waitEventIdxList) { - ret += " " + std::to_string(e); - } - ret += "]\\l"; - } - return ret; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_streamString = [&]() -> std::string { - return "- Stream idx: " + std::to_string(metaNodeExtended.schedulingInfo.streamIdx) + "\\l"; - }; - - [[maybe_unused]] auto h_barrierString = [&]() -> std::string { - if (metaNodeExtended.schedulingInfo.barrierLR != -1) { - return "- LR Event " + std::to_string(metaNodeExtended.schedulingInfo.barrierLR) + "\\l"; - ; - } - return ""; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_eventRegisterString = [&]() -> std::string { - if (metaNodeExtended.schedulingInfo.setEventIdx != -1) { - return "- Completion Event idx: " + std::to_string(metaNodeExtended.schedulingInfo.setEventIdx) + - "\\l"; - } else { - return "- Completion Event idx: None"; - } - }; - - if (nodeId == mGpuGraph.finalNodeId()) { - return std::string("Task List \n END"); - } - if (nodeId == mGpuGraph.rootNodeId()) { - return std::string("Task List \n BEGIN"); - } - return mGpuGraph.getDiGraph().getVertexProperty(nodeId).toString() + h_intro() + h_streamString() + - h_eventWaitString() + h_eventRegisterString() + "\\l"; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto edgeLabel = [&](const std::pair&) - -> std::string { - return ""; - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto edgeLabelProperty = [&]([[maybe_unused]] const std::pair& edge) - -> std::string { - return "color=\"#d9d9d9\", penwidth=7"; - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto vertexLabelProperty = [&](const size_t& v) { - if (v == mGpuGraph.finalNodeId() || (v == mGpuGraph.rootNodeId())) { - return R"(shape=box, style="rounded,filled", fillcolor="#d9d9d9", color="#6c6c6c")"; - } - const auto& metaNode = mGpuGraph.getDiGraph().getVertexProperty(v); - if (metaNode.isHu()) { - return R"(shape=box, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - if (metaNode.isSync()) { - return R"(shape=box, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - - if (metaNode.isMap()) { - return R"(shape=box, style="rounded,filled", fillcolor="#b3de69", color="#5f861d")"; - } - if (metaNode.isReduce()) { - return R"(shape=box, style="rounded,filled", fillcolor="#80b1d3", color="#2b5c7d")"; - } - if (metaNode.isStencil()) { - return R"(shape=box, style="rounded,filled", fillcolor="#bebada", color="#4e4683")"; - } - return ""; - }; - - //////////////////////////////////////////////////////////////////////////// - orderGraph.exportDotFile(fname, graphName, vertexLabel, edgeLabel, - vertexLabelProperty, edgeLabelProperty); -} - - -} // namespace Neon::skeleton::internal From 8059cf3cef27d0a09af0b51973034e17a4f73844 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Sat, 17 Sep 2022 19:20:47 -0400 Subject: [PATCH 32/67] WIP --- libNeonSet/include/Neon/set/Containter.h | 2 +- libNeonSet/include/Neon/set/Containter_imp.h | 2 +- .../Neon/set/container/AnchorContainer.h | 4 +- .../include/Neon/set/container/ContainerAPI.h | 14 +- .../set/container/ContainerExecutionType.h | 2 +- .../set/container/ContainerOperationType.h | 2 +- .../Neon/set/container/ContainerPatternType.h | 2 +- .../Neon/set/container/DeviceContainer.h | 2 +- .../set/container/DeviceManagedContainer.h | 2 +- .../DeviceThenHostManagedContainer.h | 4 +- libNeonSet/include/Neon/set/container/Graph.h | 58 +- .../Neon/set/container/GraphContainer.h | 2 +- .../Neon/set/container/HostManagedContainer.h | 2 +- .../include/Neon/set/container/Loader.h | 32 +- .../set/container/OldDeviceManagedContainer.h | 2 +- .../Neon/set/container/graph/Bfs_imp.h | 4 +- .../Neon/set/container/graph/GraphData.h | 5 +- .../set/container/graph/GraphDependency.h | 18 +- .../Neon/set/container/graph/GraphNode.h | 10 +- .../include/Neon/set/dependency/AccessType.h | 25 + .../include/Neon/set/dependency/ComputeType.h | 28 + .../Neon/set/dependency/DataDependencyType.h | 1 + .../include/Neon/set/dependency/Token.h | 8 +- .../src/set/container/AnchorContainer.cpp | 2 +- libNeonSet/src/set/container/ContainerAPI.cpp | 8 +- libNeonSet/src/set/container/Graph.cpp | 43 +- .../src/set/container/GraphContainer.cpp | 2 +- .../set/container/graph/GraphDependency.cpp | 23 +- .../src/set/depencencyTools/AccessType.cpp | 34 + .../src/set/depencencyTools/ComputeType.cpp | 21 + .../depencencyTools/DataDependencyType.cpp | 32 + libNeonSet/src/set/depencencyTools/Token.cpp | 89 +- .../include/Neon/skeleton/Skeleton.h | 21 +- .../Neon/skeleton/internal/MultiGpuGraph.h | 227 +-- .../internal/dependencyTools/DataDependency.h | 8 +- .../dependencyTools/DependencyAnalyser.h | 23 +- .../dependencyTools/UserDataManager.h | 28 +- .../skeleton/depencencyTools/Dependency.cpp | 49 +- .../depencencyTools/DependencyAnalyser.cpp | 168 +- .../depencencyTools/UserDataManager.cpp | 24 +- .../src/skeleton/internal/multiGpuGraph.cpp | 1644 ++++++----------- libNeonSys/src/sys/memory/CpuMem.cpp | 4 +- libNeonSys/src/sys/memory/GpuMem.cpp | 4 +- 43 files changed, 1150 insertions(+), 1535 deletions(-) create mode 100644 libNeonSet/include/Neon/set/dependency/AccessType.h create mode 100644 libNeonSet/include/Neon/set/dependency/ComputeType.h create mode 100644 libNeonSet/src/set/depencencyTools/AccessType.cpp create mode 100644 libNeonSet/src/set/depencencyTools/ComputeType.cpp create mode 100644 libNeonSet/src/set/depencencyTools/DataDependencyType.cpp diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index b9114e14..8da4b361 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" +#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h index 3c401836..3398818c 100644 --- a/libNeonSet/include/Neon/set/Containter_imp.h +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" +#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/container/AnchorContainer.h b/libNeonSet/include/Neon/set/container/AnchorContainer.h index 945885b3..75cc7f6b 100644 --- a/libNeonSet/include/Neon/set/container/AnchorContainer.h +++ b/libNeonSet/include/Neon/set/container/AnchorContainer.h @@ -23,7 +23,7 @@ struct AnchorContainer : ContainerAPI public: AnchorContainer(const std::string& name); - auto parse() -> const std::vector& override; + auto parse() -> const std::vector& override; auto getHostContainer() -> std::shared_ptr final; @@ -44,7 +44,7 @@ struct AnchorContainer : ContainerAPI virtual auto run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void override; private: - std::vector mEmtpy; + std::vector mEmtpy; }; diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index 28805856..f0c06b77 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -5,7 +5,7 @@ #include "Neon/set/DevSet.h" #include "Neon/set/container/ContainerExecutionType.h" -#include "Neon/set/dependencyTools/DataParsing.h" +#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" @@ -75,7 +75,7 @@ struct ContainerAPI * @return */ virtual auto parse() - -> const std::vector& = 0; + -> const std::vector& = 0; /** @@ -88,13 +88,13 @@ struct ContainerAPI * Returns a list of tokens as result of parsing the Container loading lambda. */ auto getTokens() const - -> const std::vector&; + -> const std::vector&; /** * Returns a list of tokens as result of parsing the Container loading lambda. */ auto getTokenRef() - -> std::vector&; + -> std::vector&; /** * Get the execution type for the Container. @@ -129,7 +129,7 @@ struct ContainerAPI /** * Add a new token */ - auto addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) + auto addToken(Neon::internal::dataDependency::Token& dataParsing) -> void; /** @@ -179,7 +179,7 @@ struct ContainerAPI * Set the patter for this Container based on a list of tokens. * @param tokens */ - auto setContainerPattern(const std::vector& tokens) + auto setContainerPattern(const std::vector& tokens) -> void; /** @@ -196,7 +196,7 @@ struct ContainerAPI -> void; private: - using TokenList = std::vector; + using TokenList = std::vector; std::string mName{"Anonymous"}; /**< Name of the Container */ bool mParsingDataUpdated = false; diff --git a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h index 2673c4e2..7cd591f4 100644 --- a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h +++ b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" +#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/container/ContainerOperationType.h b/libNeonSet/include/Neon/set/container/ContainerOperationType.h index edf9b061..a7725d21 100644 --- a/libNeonSet/include/Neon/set/container/ContainerOperationType.h +++ b/libNeonSet/include/Neon/set/container/ContainerOperationType.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" +#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/container/ContainerPatternType.h b/libNeonSet/include/Neon/set/container/ContainerPatternType.h index 93b16a21..3b7a1975 100644 --- a/libNeonSet/include/Neon/set/container/ContainerPatternType.h +++ b/libNeonSet/include/Neon/set/container/ContainerPatternType.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" +#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/container/DeviceContainer.h b/libNeonSet/include/Neon/set/container/DeviceContainer.h index 28b90294..ef4c25d6 100644 --- a/libNeonSet/include/Neon/set/container/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceContainer.h @@ -78,7 +78,7 @@ struct DeviceContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { if (!this->isParsingDataUpdated()) { auto parser = newParser(); diff --git a/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h index f8e9cdec..20e8701a 100644 --- a/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h @@ -62,7 +62,7 @@ struct DeviceManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { Neon::SetIdx setIdx(0); if (!this->mParsingDataUpdated) { diff --git a/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h index 42b9aa6a..2dc9b14b 100644 --- a/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h @@ -64,7 +64,7 @@ struct DeviceThenHostManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { mHost->parse(); mDevice->parse(); @@ -75,7 +75,7 @@ struct DeviceThenHostManagedContainer : ContainerAPI for (auto const& token : devTokens) { getTokenRef().push_back(token); } - std::vector filtered; + std::vector filtered; for (auto const& token : hostTokens) { bool foundMatch = false; for (auto& acceptedTokens : getTokenRef()) { diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 5403fd02..17f4f374 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -45,6 +45,16 @@ struct Graph auto addNode(const Container& container) -> GraphNode&; + /** + * Adds a dependency between two nodes of the graph + */ + auto addNodeInBetween(const GraphNode& nodeA, + Container containerB, + const GraphNode& nodeC, + GraphDependencyType ab = GraphDependencyType::user, + GraphDependencyType bc = GraphDependencyType::user) + -> GraphNode&; + /** * Remove node by maintaining the dependencies between * proceeding and following nodes @@ -58,16 +68,6 @@ struct Graph auto removeNodeAndItsDependencies(GraphNode& gn) -> Neon::set::Container; - /** - * Adds a dependency between two nodes of the graph - */ - auto addNodeInBetween(const GraphNode& nodeA, - Container containerB, - const GraphNode& nodeC, - GraphDependencyType ab = GraphDependencyType::user, - GraphDependencyType bc = GraphDependencyType::user) - -> GraphNode&; - /** * Adds a dependency between two node of the graph */ @@ -76,6 +76,10 @@ struct Graph GraphDependencyType type) -> GraphDependency&; + auto appendDataDependency(const GraphNode& nodeA, + const GraphNode& nodeB, + Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::DataUId dataUId) -> GraphDependency&; /** * Returns the dependency type between two nodes. */ @@ -146,7 +150,24 @@ struct Graph -> void; auto getNumberOfNodes() - ->int; + -> int; + + /** + * it removes redundant dependencies + */ + auto removeRedundantDependencies() -> void; + + /** + * Extract a graph node from its id + */ + auto getGraphNode(GraphData::Uid) + -> GraphNode&; + + /** + * Extract a graph node from its id + */ + auto getGraphNode(GraphData::Uid) const + -> const GraphNode&; protected: /** @@ -159,10 +180,6 @@ struct Graph */ auto helpCheckBackendStatus() -> void; - /** - * Helper - it removes redundant dependencies - */ - auto helpRemoveRedundantDependencies() -> void; /** * Compute BFS @@ -213,17 +230,6 @@ struct Graph GraphDependencyType::data}) -> Bfs; - /** - * Extract a graph node from its id - */ - auto helpGetGraphNode(GraphData::Uid) - -> GraphNode&; - - /** - * Extract a graph node from its id - */ - auto helpGetGraphNode(GraphData::Uid) const - -> const GraphNode&; /** * diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index 3630ce1a..fece4836 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -28,7 +28,7 @@ struct GraphContainer : ContainerAPI auto newParser() -> Loader; - auto parse() -> const std::vector& override; + auto parse() -> const std::vector& override; auto getGraph() -> const Neon::set::container::Graph& override; diff --git a/libNeonSet/include/Neon/set/container/HostManagedContainer.h b/libNeonSet/include/Neon/set/container/HostManagedContainer.h index 20c1b306..a0ad2a6d 100644 --- a/libNeonSet/include/Neon/set/container/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/HostManagedContainer.h @@ -71,7 +71,7 @@ struct HostManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { auto parser = newParser(); Neon::SetIdx setIdx(0); diff --git a/libNeonSet/include/Neon/set/container/Loader.h b/libNeonSet/include/Neon/set/container/Loader.h index ff18e703..82313ea3 100644 --- a/libNeonSet/include/Neon/set/container/Loader.h +++ b/libNeonSet/include/Neon/set/container/Loader.h @@ -1,8 +1,8 @@ #pragma once -//#include +// #include #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" #include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/dependency/Token.h" #include "type_traits" namespace Neon::set { @@ -151,10 +151,10 @@ struct Loader public: Loader(Neon::set::internal::ContainerAPI& container, - Neon::DeviceType devE, - Neon::SetIdx setIdx, - Neon::DataView dataView, - Neon::set::internal::LoadingMode_e::e loadingMode) + Neon::DeviceType devE, + Neon::SetIdx setIdx, + Neon::DataView dataView, + Neon::set::internal::LoadingMode_e::e loadingMode) : m_container(container), m_devE(devE), m_setIdx(setIdx), @@ -183,11 +183,10 @@ struct Loader switch (m_loadingMode) { case Neon::set::internal::LoadingMode_e::PARSE_AND_EXTRACT_LAMBDA: { - using namespace Neon::set::internal::dependencyTools; - DataUId_t uid = field.getUid(); - constexpr Access_et::e access = Access_et::WRITE; - Compute compute = computeE; - DataToken dataToken(uid, access, compute); + Neon::internal::dataDependency::DataUId uid = field.getUid(); + constexpr Neon::internal::dataDependency::AccessType access = Neon::internal::dataDependency::AccessType::WRITE; + Compute compute = computeE; + Neon::internal::dataDependency::Token dataToken(uid, access, compute); if (compute == Neon::Compute::STENCIL && (stencilOptions == StencilOptions::DEFAULT || stencilOptions == StencilOptions::LATTICE)) { @@ -222,11 +221,10 @@ struct Loader { switch (m_loadingMode) { case Neon::set::internal::LoadingMode_e::PARSE_AND_EXTRACT_LAMBDA: { - using namespace Neon::set::internal::dependencyTools; - DataUId_t uid = field.getUid(); - constexpr Access_et::e access = Access_et::READ; - Neon::Compute compute = computeE; - DataToken dataToken(uid, access, compute); + Neon::internal::dataDependency::DataUId uid = field.getUid(); + constexpr Neon::internal::dataDependency::AccessType access = Neon::internal::dataDependency::AccessType::READ; + Neon::Compute compute = computeE; + Neon::internal::dataDependency::Token dataToken(uid, access, compute); if (compute == Neon::Compute::STENCIL) { dataToken.setHaloUpdate( @@ -257,4 +255,4 @@ struct Loader } }; -} // namespace Neon \ No newline at end of file +} // namespace Neon::set \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h b/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h index ba653e0d..d41c4501 100644 --- a/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h @@ -59,7 +59,7 @@ struct OldDeviceManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { auto parser = newParser(); this->mLoadingLambda(parser); diff --git a/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h b/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h index d2025272..61e52169 100644 --- a/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h +++ b/libNeonSet/include/Neon/set/container/graph/Bfs_imp.h @@ -18,7 +18,7 @@ template auto Bfs::forEachNodeAtLevel(int levelIdx, Neon::set::container::Graph& graph, Fun fun) -> void { for (auto& nodeIdx : data.at(levelIdx)) { - auto& node = graph.helpGetGraphNode(nodeIdx); + auto& node = graph.getGraphNode(nodeIdx); fun(node); } } @@ -29,7 +29,7 @@ auto Bfs::forEachNodeByLevel(Graph& graph, Fun fun) -> void { forEachLevel([&graph, &fun](const Level& level, int levelIdx) { for (const auto& nodeIdx : level) { - auto& node = graph.helpGetGraphNode(nodeIdx); + auto& node = graph.getGraphNode(nodeIdx); fun(node, levelIdx); } }); diff --git a/libNeonSet/include/Neon/set/container/graph/GraphData.h b/libNeonSet/include/Neon/set/container/graph/GraphData.h index 65d7ac0b..972fec29 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphData.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphData.h @@ -26,7 +26,10 @@ class GraphData auto getIndex() const -> Index; private: - Uid mUid /** unique identifier for the node */; + Uid mUid /**< unique identifier for the node. + * This is different from a Container uid as in a graph the same container can appear more than once. + * */ + ; Index mIndex /** relative index w.r.t the completed graph. This value may change during the life of the graph */; }; diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index 58945e1b..a949eca0 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -1,6 +1,8 @@ #pragma once #include "GraphDependencyType.h" +#include "Neon/set/dependency/Alias.h" +#include "Neon/set/dependency/DataDependencyType.h" namespace Neon::set::container { @@ -13,10 +15,24 @@ struct GraphDependency GraphDependency(GraphDependencyType type); auto setType(GraphDependencyType type) -> void; - auto getType() const-> GraphDependencyType; + + auto getType() const -> GraphDependencyType; + + auto appendInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::DataUId dataUId) -> void; + + auto toString(std::function(int)> prefix) -> std::string; private: GraphDependencyType mType; + + struct Info + { + Neon::internal::dataDependency::DataDependencyType dataDependencyType; + Neon::internal::dataDependency::DataUId dataUId; + }; + + std::vector mInfo; // TODO - add information for data and Scheduling dependency }; diff --git a/libNeonSet/include/Neon/set/container/graph/GraphNode.h b/libNeonSet/include/Neon/set/container/graph/GraphNode.h index a0ad22d8..6e7d9629 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphNode.h @@ -8,9 +8,9 @@ namespace Neon::set::container { struct GraphNode { - std::string getLabel(bool debug); + auto getLabel(bool debug) -> std::string; - std::string getLabelProperty(); + auto getLabelProperty() -> std::string; public: GraphNode(); @@ -76,9 +76,9 @@ struct GraphNode auto helpGetDotName() -> std::string; auto helpGetDotInfo() -> std::string; - Container mContainer /**< Any Neon container */; - GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; - GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; + Container mContainer /**< Any Neon container */; + GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; + GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; ContainerPatternType getContainerpatternType() const; }; diff --git a/libNeonSet/include/Neon/set/dependency/AccessType.h b/libNeonSet/include/Neon/set/dependency/AccessType.h new file mode 100644 index 00000000..bd489f2d --- /dev/null +++ b/libNeonSet/include/Neon/set/dependency/AccessType.h @@ -0,0 +1,25 @@ +#pragma once +#include "Neon/set/Backend.h" + +namespace Neon::internal::dataDependency { + + +/** + * Define type of operation for a kernel parameter: Read or write. + * Write includes also complex operation where the parameter is both read and written. + */ +enum struct AccessType +{ + READ /**< The field or kernel parameter is in read only mode */, + WRITE /**< The field or kernel parameter is in write mode (this include read and write) */, + NONE /**< Not defined */ + +}; + +struct AccessTypeUtils +{ + static auto toString(AccessType val) -> std::string; + static auto merge(AccessType valA, AccessType valB) -> AccessType; +}; + +} // namespace Neon::dependency \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/dependency/ComputeType.h b/libNeonSet/include/Neon/set/dependency/ComputeType.h new file mode 100644 index 00000000..fe9b30bb --- /dev/null +++ b/libNeonSet/include/Neon/set/dependency/ComputeType.h @@ -0,0 +1,28 @@ +#pragma once +#include "Neon/set/Backend.h" + +namespace Neon { + + +/** + * Enumeration for the supported type of computation by the skeleton + * */ +enum struct Compute +{ + MAP /**< Map operation */, + STENCIL /**< Stencil operation */, + REDUCE /**< Reduction operation */ +}; + +struct ComputeUtils +{ + /** + * Returns a string for the selected allocator + * + * @param allocator + * @return + */ + static auto toString(Compute val) -> std::string; +}; + +} // namespace Neon \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/dependency/DataDependencyType.h b/libNeonSet/include/Neon/set/dependency/DataDependencyType.h index d043fce3..386f7d15 100644 --- a/libNeonSet/include/Neon/set/dependency/DataDependencyType.h +++ b/libNeonSet/include/Neon/set/dependency/DataDependencyType.h @@ -26,4 +26,5 @@ struct DataDependencyTypeUtils static auto toString(DataDependencyType type) -> std::string; }; +std::ostream& operator<<(std::ostream& os, Neon::internal::dataDependency::DataDependencyType const& m); } diff --git a/libNeonSet/include/Neon/set/dependency/Token.h b/libNeonSet/include/Neon/set/dependency/Token.h index fd460ed8..cddd4723 100644 --- a/libNeonSet/include/Neon/set/dependency/Token.h +++ b/libNeonSet/include/Neon/set/dependency/Token.h @@ -1,9 +1,9 @@ #pragma once #include "Neon/set/Backend.h" #include "Neon/set/HuOptions.h" -#include "Neon/set/dependencyTools/AccessType.h" -#include "Neon/set/dependencyTools/Alias.h" -#include "Neon/set/dependencyTools/ComputeType.h" +#include "Neon/set/dependency/AccessType.h" +#include "Neon/set/dependency/Alias.h" +#include "Neon/set/dependency/ComputeType.h" namespace Neon::internal::dataDependency { @@ -73,4 +73,4 @@ struct Token std::function mHuPerDevice; }; -} // namespace dependencyTools +} // namespace dependency diff --git a/libNeonSet/src/set/container/AnchorContainer.cpp b/libNeonSet/src/set/container/AnchorContainer.cpp index b100e679..bb81affe 100644 --- a/libNeonSet/src/set/container/AnchorContainer.cpp +++ b/libNeonSet/src/set/container/AnchorContainer.cpp @@ -13,7 +13,7 @@ AnchorContainer::AnchorContainer(const std::string& name) } -auto AnchorContainer::parse() -> const std::vector& +auto AnchorContainer::parse() -> const std::vector& { return mEmtpy; } diff --git a/libNeonSet/src/set/container/ContainerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp index c7e07f8d..07af566c 100644 --- a/libNeonSet/src/set/container/ContainerAPI.cpp +++ b/libNeonSet/src/set/container/ContainerAPI.cpp @@ -3,7 +3,7 @@ namespace Neon::set::internal { -auto ContainerAPI::addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) +auto ContainerAPI::addToken(Neon::internal::dataDependency::Token& dataParsing) -> void { mParsed.push_back(dataParsing); @@ -16,13 +16,13 @@ auto ContainerAPI::getName() const } auto ContainerAPI::getTokens() const - -> const std::vector& + -> const std::vector& { return mParsed; } auto ContainerAPI::getTokenRef() - -> std::vector& + -> std::vector& { return mParsed; } @@ -62,7 +62,7 @@ auto ContainerAPI::setContainerPattern(Neon::set::ContainerPatternType patternTy this->mContainerPatternType = patternType; } -auto ContainerAPI::setContainerPattern(const std::vector& tokens) +auto ContainerAPI::setContainerPattern(const std::vector& tokens) -> void { Neon::set::ContainerPatternType patternType = Neon::set::ContainerPatternType::map; diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 74a92820..d1144e9f 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -76,6 +76,39 @@ auto Graph::addDependency(const GraphNode& nodeA, nodeB.getGraphData().getUid()}); } +auto Graph::appendDataDependency(const GraphNode& nodeA, + const GraphNode& nodeB, + Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::DataUId dataUId) -> GraphDependency& +{ + helpCheckBackendStatus(); + + if (nodeA.getGraphData().getUid() == nodeB.getGraphData().getUid()) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + helpInvalidateScheduling(); + + + bool hasEdge = mRawGraph.hasEdge(nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid()); + + if (!hasEdge) { + GraphDependencyType type = GraphDependencyType::data; + + GraphDependency ab(type); + mRawGraph.addEdge(nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid(), + ab); + } + + auto& output = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid()}); + + output.appendInfo(dataDependencyType, dataUId); + + return output; +} + auto Graph::removeNode(GraphNode& gn) -> Container { helpInvalidateScheduling(); @@ -262,7 +295,7 @@ auto Graph::helpInvalidateScheduling() mSchedulingStatusIsValid = false; } -auto Graph::helpRemoveRedundantDependencies() +auto Graph::removeRedundantDependencies() -> void { // Vectors of edges to be removed @@ -497,12 +530,12 @@ auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) GraphDependencyType::user}); } -auto Graph::helpGetGraphNode(GraphData::Uid uid) -> GraphNode& +auto Graph::getGraphNode(GraphData::Uid uid) -> GraphNode& { return mRawGraph.getVertexProperty(uid); } -auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& +auto Graph::getGraphNode(GraphData::Uid uid) const -> const GraphNode& { return mRawGraph.getVertexProperty(uid); } @@ -673,7 +706,7 @@ auto Graph::ioToDot(const std::string& fname, const std::string& graphName, bool debug) -> void { - this->helpRemoveRedundantDependencies(); + this->removeRedundantDependencies(); auto vertexLabel = [&](size_t v) -> std::string { auto& node = mRawGraph.getVertexProperty(v); @@ -835,7 +868,7 @@ auto Graph::expandSubGraphs() -> void if (!validTarget) { if (atLeastOneWasFound) { helpInvalidateScheduling(); - this->helpRemoveRedundantDependencies(); + this->removeRedundantDependencies(); // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); } return; diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index e266ccb3..6325ae6a 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -27,7 +27,7 @@ auto GraphContainer::newParser() -> Loader return parser; } -auto GraphContainer::parse() -> const std::vector& +auto GraphContainer::parse() -> const std::vector& { Neon::SetIdx setIdx(0); if (!this->isParsingDataUpdated()) { diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 5bfcc022..8f171b1f 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -22,7 +22,28 @@ GraphDependency::GraphDependency(GraphDependencyType type) auto GraphDependency::getLabel() -> std::string { - return GraphDependencyTypeUtil::toString(getType()); + std::stringstream s; + s << GraphDependencyTypeUtil::toString(getType()); + s << toString([](int ) -> std::pair { + return {"\\l", ""}; + }); + return s.str(); +} + +auto GraphDependency::appendInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::DataUId dataUId) -> void +{ + mInfo.push_back({dataDependencyType, dataUId}); +} + +auto GraphDependency::toString(std::function(int)> prefixPostfix) -> std::string +{ + std::stringstream s; + for (int i = 0; i < int(mInfo.size()); ++i) { + const auto& [pre, post] = prefixPostfix(i); + s << pre << mInfo[i].dataDependencyType << " (Data Id " << mInfo[i].dataUId << ")" << post; + } + return s.str(); } } // namespace Neon::set::container diff --git a/libNeonSet/src/set/depencencyTools/AccessType.cpp b/libNeonSet/src/set/depencencyTools/AccessType.cpp new file mode 100644 index 00000000..9cbdd823 --- /dev/null +++ b/libNeonSet/src/set/depencencyTools/AccessType.cpp @@ -0,0 +1,34 @@ +#include "Neon/set/dependency/AccessType.h" + +namespace Neon::internal::dataDependency { + +auto AccessTypeUtils::toString(AccessType val) -> std::string +{ + switch (val) { + case AccessType::READ: { + return "READ"; + } + case AccessType::WRITE: { + return "WRITE"; + } + case AccessType::NONE: { + return "NONE"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(); +} + +auto AccessTypeUtils::merge(AccessType valA, AccessType valB) -> AccessType +{ + if (valA == AccessType::WRITE) + return AccessType::WRITE; + if (valB == AccessType::WRITE) + return AccessType::WRITE; + if (valA == AccessType::READ) + return AccessType::READ; + if (valB == AccessType::READ) + return AccessType::READ; + return AccessType::NONE; +} + +} // namespace Neon::set::internal \ No newline at end of file diff --git a/libNeonSet/src/set/depencencyTools/ComputeType.cpp b/libNeonSet/src/set/depencencyTools/ComputeType.cpp new file mode 100644 index 00000000..c32a7041 --- /dev/null +++ b/libNeonSet/src/set/depencencyTools/ComputeType.cpp @@ -0,0 +1,21 @@ +#include "Neon/set/dependency/ComputeType.h" + +namespace Neon { + +auto ComputeUtils::toString(Compute val) -> std::string +{ + switch (val) { + case Compute::MAP: { + return "MAP"; + } + case Compute::STENCIL: { + return "STENCIL"; + } + case Compute::REDUCE: { + return "REDUCE"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(); +} + +} // namespace Neon \ No newline at end of file diff --git a/libNeonSet/src/set/depencencyTools/DataDependencyType.cpp b/libNeonSet/src/set/depencencyTools/DataDependencyType.cpp new file mode 100644 index 00000000..fefd3644 --- /dev/null +++ b/libNeonSet/src/set/depencencyTools/DataDependencyType.cpp @@ -0,0 +1,32 @@ +#include "Neon/set/dependency/DataDependencyType.h" + +namespace Neon::internal::dataDependency { + +auto DataDependencyTypeUtils::toString(DataDependencyType val) -> std::string +{ + switch (val) { + case DataDependencyType::RAW: { + return "RAW"; + } + case DataDependencyType::WAR: { + return "WAR"; + } + case DataDependencyType::RAR: { + return "RAR"; + } + case DataDependencyType::WAW: { + return "WAW"; + } + case DataDependencyType::NONE: { + return "NONE"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(); +} + +std::ostream& operator<<(std::ostream& os, Neon::internal::dataDependency::DataDependencyType const& m){ + os << DataDependencyTypeUtils::toString(m); + return os; +} + +} \ No newline at end of file diff --git a/libNeonSet/src/set/depencencyTools/Token.cpp b/libNeonSet/src/set/depencencyTools/Token.cpp index e7604b95..b330f249 100644 --- a/libNeonSet/src/set/depencencyTools/Token.cpp +++ b/libNeonSet/src/set/depencencyTools/Token.cpp @@ -1,92 +1,77 @@ -#include "Neon/set//dependencyTools/DataParsing.h" +#include "Neon/set//dependency/Token.h" -namespace Neon { -namespace set { -namespace internal { -namespace dependencyTools { +namespace Neon::internal::dataDependency { - -DataToken::DataToken(DataUId_t uid, - Access_e access, - Compute compute) +Token::Token(DataUId uid, + AccessType access, + Compute compute) { update(uid, access, compute); - setHaloUpdate( - [&](Neon::set::HuOptions&) -> void { - NeonException exp("DataToken"); - exp << "This is not a stencil token and this is not a valid operation"; - NEON_THROW(exp); - }, - [&](Neon::SetIdx, Neon::set::HuOptions&) -> void { - NeonException exp("DataToken"); - exp << "This is not a stencil token and this is not a valid operation"; - NEON_THROW(exp); - }); } -auto DataToken::update(DataUId_t uid, - Access_e access, - Compute compute) -> void +auto Token::update(DataUId uid, + AccessType access, + Compute compute) -> void { - m_uid = uid; - m_access = access; - m_compute = compute; + mUid = uid; + mAccess = access; + mCompute = compute; setHaloUpdate( [&](Neon::set::HuOptions&) -> void { - NeonException exp("DataToken"); + NeonException exp("Token"); exp << "This is not a stencil token and this is not a valid operation"; NEON_THROW(exp); }, [&](Neon::SetIdx, Neon::set::HuOptions&) -> void { - NeonException exp("DataToken"); + NeonException exp("Token"); exp << "This is not a stencil token and this is not a valid operation"; NEON_THROW(exp); }); } -auto DataToken::access() const -> Access_e +auto Token::access() const -> AccessType { - return m_access; + return mAccess; } -auto DataToken::compute() const -> Compute +auto Token::compute() const -> Compute { - return m_compute; + return mCompute; } -auto DataToken::uid() const -> DataUId_t + +auto Token::uid() const -> DataUId { - return m_uid; + return mUid; } -auto DataToken::toString() const -> std::string + +auto Token::toString() const -> std::string { - return " uid " + std::to_string(m_uid) + - " [Op " + AccessType::toString(m_access) + - " Model " + Neon::ComputeUtils::toString(m_compute) + "]"; + return " uid " + std::to_string(mUid) + + " [Op " + AccessTypeUtils::toString(mAccess) + + " Model " + Neon::ComputeUtils::toString(mCompute) + "]"; } -auto DataToken::setHaloUpdate(std::function hu, - std::function huPerDevice) -> void +auto Token::setHaloUpdate(std::function hu, + std::function huPerDevice) -> void { - m_hu = hu; - m_huPerDevice = huPerDevice; + mHu = hu; + mHuPerDevice = huPerDevice; } -auto DataToken::getHaloUpdate() const +auto Token::getHaloUpdate() const -> const std::function& { - return m_hu; + return mHu; } -auto DataToken::getHaloUpdatePerDevice() const +auto Token::getHaloUpdatePerDevice() const -> const std::function& { - return m_huPerDevice; + return mHuPerDevice; } -auto DataToken::mergeAccess(AccessType::e tomerge) -> void +auto Token::mergeAccess(AccessType tomerge) -> void { - m_access = AccessType::merge(m_access, tomerge); + mAccess = AccessTypeUtils::merge(mAccess, tomerge); } -} // namespace dependencyTools -} // namespace internal -} // namespace set -} // namespace Neon \ No newline at end of file + +} \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/Skeleton.h b/libNeonSkeleton/include/Neon/skeleton/Skeleton.h index ef24afdc..b3ff0004 100644 --- a/libNeonSkeleton/include/Neon/skeleton/Skeleton.h +++ b/libNeonSkeleton/include/Neon/skeleton/Skeleton.h @@ -3,7 +3,7 @@ #include "Neon/set/Containter.h" #include "Neon/skeleton/Options.h" #include "Neon/skeleton/internal/MultiGpuGraph.h" -#include "Neon/skeleton/internal/StreamScheduler.h" +// #include "Neon/skeleton/internal/StreamScheduler.h" namespace Neon::skeleton { @@ -38,8 +38,8 @@ struct Skeleton } mOptions = options; mMultiGraph.init(mBackend, operations, name, options); - // m_multiGraph.io2Dot("DB_multiGpuGraph", "graphname"); - mStreamScheduler.init(mBackend, mMultiGraph); + mMultiGraph.io2Dot("DB_multiGpuGraph", "graphname"); + // mStreamScheduler.init(mBackend, mMultiGraph); // m_streamScheduler.io2Dot("DB_streamScheduler", "graphname"); } @@ -48,20 +48,21 @@ struct Skeleton { // m_multiGraph.io2Dot(fname + ".multiGpu.dot", graphname); mMultiGraph.io2DotOriginalApp(fname + ".appGraph.dot", graphname); - mStreamScheduler.io2Dot(fname + ".scheduler.dot", graphname); - mStreamScheduler.io2DotOrder(fname + ".order.dot", graphname); + // mStreamScheduler.io2Dot(fname + ".scheduler.dot", graphname); + // mStreamScheduler.io2DotOrder(fname + ".order.dot", graphname); } void run() { - mStreamScheduler.run(mOptions); + NEON_DEV_UNDER_CONSTRUCTION(""); + // mStreamScheduler.run(mOptions); } private: - Neon::Backend mBackend; - Options mOptions; - Neon::skeleton::internal::MultiGpuGraph mMultiGraph; - Neon::skeleton::internal::StreamScheduler mStreamScheduler; + Neon::Backend mBackend; + Options mOptions; + Neon::skeleton::internal::MultiGpuGraph mMultiGraph; + // Neon::skeleton::internal::StreamScheduler mStreamScheduler; bool m_inited = {false}; }; diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h b/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h index 2ba9ca98..f6b642d7 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h @@ -3,22 +3,16 @@ #include "Neon/core/types/digraph.h" #include "Neon/set//Containter.h" #include "Neon/set/Backend.h" -#include "Neon/skeleton/internal/dependencyTools/UserDataManager.h" -#include "Neon/skeleton/internal/multiGpuGraph/Edge.h" -#include "Neon/skeleton/internal/multiGpuGraph/MetaNode.h" +#include "Neon/set/container/Graph.h" #include "Neon/skeleton/Options.h" +#include "Neon/skeleton/internal/dependencyTools/UserDataManager.h" + namespace Neon::skeleton::internal { /** - * Graph storing dependency between user kernels + * Graph storing dependency between user kernels */ struct MultiGpuGraph { - public: - using DiGraph = Neon::DiGraph; - - using DiGraphScheduling = Neon::DiGraph; public: /** @@ -26,90 +20,58 @@ struct MultiGpuGraph */ MultiGpuGraph(); - void init(Neon::Backend& bk, + void init(Neon::Backend& bk, const std::vector& operations, std::string name, Options options); - /** - * Function to retrieve the container index in the user container list - * @param id - * @return - */ - auto getContainer(ContainerIdx id) -> Neon::set::Container&; - auto getContainer(ContainerIdx id) const -> const Neon::set::Container&; - - /** - * Return a reference to the data dependency graph - * @return - */ - auto getDiGraph() -> DiGraph&; - - /** - * Return a reference to the scheduling dependency graph - * @return - */ - auto getSchedulingDiGraph() -> DiGraphScheduling&; - /** * Export the graph of the user application * @param fname * @param graphName */ - auto io2DotOriginalApp(const std::string& fname, const std::string& graphName) -> void; + auto io2DotOriginalApp(const std::string& fname, + const std::string& graphName, + bool debug = false) -> void; /** * Export both the data dependency graph and the scheduling graph * @param fname * @param graphName */ - auto io2Dot(const std::string& fname, const std::string& graphName) -> void; + auto io2Dot(const std::string& fname, + const std::string& graphName, + bool debug = false) -> void; - /** - * Return the ID for the start node - * @return - */ - auto rootNodeId() const -> const size_t&; - - /** - * Return the ID for the end node - * @return - */ - auto finalNodeId() const -> const size_t&; - - /** - * Return the counter used to map all nodes to a 1D indexing - * @return - */ - auto getLinearContinuousIndexingCounter() -> size_t; private: struct Storage { - std::vector m_kContainers; - UserDataManager m_dataRecords; - - DiGraph m_userAppGraph; - DiGraph m_graph; - DiGraphScheduling m_schedulingGraph; + std::vector m_kContainers; + UserDataManager m_dataRecords; size_t m_rootNodeId; size_t m_finalNodeId; int m_setCardinality = 0; - size_t m_resetLinearContinuousIndexingCounter = 0; + + Neon::set::container::Graph mGraph; }; + + std::shared_ptr m_storage; /** * Access methods to members * @return */ - inline auto m_kContainers() -> std::vector& + inline auto m_kContainers() + -> std::vector& { return m_storage->m_kContainers; } - inline auto m_kContainers() const -> const std::vector& + inline auto m_kContainers() const + -> const std::vector& { return m_storage->m_kContainers; } @@ -123,55 +85,10 @@ struct MultiGpuGraph return m_storage->m_dataRecords; } - /** - * Access methods to members - * @return - */ - inline auto m_graph() -> DiGraph& - { - return m_storage->m_graph; - } - - /** - * Access methods to members - * @return - */ - inline auto m_schedulingGraph() -> DiGraphScheduling& - { - return m_storage->m_schedulingGraph; - } - - /** - * Access methods to members - * @return - */ - inline auto m_rootNodeId() const -> const size_t& + inline auto mGraph() + -> Neon::set::container::Graph& { - return m_storage->m_rootNodeId; - } - - inline auto m_setRootNodeId(const size_t& rootNodeId) -> void - { - m_storage->m_rootNodeId = rootNodeId; - } - - - /** - * Access methods to members - * @return - */ - inline auto m_finalNodeId() const -> const size_t& - { - return m_storage->m_finalNodeId; - } - - /** - * set final node - * @return - */ - inline auto m_setFinalNodeId(const size_t& finalNode) -> void - { - m_storage->m_finalNodeId = finalNode; + return m_storage->mGraph; } /** @@ -195,7 +112,9 @@ struct MultiGpuGraph * @param setCardinalty * @param operations */ - void parse(int setCardinalty, const std::vector&& operations); + auto parse(int setCardinalty, + const std::vector&& operations) + -> void; /** * @@ -209,16 +128,7 @@ struct MultiGpuGraph * The dependencies are extracted from the kernel container * @param container */ - auto h_parseContainer(const Neon::set::Container& inContainer, - std::vector& containerId2gNodeId, - std::vector>& specialClosureNodes) - -> void; - - /** - * helper function to close the graph with a strart and end node - * @param specialClosureNodes - */ - auto h_closure(const std::vector>& specialClosureNodes) + auto helpParseNewContainer(const Neon::set::Container& inContainer) -> void; /** @@ -226,8 +136,8 @@ struct MultiGpuGraph * @param kernelContainerIdx * @return */ - auto h_parse(ContainerIdx kernelContainerIdx) - -> std::vector; + auto helpParseContainer(Neon::set::Container& kernelContainerIdx) + -> std::vector; /** * helper function to export a dot file @@ -239,24 +149,8 @@ struct MultiGpuGraph private: - auto h_trackNewContainer(const Neon::set::Container& container, - std::vector& containerId2gNodeId) -> ContainerIdx; - - auto h_removeRedundantDependencies() -> void; - - /** - * Creates 2 nodes for - * @param uid - * @param edge - * @param infoIdx - * @param transferModeE - * @return - */ - auto h_add_hUpdateSyncNodes(size_t t0Node, - size_t t1Node, - const internal::Edge::Info& info, - Neon::set::TransferMode transferModeE = Neon::set::TransferMode::put) - -> void; + auto helpAddNewContainerToGraph(const Neon::set::Container& container) + -> Neon::set::container::GraphData::Uid; auto optimizeStandardOCC(const Neon::skeleton::Options&) -> void; @@ -264,65 +158,8 @@ struct MultiGpuGraph auto optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> void; - /** - * Breadth First Traversal - * @param f - * @return - */ - auto - h_BFT(std::function& nodes)> f) -> void; - - auto h_getBFSIndexes() -> std::unordered_map; - - // auto fuseMaps(const Neon::skeleton::Options_t& options) -> void - // { - // // BFS visit - // std::vector frontiar; - // m_graph.forEachOutEdge(m_rootNodeId, [&](const std::pair& edge) { - // frontiar.push_back(edge.second); - // }); - // - // size_t frontiarParserIdx = 0; - // - // /** - // * Return -1 if there are no condition for a fusion - // * Otherwise, it returns the node to fuse with - // */ - // auto h_conditionForFusion = [&](const size_t n0) -> int64_t { - // if (m_graph.outEdgesCount(n0) != 1) { - // return -1; - // } - // const size_t n1 = m_graph.outEdges(n0).begin()->second; - // if (m_graph.inEdgesCount(n1) != 1) { - // return -1; - // } - // if(m_graph.getVertexProperty(n1).isStencil()){ - // return -1; - // } - // return n1; - // }; - // - // auto h_fuse= [&](const size_t n0, const size_t n1){ - // //1. create a fused kernel container - // }; - // - // while (frontiarParserIdx < frontiar.size()) { - // size_t nodeId = frontiar[frontiarParserIdx]; - // if (m_graph.outEdges(nodeId).size() == 1 &&) { - // // a. Fuse - // - // // b. update nodeId to the new node - // } - // // c. continue with BFS - // } - // } - auto addSyncAndMemoryTransfers(const Neon::skeleton::Options& options) -> void; auto checkCoherency() -> void; - - - auto resetLinearContinuousIndexing() -> void; }; } // namespace Neon::skeleton::internal diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h index 96b98bb6..5e7e413d 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h @@ -7,7 +7,7 @@ namespace Neon::skeleton::internal { -struct Dependency +struct DataDependency { private: Neon::set::container::GraphData::Uid mT0 = 0; @@ -19,7 +19,7 @@ struct Dependency /** * Empty constructor */ - Dependency() = default; + DataDependency() = default; /** * Defines a dependency of type e between kernel A and B. @@ -30,7 +30,7 @@ struct Dependency * @param A * @param B */ - Dependency(Neon::set::container::GraphData::Uid t1, + DataDependency(Neon::set::container::GraphData::Uid t1, Neon::internal::dataDependency::DataDependencyType type, Neon::internal::dataDependency::DataUId m_uid, Neon::set::container::GraphData::Uid t0); @@ -69,7 +69,7 @@ struct Dependency * Static method to build an empty dependency * @return */ - static Dependency getEmpty(); + static DataDependency getEmpty(); }; } // namespace Neon::skeleton::internal \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h index 1d8fb6c9..a009e726 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h @@ -1,8 +1,6 @@ #pragma once #include "Neon/set/Backend.h" -#include "Neon/skeleton/internal/dependencyTools/Alias.h" -#include "Neon/skeleton/internal/dependencyTools/Dependency.h" -#include "Neon/set/dependencyTools/enum.h" +#include "Neon/skeleton/internal/dependencyTools/DataDependency.h" namespace Neon::skeleton::internal { @@ -11,20 +9,23 @@ namespace Neon::skeleton::internal { * Stores type of operations on data for each kernels while user code is "parsed" * It is used to construct the user kernel dependency graph */ -// TODO rename DataDependencyAnalizer_t struct DependencyAnalyser { private: - std::vector m_parsedR{}; - std::vector m_parsedW{}; + std::vector mParsedR{}; + std::vector mParsedW{}; - DataUId_t m_uid; - DataIdx_t m_idx; + Neon::internal::dataDependency::DataUId mUid; + Neon::internal::dataDependency::DataIdx mIdx; public: DependencyAnalyser() = delete; - DependencyAnalyser(DataUId_t, DataIdx_t); - auto update(ContainerIdx newKernel, Access_e newOp) -> std::vector; + DependencyAnalyser(Neon::internal::dataDependency::DataUId, + Neon::internal::dataDependency::DataIdx); + + auto update(Neon::set::container::GraphData::Uid newKernel, + Neon::internal::dataDependency::AccessType newOp) + -> std::vector; }; -} \ No newline at end of file +} // namespace Neon::skeleton::internal \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h index 9b12bc8d..9b55d3e7 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h @@ -1,8 +1,9 @@ #pragma once #include #include "Neon/set/Backend.h" -#include "Neon/set/dependencyTools/Alias.h" -#include "Neon/set/dependencyTools/enum.h" +#include "Neon/set/container/Graph.h" +#include "Neon/set/dependency/Alias.h" +#include "Neon/set/dependency/DataDependencyType.h" #include "Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h" namespace Neon::skeleton::internal { @@ -12,15 +13,17 @@ namespace Neon::skeleton::internal { * Keep track of all the data used by all kernels * * Each field is track by a local indexing. - * The indexing is determined by the map m_uid2Idx + * The indexing is determined by the map mUid2Idx * - * The local index (DataIdx_t) is used to access information on the user data - * that is stored in the vector m_depAnalyserVec. + * The local index (DataIdx) is used to access information on the user data + * that is stored in the vector mDepAnalyserVec. */ struct UserDataManager { - std::vector m_depAnalyserVec; - std::map m_uid2Idx; + std::vector mDepAnalyserVec; + std::map + mUid2Idx; private: /** @@ -28,7 +31,8 @@ struct UserDataManager * @param uid * @return */ - auto helpGetIdx(DataUId_t uid) -> DataIdx_t; + auto helpGetIdx(Neon::internal::dataDependency::DataUId uid) + -> Neon::internal::dataDependency::DataIdx; public: /** @@ -40,9 +44,9 @@ struct UserDataManager * @param uid * @return */ - auto updateStatus(ContainerIdx newKernel, - Access_e op, - DataUId_t uid) -> std::vector; + auto updateStatus(Neon::set::container::GraphData::Uid newKernel, + Neon::internal::dataDependency::AccessType op, + Neon::internal::dataDependency::DataUId uid) -> std::vector; }; -} // namespace internal +} // namespace Neon::skeleton::internal diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp index 08e83641..f6e5858b 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp @@ -1,48 +1,49 @@ -#include "Neon/skeleton/internal/dependencyTools/Dependency.h" +#include "Neon/skeleton/internal/dependencyTools/DataDependency.h" namespace Neon::skeleton::internal { -Dependency::Dependency(ContainerIdx t1, - Dependencies_e type, - DataUId_t uid, - ContainerIdx t0) +DataDependency::DataDependency(Neon::set::container::GraphData::Uid t1, + Neon::internal::dataDependency::DataDependencyType type, + Neon::internal::dataDependency::DataUId uid, + Neon::set::container::GraphData::Uid t0) { - m_t1 = t1; - m_type = type; - m_uid = uid; - m_t0 = t0; + mT1 = t1; + mType = type; + mDataUid = uid; + mT0 = t0; } -bool Dependency::isValid() +bool DataDependency::isValid() { - return m_type != Dependencies_e::NONE; + return mType != Neon::internal::dataDependency::DataDependencyType::NONE; } -auto Dependency::toString() -> std::string +auto DataDependency::toString() -> std::string { - return std::to_string(m_t1) + - " -> (" + Dependencies_et::toString(m_type) + - " [" + std::to_string(m_uid) + - "]) -> " + std::to_string(m_t0); + return std::to_string(mT1) + + " -> (" + Neon::internal::dataDependency::DataDependencyTypeUtils::toString(mType) + + " [" + std::to_string(mDataUid) + + "]) -> " + std::to_string(mT0); } -auto Dependency::type() -> Dependencies_e +auto DataDependency::type() -> Neon::internal::dataDependency::DataDependencyType { - return m_type; + return mType; } -Dependency Dependency::getEmpty() +DataDependency DataDependency::getEmpty() { - return Dependency(); + return {}; } -auto Dependency::t0() -> ContainerIdx + +auto DataDependency::t0() -> Neon::set::container::GraphData::Uid { - return m_t0; + return mT0; } -auto Dependency::t1() -> ContainerIdx +auto DataDependency::t1() -> Neon::set::container::GraphData::Uid { - return m_t1; + return mT1; } } // namespace Neon::skeleton::internal \ No newline at end of file diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp index 91e1a211..68b2741f 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp @@ -4,80 +4,138 @@ namespace Neon::skeleton::internal { -DependencyAnalyser::DependencyAnalyser(DataUId_t uid, DataIdx_t idx) +DependencyAnalyser::DependencyAnalyser(Neon::internal::dataDependency::DataUId uid, + Neon::internal::dataDependency::DataIdx idx) { - m_uid = uid; - m_idx = idx; + mUid = uid; + mIdx = idx; } -auto DependencyAnalyser::update(ContainerIdx newKernel, Access_e newOp) - -> std::vector +auto DependencyAnalyser::update(Neon::set::container::GraphData::Uid newKernel, + Neon::internal::dataDependency::AccessType newOp) + -> std::vector { switch (newOp) { - case Access_e::READ: { - if (m_parsedW.size() == 0) { - // Parsing a Read operation with no write before - // We are at the beginning of the dependencies - // a. just add the kernel in the parsed read kernels - m_parsedR.push_back(newKernel); - return std::vector(0); + case Neon::internal::dataDependency::AccessType::READ: { + if (mParsedW.size() == 0) { + // We are parsing a READ with no previous WRITE + // STEPS: + // a. Register the current kernel in the READ state machine + // b. Returns no dependencies + + // Executing step a. + mParsedR.push_back(newKernel); + // Executing step b. + return std::vector(0); } - if (m_parsedW.size() == 1) { - // Parsing a Read operation with one write before - // We have a RaW dependency - // a. add the new kernel to the read queue - // b. return a RaW between the new R and the old W - m_parsedR.push_back(newKernel); - auto t0W = m_parsedW[0]; - auto t1R = newKernel; - Dependency d(t1R, Dependencies_e::RAW, m_uid, t0W); - return {d}; + if (mParsedW.size() == 1) { + std::vector output; + // Parsing a READ after a WRITE + // STEPS: + // a. Return a RaW between the new READing kernel and the old WRITing kernel + // b. Register the current kernel in the READ state machine + //------ + + + { // Executing a. + auto t0W = mParsedW[0]; + auto t1R = newKernel; + if (t0W != t1R) { + DataDependency d(t1R, Neon::internal::dataDependency::DataDependencyType::RAW, mUid, t0W); + output.push_back(d); + } + } + + { // Executing b. + mParsedR.push_back(newKernel); + } + return output; + } else { - // Violation of the state machine integrity - NEON_THROW_UNSUPPORTED_OPERATION(""); + NEON_THROW_UNSUPPORTED_OPERATION("A Violation of the state machine integrity was detected"); } break; } - case Access_e::WRITE: { - if (m_parsedR.size() == 0 && m_parsedW.size() == 0) { - // Parsing a kernel for the first time and it is a W - // Return an empty dependency - m_parsedW.push_back(newKernel); - return std::vector(0); + case Neon::internal::dataDependency::AccessType::WRITE: { + if (mParsedR.empty() && mParsedW.empty()) { + // Parsing a WRITE as the first operation in the Container sequence. + // + // STEPS: + // a. Record the Write operation in the state machine + // b. Return no dependency + //------ + + { // Executing a. + mParsedW.push_back(newKernel); + } + + { // Executing b. + return std::vector(0); + } } - if (m_parsedR.size() != 0 && m_parsedW.size() <= 1) { - // Parsing a W kernel after - // .. none or one W old kernel - // .. one or more R old kernels - - // Fire a WaR dependency between the new W and the old Rs - std::vector res; - for (auto t0R : m_parsedR) { - auto t1W = newKernel; - if (t1W == t0R) { - continue; + + if (!mParsedR.empty() && mParsedW.empty()) { + std::vector output; + // Parsing a WRITE after some READs + // + + // STEPS: + // a. creation the vector of WAR dependencies to be returned + // b. clear state machine state, cleaning previous read token and storing the new write token + + { // Executing a. + for (const auto token_t0_READ : mParsedR) { + const auto token_t1_WRITE = newKernel; + if (token_t1_WRITE != token_t0_READ) { + DataDependency d(token_t1_WRITE, Neon::internal::dataDependency::DataDependencyType::WAR, mUid, token_t0_READ); + output.push_back(d); + } } - Dependency d(t1W, Dependencies_e::WAR, m_uid, t0R); - res.push_back(d); } - m_parsedR.clear(); - m_parsedW = std::vector(1, newKernel); - return res; + + { // Executing b. + mParsedR.clear(); + mParsedW = std::vector(1, newKernel); + } + + return output; } - if (m_parsedR.size() == 0 && m_parsedW.size() <= 1) { - // Parsing a W kernel after a W old kernel + if (!mParsedW.empty()) { + std::vector output; + // STEPS: + // a. flag a WaW dependency + // b. flag possible WaR dependencies + // b. clear state machine state, cleaning previous read token and storing the new write token + NEON_WARNING("Skeleton: WaW dependency detected."); - auto t0W = m_parsedW[0]; - auto t1W = newKernel; - Dependency d(t1W, Dependencies_e::WAW, m_uid, t0W); - m_parsedW = std::vector(1, newKernel); - return std::vector(1, d); - ; + { // Executing Step a. + auto token_t0_WRITE = mParsedW[0]; + auto token_t1_WRITE = newKernel; + if (token_t0_WRITE != token_t1_WRITE) { + DataDependency d(token_t1_WRITE, Neon::internal::dataDependency::DataDependencyType::WAW, mUid, token_t0_WRITE); + output.push_back(d); + } + } + { // Executing Step b. + for (const auto token_t0_READ : mParsedR) { + const auto token_t1_WRITE = newKernel; + if (token_t1_WRITE != token_t0_READ) { + DataDependency d(token_t1_WRITE, Neon::internal::dataDependency::DataDependencyType::WAR, mUid, token_t0_READ); + output.push_back(d); + } + } + } + { // Executing c. + + mParsedR.clear(); + mParsedW = std::vector(1, newKernel); + } + return output; } break; } - case Access_e::NONE: { + case Neon::internal::dataDependency::AccessType::NONE: { // Error NEON_THROW_UNSUPPORTED_OPTION(""); } diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp index 92a4806c..7db5a629 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp @@ -2,24 +2,26 @@ namespace Neon::skeleton::internal { -auto UserDataManager::helpGetIdx(DataUId_t uid) -> DataIdx_t +auto UserDataManager::helpGetIdx(Neon::internal::dataDependency::DataUId uid) + -> Neon::internal::dataDependency::DataIdx { - auto count = m_uid2Idx.count(uid); + auto count = mUid2Idx.count(uid); if (count == 0) { - DataIdx_t idx = m_depAnalyserVec.size(); - m_depAnalyserVec.emplace_back(uid, idx); - m_uid2Idx[uid] = idx; + Neon::internal::dataDependency::DataIdx idx = mDepAnalyserVec.size(); + mDepAnalyserVec.emplace_back(uid, idx); + mUid2Idx[uid] = idx; return idx; } - return m_uid2Idx[uid]; + return mUid2Idx[uid]; } -auto UserDataManager::updateStatus(ContainerIdx newKernel, - Access_e op, - DataUId_t uid) -> std::vector +auto UserDataManager::updateStatus(Neon::set::container::GraphData::Uid nodeUid, + Neon::internal::dataDependency::AccessType op, + Neon::internal::dataDependency::DataUId dataUid) + -> std::vector { - auto idx = helpGetIdx(uid); - auto depVec = m_depAnalyserVec[idx].update(newKernel, op); + auto idx = helpGetIdx(dataUid); + auto depVec = mDepAnalyserVec[idx].update(nodeUid, op); return depVec; } diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index c67db3e7..65d47ede 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -3,175 +3,69 @@ namespace Neon::skeleton::internal { - -// auto UserGraph_t::h_newHaloNode() -//{ -// auto node = Node_t::factory(NodeType_e::HELPER, -1); -// m_graph().addVertex(node.nodeId(), node); -// return node.nodeId(); -// } -// -// auto UserGraph_t::h_newNeonNode() -> size_t -//{ -// auto node = Node_t::factory(NodeType_e::HELPER, -1); -// m_graph().addVertex(node.nodeId(), node); -// return node.nodeId(); -// } void MultiGpuGraph::init(Neon::Backend& bk, const std::vector& operations, std::string name, Options options) { - parse(bk.devSet().setCardinality(), std::forward&&>(operations)); - m_storage->m_userAppGraph = m_graph(); - h_removeRedundantDependencies(); + mGraph() = Neon::set::container::Graph(bk); + parse(bk.devSet().setCardinality(), + std::forward&&>(operations)); + mGraph().removeRedundantDependencies(); + h_io2Dot("t0_" + name + ".dot", "i"); optimizations(options); h_io2Dot("t1_" + name + ".dot", "i"); addSyncAndMemoryTransfers(options); - h_removeRedundantDependencies(); + + mGraph().removeRedundantDependencies(); + checkCoherency(); h_io2Dot("t2_" + name + ".dot", "i"); - resetLinearContinuousIndexing(); } void MultiGpuGraph::parse(int setCardinalty, const std::vector&& operations) { m_setCardinality() = setCardinalty; - std::vector containerId2gNodeId; - std::vector> specialClosureNodes; - int i = 0; for (auto&& k : operations) { - h_parseContainer(k, - containerId2gNodeId, - specialClosureNodes); - i++; + helpParseNewContainer(k); } - h_closure(specialClosureNodes); } -void MultiGpuGraph::h_parseContainer(const Neon::set::Container& inContainer, - std::vector& containerId2gNodeId, - std::vector>& specialClosureNodes) +void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContainer) { + // Register and retrieve the id for the new container // add a node - ContainerIdx containerIdx = h_trackNewContainer(inContainer, containerId2gNodeId); + Neon::set::container::GraphData::Uid graphNodeUid = helpAddNewContainerToGraph(inContainer); // Parsing all the data toke used by the kernel container - std::vector tokens = h_parse(containerIdx); - int detectedDependencies = 0; + std::vector tokens = helpParseContainer(mGraph().getGraphNode(graphNodeUid).getContainer()); + int detectedDependencies = 0; + + // Tokens are based on the multi-GPU data loaded by Containers for (auto& token : tokens) { - // TODO@Max(if the kernelData is used for stencil store it for future halo update) - if (token.compute() == Neon::Compute::REDUCE) { - const NodeId nodeId = containerId2gNodeId[containerIdx]; - auto& nodeMeta = m_graph().getVertexProperty(nodeId); - if (nodeMeta.isStencil()) { - NEON_THROW_UNSUPPORTED_OPTION("The skeleton does not suport container with both reduce and stencil operations."); - } - nodeMeta.setCompute(Neon::Compute::REDUCE); - } - // update the dependency state machine with the new toke. + // update the dependency state machine with the new token. // newDependencies are the detected dependencies - auto newDependencies = m_dataRecords().updateStatus(containerIdx, token.access(), token.uid()); - if (newDependencies.size() == 0 && - token.compute() == Neon::Compute::STENCIL) { - - const size_t stencilNode = containerId2gNodeId[containerIdx]; - auto& nodeMeta = m_graph().getVertexProperty(stencilNode); - nodeMeta.setCompute(Neon::Compute::STENCIL); - auto newEdge = Edge::factory(token, Dependencies_e::RAW); - specialClosureNodes.push_back({stencilNode, newEdge}); + auto newDependencies = m_dataRecords().updateStatus(graphNodeUid, token.access(), token.uid()); - detectedDependencies++; - } for (auto& dep : newDependencies) { detectedDependencies++; + const auto& n0 = mGraph().getGraphNode(dep.t0()); + const auto& n1 = mGraph().getGraphNode(dep.t1()); - const size_t nodeid_t0 = containerId2gNodeId[dep.t0()]; - const size_t nodeid_t1 = containerId2gNodeId[dep.t1()]; - - if (!m_graph().hasEdge(nodeid_t0, nodeid_t1)) { - auto newEdge = Edge::factory(token, dep.type()); - m_graph().addEdge(nodeid_t0, nodeid_t1, newEdge); - } else { - auto& edgeVal = m_graph().getEdgeProperty({nodeid_t0, nodeid_t1}); - edgeVal.append(token, dep.type()); - } - if (token.compute() == Neon::Compute::STENCIL) { - auto& node = m_graph().getVertexProperty(nodeid_t1); - node.setCompute(Neon::Compute::STENCIL); - } + mGraph().appendDataDependency(n0, n1, + dep.type(), + token.uid()); } } } -auto MultiGpuGraph::getContainer(ContainerIdx id) - -> Neon::set::Container& +auto MultiGpuGraph::helpParseContainer(Neon::set::Container& container) + -> std::vector { - return m_kContainers()[id]; -} - -auto MultiGpuGraph::getContainer(ContainerIdx id) const - -> const Neon::set::Container& -{ - return m_kContainers()[id]; -} - - -/** - * Helper function to close the graph with a begin and end emtpy nodes - * @param specialClosureNodes - */ -auto MultiGpuGraph::h_closure(const std::vector>& specialClosureNodes) - -> void -{ - // using NodeType_e = internal::userGraph::NodeType_e; - - // Adding the kernel container into the graph - auto node = MetaNode::factory(MetaNodeType_e::HELPER, "Begin", -1); - m_graph().addVertex(node.nodeId(), node); - m_setRootNodeId(node.nodeId()); - - // Adding the kernel container into the graph - node = MetaNode::factory(MetaNodeType_e::HELPER, "End", -1); - m_graph().addVertex(node.nodeId(), node); - m_setFinalNodeId(node.nodeId()); - - m_graph().forEachVertex([&](size_t nodeId) { - if (m_graph().inEdges(nodeId).size() == 0) { - if (nodeId != m_rootNodeId() && nodeId != m_finalNodeId()) { - m_graph().addEdge(m_rootNodeId(), nodeId); - } - } - if (m_graph().outEdges(nodeId).size() == 0) { - if (nodeId != m_rootNodeId() && nodeId != m_finalNodeId()) { - m_graph().addEdge(nodeId, m_finalNodeId()); - } - } - }); - - for (auto& specialClosureNode : specialClosureNodes) { - size_t node_t0 = m_rootNodeId(); - size_t node_t1 = std::get(specialClosureNode); - auto& edgeMetaData = std::get(specialClosureNode); - if (m_graph().hasEdge({node_t0, node_t1})) { - Edge& edge = m_graph().getEdgeProperty({node_t0, node_t1}); - edge = edgeMetaData; - } - } - this->h_io2Dot("DB.dot", ""); - - // h_io2Dot("test.dot", "g"); -} - - -auto MultiGpuGraph::h_parse(ContainerIdx kernelContainerIdx) - -> std::vector -{ - auto& container = getContainer(kernelContainerIdx); auto& kcInterface = container.getContainerInterface(); auto& tokens = kcInterface.parse(); return tokens; @@ -180,279 +74,26 @@ auto MultiGpuGraph::h_parse(ContainerIdx kernelContainerIdx) auto MultiGpuGraph::h_io2Dot([[maybe_unused]] const std::string& fname, [[maybe_unused]] const std::string& graphName) -> void { - // io2Dot(fname, graphName); - return; + io2Dot(fname, graphName, true); } -auto MultiGpuGraph::io2Dot(const std::string& fname, const std::string& graphName) -> void +auto MultiGpuGraph::io2Dot(const std::string& fname, const std::string& graphName, bool debug) -> void { - // http://www.graphviz.org/doc/info/shapes.html - auto clone = m_graph(); - m_schedulingGraph().forEachEdge([&](const DiGraphScheduling::Edge& edge) { - auto edgeMeta = Edge::factorySchedulingEdge(); - clone.addEdge(edge.first, edge.second, edgeMeta); - }); - - auto vertexLabel = [&](size_t v) -> std::string { - if (v == m_finalNodeId()) { - return std::string("END"); //+ "DEBUG" + std::to_string(m_graph().getVertexProperty(v).nodeId()); - } - if (v == m_rootNodeId()) { - return std::string("BEGIN"); // + "DEBUG" + std::to_string(m_graph().getVertexProperty(v).nodeId()); - } - return clone.getVertexProperty(v).toString(); - }; - - auto edgeLabel = [&](const std::pair& edge) - -> std::string { - const auto& metaEdge = clone.getEdgeProperty(edge); - if (metaEdge.m_isSchedulingEdge) { - return ""; - } - if (metaEdge.nDependencies() > 0) { - return metaEdge.toString(); - } - return ""; - }; - - auto edgeLabelProperty = [&](const std::pair& edge) - -> std::string { - const auto& metaEdge = clone.getEdgeProperty(edge); - if (metaEdge.m_isSchedulingEdge) { - // return "style=dashed, color=\"#2A9D8F\""; - return "style=dashed, color=\"#F4A261\", penwidth=7"; - } - return "color=\"#d9d9d9\", penwidth=7"; - }; - - auto vertexLabelProperty = [&](const size_t& v) { - if (v == m_finalNodeId() || (v == m_rootNodeId())) { - return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; - } - const auto& metaNode = clone.getVertexProperty(v); - if (metaNode.isHu()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - if (metaNode.isSync()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - - if (metaNode.isMap()) { - return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; - } - if (metaNode.isReduce()) { - return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; - } - if (metaNode.isStencil()) { - return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; - } - return ""; - }; - - clone.exportDotFile(fname, graphName, vertexLabel, edgeLabel, vertexLabelProperty, edgeLabelProperty); + mGraph().ioToDot(fname, graphName, debug); } -auto MultiGpuGraph::io2DotOriginalApp(const std::string& fname, const std::string& graphName) -> void +auto MultiGpuGraph::io2DotOriginalApp(const std::string& fname, const std::string& graphName, bool debug) -> void { - // http://www.graphviz.org/doc/info/shapes.html - auto& clone = m_storage->m_userAppGraph; - - auto vertexLabel = [&](size_t v) -> std::string { - if (v == m_finalNodeId()) { - return std::string("END"); // + "DEBUG" + std::to_string(m_graph().getVertexProperty(v).nodeId()); - } - if (v == m_rootNodeId()) { - return std::string("BEGIN"); // + "DEBUG" + std::to_string(m_graph().getVertexProperty(v).nodeId()); - } - return clone.getVertexProperty(v).toString(); - }; - - auto edgeLabel = [&](const std::pair& edge) - -> std::string { - const auto& metaEdge = clone.getEdgeProperty(edge); - if (metaEdge.m_isSchedulingEdge) { - return ""; - } - if (metaEdge.nDependencies() > 0) { - return metaEdge.toString(); - } - return ""; - }; - - auto edgeLabelProperty = [&](const std::pair& edge) - -> std::string { - const auto& metaEdge = clone.getEdgeProperty(edge); - if (metaEdge.m_isSchedulingEdge) { - // return "style=dashed, color=\"#2A9D8F\""; - return "style=dashed, color=\"#F4A261\", penwidth=7"; - } - return "color=\"#d9d9d9\", penwidth=7"; - }; - - auto vertexLabelProperty = [&](const size_t& v) { - if (v == m_finalNodeId() || (v == m_rootNodeId())) { - return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; - } - const auto& metaNode = clone.getVertexProperty(v); - if (metaNode.isHu()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - if (metaNode.isSync()) { - return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; - } - - if (metaNode.isMap()) { - return R"(style=filled, fillcolor="#b3de69", color="#5f861d")"; - } - if (metaNode.isReduce()) { - return R"(style=filled, fillcolor="#80b1d3", color="#2b5c7d")"; - } - if (metaNode.isStencil()) { - return R"(style=filled, fillcolor="#bebada", color="#4e4683")"; - } - return ""; - }; - - clone.exportDotFile(fname, graphName, vertexLabel, edgeLabel, vertexLabelProperty, edgeLabelProperty); -} - -auto MultiGpuGraph::h_trackNewContainer(const Neon::set::Container& container, - std::vector& containerId2gNodeId) -> ContainerIdx -{ - ContainerIdx kernelContainerIdx = m_kContainers().size(); - m_kContainers().push_back(container); - - // Adding the kernel container into the graph - auto node = MetaNode::factory(MetaNodeType_e::CONTAINER, container.getName(), kernelContainerIdx); - m_graph().addVertex(node.nodeId(), node); - - containerId2gNodeId.push_back(node.nodeId()); - - return kernelContainerIdx; + mGraph().ioToDot(fname, graphName, debug); } -auto MultiGpuGraph::h_removeRedundantDependencies() -> void +auto MultiGpuGraph::helpAddNewContainerToGraph(const Neon::set::Container& container) -> Neon::set::container::GraphData::Uid { - std::vector> edgesToBeRemoved; - m_graph().forEachVertex([&](size_t node) { - // Looping over all nodes - const auto& children = m_graph().outNeighbors(node); - // Checking sons. If no more than one, move to the next node - if (children.size() <= 1) { - return; - } - for (const auto& child : children) { - if (m_graph().inEdges(child).size() <= 1) { - // This child can only be reach by once father - // No redundant path here - continue; - } - bool foundRedundant = false; - for (const auto& sibling : children) { - if (sibling == child) { - continue; - } - auto frontiar = m_graph().outNeighbors(sibling); - while (frontiar.size() != 0) { - auto nextFrontiar = std::set(); - - for (const auto& eInFrintier : frontiar) { - if (eInFrintier == child) { - foundRedundant = true; - break; - } else { - for (auto nextE : m_graph().outNeighbors(eInFrintier)) { - nextFrontiar.insert(nextE); - } - } - } // end FOF - if (foundRedundant) { - break; - } - frontiar = nextFrontiar; - } - if (foundRedundant) - break; - } - if (foundRedundant) { - edgesToBeRemoved.push_back({node, child}); - } - } - }); - for (const auto& toBeRemoved : edgesToBeRemoved) { - m_graph().removeEdge(toBeRemoved); - } + const auto& graphNode = mGraph().addNode(container); + Neon::set::container::GraphData::Uid uid = graphNode.getGraphData().getUid(); + return uid; } -/** - * Creates 2 nodes for - * @param uid - * @param edge - * @param infoIdx - * @param transferModeE - * @return - */ -auto MultiGpuGraph::h_add_hUpdateSyncNodes(size_t t0Node, - size_t t1Node, - const internal::Edge::Info& info, - Neon::set::TransferMode transferModeE) - -> void -{ - auto getNewEdge = [&]() { - const bool haloUpdate = true; - return internal::Edge::factory(info.token, info.dependency, haloUpdate); - }; - - auto hupNode = MetaNode::haloUpdateFactory(transferModeE, - info.token.uid(), - info.token.getHaloUpdate(), - info.token.getHaloUpdatePerDevice()); - - m_graph().addVertex(hupNode.nodeId(), hupNode); - - auto syncNode = MetaNode::syncLeftRightFactory(info.token.uid()); - m_graph().addVertex(syncNode.nodeId(), syncNode); - - size_t syncNodet0; - size_t syncNodet1; - - if (transferModeE == Neon::set::TransferMode::put) { - syncNodet0 = hupNode.nodeId(); - syncNodet1 = syncNode.nodeId(); - } else { - syncNodet0 = syncNode.nodeId(); - syncNodet1 = hupNode.nodeId(); - } - - { // linking the two halo and sync nodes - auto hpSycInternlaEdge = getNewEdge(); - m_graph().addEdge(syncNodet0, syncNodet1, hpSycInternlaEdge); - } - - { - { - auto fromT0 = getNewEdge(); - m_graph().addEdge(t0Node, syncNodet0, fromT0); - } - { - auto toT1 = getNewEdge(); - m_graph().addEdge(syncNodet1, t1Node, toT1); - } - } - - const auto& inNgh = m_schedulingGraph().inNeighbors(t1Node); - if (!inNgh.empty()) { - m_schedulingGraph().addVertex(syncNodet0); - } - for (const auto& toBeFirst : inNgh) { - m_schedulingGraph().addEdge(toBeFirst, syncNodet0); - } - - for (const auto& toBeFirst : inNgh) { - m_schedulingGraph().removeEdge(toBeFirst, t1Node); - } - return; -} auto MultiGpuGraph::optimizations(const Neon::skeleton::Options& options) -> void { @@ -470,699 +111,566 @@ auto MultiGpuGraph::optimizations(const Neon::skeleton::Options& options) -> voi auto MultiGpuGraph::optimizeStandardOCC(const Neon::skeleton::Options&) -> void { - /** - * Objective: - * a. detect all stencil nodes - * b. each stencil node is slipped into internal and boundary - * c. all the dependency must be cloned too - */ - using Compute_e = Neon::Compute; - - // Detects all stencil nodes - std::vector stencilNodes; - m_graph().forEachVertex([&](size_t nodeId) { - const auto& node = m_graph().getVertexProperty(nodeId); - if (node.getCompute() == Compute_e::STENCIL) { - if (node.getDataView() != Neon::DataView::INTERNAL) { - stencilNodes.push_back(nodeId); - } - } - }); - // Cloning each stencil node - for (auto&& stencilNode : stencilNodes) { - // Data used by the helper functions - const auto inEdges = m_graph().inEdges(stencilNode); - const auto outEdges = m_graph().outEdges(stencilNode); - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneStencilNode = [&](const Neon::DataView& dataView) -> size_t { - const auto& toBeCloned = m_graph().getVertexProperty(stencilNode); - auto clone = toBeCloned.clone(); - clone.setDataView(dataView); - m_graph().addVertex(clone.nodeId(), clone); - return clone.nodeId(); - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneIncomingConnections = [&](size_t clone) -> void { - std::for_each(outEdges.begin(), outEdges.end(), - [&](const DiGraph::Edge& edge) { - auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); - m_graph().addEdge(clone, edge.second, clonedEdge); - }); - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneOutgoingConnections = [&](size_t clone) -> void { - std::for_each(inEdges.begin(), inEdges.end(), - [&](const DiGraph::Edge& edge) { - auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); - m_graph().addEdge(edge.first, clone, clonedEdge); - }); - }; - // HELPER ////////////////////////////////////////////////////////////////////////// - auto cloningProcess = [&](const Neon::DataView& dataView) -> NodeId { - NodeId cloneId = h_cloneStencilNode(dataView); - h_cloneIncomingConnections(cloneId); - h_cloneOutgoingConnections(cloneId); - return cloneId; - }; - //////////////////////////////////////////////////////////////////////////// - NodeId internalNode = cloningProcess(Neon::DataView::INTERNAL); - NodeId boundaryNode = cloningProcess(Neon::DataView::BOUNDARY); - for (auto& node : {internalNode, boundaryNode}) { - m_schedulingGraph().hasVertex(node); - m_schedulingGraph().addVertex(node); - } - - if (!m_schedulingGraph().hasEdge({boundaryNode, internalNode})) { - m_schedulingGraph().addEdge(internalNode, boundaryNode); - } - } - - for (auto&& stencilNode : stencilNodes) { - m_graph().removeVertex(stencilNode); - } + NEON_DEV_UNDER_CONSTRUCTION(""); + + // /** + // * Objective: + // * a. detect all stencil nodes + // * b. each stencil node is slipped into internal and boundary + // * c. all the dependency must be cloned too + // */ + // using Compute_e = Neon::Compute; + // + // // Detects all stencil nodes + // std::vector stencilNodes; + // m_graph().forEachVertex([&](size_t nodeId) { + // const auto& node = m_graph().getVertexProperty(nodeId); + // if (node.getCompute() == Compute_e::STENCIL) { + // if (node.getDataView() != Neon::DataView::INTERNAL) { + // stencilNodes.push_back(nodeId); + // } + // } + // }); + // // Cloning each stencil node + // for (auto&& stencilNode : stencilNodes) { + // // Data used by the helper functions + // const auto inEdges = m_graph().inEdges(stencilNode); + // const auto outEdges = m_graph().outEdges(stencilNode); + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneStencilNode = [&](const Neon::DataView& dataView) -> size_t { + // const auto& toBeCloned = m_graph().getVertexProperty(stencilNode); + // auto clone = toBeCloned.clone(); + // clone.setDataView(dataView); + // m_graph().addVertex(clone.nodeId(), clone); + // return clone.nodeId(); + // }; + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneIncomingConnections = [&](size_t clone) -> void { + // std::for_each(outEdges.begin(), outEdges.end(), + // [&](const DiGraph::Edge& edge) { + // auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); + // m_graph().addEdge(clone, edge.second, clonedEdge); + // }); + // }; + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneOutgoingConnections = [&](size_t clone) -> void { + // std::for_each(inEdges.begin(), inEdges.end(), + // [&](const DiGraph::Edge& edge) { + // auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); + // m_graph().addEdge(edge.first, clone, clonedEdge); + // }); + // }; + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto cloningProcess = [&](const Neon::DataView& dataView) -> NodeId { + // NodeId cloneId = h_cloneStencilNode(dataView); + // h_cloneIncomingConnections(cloneId); + // h_cloneOutgoingConnections(cloneId); + // return cloneId; + // }; + // //////////////////////////////////////////////////////////////////////////// + // NodeId internalNode = cloningProcess(Neon::DataView::INTERNAL); + // NodeId boundaryNode = cloningProcess(Neon::DataView::BOUNDARY); + // for (auto& node : {internalNode, boundaryNode}) { + // m_schedulingGraph().hasVertex(node); + // m_schedulingGraph().addVertex(node); + // } + // + // if (!m_schedulingGraph().hasEdge({boundaryNode, internalNode})) { + // m_schedulingGraph().addEdge(internalNode, boundaryNode); + // } + // } + // + // for (auto&& stencilNode : stencilNodes) { + // m_graph().removeVertex(stencilNode); + // } } auto MultiGpuGraph::optimizeExtendedOCC(const Neon::skeleton::Options&) -> void { - - // Detects all stencil nodes - std::vector potentialStencilNodes; - m_graph().forEachVertex([&](size_t nodeId) { - const auto& node = m_graph().getVertexProperty(nodeId); - if (node.getCompute() == Neon::Compute::STENCIL) { - if (node.getDataView() == Neon::DataView::STANDARD) { - potentialStencilNodes.push_back(nodeId); - } - } - }); - std::vector targetStencilNodes; - - for (auto& potentialStencilNode : potentialStencilNodes) { - bool attachedToRoot = false; - bool proceedByMap = false; - m_graph().forEachInEdge(potentialStencilNode, [&](const std::pair& edge) { - if (edge.first == m_rootNodeId()) { - attachedToRoot = true; - } - if (!m_graph().getVertexProperty(edge.first).isStencil()) { - proceedByMap = true; - } - }); - if (!attachedToRoot && proceedByMap) { - targetStencilNodes.push_back(potentialStencilNode); - } - } - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneKernelNodeNode = [&](size_t node, const Neon::DataView& dataView) -> size_t { - const auto& toBeCloned = m_graph().getVertexProperty(node); - auto clone = toBeCloned.clone(); - clone.setDataView(dataView); - m_graph().addVertex(clone.nodeId(), clone); - return clone.nodeId(); - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneOutgoingConnections = [&](std::set> outEdges, size_t clone) -> void { - std::for_each(outEdges.begin(), outEdges.end(), - [&](const DiGraph::Edge& edge) { - auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); - m_graph().addEdge(clone, edge.second, clonedEdge); - }); - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneIncomingConnections = [&](std::set> inEdges, size_t clone) -> void { - std::for_each(inEdges.begin(), inEdges.end(), - [&](const DiGraph::Edge& edge) { - auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); - m_graph().addEdge(edge.first, clone, clonedEdge); - }); - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloningProcess = [&](size_t st1, std::vector mt0s) -> void { - /** - * st1: stencil node - * mt0s: set of map nodes at the previous level - * - * st1 stencil t1 - * mto are map at t0 - */ - this->h_io2Dot("A.dot", "A"); - // Cloning the stencil node - size_t st1_internal = h_cloneKernelNodeNode(st1, Neon::DataView::INTERNAL); - size_t st1_boundary = h_cloneKernelNodeNode(st1, Neon::DataView::BOUNDARY); - m_schedulingGraph().addVertex(st1_internal); - m_schedulingGraph().addVertex(st1_boundary); - m_schedulingGraph().addEdge(st1_internal, st1_boundary); - - this->h_io2Dot("B.dot", "B"); - - { - auto inE = m_graph().inEdges(st1); - h_cloneIncomingConnections(inE, st1_internal); - h_cloneIncomingConnections(inE, st1_boundary); - } - { - auto outE = m_graph().outEdges(st1); - h_cloneOutgoingConnections(outE, st1_internal); - h_cloneOutgoingConnections(outE, st1_boundary); - } - this->h_io2Dot("C.dot", "B"); - - for (auto& mt0 : mt0s) { - // cloning map node into boundary and internal - size_t mapInternal = h_cloneKernelNodeNode(mt0, Neon::DataView::INTERNAL); - size_t mapBoundary = h_cloneKernelNodeNode(mt0, Neon::DataView::BOUNDARY); - m_schedulingGraph().addVertex(mapInternal); - m_schedulingGraph().addVertex(mapBoundary); - m_schedulingGraph().addEdge(mapBoundary, mapInternal); - - { - auto inE = m_graph().inEdges(mt0); - h_cloneIncomingConnections(inE, mapInternal); - h_cloneIncomingConnections(inE, mapBoundary); - } - this->h_io2Dot("D.dot", "B"); - - { - auto outE = m_graph().outEdges(mt0); - h_cloneOutgoingConnections(outE, mapInternal); - h_cloneOutgoingConnections(outE, mapBoundary); - } - - { // the stencil arc from map_internal and stencil{internal/boundary} mast be set to map - for (auto& st1Target : {st1_internal, st1_boundary}) { - auto& edge = m_graph().getEdgeProperty({mapInternal, st1Target}); - auto& infos = edge.infoMutable(); - for (auto& info : infos) { - info.flag_discardStencilDep = true; - } - } - } - - this->h_io2Dot("E.dot", "B"); - // //m_graph().removeEdge({internal, st1_boundary}); - // //m_graph().removeEdge({boundary, st1_internal}); - this->h_io2Dot("F.dot", "B"); - } - m_graph().removeVertex(st1); - this->h_io2Dot("G.dot", "B"); - for (auto& mt0 : mt0s) { - m_graph().removeVertex(mt0); - } - this->h_io2Dot("H.dot", "B"); - }; - - //////////////////////////////////////////////////////////////////////////// - auto node2Level = h_getBFSIndexes(); - for (auto&& stencilNode : targetStencilNodes) { - int stencilNodeLevel = node2Level[stencilNode]; - std::vector toClone; - auto inNodes = m_graph().inNeighbors(stencilNode); - for (const auto& inNode : inNodes) { - if (node2Level[inNode] == stencilNodeLevel - 1) { - toClone.push_back(inNode); - } - } - h_cloningProcess(stencilNode, toClone); - } + NEON_DEV_UNDER_CONSTRUCTION(""); + + // + // // Detects all stencil nodes + // std::vector potentialStencilNodes; + // m_graph().forEachVertex([&](size_t nodeId) { + // const auto& node = m_graph().getVertexProperty(nodeId); + // if (node.getCompute() == Neon::Compute::STENCIL) { + // if (node.getDataView() == Neon::DataView::STANDARD) { + // potentialStencilNodes.push_back(nodeId); + // } + // } + // }); + // std::vector targetStencilNodes; + // + // for (auto& potentialStencilNode : potentialStencilNodes) { + // bool attachedToRoot = false; + // bool proceedByMap = false; + // m_graph().forEachInEdge(potentialStencilNode, [&](const std::pair& edge) { + // if (edge.first == m_rootNodeId()) { + // attachedToRoot = true; + // } + // if (!m_graph().getVertexProperty(edge.first).isStencil()) { + // proceedByMap = true; + // } + // }); + // if (!attachedToRoot && proceedByMap) { + // targetStencilNodes.push_back(potentialStencilNode); + // } + // } + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneKernelNodeNode = [&](size_t node, const Neon::DataView& dataView) -> size_t { + // const auto& toBeCloned = m_graph().getVertexProperty(node); + // auto clone = toBeCloned.clone(); + // clone.setDataView(dataView); + // m_graph().addVertex(clone.nodeId(), clone); + // return clone.nodeId(); + // }; + // + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneOutgoingConnections = [&](std::set> outEdges, size_t clone) -> void { + // std::for_each(outEdges.begin(), outEdges.end(), + // [&](const DiGraph::Edge& edge) { + // auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); + // m_graph().addEdge(clone, edge.second, clonedEdge); + // }); + // }; + // + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneIncomingConnections = [&](std::set> inEdges, size_t clone) -> void { + // std::for_each(inEdges.begin(), inEdges.end(), + // [&](const DiGraph::Edge& edge) { + // auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); + // m_graph().addEdge(edge.first, clone, clonedEdge); + // }); + // }; + // + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloningProcess = [&](size_t st1, std::vector mt0s) -> void { + // /** + // * st1: stencil node + // * mt0s: set of map nodes at the previous level + // * + // * st1 stencil t1 + // * mto are map at t0 + // */ + // this->h_io2Dot("A.dot", "A"); + // // Cloning the stencil node + // size_t st1_internal = h_cloneKernelNodeNode(st1, Neon::DataView::INTERNAL); + // size_t st1_boundary = h_cloneKernelNodeNode(st1, Neon::DataView::BOUNDARY); + // m_schedulingGraph().addVertex(st1_internal); + // m_schedulingGraph().addVertex(st1_boundary); + // m_schedulingGraph().addEdge(st1_internal, st1_boundary); + // + // this->h_io2Dot("B.dot", "B"); + // + // { + // auto inE = m_graph().inEdges(st1); + // h_cloneIncomingConnections(inE, st1_internal); + // h_cloneIncomingConnections(inE, st1_boundary); + // } + // { + // auto outE = m_graph().outEdges(st1); + // h_cloneOutgoingConnections(outE, st1_internal); + // h_cloneOutgoingConnections(outE, st1_boundary); + // } + // this->h_io2Dot("C.dot", "B"); + // + // for (auto& mt0 : mt0s) { + // // cloning map node into boundary and internal + // size_t mapInternal = h_cloneKernelNodeNode(mt0, Neon::DataView::INTERNAL); + // size_t mapBoundary = h_cloneKernelNodeNode(mt0, Neon::DataView::BOUNDARY); + // m_schedulingGraph().addVertex(mapInternal); + // m_schedulingGraph().addVertex(mapBoundary); + // m_schedulingGraph().addEdge(mapBoundary, mapInternal); + // + // { + // auto inE = m_graph().inEdges(mt0); + // h_cloneIncomingConnections(inE, mapInternal); + // h_cloneIncomingConnections(inE, mapBoundary); + // } + // this->h_io2Dot("D.dot", "B"); + // + // { + // auto outE = m_graph().outEdges(mt0); + // h_cloneOutgoingConnections(outE, mapInternal); + // h_cloneOutgoingConnections(outE, mapBoundary); + // } + // + // { // the stencil arc from map_internal and stencil{internal/boundary} mast be set to map + // for (auto& st1Target : {st1_internal, st1_boundary}) { + // auto& edge = m_graph().getEdgeProperty({mapInternal, st1Target}); + // auto& infos = edge.infoMutable(); + // for (auto& info : infos) { + // info.flag_discardStencilDep = true; + // } + // } + // } + // + // this->h_io2Dot("E.dot", "B"); + // // //m_graph().removeEdge({internal, st1_boundary}); + // // //m_graph().removeEdge({boundary, st1_internal}); + // this->h_io2Dot("F.dot", "B"); + // } + // m_graph().removeVertex(st1); + // this->h_io2Dot("G.dot", "B"); + // for (auto& mt0 : mt0s) { + // m_graph().removeVertex(mt0); + // } + // this->h_io2Dot("H.dot", "B"); + // }; + // + // //////////////////////////////////////////////////////////////////////////// + // auto node2Level = h_getBFSIndexes(); + // for (auto&& stencilNode : targetStencilNodes) { + // int stencilNodeLevel = node2Level[stencilNode]; + // std::vector toClone; + // auto inNodes = m_graph().inNeighbors(stencilNode); + // for (const auto& inNode : inNodes) { + // if (node2Level[inNode] == stencilNodeLevel - 1) { + // toClone.push_back(inNode); + // } + // } + // h_cloningProcess(stencilNode, toClone); + // } } auto MultiGpuGraph::optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> void { - - // Detects all stencil nodes - std::vector potentialStencilNodes; - m_graph().forEachVertex([&](size_t nodeId) { - const auto& node = m_graph().getVertexProperty(nodeId); - if (node.getCompute() == Neon::Compute::STENCIL) { - if (node.getDataView() == Neon::DataView::STANDARD) { - potentialStencilNodes.push_back(nodeId); - } - } - }); - std::vector targetStencilNodes; - - for (auto& potentialStencilNode : potentialStencilNodes) { - bool attachedToRoot = false; - bool attachedToFinal = false; - bool proceedByMap = false; - bool followedByMapOrDot = false; - - m_graph().forEachInEdge(potentialStencilNode, [&](const std::pair& edge) { - if (edge.first == m_rootNodeId()) { - attachedToRoot = true; - } - // only MAP front kernels can be splitted - if (m_graph().getVertexProperty(edge.first).isMap()) { - proceedByMap = true; - } - }); - m_graph().forEachOutEdge(potentialStencilNode, [&](const std::pair& edge) { - if (edge.second == m_finalNodeId()) { - attachedToFinal = true; - } - - // only MAP or DOT (-> not STENCIL) back kernels can be splitted - if (!m_graph().getVertexProperty(edge.second).isStencil()) { - followedByMapOrDot = true; - } - }); - if (!attachedToRoot && !attachedToFinal && proceedByMap && followedByMapOrDot) { - targetStencilNodes.push_back(potentialStencilNode); - } - } - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneKernelNodeNode = [&](size_t node, const Neon::DataView& dataView) -> size_t { - const auto& toBeCloned = m_graph().getVertexProperty(node); - auto clone = toBeCloned.clone(); - clone.setDataView(dataView); - m_graph().addVertex(clone.nodeId(), clone); - return clone.nodeId(); - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneOutgoingConnections = [&](std::set> outEdges, size_t clone) -> void { - std::for_each(outEdges.begin(), outEdges.end(), - [&](const DiGraph::Edge& edge) { - auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); - m_graph().addEdge(clone, edge.second, clonedEdge); - }); - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloneIncomingConnections = [&](std::set> inEdges, size_t clone) -> void { - std::for_each(inEdges.begin(), inEdges.end(), - [&](const DiGraph::Edge& edge) { - auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); - m_graph().addEdge(edge.first, clone, clonedEdge); - }); - }; - - // HELPER ////////////////////////////////////////////////////////////////////////// - auto h_cloningProcess = [&](const std::set& frontNodes, - size_t StencilNode, - const std::set& backNodes) -> void { - std::set backNodesInternal; - std::set backNodesBoundary; - std::set frontMapInternal; - - /** - * st1: stencil node - * mt0s: set of map nodes at the previous level - * - * st1 stencil t1 - * mto are map at t0 - */ - this->h_io2Dot("A.dot", "A"); - - // Cloning from the back toward the front - for (auto& mapBack : backNodes) { - // cloning map node into boundary and internal - size_t mapInternal = h_cloneKernelNodeNode(mapBack, Neon::DataView::INTERNAL); - size_t mapBoundary = h_cloneKernelNodeNode(mapBack, Neon::DataView::BOUNDARY); - - backNodesInternal.insert(mapInternal); - backNodesBoundary.insert(mapBoundary); - - m_schedulingGraph().addVertex(mapInternal); - m_schedulingGraph().addVertex(mapBoundary); - - const auto& metaNode = m_graph().getVertexProperty(mapBack); - if (metaNode.isReduce()) { - m_graph().addEdge(mapInternal, mapBoundary); - } else { - m_schedulingGraph().addEdge(mapInternal, mapBoundary); - } - - - { - auto inE = m_graph().inEdges(mapBack); - h_cloneIncomingConnections(inE, mapInternal); - h_cloneIncomingConnections(inE, mapBoundary); - } - this->h_io2Dot("D.cloning.back.dot", "B"); - - { - auto outE = m_graph().outEdges(mapBack); - h_cloneOutgoingConnections(outE, mapInternal); - h_cloneOutgoingConnections(outE, mapBoundary); - } - - this->h_io2Dot("E.cloning.back.dot", "B"); - } - - for (auto& mapBack : backNodes) { - m_graph().removeVertex(mapBack); - } - - - for (auto& mapFront : frontNodes) { - // cloning map node into boundary and internal - size_t mapBoundary = h_cloneKernelNodeNode(mapFront, Neon::DataView::BOUNDARY); - size_t mapInternal = h_cloneKernelNodeNode(mapFront, Neon::DataView::INTERNAL); - - frontMapInternal.insert(mapInternal); - - m_schedulingGraph().addVertex(mapInternal); - m_schedulingGraph().addVertex(mapBoundary); - m_schedulingGraph().addEdge(mapBoundary, mapInternal); - - { - auto inE = m_graph().inEdges(mapFront); - h_cloneIncomingConnections(inE, mapInternal); - h_cloneIncomingConnections(inE, mapBoundary); - } - this->h_io2Dot("D.cloning.front.dot", "B"); - - { - auto outE = m_graph().outEdges(mapFront); - h_cloneOutgoingConnections(outE, mapInternal); - h_cloneOutgoingConnections(outE, mapBoundary); - } - - this->h_io2Dot("E.cloning.front.dot", "B"); - } - for (auto& mapFront : frontNodes) { - m_graph().removeVertex(mapFront); - } - - // Cloning the stencil node - size_t st1_internal = h_cloneKernelNodeNode(StencilNode, Neon::DataView::INTERNAL); - size_t st1_boundary = h_cloneKernelNodeNode(StencilNode, Neon::DataView::BOUNDARY); - m_schedulingGraph().addVertex(st1_internal); - m_schedulingGraph().addVertex(st1_boundary); - m_schedulingGraph().addEdge(st1_internal, st1_boundary); - - this->h_io2Dot("B.dot", "B"); - - { - auto inE = m_graph().inEdges(StencilNode); - h_cloneIncomingConnections(inE, st1_internal); - h_cloneIncomingConnections(inE, st1_boundary); - } - { - auto outE = m_graph().outEdges(StencilNode); - h_cloneOutgoingConnections(outE, st1_internal); - h_cloneOutgoingConnections(outE, st1_boundary); - } - - for (auto& backNodeIternal : backNodesInternal) { - m_schedulingGraph().addVertex(backNodeIternal); - m_schedulingGraph().addVertex(st1_boundary); - m_schedulingGraph().addEdge(backNodeIternal, st1_boundary); - } - this->h_io2Dot("C.dot", "B"); - - m_graph().removeVertex(StencilNode); - - - for (const auto& node : backNodesBoundary) { - m_graph().removeEdge(st1_internal, node); - } - for (const auto& node : backNodesInternal) { - m_graph().removeEdge(st1_boundary, node); - } - { // the stencil arc from map_internal and stencil{internal/boundary} mast be set to map - for (auto& st1Target : {st1_internal, st1_boundary}) { - for (auto& mapInternal : frontMapInternal) { - auto& edge = m_graph().getEdgeProperty({mapInternal, st1Target}); - auto& infos = edge.infoMutable(); - for (auto& info : infos) { - info.flag_discardStencilDep = true; - } - } - } - } - - - this->h_io2Dot("HHH.dot", "B"); - }; - - //////////////////////////////////////////////////////////////////////////// - auto node2Level = h_getBFSIndexes(); - for (auto&& stencilNode : targetStencilNodes) { - int stencilNodeLevel = node2Level[stencilNode]; - std::set frontToClone; - std::set backToClone; - - auto inNodes = m_graph().inNeighbors(stencilNode); - for (const auto& inNode : inNodes) { - if (node2Level[inNode] == stencilNodeLevel - 1) { - frontToClone.insert(inNode); - } - } - - auto outNodes = m_graph().outNeighbors(stencilNode); - for (const auto& outNode : outNodes) { - if (outNode != m_finalNodeId()) { - backToClone.insert(outNode); - } - } - h_cloningProcess(frontToClone, stencilNode, backToClone); - } -} - -/** - * Breadth First Traversal - * @param f - * @return - */ -auto MultiGpuGraph::h_BFT(std::function& nodes)> f) - -> void -{ - std::set visited; - std::vector> levels; - levels.push_back(std::set()); - - size_t level = 0; - levels[level].insert(m_rootNodeId()); - - auto h_recordNewNode = [&](size_t node, size_t nodeLevel) -> bool { - if (!visited.insert(node).second) { - return false; - } - levels.at(nodeLevel).insert(node); - return true; - }; - - while (level < levels.size() && levels[level].size() > 0) { - levels.push_back(std::set()); - for (const auto& n : levels[level]) { - auto nghSet = m_graph().neighbors(n); - for (const auto& ngh : nghSet) { - h_recordNewNode(ngh, level + 1); - } - } - level++; - } - - // Reset level for visiting - level = 0; - while (level < levels.size() && levels[level].size() > 0) { - f(int(level), levels[level]); - level++; - } - return; -} - -auto MultiGpuGraph::h_getBFSIndexes() -> std::unordered_map -{ - std::unordered_map map; - - h_BFT([&](int level, - const std::set& nodes) { - for (const auto& n : nodes) { - map[n] = level; - } - }); - - return map; + NEON_DEV_UNDER_CONSTRUCTION(""); + + // + // // Detects all stencil nodes + // std::vector potentialStencilNodes; + // m_graph().forEachVertex([&](size_t nodeId) { + // const auto& node = m_graph().getVertexProperty(nodeId); + // if (node.getCompute() == Neon::Compute::STENCIL) { + // if (node.getDataView() == Neon::DataView::STANDARD) { + // potentialStencilNodes.push_back(nodeId); + // } + // } + // }); + // std::vector targetStencilNodes; + // + // for (auto& potentialStencilNode : potentialStencilNodes) { + // bool attachedToRoot = false; + // bool attachedToFinal = false; + // bool proceedByMap = false; + // bool followedByMapOrDot = false; + // + // m_graph().forEachInEdge(potentialStencilNode, [&](const std::pair& edge) { + // if (edge.first == m_rootNodeId()) { + // attachedToRoot = true; + // } + // // only MAP front kernels can be splitted + // if (m_graph().getVertexProperty(edge.first).isMap()) { + // proceedByMap = true; + // } + // }); + // m_graph().forEachOutEdge(potentialStencilNode, [&](const std::pair& edge) { + // if (edge.second == m_finalNodeId()) { + // attachedToFinal = true; + // } + // + // // only MAP or DOT (-> not STENCIL) back kernels can be splitted + // if (!m_graph().getVertexProperty(edge.second).isStencil()) { + // followedByMapOrDot = true; + // } + // }); + // if (!attachedToRoot && !attachedToFinal && proceedByMap && followedByMapOrDot) { + // targetStencilNodes.push_back(potentialStencilNode); + // } + // } + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneKernelNodeNode = [&](size_t node, const Neon::DataView& dataView) -> size_t { + // const auto& toBeCloned = m_graph().getVertexProperty(node); + // auto clone = toBeCloned.clone(); + // clone.setDataView(dataView); + // m_graph().addVertex(clone.nodeId(), clone); + // return clone.nodeId(); + // }; + // + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneOutgoingConnections = [&](std::set> outEdges, size_t clone) -> void { + // std::for_each(outEdges.begin(), outEdges.end(), + // [&](const DiGraph::Edge& edge) { + // auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); + // m_graph().addEdge(clone, edge.second, clonedEdge); + // }); + // }; + // + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloneIncomingConnections = [&](std::set> inEdges, size_t clone) -> void { + // std::for_each(inEdges.begin(), inEdges.end(), + // [&](const DiGraph::Edge& edge) { + // auto clonedEdge = m_graph().getEdgeProperty(edge).clone(); + // m_graph().addEdge(edge.first, clone, clonedEdge); + // }); + // }; + // + // // HELPER ////////////////////////////////////////////////////////////////////////// + // auto h_cloningProcess = [&](const std::set& frontNodes, + // size_t StencilNode, + // const std::set& backNodes) -> void { + // std::set backNodesInternal; + // std::set backNodesBoundary; + // std::set frontMapInternal; + // + // /** + // * st1: stencil node + // * mt0s: set of map nodes at the previous level + // * + // * st1 stencil t1 + // * mto are map at t0 + // */ + // this->h_io2Dot("A.dot", "A"); + // + // // Cloning from the back toward the front + // for (auto& mapBack : backNodes) { + // // cloning map node into boundary and internal + // size_t mapInternal = h_cloneKernelNodeNode(mapBack, Neon::DataView::INTERNAL); + // size_t mapBoundary = h_cloneKernelNodeNode(mapBack, Neon::DataView::BOUNDARY); + // + // backNodesInternal.insert(mapInternal); + // backNodesBoundary.insert(mapBoundary); + // + // m_schedulingGraph().addVertex(mapInternal); + // m_schedulingGraph().addVertex(mapBoundary); + // + // const auto& metaNode = m_graph().getVertexProperty(mapBack); + // if (metaNode.isReduce()) { + // m_graph().addEdge(mapInternal, mapBoundary); + // } else { + // m_schedulingGraph().addEdge(mapInternal, mapBoundary); + // } + // + // + // { + // auto inE = m_graph().inEdges(mapBack); + // h_cloneIncomingConnections(inE, mapInternal); + // h_cloneIncomingConnections(inE, mapBoundary); + // } + // this->h_io2Dot("D.cloning.back.dot", "B"); + // + // { + // auto outE = m_graph().outEdges(mapBack); + // h_cloneOutgoingConnections(outE, mapInternal); + // h_cloneOutgoingConnections(outE, mapBoundary); + // } + // + // this->h_io2Dot("E.cloning.back.dot", "B"); + // } + // + // for (auto& mapBack : backNodes) { + // m_graph().removeVertex(mapBack); + // } + // + // + // for (auto& mapFront : frontNodes) { + // // cloning map node into boundary and internal + // size_t mapBoundary = h_cloneKernelNodeNode(mapFront, Neon::DataView::BOUNDARY); + // size_t mapInternal = h_cloneKernelNodeNode(mapFront, Neon::DataView::INTERNAL); + // + // frontMapInternal.insert(mapInternal); + // + // m_schedulingGraph().addVertex(mapInternal); + // m_schedulingGraph().addVertex(mapBoundary); + // m_schedulingGraph().addEdge(mapBoundary, mapInternal); + // + // { + // auto inE = m_graph().inEdges(mapFront); + // h_cloneIncomingConnections(inE, mapInternal); + // h_cloneIncomingConnections(inE, mapBoundary); + // } + // this->h_io2Dot("D.cloning.front.dot", "B"); + // + // { + // auto outE = m_graph().outEdges(mapFront); + // h_cloneOutgoingConnections(outE, mapInternal); + // h_cloneOutgoingConnections(outE, mapBoundary); + // } + // + // this->h_io2Dot("E.cloning.front.dot", "B"); + // } + // for (auto& mapFront : frontNodes) { + // m_graph().removeVertex(mapFront); + // } + // + // // Cloning the stencil node + // size_t st1_internal = h_cloneKernelNodeNode(StencilNode, Neon::DataView::INTERNAL); + // size_t st1_boundary = h_cloneKernelNodeNode(StencilNode, Neon::DataView::BOUNDARY); + // m_schedulingGraph().addVertex(st1_internal); + // m_schedulingGraph().addVertex(st1_boundary); + // m_schedulingGraph().addEdge(st1_internal, st1_boundary); + // + // this->h_io2Dot("B.dot", "B"); + // + // { + // auto inE = m_graph().inEdges(StencilNode); + // h_cloneIncomingConnections(inE, st1_internal); + // h_cloneIncomingConnections(inE, st1_boundary); + // } + // { + // auto outE = m_graph().outEdges(StencilNode); + // h_cloneOutgoingConnections(outE, st1_internal); + // h_cloneOutgoingConnections(outE, st1_boundary); + // } + // + // for (auto& backNodeIternal : backNodesInternal) { + // m_schedulingGraph().addVertex(backNodeIternal); + // m_schedulingGraph().addVertex(st1_boundary); + // m_schedulingGraph().addEdge(backNodeIternal, st1_boundary); + // } + // this->h_io2Dot("C.dot", "B"); + // + // m_graph().removeVertex(StencilNode); + // + // + // for (const auto& node : backNodesBoundary) { + // m_graph().removeEdge(st1_internal, node); + // } + // for (const auto& node : backNodesInternal) { + // m_graph().removeEdge(st1_boundary, node); + // } + // { // the stencil arc from map_internal and stencil{internal/boundary} mast be set to map + // for (auto& st1Target : {st1_internal, st1_boundary}) { + // for (auto& mapInternal : frontMapInternal) { + // auto& edge = m_graph().getEdgeProperty({mapInternal, st1Target}); + // auto& infos = edge.infoMutable(); + // for (auto& info : infos) { + // info.flag_discardStencilDep = true; + // } + // } + // } + // } + // + // + // this->h_io2Dot("HHH.dot", "B"); + // }; + // + // //////////////////////////////////////////////////////////////////////////// + // auto node2Level = h_getBFSIndexes(); + // for (auto&& stencilNode : targetStencilNodes) { + // int stencilNodeLevel = node2Level[stencilNode]; + // std::set frontToClone; + // std::set backToClone; + // + // auto inNodes = m_graph().inNeighbors(stencilNode); + // for (const auto& inNode : inNodes) { + // if (node2Level[inNode] == stencilNodeLevel - 1) { + // frontToClone.insert(inNode); + // } + // } + // + // auto outNodes = m_graph().outNeighbors(stencilNode); + // for (const auto& outNode : outNodes) { + // if (outNode != m_finalNodeId()) { + // backToClone.insert(outNode); + // } + // } + // h_cloningProcess(frontToClone, stencilNode, backToClone); + // } } -auto MultiGpuGraph::getDiGraph() -> DiGraph& -{ - return m_graph(); -} -auto MultiGpuGraph::getSchedulingDiGraph() -> DiGraphScheduling& -{ - return m_schedulingGraph(); -} -// auto fuseMaps(const Neon::skeleton::Options_t& options) -> void -// { -// // BFS visit -// std::vector frontiar; -// m_graph().forEachOutEdge(m_rootNodeId, [&](const std::pair& edge) { -// frontiar.push_back(edge.second); -// }); -// -// size_t frontiarParserIdx = 0; -// -// /** -// * Return -1 if there are no condition for a fusion -// * Otherwise, it returns the node to fuse with -// */ -// auto h_conditionForFusion = [&](const size_t n0) -> int64_t { -// if (m_graph().outEdgesCount(n0) != 1) { -// return -1; -// } -// const size_t n1 = m_graph().outEdges(n0).begin()->second; -// if (m_graph().inEdgesCount(n1) != 1) { -// return -1; -// } -// if(m_graph().getVertexProperty(n1).isStencil()){ -// return -1; -// } -// return n1; -// }; -// -// auto h_fuse= [&](const size_t n0, const size_t n1){ -// //1. create a fused kernel container -// }; -// -// while (frontiarParserIdx < frontiar.size()) { -// size_t nodeId = frontiar[frontiarParserIdx]; -// if (m_graph().outEdges(nodeId).size() == 1 &&) { -// // a. Fuse -// -// // b. update nodeId to the new node -// } -// // c. continue with BFS -// } -// } -auto MultiGpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options& options) -> void +auto MultiGpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> void { - if (m_setCardinality() == 1) { - return; - } - - // Detects all stencil nodes - std::vector stencilNodes; - m_graph().forEachVertex([&](size_t nodeId) { - const auto& node = m_graph().getVertexProperty(nodeId); - if (node.getCompute() == Neon::Compute::STENCIL) { - if (node.getDataView() != Neon::DataView::INTERNAL) { - stencilNodes.push_back(nodeId); - } - } - }); - for (auto&& stencilNode : stencilNodes) { - - const auto inEdges = m_graph().inEdges(stencilNode); - int detectedStencilEdges = 0; - [[maybe_unused]] auto& nodeInfo = m_graph().getVertexProperty(stencilNode); - - - // m_graph().forEachInEdge(stencilNode, - // We are using a copy of the inEdges, - // so we can modify the graph without any issue - std::for_each(inEdges.begin(), inEdges.end(), - [&](const DiGraph::Edge& edge) { - bool visited = false; - auto& edgeP = m_graph().getEdgeProperty(edge); - auto& targetProperty = edgeP.infoMutable(); - - // remove_if only move elements at the end of the vector - auto end = std::remove_if(targetProperty.begin(), - targetProperty.end(), - [&](Edge::Info& info) -> bool { - if (info.token.compute() == Neon::Compute::STENCIL && !info.flag_discardStencilDep) { - visited = true; - detectedStencilEdges++; - h_add_hUpdateSyncNodes(edge.first, - edge.second, - info, - options.transferMode()); - - return true; - } else { - visited = true; - return false; - } - }); - - targetProperty.erase(end, targetProperty.end()); - if (detectedStencilEdges > 0 && m_graph().getEdgeProperty(edge).nDependencies() == 0) { - m_graph().removeEdge(edge); - } - }); - - if (detectedStencilEdges != 1) { - NEON_THROW_UNSUPPORTED_OPTION("Only one stencil in field is supported for now"); - } - } + NEON_DEV_UNDER_CONSTRUCTION(""); + // if (m_setCardinality() == 1) { + // return; + // } + // + // // Detects all stencil nodes + // std::vector stencilNodes; + // m_graph().forEachVertex([&](size_t nodeId) { + // const auto& node = m_graph().getVertexProperty(nodeId); + // if (node.getCompute() == Neon::Compute::STENCIL) { + // if (node.getDataView() != Neon::DataView::INTERNAL) { + // stencilNodes.push_back(nodeId); + // } + // } + // }); + // for (auto&& stencilNode : stencilNodes) { + // + // const auto inEdges = m_graph().inEdges(stencilNode); + // int detectedStencilEdges = 0; + // [[maybe_unused]] auto& nodeInfo = m_graph().getVertexProperty(stencilNode); + // + // + // // m_graph().forEachInEdge(stencilNode, + // // We are using a copy of the inEdges, + // // so we can modify the graph without any issue + // std::for_each(inEdges.begin(), inEdges.end(), + // [&](const DiGraph::Edge& edge) { + // bool visited = false; + // auto& edgeP = m_graph().getEdgeProperty(edge); + // auto& targetProperty = edgeP.infoMutable(); + // + // // remove_if only move elements at the end of the vector + // auto end = std::remove_if(targetProperty.begin(), + // targetProperty.end(), + // [&](Edge::Info& info) -> bool { + // if (info.token.compute() == Neon::Compute::STENCIL && !info.flag_discardStencilDep) { + // visited = true; + // detectedStencilEdges++; + // h_add_hUpdateSyncNodes(edge.first, + // edge.second, + // info, + // options.transferMode()); + // + // return true; + // } else { + // visited = true; + // return false; + // } + // }); + // + // targetProperty.erase(end, targetProperty.end()); + // if (detectedStencilEdges > 0 && m_graph().getEdgeProperty(edge).nDependencies() == 0) { + // m_graph().removeEdge(edge); + // } + // }); + // + // if (detectedStencilEdges != 1) { + // NEON_THROW_UNSUPPORTED_OPTION("Only one stencil in field is supported for now"); + // } + // } } auto MultiGpuGraph::checkCoherency() -> void { - // Detects all stencil nodes - std::vector stencilNodes; - m_graph().forEachVertex([&](size_t nodeId) { - const auto& node = m_graph().getVertexProperty(nodeId); - if (node.getCompute() == Neon::Compute::STENCIL) { - if (m_setCardinality() == 1) { - m_graph().getVertexProperty(nodeId).setAsCoherent(); - return; - } - - if (node.getDataView() == Neon::DataView::INTERNAL) { - m_graph().getVertexProperty(nodeId).setAsCoherent(); - } else { - stencilNodes.push_back(nodeId); - } - } - }); - for (auto&& stencilNode : stencilNodes) { - bool isMemoryCoherent = true; - m_graph().forEachInEdge(stencilNode, [&](const DiGraph::Edge& edge) -> void { - const auto& e = m_graph().getEdgeProperty(edge); - for (const auto& i : e.info()) { - if (i.isStencil() && !i.isHu()) { - isMemoryCoherent = false; - } - } - }); - if (isMemoryCoherent) { - m_graph().getVertexProperty(stencilNode).setAsCoherent(); - } - } -} - -auto MultiGpuGraph::resetLinearContinuousIndexing() -> void -{ - m_storage->m_resetLinearContinuousIndexingCounter = 0; - m_graph().forEachVertex([&](size_t nodeId) { - auto& node = m_graph().getVertexProperty(nodeId); - node.setLinearContinuousIndex(m_storage->m_resetLinearContinuousIndexingCounter); - m_storage->m_resetLinearContinuousIndexingCounter++; - }); -} - -auto MultiGpuGraph::getLinearContinuousIndexingCounter() -> size_t -{ - return m_storage->m_resetLinearContinuousIndexingCounter; + // // Detects all stencil nodes + // std::vector stencilNodes; + // m_graph().forEachVertex([&](size_t nodeId) { + // const auto& node = m_graph().getVertexProperty(nodeId); + // if (node.getCompute() == Neon::Compute::STENCIL) { + // if (m_setCardinality() == 1) { + // m_graph().getVertexProperty(nodeId).setAsCoherent(); + // return; + // } + // + // if (node.getDataView() == Neon::DataView::INTERNAL) { + // m_graph().getVertexProperty(nodeId).setAsCoherent(); + // } else { + // stencilNodes.push_back(nodeId); + // } + // } + // }); + // for (auto&& stencilNode : stencilNodes) { + // bool isMemoryCoherent = true; + // m_graph().forEachInEdge(stencilNode, [&](const DiGraph::Edge& edge) -> void { + // const auto& e = m_graph().getEdgeProperty(edge); + // for (const auto& i : e.info()) { + // if (i.isStencil() && !i.isHu()) { + // isMemoryCoherent = false; + // } + // } + // }); + // if (isMemoryCoherent) { + // m_graph().getVertexProperty(stencilNode).setAsCoherent(); + // } + // } } -/** - * Access methods to members - * @return - */ -auto MultiGpuGraph::rootNodeId() const -> const size_t& -{ - return m_rootNodeId(); -} - -/** - * Access methods to members - * @return - */ -auto MultiGpuGraph::finalNodeId() const -> const size_t& -{ - return m_finalNodeId(); -} MultiGpuGraph::MultiGpuGraph() { m_storage = std::make_shared(); diff --git a/libNeonSys/src/sys/memory/CpuMem.cpp b/libNeonSys/src/sys/memory/CpuMem.cpp index 36745e6d..014b7a40 100644 --- a/libNeonSys/src/sys/memory/CpuMem.cpp +++ b/libNeonSys/src/sys/memory/CpuMem.cpp @@ -112,7 +112,7 @@ void* CpuMem::allocateMem(const Neon::Allocator& allocType, size_t size) } default: { Neon::NeonException exp("CpuMem_t"); - exp << "Unsupported->memory.allocation m_type " << allocType << " for device " << m_cpuDev->getIdx(); + exp << "Unsupported->memory.allocation mType " << allocType << " for device " << m_cpuDev->getIdx(); NEON_THROW(exp); } } @@ -145,7 +145,7 @@ void CpuMem::releaseMem(const Neon::Allocator& allocType, size_t size, void* mem } default: { Neon::NeonException exp("CpuMem_t"); - exp << "Unsupported memory de-allocation m_type " << allocType << " for device " << m_cpuDev->getIdx(); + exp << "Unsupported memory de-allocation mType " << allocType << " for device " << m_cpuDev->getIdx(); NEON_THROW(exp); } } diff --git a/libNeonSys/src/sys/memory/GpuMem.cpp b/libNeonSys/src/sys/memory/GpuMem.cpp index eed4de91..c4d6ad18 100644 --- a/libNeonSys/src/sys/memory/GpuMem.cpp +++ b/libNeonSys/src/sys/memory/GpuMem.cpp @@ -52,7 +52,7 @@ void* GpuMem::allocateMem(const Neon::Allocator& allocType, size_t size) default: { Neon::NeonException exp("GpuMem_t"); - exp << "Unsupported memory allocation m_type " << AllocatorUtils::toString(allocType) << " for device " << m_gpuDev->getIdx(); + exp << "Unsupported memory allocation mType " << AllocatorUtils::toString(allocType) << " for device " << m_gpuDev->getIdx(); NEON_THROW(exp); } } @@ -71,7 +71,7 @@ void GpuMem::releaseMem(const Neon::Allocator& allocType, size_t size, void* mem default: { Neon::NeonException exp("GpuMem_t"); - exp << "Unsupported memory de-allocation m_type " << allocType << " for device " << m_gpuDev->getIdx(); + exp << "Unsupported memory de-allocation mType " << allocType << " for device " << m_gpuDev->getIdx(); NEON_THROW(exp); } } From b9c587bc08b1b1ada23a89483702cc752a609e2a Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Mon, 12 Sep 2022 13:36:29 -0400 Subject: [PATCH 33/67] New container graph completed, including unit tests. --- .../include/Neon/domain/tools/TestData.h | 3 +- libNeonSet/include/Neon/set/container/Graph.h | 59 ++++++++++--- .../Neon/set/container/GraphContainer.h | 4 +- .../Neon/set/container/graph/GraphData.h | 4 +- libNeonSet/src/set/container/Graph.cpp | 86 ++++++++++++------- .../src/set/container/GraphContainer.cpp | 11 +-- .../src/setUt_containerGraph_NestedGraphs.cpp | 57 +++--------- .../setUt_containerGraph_ThreePipedMaps.cpp | 43 +++++----- 8 files changed, 149 insertions(+), 118 deletions(-) diff --git a/libNeonDomain/include/Neon/domain/tools/TestData.h b/libNeonDomain/include/Neon/domain/tools/TestData.h index f2d1a534..54fff3bc 100644 --- a/libNeonDomain/include/Neon/domain/tools/TestData.h +++ b/libNeonDomain/include/Neon/domain/tools/TestData.h @@ -342,7 +342,8 @@ auto TestData::laplace(IODomain& A, NEON_IO IODomain& B) } template -auto TestData::compare(FieldNames name, T tollerance) -> bool +auto TestData::compare(FieldNames name, + [[maybe_unused]] T tollerance) -> bool { bool isTheSame = false; if constexpr (std::is_integral_v) { diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 71956308..5403fd02 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -9,6 +9,14 @@ namespace Neon::set::container { +/** + * Abstraction for a graph of containers. + * Each graph node represents a Neon container, + * directed edges of the graph are dependencies between the containers. + * Dependencies my be data driven or user provided. + * + * + */ struct Graph { using Uid = GraphData::Uid; @@ -98,15 +106,24 @@ struct Graph auto getSubsequentGraphNodes(const GraphNode& graphNode, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) -> std::vector; + /** + * Set the stream to run the graph. + * We provide a preset function so that some initialization + * could be only once, before executing the run method. + */ auto runtimePreSet(int anchorStream) -> void; + /** - * Execute the scheduling operation associated to the node + * Execute the graph on all devices */ auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void; + /** + * Run the graph on a target device. + */ auto run(Neon::SetIdx setIdx, int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) @@ -116,21 +133,34 @@ struct Graph const std::string& graphName, bool debug) -> void; + /** + * Returns a reference for the used backend. + */ auto getBackend() const -> const Neon::Backend&; + /** + * Recursively iterate through the graph nodes + * to expand any graph type of node. + */ auto expandSubGraphs() -> void; + auto getNumberOfNodes() + ->int; + protected: /** * Invalidate all scheduling information that were computed */ auto helpInvalidateScheduling() -> void; + /** + * Helper - it checks the initialization of the backend. + */ auto helpCheckBackendStatus() -> void; /** - * Remove redundant dependencies + * Helper - it removes redundant dependencies */ auto helpRemoveRedundantDependencies() -> void; @@ -205,41 +235,44 @@ struct Graph -> void; /** - * Execute + * Helper - it executes the graph on all devices */ auto helpExecute(int anchorStream) -> void; + /** + * Helper - it executes the graph on a target device + */ auto helpExecute(Neon::SetIdx setIdx, int anchorStream) -> void; /** - * Resetting node's data related to scheduling + * Helper - It resets node scheduling data */ auto helpComputeScheduling_00_resetData() -> void; /** - * Resetting node's data related to scheduling + * Helper - it generates a BFS visit structure for the graph */ auto helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) -> Bfs; /** - * Maps node to streams. + * Helper - it maps node to streams. * Returns the max stream Id used by the scheduling */ auto helpComputeScheduling_02_mappingStreams(Bfs& bfs, bool filterOutAnchors, int anchorStream) -> int; /** - * Define events to be waited and fired from each node + * Helper - it defines events to be waited and fired from each node * Returns the max event Id used by the scheduling. */ auto helpComputeScheduling_03_events(Bfs& bfs) -> int; /** - * Booking the required resources from the backend. + * Helper - it Books the required resources from the backend. */ auto helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) -> void; @@ -247,13 +280,13 @@ struct Graph using RawGraph = DiGraph; - Uid mUidCounter; - RawGraph mRawGraph; + Uid mUidCounter /**< internal counter to create node uids */; + RawGraph mRawGraph /**< raw graph structure */; bool mSchedulingStatusIsValid; - int mMaxNumberStreams; - Bfs mBfs; + int mMaxNumberStreams /**< Max number of streams used in the scheduling phase */; + Bfs mBfs /**< Structure for the BFS visit. */; - Backend mBackend; + Backend mBackend /**< Backend used to create streams and events */; bool mBackendIsSet = false; bool mFilterOutAnchorsPreSet = false; diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index b53b2628..3630ce1a 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -40,7 +40,9 @@ struct GraphContainer : ContainerAPI * @param streamIdx * @param dataView */ - auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + auto run(int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void override; auto run(Neon::SetIdx setIdx, int streamIdx = 0, diff --git a/libNeonSet/include/Neon/set/container/graph/GraphData.h b/libNeonSet/include/Neon/set/container/graph/GraphData.h index 65d7ac0b..9c21db5a 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphData.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphData.h @@ -8,8 +8,8 @@ namespace Neon::set::container { class GraphData { public: - using Uid = uint32_t; - using Index = uint32_t; + using Uid = uint64_t; + using Index = uint64_t; constexpr static Uid notSet = 0; constexpr static Uid beginUid = 1; diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 027ec2bb..1cda2945 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -112,7 +112,7 @@ auto Graph::removeNode(GraphNode& gn) -> Container } mRawGraph.removeVertex(uidB); - gn.getGraphData().setUid(-1); + gn.getGraphData().setUid(GraphData::notSet); return gn.getContainer(); } @@ -156,7 +156,7 @@ auto Graph::removeNodeAndItsDependencies(GraphNode& gn) } mRawGraph.removeVertex(uidB); - gn.getGraphData().setUid(-1); + gn.getGraphData().setUid(GraphData::notSet); return gn.getContainer(); } @@ -192,7 +192,8 @@ auto Graph::getProceedingGraphNodes(const GraphNode& grap } auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, - const std::vector& dependencyTypes) -> std::vector + const std::vector& dependencyTypes) + -> std::vector { std::vector nodes; @@ -255,20 +256,23 @@ auto Graph::getDependencyType(const GraphNode& nodeA, return dependencyType; } -auto Graph::helpInvalidateScheduling() -> void +auto Graph::helpInvalidateScheduling() + -> void { mSchedulingStatusIsValid = false; } -auto Graph::helpRemoveRedundantDependencies() -> void +auto Graph::helpRemoveRedundantDependencies() + -> void { // Vectors of edges to be removed std::vector> edgesToBeRemoved; - mRawGraph.forEachVertex([&](size_t visitingNode) { + mRawGraph.forEachVertex([&](size_t diGraphNodeId) { // In this body we are looping over all nodes // For each node do: // Check node's children + auto visitingNode = mRawGraph.getVertexProperty(diGraphNodeId).getGraphData().getUid(); const auto& children = helpGetOutNeighbors(visitingNode, false); if (children.size() <= 1) { // If no more than one, move to the next node @@ -330,7 +334,8 @@ auto Graph::helpRemoveRedundantDependencies() -> void auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, bool filteredOut, - const std::vector& dependencyTypes) -> std::set + const std::vector& dependencyTypes) + -> std::set { std::set outNgh; mRawGraph.forEachOutEdge( @@ -350,7 +355,10 @@ auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, return outNgh; } -auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, bool filterOutBegin, const std::vector& dependencyTypes) -> std::set +auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, + bool filterOutBegin, + const std::vector& dependencyTypes) + -> std::set { std::set inNgh; mRawGraph.forEachInEdge( @@ -371,7 +379,8 @@ auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, bool filterOutBegin, cons auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, bool filterOutEnd, - const std::vector& dependencyTypes) -> std::set> + const std::vector& dependencyTypes) + -> std::set> { std::set> outEdges; mRawGraph.forEachOutEdge( @@ -392,7 +401,8 @@ auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, auto Graph::helpGetInEdges(GraphData::Uid nodeUid, bool filterOutBegin, - const std::vector& dependencyTypes) -> std::set> + const std::vector& dependencyTypes) + -> std::set> { std::set> inEdges; mRawGraph.forEachInEdge( @@ -471,7 +481,8 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd return bfs; } -auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> void +auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) + -> void { helpComputeScheduling_00_resetData(); mBfs = helpComputeScheduling_01_generatingBFS(filterOutAnchors); @@ -480,7 +491,8 @@ auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> vo helpComputeScheduling_04_ensureResources(maxStreamId, maxEventId); } -auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) -> Bfs +auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) + -> Bfs { return helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); @@ -610,7 +622,8 @@ auto Graph::helpComputeScheduling_02_mappingStreams(Bfs& bfs, return mMaxNumberStreams - 1; } -auto Graph::helpComputeScheduling_03_events(Bfs& bfs) -> int +auto Graph::helpComputeScheduling_03_events(Bfs& bfs) + -> int { int eventCount = 0; @@ -648,7 +661,8 @@ auto Graph::helpComputeScheduling_03_events(Bfs& bfs) -> int return eventCount - 1; } -auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) +auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, + int maxEventId) -> void { auto bk = getBackend(); @@ -707,7 +721,8 @@ Graph::Graph(const Backend& bk) helpInvalidateScheduling(); } -auto Graph::getBackend() const -> const Neon::Backend& +auto Graph::getBackend() const + -> const Neon::Backend& { if (mBackendIsSet) { return mBackend; @@ -717,12 +732,17 @@ auto Graph::getBackend() const -> const Neon::Backend& NEON_THROW(ex); } -auto Graph::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, - Neon::DataView /*dataView*/) +auto Graph::run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void { - NEON_THROW_UNSUPPORTED_OPERATION(""); + if (dataView != Neon::DataView::STANDARD) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + + this->runtimePreSet(streamIdx); + this->helpExecute(setIdx, streamIdx); } auto Graph::run(int streamIdx, @@ -732,12 +752,14 @@ auto Graph::run(int streamIdx, if (dataView != Neon::DataView::STANDARD) { NEON_THROW_UNSUPPORTED_OPERATION(""); } + this->runtimePreSet(streamIdx); this->helpExecute(streamIdx); } auto Graph::helpExecute(Neon::SetIdx setIdx, - int anchorStream) -> void + int anchorStream) + -> void { if (anchorStream > -1 && (anchorStream != mAnchorStreamPreSet || mFilterOutAnchorsPreSet == true)) { Neon::NeonException ex(""); @@ -815,11 +837,11 @@ auto Graph::expandSubGraphs() -> void if (atLeastOneWasFound) { helpInvalidateScheduling(); this->helpRemoveRedundantDependencies(); - // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); } return; } - // this->ioToDot(std::to_string(i) + "_t_00", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_00", "kllkj", true); auto& newTarget = mRawGraph.getVertexProperty(newTargetId); const auto& subGraph = newTarget.getContainer().getContainerInterface().getGraph(); @@ -833,7 +855,7 @@ auto Graph::expandSubGraphs() -> void fromOldToNew.insert(std::pair(oldNode.getGraphData().getUid(), newNode.getGraphData().getUid())); }); - ///this->ioToDot(std::to_string(i) + "_t_01", "kllkj", true); + /// this->ioToDot(std::to_string(i) + "_t_01", "kllkj", true); // Cloning the subGraph edges into the graph subGraph.mRawGraph.forEachEdge([&](std::pair edge) { @@ -846,7 +868,7 @@ auto Graph::expandSubGraphs() -> void this->addDependency(nodeA, nodeB, oldDep.getType()); }); - //this->ioToDot(std::to_string(i) + "_t_02", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_02", "kllkj", true); { // Removing the cloned begin and end from the subGraph auto oldBeginId = subGraph.getBeginNode().getGraphData().getUid(); @@ -861,25 +883,29 @@ auto Graph::expandSubGraphs() -> void this->removeNode(toBeRemovedBeginNode); this->removeNode(toBeRemovedEndNode); } - // this->ioToDot(std::to_string(i) + "_t_03", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_03", "kllkj", true); { // Removing subGraph and depedencies this->removeNodeAndItsDependencies(newTarget); - std::cout << "removing " << newTarget.getContainer().getName() << std::endl; } - //this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); } - } -auto Graph::helpCheckBackendStatus() -> void +auto Graph::helpCheckBackendStatus() + -> void { - if(!mBackendIsSet){ + if (!mBackendIsSet) { NeonException exception("Container Graph"); exception << "A backend was not registered with the Graph"; NEON_THROW(exception); } } +auto Graph::getNumberOfNodes() -> int +{ + // We remove 2 because of the head and tail holders. + return int(mRawGraph.numVertices() - 2); +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index bd4aa473..e266ccb3 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -66,14 +66,11 @@ auto GraphContainer::run(int streamIdx, mGraph->run(streamIdx, dataView); } -auto GraphContainer::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, - Neon::DataView /*dataView*/) -> void +auto GraphContainer::run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void { - // if (ContainerExecutionType::graph == this->getContainerExecutionType()) { - // mGraph->run(setIdx, streamIdx, dataView); - // } - // NEON_THROW_UNSUPPORTED_OPTION(""); + mGraph->run(setIdx, streamIdx, dataView); } } // namespace Neon::set::internal diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp index 8f2dcaec..19a26bdf 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp @@ -20,6 +20,7 @@ #include "setUt_containerGraph_runHelper.h" #include "Neon/set/container/Graph.h" +#define DEBUG_MODE 0 using namespace Neon::domain::tool::testing; static const std::string testFilePrefix("setUt_containerGraph_nestedGraph"); @@ -32,7 +33,6 @@ void NestedGraphsTest(TestData& data) const std::string appName(testFilePrefix); const Type scalarVal = 2; - const int nIterations = 10; auto fR = data.getGrid().template newPatternScalar(); fR() = scalarVal; @@ -43,21 +43,21 @@ void NestedGraphsTest(TestData& data) { // NEON auto& X = data.getField(FieldNames::X); - auto& Y = data.getField(FieldNames::Y); auto& Z = data.getField(FieldNames::Z); - auto& W = data.getField(FieldNames::W); auto generateInnerGraph = [&](std::string name) -> Neon::set::Container { - Neon::set::container::Graph graph; + Neon::set::container::Graph graph(data.getBackend()); - auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, name+"-StageA")); - auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, name+"-StageC")); - graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, name+"-StageB"), nodeC); + auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, name + "-StageA")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, name + "-StageC")); + graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, name + "-StageB"), nodeC); -// graph.ioToDot(appName, "UserGraph", false); -// graph.ioToDot(appName + "-debug", "UserGraph", true); +#if (DEBUG_MODE == 1) + graph.ioToDot(appName, "UserGraph", false); + graph.ioToDot(appName + "-debug", "UserGraph", true); +#endif auto container = Neon::set::Container::factoryGraph(name, graph, [](Neon::SetIdx, Neon::set::Loader&) {}); return container; @@ -73,14 +73,14 @@ void NestedGraphsTest(TestData& data) graph.addNode(nodeC); { - auto fname = appName + "_withSubGraph"; + auto fname = appName + "_withSubGraph"; graph.runtimePreSet(0); graph.ioToDot(fname, "UserGraph", false); graph.ioToDot(fname + "-debug", "UserGraph", true); } { - auto fname = appName + "_expandSubGraphs"; + auto fname = appName + "_expandSubGraphs"; graph.expandSubGraphs(); graph.runtimePreSet(0); @@ -88,39 +88,8 @@ void NestedGraphsTest(TestData& data) graph.ioToDot(fname + "-debug", "UserGraph", true); } - // timer.start(); - // for (int i = 0; i < nIterations; i++) { - // skl.run(); - // } - // data.getBackend().syncAll(); - // timer.stop(); + ASSERT_EQ(graph.getNumberOfNodes(), 9); } - - { // Golden data - //auto time = timer.time(); - - Type dR = scalarVal; - auto& X = data.getIODomain(FieldNames::X); - auto& Y = data.getIODomain(FieldNames::Y); - - for (int i = 0; i < nIterations; i++) { - data.axpy(&dR, Y, X); - data.laplace(X, Y); - data.axpy(&dR, Y, Y); - } - } - bool isOk = data.compare(FieldNames::X); - isOk = isOk && data.compare(FieldNames::Y); - - /*{ // DEBUG - data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); - data.getField(FieldNames::X).ioToVtk("Field_X", "X"); - - data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); - data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); - }*/ - - ASSERT_TRUE(isOk); } template @@ -152,3 +121,5 @@ TEST(NestedGraphs, eGrid) using Type = int32_t; runOneTestConfiguration("eGrid_t", NestedGraphs, 1, 1); } + +#undef DEBUG_MODE \ No newline at end of file diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp index e4fc7e3c..2459f203 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp @@ -21,6 +21,8 @@ #include "Neon/set/container/Graph.h" +#define DEBUG_MODE 0 + using namespace Neon::domain::tool::testing; static const std::string testFilePrefix("setUt_containerGraph"); @@ -32,7 +34,7 @@ void ThreePippedMapsTest(TestData& data) const std::string appName(testFilePrefix); const Type scalarVal = 2; - const int nIterations = 10; + const int nIterations = 3; auto fR = data.getGrid().template newPatternScalar(); fR() = scalarVal; @@ -47,47 +49,45 @@ void ThreePippedMapsTest(TestData& data) auto& Z = data.getField(FieldNames::Z); auto& W = data.getField(FieldNames::W); - Neon::set::container::Graph graph; + Neon::set::container::Graph graph(data.getBackend()); auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); - auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, "nodeB"), nodeC); graph.ioToDot(appName, "UserGraph", false); graph.ioToDot(appName + "-debug", "UserGraph", true); + graph.runtimePreSet(0); - // timer.start(); - // for (int i = 0; i < nIterations; i++) { - // skl.run(); - // } - // data.getBackend().syncAll(); - // timer.stop(); + for (int i = 0; i < nIterations; i++) { + graph.run(0); + } } { // Golden data - auto time = timer.time(); - Type dR = scalarVal; auto& X = data.getIODomain(FieldNames::X); auto& Y = data.getIODomain(FieldNames::Y); + auto& Z = data.getIODomain(FieldNames::Z); + auto& W = data.getIODomain(FieldNames::W); for (int i = 0; i < nIterations; i++) { - data.axpy(&dR, Y, X); - data.laplace(X, Y); - data.axpy(&dR, Y, Y); + data.axpy(&dR, W, X); + data.axpy(&dR, W, Y); + data.axpy(&dR, W, Z); } } bool isOk = data.compare(FieldNames::X); isOk = isOk && data.compare(FieldNames::Y); - /*{ // DEBUG - data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); - data.getField(FieldNames::X).ioToVtk("Field_X", "X"); +#if (DEBUG_MODE == 1) + data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); + data.getField(FieldNames::X).ioToVtk("Field_X", "X"); - data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); - data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); - }*/ + data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); + data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); +#endif ASSERT_TRUE(isOk); } @@ -117,8 +117,9 @@ int getNGpus() TEST(ThreePippedMaps, eGrid) { - int nGpus = getNGpus(); using Grid = Neon::domain::internal::eGrid::eGrid; using Type = int32_t; runOneTestConfiguration("eGrid_t", ThreePippedMaps, 1, 1); } + +#undef DEBUG_MODE \ No newline at end of file From c3383ab57175e2f45bfab77a6df82bc853557dd6 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Mon, 12 Sep 2022 13:36:29 -0400 Subject: [PATCH 34/67] New container graph completed, including unit tests. --- .../include/Neon/domain/tools/TestData.h | 3 +- libNeonSet/include/Neon/set/container/Graph.h | 59 ++++++++++--- .../Neon/set/container/GraphContainer.h | 4 +- .../Neon/set/container/graph/GraphData.h | 4 +- libNeonSet/src/set/container/Graph.cpp | 88 ++++++++++++------- .../src/set/container/GraphContainer.cpp | 11 +-- .../src/setUt_containerGraph_NestedGraphs.cpp | 57 +++--------- .../setUt_containerGraph_ThreePipedMaps.cpp | 43 ++++----- 8 files changed, 150 insertions(+), 119 deletions(-) diff --git a/libNeonDomain/include/Neon/domain/tools/TestData.h b/libNeonDomain/include/Neon/domain/tools/TestData.h index f2d1a534..54fff3bc 100644 --- a/libNeonDomain/include/Neon/domain/tools/TestData.h +++ b/libNeonDomain/include/Neon/domain/tools/TestData.h @@ -342,7 +342,8 @@ auto TestData::laplace(IODomain& A, NEON_IO IODomain& B) } template -auto TestData::compare(FieldNames name, T tollerance) -> bool +auto TestData::compare(FieldNames name, + [[maybe_unused]] T tollerance) -> bool { bool isTheSame = false; if constexpr (std::is_integral_v) { diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 71956308..5403fd02 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -9,6 +9,14 @@ namespace Neon::set::container { +/** + * Abstraction for a graph of containers. + * Each graph node represents a Neon container, + * directed edges of the graph are dependencies between the containers. + * Dependencies my be data driven or user provided. + * + * + */ struct Graph { using Uid = GraphData::Uid; @@ -98,15 +106,24 @@ struct Graph auto getSubsequentGraphNodes(const GraphNode& graphNode, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) -> std::vector; + /** + * Set the stream to run the graph. + * We provide a preset function so that some initialization + * could be only once, before executing the run method. + */ auto runtimePreSet(int anchorStream) -> void; + /** - * Execute the scheduling operation associated to the node + * Execute the graph on all devices */ auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void; + /** + * Run the graph on a target device. + */ auto run(Neon::SetIdx setIdx, int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) @@ -116,21 +133,34 @@ struct Graph const std::string& graphName, bool debug) -> void; + /** + * Returns a reference for the used backend. + */ auto getBackend() const -> const Neon::Backend&; + /** + * Recursively iterate through the graph nodes + * to expand any graph type of node. + */ auto expandSubGraphs() -> void; + auto getNumberOfNodes() + ->int; + protected: /** * Invalidate all scheduling information that were computed */ auto helpInvalidateScheduling() -> void; + /** + * Helper - it checks the initialization of the backend. + */ auto helpCheckBackendStatus() -> void; /** - * Remove redundant dependencies + * Helper - it removes redundant dependencies */ auto helpRemoveRedundantDependencies() -> void; @@ -205,41 +235,44 @@ struct Graph -> void; /** - * Execute + * Helper - it executes the graph on all devices */ auto helpExecute(int anchorStream) -> void; + /** + * Helper - it executes the graph on a target device + */ auto helpExecute(Neon::SetIdx setIdx, int anchorStream) -> void; /** - * Resetting node's data related to scheduling + * Helper - It resets node scheduling data */ auto helpComputeScheduling_00_resetData() -> void; /** - * Resetting node's data related to scheduling + * Helper - it generates a BFS visit structure for the graph */ auto helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) -> Bfs; /** - * Maps node to streams. + * Helper - it maps node to streams. * Returns the max stream Id used by the scheduling */ auto helpComputeScheduling_02_mappingStreams(Bfs& bfs, bool filterOutAnchors, int anchorStream) -> int; /** - * Define events to be waited and fired from each node + * Helper - it defines events to be waited and fired from each node * Returns the max event Id used by the scheduling. */ auto helpComputeScheduling_03_events(Bfs& bfs) -> int; /** - * Booking the required resources from the backend. + * Helper - it Books the required resources from the backend. */ auto helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) -> void; @@ -247,13 +280,13 @@ struct Graph using RawGraph = DiGraph; - Uid mUidCounter; - RawGraph mRawGraph; + Uid mUidCounter /**< internal counter to create node uids */; + RawGraph mRawGraph /**< raw graph structure */; bool mSchedulingStatusIsValid; - int mMaxNumberStreams; - Bfs mBfs; + int mMaxNumberStreams /**< Max number of streams used in the scheduling phase */; + Bfs mBfs /**< Structure for the BFS visit. */; - Backend mBackend; + Backend mBackend /**< Backend used to create streams and events */; bool mBackendIsSet = false; bool mFilterOutAnchorsPreSet = false; diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index b53b2628..3630ce1a 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -40,7 +40,9 @@ struct GraphContainer : ContainerAPI * @param streamIdx * @param dataView */ - auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + auto run(int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void override; auto run(Neon::SetIdx setIdx, int streamIdx = 0, diff --git a/libNeonSet/include/Neon/set/container/graph/GraphData.h b/libNeonSet/include/Neon/set/container/graph/GraphData.h index 65d7ac0b..9c21db5a 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphData.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphData.h @@ -8,8 +8,8 @@ namespace Neon::set::container { class GraphData { public: - using Uid = uint32_t; - using Index = uint32_t; + using Uid = uint64_t; + using Index = uint64_t; constexpr static Uid notSet = 0; constexpr static Uid beginUid = 1; diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 027ec2bb..d9541cdb 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -112,7 +112,7 @@ auto Graph::removeNode(GraphNode& gn) -> Container } mRawGraph.removeVertex(uidB); - gn.getGraphData().setUid(-1); + gn.getGraphData().setUid(GraphData::notSet); return gn.getContainer(); } @@ -156,7 +156,7 @@ auto Graph::removeNodeAndItsDependencies(GraphNode& gn) } mRawGraph.removeVertex(uidB); - gn.getGraphData().setUid(-1); + gn.getGraphData().setUid(GraphData::notSet); return gn.getContainer(); } @@ -192,7 +192,8 @@ auto Graph::getProceedingGraphNodes(const GraphNode& grap } auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, - const std::vector& dependencyTypes) -> std::vector + const std::vector& dependencyTypes) + -> std::vector { std::vector nodes; @@ -255,20 +256,23 @@ auto Graph::getDependencyType(const GraphNode& nodeA, return dependencyType; } -auto Graph::helpInvalidateScheduling() -> void +auto Graph::helpInvalidateScheduling() + -> void { mSchedulingStatusIsValid = false; } -auto Graph::helpRemoveRedundantDependencies() -> void +auto Graph::helpRemoveRedundantDependencies() + -> void { // Vectors of edges to be removed std::vector> edgesToBeRemoved; - mRawGraph.forEachVertex([&](size_t visitingNode) { + mRawGraph.forEachVertex([&](size_t diGraphNodeId) { // In this body we are looping over all nodes // For each node do: // Check node's children + auto visitingNode = mRawGraph.getVertexProperty(diGraphNodeId).getGraphData().getUid(); const auto& children = helpGetOutNeighbors(visitingNode, false); if (children.size() <= 1) { // If no more than one, move to the next node @@ -330,7 +334,8 @@ auto Graph::helpRemoveRedundantDependencies() -> void auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, bool filteredOut, - const std::vector& dependencyTypes) -> std::set + const std::vector& dependencyTypes) + -> std::set { std::set outNgh; mRawGraph.forEachOutEdge( @@ -350,7 +355,10 @@ auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, return outNgh; } -auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, bool filterOutBegin, const std::vector& dependencyTypes) -> std::set +auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, + bool filterOutBegin, + const std::vector& dependencyTypes) + -> std::set { std::set inNgh; mRawGraph.forEachInEdge( @@ -371,7 +379,8 @@ auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, bool filterOutBegin, cons auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, bool filterOutEnd, - const std::vector& dependencyTypes) -> std::set> + const std::vector& dependencyTypes) + -> std::set> { std::set> outEdges; mRawGraph.forEachOutEdge( @@ -392,7 +401,8 @@ auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, auto Graph::helpGetInEdges(GraphData::Uid nodeUid, bool filterOutBegin, - const std::vector& dependencyTypes) -> std::set> + const std::vector& dependencyTypes) + -> std::set> { std::set> inEdges; mRawGraph.forEachInEdge( @@ -471,7 +481,8 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd return bfs; } -auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> void +auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) + -> void { helpComputeScheduling_00_resetData(); mBfs = helpComputeScheduling_01_generatingBFS(filterOutAnchors); @@ -480,7 +491,8 @@ auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) -> vo helpComputeScheduling_04_ensureResources(maxStreamId, maxEventId); } -auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) -> Bfs +auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) + -> Bfs { return helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); @@ -498,7 +510,7 @@ auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& auto Graph::helpComputeScheduling_00_resetData() -> void { - mRawGraph.forEachVertex([&](const int& graphNodeId) { + mRawGraph.forEachVertex([&](const GraphData::Uid & graphNodeId) { auto& targetNode = mRawGraph.getVertexProperty(graphNodeId); targetNode.getScheduling().reset(); }); @@ -610,7 +622,8 @@ auto Graph::helpComputeScheduling_02_mappingStreams(Bfs& bfs, return mMaxNumberStreams - 1; } -auto Graph::helpComputeScheduling_03_events(Bfs& bfs) -> int +auto Graph::helpComputeScheduling_03_events(Bfs& bfs) + -> int { int eventCount = 0; @@ -648,7 +661,8 @@ auto Graph::helpComputeScheduling_03_events(Bfs& bfs) -> int return eventCount - 1; } -auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) +auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, + int maxEventId) -> void { auto bk = getBackend(); @@ -707,7 +721,8 @@ Graph::Graph(const Backend& bk) helpInvalidateScheduling(); } -auto Graph::getBackend() const -> const Neon::Backend& +auto Graph::getBackend() const + -> const Neon::Backend& { if (mBackendIsSet) { return mBackend; @@ -717,12 +732,17 @@ auto Graph::getBackend() const -> const Neon::Backend& NEON_THROW(ex); } -auto Graph::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, - Neon::DataView /*dataView*/) +auto Graph::run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void { - NEON_THROW_UNSUPPORTED_OPERATION(""); + if (dataView != Neon::DataView::STANDARD) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + + this->runtimePreSet(streamIdx); + this->helpExecute(setIdx, streamIdx); } auto Graph::run(int streamIdx, @@ -732,12 +752,14 @@ auto Graph::run(int streamIdx, if (dataView != Neon::DataView::STANDARD) { NEON_THROW_UNSUPPORTED_OPERATION(""); } + this->runtimePreSet(streamIdx); this->helpExecute(streamIdx); } auto Graph::helpExecute(Neon::SetIdx setIdx, - int anchorStream) -> void + int anchorStream) + -> void { if (anchorStream > -1 && (anchorStream != mAnchorStreamPreSet || mFilterOutAnchorsPreSet == true)) { Neon::NeonException ex(""); @@ -815,11 +837,11 @@ auto Graph::expandSubGraphs() -> void if (atLeastOneWasFound) { helpInvalidateScheduling(); this->helpRemoveRedundantDependencies(); - // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_05", "kllkj", true); } return; } - // this->ioToDot(std::to_string(i) + "_t_00", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_00", "kllkj", true); auto& newTarget = mRawGraph.getVertexProperty(newTargetId); const auto& subGraph = newTarget.getContainer().getContainerInterface().getGraph(); @@ -833,7 +855,7 @@ auto Graph::expandSubGraphs() -> void fromOldToNew.insert(std::pair(oldNode.getGraphData().getUid(), newNode.getGraphData().getUid())); }); - ///this->ioToDot(std::to_string(i) + "_t_01", "kllkj", true); + /// this->ioToDot(std::to_string(i) + "_t_01", "kllkj", true); // Cloning the subGraph edges into the graph subGraph.mRawGraph.forEachEdge([&](std::pair edge) { @@ -846,7 +868,7 @@ auto Graph::expandSubGraphs() -> void this->addDependency(nodeA, nodeB, oldDep.getType()); }); - //this->ioToDot(std::to_string(i) + "_t_02", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_02", "kllkj", true); { // Removing the cloned begin and end from the subGraph auto oldBeginId = subGraph.getBeginNode().getGraphData().getUid(); @@ -861,25 +883,29 @@ auto Graph::expandSubGraphs() -> void this->removeNode(toBeRemovedBeginNode); this->removeNode(toBeRemovedEndNode); } - // this->ioToDot(std::to_string(i) + "_t_03", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_03", "kllkj", true); { // Removing subGraph and depedencies this->removeNodeAndItsDependencies(newTarget); - std::cout << "removing " << newTarget.getContainer().getName() << std::endl; } - //this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); + // this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); } - } -auto Graph::helpCheckBackendStatus() -> void +auto Graph::helpCheckBackendStatus() + -> void { - if(!mBackendIsSet){ + if (!mBackendIsSet) { NeonException exception("Container Graph"); exception << "A backend was not registered with the Graph"; NEON_THROW(exception); } } +auto Graph::getNumberOfNodes() -> int +{ + // We remove 2 because of the head and tail holders. + return int(mRawGraph.numVertices() - 2); +} } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index bd4aa473..e266ccb3 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -66,14 +66,11 @@ auto GraphContainer::run(int streamIdx, mGraph->run(streamIdx, dataView); } -auto GraphContainer::run(Neon::SetIdx /*setIdx*/, - int /*streamIdx*/, - Neon::DataView /*dataView*/) -> void +auto GraphContainer::run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void { - // if (ContainerExecutionType::graph == this->getContainerExecutionType()) { - // mGraph->run(setIdx, streamIdx, dataView); - // } - // NEON_THROW_UNSUPPORTED_OPTION(""); + mGraph->run(setIdx, streamIdx, dataView); } } // namespace Neon::set::internal diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp index 8f2dcaec..19a26bdf 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_NestedGraphs.cpp @@ -20,6 +20,7 @@ #include "setUt_containerGraph_runHelper.h" #include "Neon/set/container/Graph.h" +#define DEBUG_MODE 0 using namespace Neon::domain::tool::testing; static const std::string testFilePrefix("setUt_containerGraph_nestedGraph"); @@ -32,7 +33,6 @@ void NestedGraphsTest(TestData& data) const std::string appName(testFilePrefix); const Type scalarVal = 2; - const int nIterations = 10; auto fR = data.getGrid().template newPatternScalar(); fR() = scalarVal; @@ -43,21 +43,21 @@ void NestedGraphsTest(TestData& data) { // NEON auto& X = data.getField(FieldNames::X); - auto& Y = data.getField(FieldNames::Y); auto& Z = data.getField(FieldNames::Z); - auto& W = data.getField(FieldNames::W); auto generateInnerGraph = [&](std::string name) -> Neon::set::Container { - Neon::set::container::Graph graph; + Neon::set::container::Graph graph(data.getBackend()); - auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, name+"-StageA")); - auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, name+"-StageC")); - graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, name+"-StageB"), nodeC); + auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, name + "-StageA")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, name + "-StageC")); + graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, name + "-StageB"), nodeC); -// graph.ioToDot(appName, "UserGraph", false); -// graph.ioToDot(appName + "-debug", "UserGraph", true); +#if (DEBUG_MODE == 1) + graph.ioToDot(appName, "UserGraph", false); + graph.ioToDot(appName + "-debug", "UserGraph", true); +#endif auto container = Neon::set::Container::factoryGraph(name, graph, [](Neon::SetIdx, Neon::set::Loader&) {}); return container; @@ -73,14 +73,14 @@ void NestedGraphsTest(TestData& data) graph.addNode(nodeC); { - auto fname = appName + "_withSubGraph"; + auto fname = appName + "_withSubGraph"; graph.runtimePreSet(0); graph.ioToDot(fname, "UserGraph", false); graph.ioToDot(fname + "-debug", "UserGraph", true); } { - auto fname = appName + "_expandSubGraphs"; + auto fname = appName + "_expandSubGraphs"; graph.expandSubGraphs(); graph.runtimePreSet(0); @@ -88,39 +88,8 @@ void NestedGraphsTest(TestData& data) graph.ioToDot(fname + "-debug", "UserGraph", true); } - // timer.start(); - // for (int i = 0; i < nIterations; i++) { - // skl.run(); - // } - // data.getBackend().syncAll(); - // timer.stop(); + ASSERT_EQ(graph.getNumberOfNodes(), 9); } - - { // Golden data - //auto time = timer.time(); - - Type dR = scalarVal; - auto& X = data.getIODomain(FieldNames::X); - auto& Y = data.getIODomain(FieldNames::Y); - - for (int i = 0; i < nIterations; i++) { - data.axpy(&dR, Y, X); - data.laplace(X, Y); - data.axpy(&dR, Y, Y); - } - } - bool isOk = data.compare(FieldNames::X); - isOk = isOk && data.compare(FieldNames::Y); - - /*{ // DEBUG - data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); - data.getField(FieldNames::X).ioToVtk("Field_X", "X"); - - data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); - data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); - }*/ - - ASSERT_TRUE(isOk); } template @@ -152,3 +121,5 @@ TEST(NestedGraphs, eGrid) using Type = int32_t; runOneTestConfiguration("eGrid_t", NestedGraphs, 1, 1); } + +#undef DEBUG_MODE \ No newline at end of file diff --git a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp index e4fc7e3c..2459f203 100644 --- a/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp +++ b/libNeonSet/tests/unit/setUt_containerGraph/src/setUt_containerGraph_ThreePipedMaps.cpp @@ -21,6 +21,8 @@ #include "Neon/set/container/Graph.h" +#define DEBUG_MODE 0 + using namespace Neon::domain::tool::testing; static const std::string testFilePrefix("setUt_containerGraph"); @@ -32,7 +34,7 @@ void ThreePippedMapsTest(TestData& data) const std::string appName(testFilePrefix); const Type scalarVal = 2; - const int nIterations = 10; + const int nIterations = 3; auto fR = data.getGrid().template newPatternScalar(); fR() = scalarVal; @@ -47,47 +49,45 @@ void ThreePippedMapsTest(TestData& data) auto& Z = data.getField(FieldNames::Z); auto& W = data.getField(FieldNames::W); - Neon::set::container::Graph graph; + Neon::set::container::Graph graph(data.getBackend()); auto nodeA = graph.addNode(UserTools::axpy(fR, W, X, "nodeA")); - auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); + auto nodeC = graph.addNode(UserTools::axpy(fR, W, Y, "nodeC")); graph.addNodeInBetween(nodeA, UserTools::axpy(fR, W, Z, "nodeB"), nodeC); graph.ioToDot(appName, "UserGraph", false); graph.ioToDot(appName + "-debug", "UserGraph", true); + graph.runtimePreSet(0); - // timer.start(); - // for (int i = 0; i < nIterations; i++) { - // skl.run(); - // } - // data.getBackend().syncAll(); - // timer.stop(); + for (int i = 0; i < nIterations; i++) { + graph.run(0); + } } { // Golden data - auto time = timer.time(); - Type dR = scalarVal; auto& X = data.getIODomain(FieldNames::X); auto& Y = data.getIODomain(FieldNames::Y); + auto& Z = data.getIODomain(FieldNames::Z); + auto& W = data.getIODomain(FieldNames::W); for (int i = 0; i < nIterations; i++) { - data.axpy(&dR, Y, X); - data.laplace(X, Y); - data.axpy(&dR, Y, Y); + data.axpy(&dR, W, X); + data.axpy(&dR, W, Y); + data.axpy(&dR, W, Z); } } bool isOk = data.compare(FieldNames::X); isOk = isOk && data.compare(FieldNames::Y); - /*{ // DEBUG - data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); - data.getField(FieldNames::X).ioToVtk("Field_X", "X"); +#if (DEBUG_MODE == 1) + data.getIODomain(FieldNames::X).ioToVti("IODomain_X", "X"); + data.getField(FieldNames::X).ioToVtk("Field_X", "X"); - data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); - data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); - }*/ + data.getIODomain(FieldNames::Y).ioToVti("IODomain_Y", "Y"); + data.getField(FieldNames::Y).ioToVtk("Field_Y", "Y"); +#endif ASSERT_TRUE(isOk); } @@ -117,8 +117,9 @@ int getNGpus() TEST(ThreePippedMaps, eGrid) { - int nGpus = getNGpus(); using Grid = Neon::domain::internal::eGrid::eGrid; using Type = int32_t; runOneTestConfiguration("eGrid_t", ThreePippedMaps, 1, 1); } + +#undef DEBUG_MODE \ No newline at end of file From 0b3aa250b27076348c4b0a1364b962c1e65a606e Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Sun, 18 Sep 2022 11:32:28 -0400 Subject: [PATCH 35/67] WIP --- libNeonSet/include/Neon/set/container/Graph.h | 21 ++- .../set/container/graph/GraphDependency.h | 16 ++- .../include/Neon/set/dependency/Alias.h | 8 +- libNeonSet/src/set/container/Graph.cpp | 60 +++++--- .../set/container/graph/GraphDependency.cpp | 46 ++++-- .../src/skeleton/internal/multiGpuGraph.cpp | 133 +++++++++--------- 6 files changed, 178 insertions(+), 106 deletions(-) diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 17f4f374..edeecd28 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -79,7 +79,8 @@ struct Graph auto appendDataDependency(const GraphNode& nodeA, const GraphNode& nodeB, Neon::internal::dataDependency::DataDependencyType dataDependencyType, - Neon::internal::dataDependency::DataUId dataUId) -> GraphDependency&; + size_t dataUId, + Compute compute) -> GraphDependency&; /** * Returns the dependency type between two nodes. */ @@ -87,6 +88,12 @@ struct Graph const GraphNode& nodeB) -> GraphDependencyType; + /** + * Returns the dependency information + */ + auto getDependency(const GraphNode& nodeA, + const GraphNode& nodeB) + -> const GraphDependency&; /** * Clone a node and return a reference to the new clone. * The cloning process connects the clone the the same nodes of the original @@ -169,6 +176,18 @@ struct Graph auto getGraphNode(GraphData::Uid) const -> const GraphNode&; + template + auto forEachNode(Fun f) -> void + { + mRawGraph.forEachVertex([&](size_t v) { + GraphData::Uid node = v; + if (node != GraphData::beginUid && node != GraphData::endUid) { + f(node); + } + }); + } + + protected: /** * Invalidate all scheduling information that were computed diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index a949eca0..6d88e784 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -2,6 +2,7 @@ #include "GraphDependencyType.h" #include "Neon/set/dependency/Alias.h" +#include "Neon/set/dependency/ComputeType.h" #include "Neon/set/dependency/DataDependencyType.h" namespace Neon::set::container { @@ -12,6 +13,7 @@ struct GraphDependency public: GraphDependency(); + GraphDependency(GraphDependencyType type); auto setType(GraphDependencyType type) -> void; @@ -19,20 +21,26 @@ struct GraphDependency auto getType() const -> GraphDependencyType; auto appendInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, - Neon::internal::dataDependency::DataUId dataUId) -> void; + Neon::internal::dataDependency::DataUId dataUId, + Neon::Compute compute) -> void; auto toString(std::function(int)> prefix) -> std::string; - private: - GraphDependencyType mType; + auto getListStencilData() const -> std::vector; + auto hasStencilDependency() const -> bool; + + private: struct Info { Neon::internal::dataDependency::DataDependencyType dataDependencyType; Neon::internal::dataDependency::DataUId dataUId; + Neon::Compute compute; }; - std::vector mInfo; + GraphDependencyType mType; + std::vector mInfo; + bool mHasStencilDependency = false; // TODO - add information for data and Scheduling dependency }; diff --git a/libNeonSet/include/Neon/set/dependency/Alias.h b/libNeonSet/include/Neon/set/dependency/Alias.h index 30009520..67b50294 100644 --- a/libNeonSet/include/Neon/set/dependency/Alias.h +++ b/libNeonSet/include/Neon/set/dependency/Alias.h @@ -1,17 +1,17 @@ #pragma once #include "Neon/set/Backend.h" +#include "Neon/set/MultiDeviceObjectUid.h" namespace Neon::internal::dataDependency { /** * Unique identifier for a kernel parameter */ -using DataUId = int64_t; +using DataUId = Neon::set::MultiDeviceObjectUid; /** * Unique identifier for a kernel parameter */ -using DataIdx = int64_t; +using DataIdx = Neon::set::MultiDeviceObjectUid; - -} // namespace Neon::dataDependency +} // namespace Neon::internal::dataDependency diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index f345b983..661c6075 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -79,7 +79,8 @@ auto Graph::addDependency(const GraphNode& nodeA, auto Graph::appendDataDependency(const GraphNode& nodeA, const GraphNode& nodeB, Neon::internal::dataDependency::DataDependencyType dataDependencyType, - Neon::internal::dataDependency::DataUId dataUId) -> GraphDependency& + size_t dataUId, + Compute compute) -> GraphDependency& { helpCheckBackendStatus(); @@ -104,7 +105,7 @@ auto Graph::appendDataDependency(const GraphNode& auto& output = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), nodeB.getGraphData().getUid()}); - output.appendInfo(dataDependencyType, dataUId); + output.appendInfo(dataDependencyType, dataUId, compute); return output; } @@ -279,14 +280,20 @@ auto Graph::cloneNode(const GraphNode& graphNode) auto Graph::getDependencyType(const GraphNode& nodeA, const GraphNode& nodeB) -> GraphDependencyType +{ + auto dependency = getDependency(nodeA, nodeB); + auto dependencyType = dependency.getType(); + return dependencyType; +} + +auto Graph::getDependency(const GraphNode& nodeA, + const GraphNode& nodeB) -> const GraphDependency& { auto uidA = nodeA.getGraphData().getUid(); auto uidB = nodeB.getGraphData().getUid(); - auto edgePropetry = mRawGraph.getEdgeProperty({uidA, uidB}); - auto dependencyType = edgePropetry.getType(); - - return dependencyType; + const auto& dependency = mRawGraph.getEdgeProperty({uidA, uidB}); + return dependency; } auto Graph::helpInvalidateScheduling() @@ -304,37 +311,37 @@ auto Graph::removeRedundantDependencies() // In this body we are looping over all nodes // For each node do: - // Check node's children - auto visitingNode = mRawGraph.getVertexProperty(diGraphNodeId).getGraphData().getUid(); - const auto& children = helpGetOutNeighbors(visitingNode, false); - if (children.size() <= 1) { + // Check node's childrenUid + auto visitingNodeUid = mRawGraph.getVertexProperty(diGraphNodeId).getGraphData().getUid(); + const auto& childrenUid = helpGetOutNeighbors(visitingNodeUid, false); + if (childrenUid.size() <= 1) { // If no more than one, move to the next node // Nothing to do for the visiting node as there are no redundant paths // Let's move to another return; } // Start checking for redundant paths - for (const auto& targetChild : children) { - if (helpGetInEdges(targetChild, false).size() <= 1) { - // This targetChild can only be reached by one father + for (const auto& targetChildUid : childrenUid) { + if (helpGetInEdges(targetChildUid, false).size() <= 1) { + // This targetChildUid can only be reached by one father // No redundant path here continue; } bool foundRedundant = false; // Checking all siblings' paths. - // We are looking for the targetChild in the path of any of its siblings. + // We are looking for the targetChildUid in the path of any of its siblings. // A BFS visit is used for the process. - for (const auto& targetSibling : children) { - if (targetSibling == targetChild) { + for (const auto& targetSiblingUid : childrenUid) { + if (targetSiblingUid == targetChildUid) { continue; } - // first BFS frontier are the targetSibling's child - auto frontier = mRawGraph.outNeighbors(targetSibling); + // first BFS frontier are the targetSiblingUid's child + auto frontier = mRawGraph.outNeighbors(targetSiblingUid); while (frontier.size() != 0) { auto nextFrontier = std::set(); for (const auto& nodeInFrontier : frontier) { - if (nodeInFrontier == targetChild) { + if (nodeInFrontier == targetChildUid) { // We have found a redundant path foundRedundant = true; break; @@ -356,7 +363,18 @@ auto Graph::removeRedundantDependencies() break; } if (foundRedundant) { - edgesToBeRemoved.push_back({visitingNode, targetChild}); + // Flag as redundant only if the edge is not of type stencil + const bool isStencilEdge = std::invoke([&] { + const auto& visitingNode = mRawGraph.getVertexProperty(visitingNodeUid); + const auto& targetChild = mRawGraph.getVertexProperty(targetChildUid); + const auto& dependency = this->getDependency(visitingNode, targetChild); + const bool output = dependency.hasStencilDependency(); + return output; + }); + + if (!isStencilEdge) { + edgesToBeRemoved.push_back({visitingNodeUid, targetChildUid}); + } } } }); @@ -543,7 +561,7 @@ auto Graph::getGraphNode(GraphData::Uid uid) const -> const GraphNode& auto Graph::helpComputeScheduling_00_resetData() -> void { - mRawGraph.forEachVertex([&](const GraphData::Uid & graphNodeId) { + mRawGraph.forEachVertex([&](const GraphData::Uid& graphNodeId) { auto& targetNode = mRawGraph.getVertexProperty(graphNodeId); targetNode.getScheduling().reset(); }); diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 8f171b1f..30c1a0aa 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -1,9 +1,20 @@ -#include "Neon/set/container/graph/GraphDependency.h" #include + +#include "Neon/set/container/graph/GraphDependency.h" +// #include "Neon/set/dependency/Alias.h" +// #include "Neon/set/dependency/ComputeType.h" + namespace Neon::set::container { GraphDependency::GraphDependency() { + mHasStencilDependency = false; +} + +GraphDependency::GraphDependency(GraphDependencyType type) +{ + mHasStencilDependency = false; + setType(type); } auto GraphDependency::setType(GraphDependencyType type) -> void @@ -15,27 +26,18 @@ auto GraphDependency::getType() const -> GraphDependencyType { return mType; } -GraphDependency::GraphDependency(GraphDependencyType type) -{ - setType(type); -} + auto GraphDependency::getLabel() -> std::string { std::stringstream s; s << GraphDependencyTypeUtil::toString(getType()); - s << toString([](int ) -> std::pair { + s << toString([](int) -> std::pair { return {"\\l", ""}; }); return s.str(); } -auto GraphDependency::appendInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, - Neon::internal::dataDependency::DataUId dataUId) -> void -{ - mInfo.push_back({dataDependencyType, dataUId}); -} - auto GraphDependency::toString(std::function(int)> prefixPostfix) -> std::string { std::stringstream s; @@ -46,4 +48,24 @@ auto GraphDependency::toString(std::function return s.str(); } +auto GraphDependency::appendInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::DataUId dataUId, + Neon::Compute compute) -> void +{ + mInfo.push_back({dataDependencyType, dataUId, compute}); + if(compute == Neon::Compute::STENCIL){ + mHasStencilDependency = true; + } +} + +auto GraphDependency::getListStencilData() const -> std::vector +{ + std::vector output; + for (const auto i : mInfo) { + if (i.compute == Neon::Compute::STENCIL) { + output.push_back(i.dataUId); + } + } +} + } // namespace Neon::set::container diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index 65d47ede..5678f576 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -24,7 +24,8 @@ void MultiGpuGraph::init(Neon::Backend& bk, h_io2Dot("t2_" + name + ".dot", "i"); } -void MultiGpuGraph::parse(int setCardinalty, const std::vector&& operations) +void MultiGpuGraph::parse(int setCardinalty, + const std::vector&& operations) { m_setCardinality() = setCardinalty; @@ -42,7 +43,6 @@ void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContaine // Parsing all the data toke used by the kernel container std::vector tokens = helpParseContainer(mGraph().getGraphNode(graphNodeUid).getContainer()); - int detectedDependencies = 0; // Tokens are based on the multi-GPU data loaded by Containers for (auto& token : tokens) { @@ -52,13 +52,12 @@ void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContaine auto newDependencies = m_dataRecords().updateStatus(graphNodeUid, token.access(), token.uid()); for (auto& dep : newDependencies) { - detectedDependencies++; const auto& n0 = mGraph().getGraphNode(dep.t0()); const auto& n1 = mGraph().getGraphNode(dep.t1()); - mGraph().appendDataDependency(n0, n1, dep.type(), - token.uid()); + token.uid(), + token.compute()); } } } @@ -574,66 +573,72 @@ auto MultiGpuGraph::optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> auto MultiGpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> void { + + if (m_setCardinality() == 1) { + return; + } + + // Detects all stencil nodes + std::vector stencilNodesUids; + + mGraph().forEachNode([&](Neon::set::container::GraphData::Uid nodeUid) { + const auto& node = mGraph().getGraphNode(nodeUid); + auto pattern = node.getContainer().getContainerInterface().getContainerPatternType(); + if (pattern == Neon::set::ContainerPatternType::stencil) { + auto dw = node.getScheduling().getDataView(); + if (dw != Neon::DataView::INTERNAL) { + stencilNodesUids.push_back(nodeUid); + } + } + }); + + for (auto&& stencilNodeUid : stencilNodesUids) { + const auto& stencilNode = mGraph().getGraphNode(stencilNodeUid); + + const auto inEdges = m_graph().inEdges(stencilNode); + int detectedStencilEdges = 0; + [[maybe_unused]] auto& nodeInfo = m_graph().getVertexProperty(stencilNode); + + + // m_graph().forEachInEdge(stencilNode, + // We are using a copy of the inEdges, + // so we can modify the graph without any issue + std::for_each(inEdges.begin(), inEdges.end(), + [&](const DiGraph::Edge& edge) { + bool visited = false; + auto& edgeP = m_graph().getEdgeProperty(edge); + auto& targetProperty = edgeP.infoMutable(); + + // remove_if only move elements at the end of the vector + auto end = std::remove_if(targetProperty.begin(), + targetProperty.end(), + [&](Edge::Info& info) -> bool { + if (info.token.compute() == Neon::Compute::STENCIL && !info.flag_discardStencilDep) { + visited = true; + detectedStencilEdges++; + h_add_hUpdateSyncNodes(edge.first, + edge.second, + info, + options.transferMode()); + + return true; + } else { + visited = true; + return false; + } + }); + + targetProperty.erase(end, targetProperty.end()); + if (detectedStencilEdges > 0 && m_graph().getEdgeProperty(edge).nDependencies() == 0) { + m_graph().removeEdge(edge); + } + }); + + if (detectedStencilEdges != 1) { + NEON_THROW_UNSUPPORTED_OPTION("Only one stencil in field is supported for now"); + } + } NEON_DEV_UNDER_CONSTRUCTION(""); - // if (m_setCardinality() == 1) { - // return; - // } - // - // // Detects all stencil nodes - // std::vector stencilNodes; - // m_graph().forEachVertex([&](size_t nodeId) { - // const auto& node = m_graph().getVertexProperty(nodeId); - // if (node.getCompute() == Neon::Compute::STENCIL) { - // if (node.getDataView() != Neon::DataView::INTERNAL) { - // stencilNodes.push_back(nodeId); - // } - // } - // }); - // for (auto&& stencilNode : stencilNodes) { - // - // const auto inEdges = m_graph().inEdges(stencilNode); - // int detectedStencilEdges = 0; - // [[maybe_unused]] auto& nodeInfo = m_graph().getVertexProperty(stencilNode); - // - // - // // m_graph().forEachInEdge(stencilNode, - // // We are using a copy of the inEdges, - // // so we can modify the graph without any issue - // std::for_each(inEdges.begin(), inEdges.end(), - // [&](const DiGraph::Edge& edge) { - // bool visited = false; - // auto& edgeP = m_graph().getEdgeProperty(edge); - // auto& targetProperty = edgeP.infoMutable(); - // - // // remove_if only move elements at the end of the vector - // auto end = std::remove_if(targetProperty.begin(), - // targetProperty.end(), - // [&](Edge::Info& info) -> bool { - // if (info.token.compute() == Neon::Compute::STENCIL && !info.flag_discardStencilDep) { - // visited = true; - // detectedStencilEdges++; - // h_add_hUpdateSyncNodes(edge.first, - // edge.second, - // info, - // options.transferMode()); - // - // return true; - // } else { - // visited = true; - // return false; - // } - // }); - // - // targetProperty.erase(end, targetProperty.end()); - // if (detectedStencilEdges > 0 && m_graph().getEdgeProperty(edge).nDependencies() == 0) { - // m_graph().removeEdge(edge); - // } - // }); - // - // if (detectedStencilEdges != 1) { - // NEON_THROW_UNSUPPORTED_OPTION("Only one stencil in field is supported for now"); - // } - // } } auto MultiGpuGraph::checkCoherency() -> void From c696b27667b0b5ca654570babdae65644096abbc Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Sun, 18 Sep 2022 11:36:10 -0400 Subject: [PATCH 36/67] Fixing compilation issue on windows. --- .../include/Neon/domain/tools/TestData.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libNeonDomain/include/Neon/domain/tools/TestData.h b/libNeonDomain/include/Neon/domain/tools/TestData.h index 54fff3bc..97c1b9c7 100644 --- a/libNeonDomain/include/Neon/domain/tools/TestData.h +++ b/libNeonDomain/include/Neon/domain/tools/TestData.h @@ -300,13 +300,13 @@ template auto TestData::axpy(const Type* alpha, IODomain& A, IODomain& B) -> void { - this->template forEachActiveIODomain([&](const Neon::index_3d& /*idx*/, - int /*cardinality*/, - Type& a, - Type& b) { + this->forEachActiveIODomain([&](const Neon::index_3d& /*idx*/, + int /*cardinality*/, + Type& a, + Type& b) { b += (*alpha) * a; }, - A, B); + A, B); } template @@ -342,16 +342,16 @@ auto TestData::laplace(IODomain& A, NEON_IO IODomain& B) } template -auto TestData::compare(FieldNames name, +auto TestData::compare(FieldNames name, [[maybe_unused]] T tollerance) -> bool { bool isTheSame = false; if constexpr (std::is_integral_v) { bool foundAnIssue = false; this->compare(name, [&](const Neon::index_3d& /*idx*/, - int /*cardinality*/, - const T& golden, - const T& computed) { + int /*cardinality*/, + const T& golden, + const T& computed) { if (golden != computed) { { #pragma omp critical From 7401d94b9ad71b9f6122fd8f74e1c06c63474146 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Sun, 18 Sep 2022 12:16:13 -0400 Subject: [PATCH 37/67] WIP --- libNeonSet/include/Neon/set/container/Graph.h | 8 ++++++ .../set/container/graph/GraphDependency.h | 12 ++++++++- libNeonSet/src/set/container/Graph.cpp | 19 ++++++-------- .../set/container/graph/GraphDependency.cpp | 26 +++++++++++++++++-- .../src/skeleton/internal/multiGpuGraph.cpp | 18 +++++++++++++ 5 files changed, 69 insertions(+), 14 deletions(-) diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index edeecd28..c15173df 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -187,6 +187,14 @@ struct Graph }); } + template + auto forEachDependency(Fun f) -> void + { + mRawGraph.forEachEdge([&](std::pair edge) { + const auto& depedency = mRawGraph.getEdgeProperty(edge); + f(depedency); + }); + } protected: /** diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index 6d88e784..2f6690b4 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -1,6 +1,7 @@ #pragma once #include "GraphDependencyType.h" +#include "Neon/set/container/graph/GraphData.h" #include "Neon/set/dependency/Alias.h" #include "Neon/set/dependency/ComputeType.h" #include "Neon/set/dependency/DataDependencyType.h" @@ -14,7 +15,9 @@ struct GraphDependency public: GraphDependency(); - GraphDependency(GraphDependencyType type); + GraphDependency(GraphDependencyType type, + GraphData::Uid source, + GraphData::Uid destination); auto setType(GraphDependencyType type) -> void; @@ -30,6 +33,11 @@ struct GraphDependency auto hasStencilDependency() const -> bool; + auto getSource() const -> GraphData::Uid; + + auto getDestination() const -> GraphData::Uid; + + private: struct Info { @@ -41,6 +49,8 @@ struct GraphDependency GraphDependencyType mType; std::vector mInfo; bool mHasStencilDependency = false; + GraphData::Uid mSource; + GraphData::Uid mDestination; // TODO - add information for data and Scheduling dependency }; diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 661c6075..6ecdc326 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -66,14 +66,15 @@ auto Graph::addDependency(const GraphNode& nodeA, } helpInvalidateScheduling(); - GraphDependency ab(type); + auto nodeAuid = nodeA.getGraphData().getUid(); + auto nodeBuid = nodeB.getGraphData().getUid(); - mRawGraph.addEdge(nodeA.getGraphData().getUid(), - nodeB.getGraphData().getUid(), - ab); + GraphDependency ab(type, nodeAuid, nodeBuid); - return mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), - nodeB.getGraphData().getUid()}); + mRawGraph.addEdge(nodeAuid, nodeBuid, ab); + + return mRawGraph.getEdgeProperty({nodeAuid, + nodeBuid}); } auto Graph::appendDataDependency(const GraphNode& nodeA, @@ -95,11 +96,7 @@ auto Graph::appendDataDependency(const GraphNode& if (!hasEdge) { GraphDependencyType type = GraphDependencyType::data; - - GraphDependency ab(type); - mRawGraph.addEdge(nodeA.getGraphData().getUid(), - nodeB.getGraphData().getUid(), - ab); + addDependency(nodeA, nodeB, type); } auto& output = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 30c1a0aa..665fe608 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -9,12 +9,18 @@ namespace Neon::set::container { GraphDependency::GraphDependency() { mHasStencilDependency = false; + mSource = GraphData::notSet; + mDestination = GraphData::notSet; } -GraphDependency::GraphDependency(GraphDependencyType type) +GraphDependency::GraphDependency(GraphDependencyType type, + GraphData::Uid source, + GraphData::Uid destination) { mHasStencilDependency = false; setType(type); + mSource = source; + mDestination = destination; } auto GraphDependency::setType(GraphDependencyType type) -> void @@ -53,7 +59,7 @@ auto GraphDependency::appendInfo(Neon::internal::dataDependency::DataDependencyT Neon::Compute compute) -> void { mInfo.push_back({dataDependencyType, dataUId, compute}); - if(compute == Neon::Compute::STENCIL){ + if (compute == Neon::Compute::STENCIL) { mHasStencilDependency = true; } } @@ -66,6 +72,22 @@ auto GraphDependency::getListStencilData() const -> std::vector GraphData::Uid +{ + return mSource; +} + +auto GraphDependency::getDestination() const -> GraphData::Uid +{ + return mDestination; +} + +auto GraphDependency::hasStencilDependency() const -> bool +{ + return mHasStencilDependency; } } // namespace Neon::set::container diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index 5678f576..1102f89b 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -578,6 +578,24 @@ auto MultiGpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> return; } + std::vector stencilDependencies; + mGraph().forEachDependency([&](const Neon::set::container::GraphDependency& dep) { + if (dep.hasStencilDependency()) { + stencilDependencies.push_back(&dep); + } + }); + + for(auto depPtr : stencilDependencies){ + const auto& dep = *depPtr; + auto nodeA = mGraph().getGraphNode(dep.getSource()); + auto nodeB = mGraph().getGraphNode(dep.getDestination()); + + auto& newHaloContainer = Neon::set::Container::factoryHaloUpdate(); + + mGraph().addNodeInBetween() + } + + // Detects all stencil nodes std::vector stencilNodesUids; From 0b3b74f7de691bc13fabb86ec7b9c6669f9504b6 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Sat, 24 Sep 2022 08:50:15 -0400 Subject: [PATCH 38/67] WIP --- .../include/Neon/domain/interface/FieldBase.h | 9 ++- .../Neon/domain/interface/FieldBase_imp.h | 10 ++- .../Neon/domain/internal/dGrid/dField.h | 5 +- .../Neon/domain/internal/dGrid/dField_imp.h | 9 ++- .../Neon/domain/internal/dGrid/dGrid.h | 4 +- .../Neon/domain/internal/dGrid/dGrid_imp.h | 22 +++---- libNeonSet/include/Neon/set/Containter.h | 1 + .../include/Neon/set/container/ContainerAPI.h | 5 +- libNeonSet/include/Neon/set/container/Graph.h | 28 ++++----- .../include/Neon/set/container/Loader.h | 4 +- .../include/Neon/set/container/graph/Bfs.h | 4 +- .../Neon/set/container/graph/GraphData.h | 36 ----------- .../set/container/graph/GraphDependency.h | 61 +++++++++++++------ .../Neon/set/container/graph/GraphInfo.h | 36 +++++++++++ .../Neon/set/container/graph/GraphNode.h | 10 +-- .../include/Neon/set/dependency/Alias.h | 4 +- .../include/Neon/set/dependency/Token.h | 9 +-- libNeonSet/src/set/container/Graph.cpp | 52 ++++++++-------- libNeonSet/src/set/container/graph/Bfs.cpp | 8 +-- .../set/container/graph/GraphDependency.cpp | 37 +++++++---- .../src/set/container/graph/GraphNode.cpp | 10 +-- .../container/graph/GraphNodeOrganization.cpp | 14 ++--- libNeonSet/src/set/depencencyTools/Token.cpp | 8 +-- .../Neon/skeleton/internal/MultiGpuGraph.h | 2 +- .../internal/dependencyTools/DataDependency.h | 16 ++--- .../dependencyTools/DependencyAnalyser.h | 14 ++--- .../dependencyTools/UserDataManager.h | 12 ++-- .../skeleton/depencencyTools/Dependency.cpp | 10 +-- .../depencencyTools/DependencyAnalyser.cpp | 10 +-- .../depencencyTools/UserDataManager.cpp | 10 +-- .../src/skeleton/internal/multiGpuGraph.cpp | 23 ++++--- 31 files changed, 271 insertions(+), 212 deletions(-) delete mode 100644 libNeonSet/include/Neon/set/container/graph/GraphData.h create mode 100644 libNeonSet/include/Neon/set/container/graph/GraphInfo.h diff --git a/libNeonDomain/include/Neon/domain/interface/FieldBase.h b/libNeonDomain/include/Neon/domain/interface/FieldBase.h index 87af6bc4..caab3920 100644 --- a/libNeonDomain/include/Neon/domain/interface/FieldBase.h +++ b/libNeonDomain/include/Neon/domain/interface/FieldBase.h @@ -4,6 +4,7 @@ #include "Neon/core/tools/io/IODense.h" #include "Neon/core/types/Macros.h" +#include "Neon/set/Containter.h" #include "Neon/set/DataConfig.h" #include "Neon/set/DevSet.h" #include "Neon/set/HuOptions.h" @@ -12,7 +13,6 @@ #include "GridBase.h" #include "Neon/domain/interface/common.h" - namespace Neon::domain::interface { template @@ -25,8 +25,8 @@ class FieldBase FieldBase(); - FieldBase(const std::string fieldUserName, - const std::string fieldClassName, + FieldBase(const std::string& fieldUserName, + const std::string& fieldClassName, const Neon::index_3d& dimension, int cardinality, T outsideVal, @@ -57,6 +57,9 @@ class FieldBase virtual auto haloUpdate(Neon::set::HuOptions& opt) -> void = 0; + virtual auto haloUpdateContainer(Neon::set::HuOptions& opt) const + -> Neon::set::Container; + auto getDimension() const -> const Neon::index_3d&; diff --git a/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h b/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h index 9a93a1d8..0e1db205 100644 --- a/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h +++ b/libNeonDomain/include/Neon/domain/interface/FieldBase_imp.h @@ -13,8 +13,8 @@ FieldBase::FieldBase() } template -FieldBase::FieldBase(const std::string FieldBaseUserName, - const std::string fieldClassName, +FieldBase::FieldBase(const std::string& FieldBaseUserName, + const std::string& fieldClassName, const Neon::index_3d& dimension, int cardinality, T outsideVal, @@ -263,6 +263,12 @@ auto FieldBase::getClassName() const -> const std::string& return mStorage->className; } +template +auto FieldBase::haloUpdateContainer(set::HuOptions& /*opt*/) const -> Neon::set::Container +{ + NEON_THROW_UNSUPPORTED_OPERATION(""); +} + template FieldBase::Storage::Storage(const std::string FieldBaseUserName, const std::string fieldClassName, diff --git a/libNeonDomain/include/Neon/domain/internal/dGrid/dField.h b/libNeonDomain/include/Neon/domain/internal/dGrid/dField.h index e9f1632b..5a591ebf 100644 --- a/libNeonDomain/include/Neon/domain/internal/dGrid/dField.h +++ b/libNeonDomain/include/Neon/domain/internal/dGrid/dField.h @@ -43,7 +43,7 @@ class dField : public Neon::domain::interface::FieldBaseTemplate Self&; @@ -61,6 +61,9 @@ class dField : public Neon::domain::interface::FieldBaseTemplate void final; + auto haloUpdateContainer(Neon::set::HuOptions& opt) const + -> Neon::set::Container final; + auto haloUpdate(SetIdx setIdx, Neon::set::HuOptions& opt) const -> void; //TODO add this function to the API if performance boost is reasonable -> void final; diff --git a/libNeonDomain/include/Neon/domain/internal/dGrid/dField_imp.h b/libNeonDomain/include/Neon/domain/internal/dGrid/dField_imp.h index 8c6bd5d4..335d6a77 100644 --- a/libNeonDomain/include/Neon/domain/internal/dGrid/dField_imp.h +++ b/libNeonDomain/include/Neon/domain/internal/dGrid/dField_imp.h @@ -19,8 +19,7 @@ dField::dField(const std::string& fieldUserName, T(0), dataUse, memoryOptions, - haloStatus) -{ + haloStatus) { mDataUse = dataUse; mMemoryOptions = memoryOptions; @@ -561,4 +560,10 @@ auto dField::swap(dField::Field& A, dField::Field& B) -> void std::swap(A, B); } +template +auto dField::haloUpdateContainer(set::HuOptions& opt) const -> Neon::set::Container +{ + NEON_THROW_UNSUPPORTED_OPERATION(""); +} + } // namespace Neon::domain::internal::dGrid diff --git a/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid.h b/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid.h index c58212ac..c63a5097 100644 --- a/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid.h +++ b/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid.h @@ -88,7 +88,7 @@ class dGrid : public Neon::domain::interface::GridBaseTemplate * Creates a new Field */ template - auto newField(const std::string fieldUserName, + auto newField(const std::string& fieldUserName, int cardinality, T inactiveValue, Neon::DataUse dataUse = Neon::DataUse::IO_COMPUTE, @@ -183,7 +183,7 @@ class dGrid : public Neon::domain::interface::GridBaseTemplate Neon::index_3d halo; std::vector> partitionIndexSpaceVec; - Neon::sys::patterns::Engine reduceEngine; + Neon::sys::patterns::Engine reduceEngine; }; std::shared_ptr m_data; }; diff --git a/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid_imp.h b/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid_imp.h index f40e51f5..a6720ca8 100644 --- a/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid_imp.h +++ b/libNeonDomain/include/Neon/domain/internal/dGrid/dGrid_imp.h @@ -110,7 +110,7 @@ dGrid::dGrid(const Neon::Backend& backend, template -auto dGrid::newField(const std::string fieldUserName, +auto dGrid::newField(const std::string& fieldUserName, int cardinality, [[maybe_unused]] T inactiveValue, Neon::DataUse dataUse, @@ -162,11 +162,11 @@ auto dGrid::getContainer(const std::string& name, { const Neon::index_3d& defaultBlockSize = getDefaultBlock(); Neon::set::Container kContainer = Neon::set::Container::factory(name, - Neon::set::internal::ContainerAPI::DataViewSupport::on, - *this, - lambda, - defaultBlockSize, - [](const Neon::index_3d&) { return size_t(0); }); + Neon::set::internal::ContainerAPI::DataViewSupport::on, + *this, + lambda, + defaultBlockSize, + [](const Neon::index_3d&) { return size_t(0); }); return kContainer; } @@ -180,11 +180,11 @@ auto dGrid::getContainer(const std::string& name, { const Neon::index_3d& defaultBlockSize = getDefaultBlock(); Neon::set::Container kContainer = Neon::set::Container::factory(name, - Neon::set::internal::ContainerAPI::DataViewSupport::on, - *this, - lambda, - blockSize, - [sharedMem](const Neon::index_3d&) { return sharedMem; }); + Neon::set::internal::ContainerAPI::DataViewSupport::on, + *this, + lambda, + blockSize, + [sharedMem](const Neon::index_3d&) { return sharedMem; }); return kContainer; } diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 8da4b361..8f95f950 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -16,6 +16,7 @@ struct Container { public: Container() = default; + virtual ~Container() = default; /** * Run a Neon Container on a given stream and with a given data view diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index f0c06b77..21ef409f 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -1,10 +1,9 @@ #pragma once -#include "Neon/set/container/ContainerOperationType.h" -#include "Neon/set/container/ContainerPatternType.h" - #include "Neon/set/DevSet.h" #include "Neon/set/container/ContainerExecutionType.h" +#include "Neon/set/container/ContainerOperationType.h" +#include "Neon/set/container/ContainerPatternType.h" #include "Neon/set/dependency/Token.h" #include "functional" diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index c15173df..3f817a9c 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -19,8 +19,8 @@ namespace Neon::set::container { */ struct Graph { - using Uid = GraphData::Uid; - using Index = GraphData::Index; + using Uid = GraphInfo::NodeUid; + using Index = GraphInfo::NodeIdx; friend struct Bfs; public: @@ -167,21 +167,21 @@ struct Graph /** * Extract a graph node from its id */ - auto getGraphNode(GraphData::Uid) + auto getGraphNode(GraphInfo::NodeUid) -> GraphNode&; /** * Extract a graph node from its id */ - auto getGraphNode(GraphData::Uid) const + auto getGraphNode(GraphInfo::NodeUid) const -> const GraphNode&; template auto forEachNode(Fun f) -> void { mRawGraph.forEachVertex([&](size_t v) { - GraphData::Uid node = v; - if (node != GraphData::beginUid && node != GraphData::endUid) { + GraphInfo::NodeUid node = v; + if (node != GraphInfo::beginUid && node != GraphInfo::endUid) { f(node); } }); @@ -216,38 +216,38 @@ struct Graph /** * Returns the out-neighbour of a target node */ - auto helpGetOutNeighbors(GraphData::Uid, + auto helpGetOutNeighbors(GraphInfo::NodeUid, bool fileterOutEnd = true, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) - -> std::set; + -> std::set; /** * Returns the in-neighbour of a target node */ - auto helpGetInNeighbors(GraphData::Uid nodeUid, + auto helpGetInNeighbors(GraphInfo::NodeUid nodeUid, bool fileterOutBegin = true, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) - -> std::set; + -> std::set; /** * Returns the out-edges of a target node */ - auto helpGetOutEdges(GraphData::Uid, + auto helpGetOutEdges(GraphInfo::NodeUid, bool filterOutEnd = true, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) - -> std::set>; + -> std::set>; /** * Returns the in-edges of a target node */ - auto helpGetInEdges(GraphData::Uid nodeUid, + auto helpGetInEdges(GraphInfo::NodeUid nodeUid, bool filterOutBegin = true, const std::vector& dependencyTypes = {GraphDependencyType::user, GraphDependencyType::data}) - -> std::set>; + -> std::set>; /** * Returns nodes Ids for a BFS visit diff --git a/libNeonSet/include/Neon/set/container/Loader.h b/libNeonSet/include/Neon/set/container/Loader.h index 82313ea3..77fb8fc4 100644 --- a/libNeonSet/include/Neon/set/container/Loader.h +++ b/libNeonSet/include/Neon/set/container/Loader.h @@ -183,7 +183,7 @@ struct Loader switch (m_loadingMode) { case Neon::set::internal::LoadingMode_e::PARSE_AND_EXTRACT_LAMBDA: { - Neon::internal::dataDependency::DataUId uid = field.getUid(); + Neon::internal::dataDependency::MdObjUid uid = field.getUid(); constexpr Neon::internal::dataDependency::AccessType access = Neon::internal::dataDependency::AccessType::WRITE; Compute compute = computeE; Neon::internal::dataDependency::Token dataToken(uid, access, compute); @@ -221,7 +221,7 @@ struct Loader { switch (m_loadingMode) { case Neon::set::internal::LoadingMode_e::PARSE_AND_EXTRACT_LAMBDA: { - Neon::internal::dataDependency::DataUId uid = field.getUid(); + Neon::internal::dataDependency::MdObjUid uid = field.getUid(); constexpr Neon::internal::dataDependency::AccessType access = Neon::internal::dataDependency::AccessType::READ; Neon::Compute compute = computeE; Neon::internal::dataDependency::Token dataToken(uid, access, compute); diff --git a/libNeonSet/include/Neon/set/container/graph/Bfs.h b/libNeonSet/include/Neon/set/container/graph/Bfs.h index 0208af63..1e44dc8b 100644 --- a/libNeonSet/include/Neon/set/container/graph/Bfs.h +++ b/libNeonSet/include/Neon/set/container/graph/Bfs.h @@ -1,6 +1,6 @@ #pragma once -#include "Neon/set/container/graph/GraphData.h" +#include "Neon/set/container/graph/GraphInfo.h" namespace Neon::set::container { @@ -8,7 +8,7 @@ struct Graph; struct Bfs { - using Level = std::vector; + using Level = std::vector; /** * Returns the number of levels */ diff --git a/libNeonSet/include/Neon/set/container/graph/GraphData.h b/libNeonSet/include/Neon/set/container/graph/GraphData.h deleted file mode 100644 index 7604f878..00000000 --- a/libNeonSet/include/Neon/set/container/graph/GraphData.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include "vector" - -namespace Neon::set::container { - -class GraphData -{ - public: - using Uid = uint64_t; - using Index = uint64_t; - - constexpr static Uid notSet = 0; - constexpr static Uid beginUid = 1; - constexpr static Uid endUid = 2; - constexpr static Uid firstInternal = 3; - - GraphData(); - GraphData(int uid); - - auto setUid(Uid uid) -> void; - auto setIndex(Index index) -> void; - - auto getUid() const -> Uid; - auto getIndex() const -> Index; - - private: - Uid mUid /**< unique identifier for the node. - * This is different from a Container uid as in a graph the same container can appear more than once. - * */ - ; - Index mIndex /** relative index w.r.t the completed graph. This value may change during the life of the graph */; -}; - -} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index 2f6690b4..92f04140 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -1,56 +1,83 @@ #pragma once #include "GraphDependencyType.h" -#include "Neon/set/container/graph/GraphData.h" +#include "Neon/set/container/graph/GraphInfo.h" #include "Neon/set/dependency/Alias.h" #include "Neon/set/dependency/ComputeType.h" #include "Neon/set/dependency/DataDependencyType.h" +#include "Neon/set/Containter.h" namespace Neon::set::container { struct GraphDependency { - std::string getLabel(); public: + struct Info + { + Info(Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::MdObjUid UId, + Neon::Compute compute) + : dataDependencyType(dataDependencyType), + dataUId(UId), + compute(compute) + { + } + + Info(Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::MdObjUid UId, + Neon::Compute compute, + Neon::set::Container& haloUpdate) + : dataDependencyType(dataDependencyType), + dataUId(UId), + compute(compute), + haloUpdate(haloUpdate) + { + } + + Neon::internal::dataDependency::DataDependencyType dataDependencyType; + Neon::internal::dataDependency::MdObjUid dataUId; + Neon::Compute compute; + Neon::set::Container haloUpdate; + }; + GraphDependency(); GraphDependency(GraphDependencyType type, - GraphData::Uid source, - GraphData::Uid destination); + GraphInfo::NodeUid source, + GraphInfo::NodeUid destination); auto setType(GraphDependencyType type) -> void; auto getType() const -> GraphDependencyType; auto appendInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, - Neon::internal::dataDependency::DataUId dataUId, + Neon::internal::dataDependency::MdObjUid dataUId, Neon::Compute compute) -> void; + auto appendStencilInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::MdObjUid dataUId, + Neon::set::Container& container) -> void; + auto toString(std::function(int)> prefix) -> std::string; - auto getListStencilData() const -> std::vector; + auto getListStencilInfo() const + -> std::vector; auto hasStencilDependency() const -> bool; - auto getSource() const -> GraphData::Uid; + auto getSource() const -> GraphInfo::NodeUid; - auto getDestination() const -> GraphData::Uid; + auto getDestination() const -> GraphInfo::NodeUid; + auto getLabel() -> std::string; private: - struct Info - { - Neon::internal::dataDependency::DataDependencyType dataDependencyType; - Neon::internal::dataDependency::DataUId dataUId; - Neon::Compute compute; - }; - GraphDependencyType mType; std::vector mInfo; bool mHasStencilDependency = false; - GraphData::Uid mSource; - GraphData::Uid mDestination; + GraphInfo::NodeUid mSource; + GraphInfo::NodeUid mDestination; // TODO - add information for data and Scheduling dependency }; diff --git a/libNeonSet/include/Neon/set/container/graph/GraphInfo.h b/libNeonSet/include/Neon/set/container/graph/GraphInfo.h new file mode 100644 index 00000000..b834f638 --- /dev/null +++ b/libNeonSet/include/Neon/set/container/graph/GraphInfo.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include "vector" + +namespace Neon::set::container { + +class GraphInfo +{ + public: + using NodeUid = uint64_t; + using NodeIdx = uint64_t; + + constexpr static NodeUid notSet = 0; + constexpr static NodeUid beginUid = 1; + constexpr static NodeUid endUid = 2; + constexpr static NodeUid firstInternal = 3; + + GraphInfo(); + GraphInfo(int uid); + + auto setUid(NodeUid uid) -> void; + auto setIndex(NodeIdx index) -> void; + + auto getUid() const -> NodeUid; + auto getIndex() const -> NodeIdx; + + private: + NodeUid mUid /**< unique identifier for the node. + * This is different from a Container uid as in a graph the same container can appear more than once. + * */ + ; + NodeIdx mIndex /** relative index w.r.t the completed graph. This value may change during the life of the graph */; +}; + +} // namespace Neon::set::container diff --git a/libNeonSet/include/Neon/set/container/graph/GraphNode.h b/libNeonSet/include/Neon/set/container/graph/GraphNode.h index 6e7d9629..2dfd3bff 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphNode.h @@ -1,6 +1,6 @@ #pragma once -#include "GraphData.h" +#include "GraphInfo.h" #include "GraphNodeScheduling.h" #include "Neon/set/Containter.h" @@ -16,7 +16,7 @@ struct GraphNode GraphNode(); GraphNode(const Container& container, - GraphData::Uid uid); + GraphInfo::NodeUid uid); /** * Factory method to generate a begin node @@ -36,12 +36,12 @@ struct GraphNode /** * Returns a reference to graph information related to this node. * */ - auto getGraphData() -> GraphData&; + auto getGraphData() -> GraphInfo&; /** * Returns a reference to some graph information related to this node. * */ - auto getGraphData() const -> const GraphData&; + auto getGraphData() const -> const GraphInfo&; /** * Returns the scheduling information to run this node @@ -78,7 +78,7 @@ struct GraphNode Container mContainer /**< Any Neon container */; GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; - GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; + GraphInfo mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; ContainerPatternType getContainerpatternType() const; }; diff --git a/libNeonSet/include/Neon/set/dependency/Alias.h b/libNeonSet/include/Neon/set/dependency/Alias.h index 67b50294..055c92d0 100644 --- a/libNeonSet/include/Neon/set/dependency/Alias.h +++ b/libNeonSet/include/Neon/set/dependency/Alias.h @@ -7,11 +7,11 @@ namespace Neon::internal::dataDependency { /** * Unique identifier for a kernel parameter */ -using DataUId = Neon::set::MultiDeviceObjectUid; +using MdObjUid = Neon::set::MultiDeviceObjectUid; /** * Unique identifier for a kernel parameter */ -using DataIdx = Neon::set::MultiDeviceObjectUid; +using MdObjIdx = Neon::set::MultiDeviceObjectUid; } // namespace Neon::internal::dataDependency diff --git a/libNeonSet/include/Neon/set/dependency/Token.h b/libNeonSet/include/Neon/set/dependency/Token.h index cddd4723..febb09da 100644 --- a/libNeonSet/include/Neon/set/dependency/Token.h +++ b/libNeonSet/include/Neon/set/dependency/Token.h @@ -1,4 +1,5 @@ #pragma once + #include "Neon/set/Backend.h" #include "Neon/set/HuOptions.h" #include "Neon/set/dependency/AccessType.h" @@ -19,21 +20,21 @@ struct Token /** * Unique constructor */ - Token(DataUId m_uid, + Token(MdObjUid m_uid, AccessType m_access, Neon::Compute m_compute); /** * Method to update a token */ - auto update(DataUId m_uid, + auto update(MdObjUid m_uid, AccessType m_access, Neon::Compute m_compute) -> void; /** * It returns the multi-GPU data uid */ - auto uid() const -> DataUId; + auto uid() const -> MdObjUid; /** * It returns the type of data access @@ -66,7 +67,7 @@ struct Token private: - DataUId mUid; + MdObjUid mUid; AccessType mAccess; Compute mCompute; std::function mHu; diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 6ecdc326..12460eb3 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -8,7 +8,7 @@ Graph::Graph() { auto begin = GraphNode::newBeginNode(); auto end = GraphNode::newEndNode(); - mUidCounter = GraphData::firstInternal; + mUidCounter = GraphInfo::firstInternal; mRawGraph.addVertex(begin.getGraphData().getUid(), begin); mRawGraph.addVertex(end.getGraphData().getUid(), end); @@ -18,12 +18,12 @@ Graph::Graph() auto Graph::getBeginNode() const -> const GraphNode& { - return mRawGraph.getVertexProperty(GraphData::beginUid); + return mRawGraph.getVertexProperty(GraphInfo::beginUid); } auto Graph::getEndNode() const -> const GraphNode& { - return mRawGraph.getVertexProperty(GraphData::endUid); + return mRawGraph.getVertexProperty(GraphInfo::endUid); } auto Graph::addNodeInBetween(const GraphNode& nodeA, @@ -143,7 +143,7 @@ auto Graph::removeNode(GraphNode& gn) -> Container } mRawGraph.removeVertex(uidB); - gn.getGraphData().setUid(GraphData::notSet); + gn.getGraphData().setUid(GraphInfo::notSet); return gn.getContainer(); } @@ -187,7 +187,7 @@ auto Graph::removeNodeAndItsDependencies(GraphNode& gn) } mRawGraph.removeVertex(uidB); - gn.getGraphData().setUid(GraphData::notSet); + gn.getGraphData().setUid(GraphInfo::notSet); return gn.getContainer(); } @@ -380,15 +380,15 @@ auto Graph::removeRedundantDependencies() } } -auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, +auto Graph::helpGetOutNeighbors(GraphInfo::NodeUid nodeUid, bool filteredOut, const std::vector& dependencyTypes) - -> std::set + -> std::set { - std::set outNgh; + std::set outNgh; mRawGraph.forEachOutEdge( nodeUid, - [&](std::pair edge) { + [&](std::pair edge) { auto& edgeProp = mRawGraph.getEdgeProperty(edge); for (auto& depType : dependencyTypes) { if (depType == edgeProp.getType()) { @@ -403,15 +403,15 @@ auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, return outNgh; } -auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, +auto Graph::helpGetInNeighbors(GraphInfo::NodeUid nodeUid, bool filterOutBegin, const std::vector& dependencyTypes) - -> std::set + -> std::set { - std::set inNgh; + std::set inNgh; mRawGraph.forEachInEdge( nodeUid, - [&](std::pair edge) { + [&](std::pair edge) { auto& edgeProp = mRawGraph.getEdgeProperty(edge); for (auto& depType : dependencyTypes) { if (depType == edgeProp.getType()) { @@ -425,15 +425,15 @@ auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, return inNgh; } -auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, +auto Graph::helpGetOutEdges(GraphInfo::NodeUid nodeUid, bool filterOutEnd, const std::vector& dependencyTypes) - -> std::set> + -> std::set> { - std::set> outEdges; + std::set> outEdges; mRawGraph.forEachOutEdge( nodeUid, - [&](std::pair edge) { + [&](std::pair edge) { auto& edgeProp = mRawGraph.getEdgeProperty(edge); for (auto& depType : dependencyTypes) { if (depType == edgeProp.getType()) { @@ -447,15 +447,15 @@ auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, return outEdges; } -auto Graph::helpGetInEdges(GraphData::Uid nodeUid, +auto Graph::helpGetInEdges(GraphInfo::NodeUid nodeUid, bool filterOutBegin, const std::vector& dependencyTypes) - -> std::set> + -> std::set> { - std::set> inEdges; + std::set> inEdges; mRawGraph.forEachInEdge( nodeUid, - [&](std::pair edge) { + [&](std::pair edge) { auto& edgeProp = mRawGraph.getEdgeProperty(edge); for (auto& depType : dependencyTypes) { if (depType == edgeProp.getType()) { @@ -473,7 +473,7 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd const std::vector& dependencyTypes) -> Bfs { - using Frontier = std::unordered_map; + using Frontier = std::unordered_map; Bfs bfs; @@ -546,19 +546,19 @@ auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) GraphDependencyType::user}); } -auto Graph::getGraphNode(GraphData::Uid uid) -> GraphNode& +auto Graph::getGraphNode(GraphInfo::NodeUid uid) -> GraphNode& { return mRawGraph.getVertexProperty(uid); } -auto Graph::getGraphNode(GraphData::Uid uid) const -> const GraphNode& +auto Graph::getGraphNode(GraphInfo::NodeUid uid) const -> const GraphNode& { return mRawGraph.getVertexProperty(uid); } auto Graph::helpComputeScheduling_00_resetData() -> void { - mRawGraph.forEachVertex([&](const GraphData::Uid& graphNodeId) { + mRawGraph.forEachVertex([&](const GraphInfo::NodeUid& graphNodeId) { auto& targetNode = mRawGraph.getVertexProperty(graphNodeId); targetNode.getScheduling().reset(); }); @@ -761,7 +761,7 @@ Graph::Graph(const Backend& bk) auto begin = GraphNode::newBeginNode(); auto end = GraphNode::newEndNode(); - mUidCounter = GraphData::firstInternal; + mUidCounter = GraphInfo::firstInternal; mRawGraph.addVertex(begin.getGraphData().getUid(), begin); mRawGraph.addVertex(end.getGraphData().getUid(), end); diff --git a/libNeonSet/src/set/container/graph/Bfs.cpp b/libNeonSet/src/set/container/graph/Bfs.cpp index 12a64697..62961777 100644 --- a/libNeonSet/src/set/container/graph/Bfs.cpp +++ b/libNeonSet/src/set/container/graph/Bfs.cpp @@ -11,9 +11,9 @@ auto Bfs::getNumberOfLevels() -> int /** * Returns a reference to a level and it's level index */ -auto Bfs::getNewLevel() -> std::pair&, int> +auto Bfs::getNewLevel() -> std::pair&, int> { - data.push_back(std::vector()); + data.push_back(std::vector()); int idx = int(data.size()) - 1; return {data[idx], idx}; } @@ -22,7 +22,7 @@ auto Bfs::getNewLevel() -> std::pair&, int> * Returns a reference to a specific level */ auto Bfs::getLevel(int levelId) const - -> const std::vector& + -> const std::vector& { return data[levelId]; } @@ -30,7 +30,7 @@ auto Bfs::getLevel(int levelId) const /** * Returns a reference to a specific level */ -auto Bfs::getLevel(int levelId) -> std::vector& +auto Bfs::getLevel(int levelId) -> std::vector& { return data[levelId]; } diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 665fe608..c3b5e490 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -1,5 +1,6 @@ #include +#include "Neon/set/Containter.h" #include "Neon/set/container/graph/GraphDependency.h" // #include "Neon/set/dependency/Alias.h" // #include "Neon/set/dependency/ComputeType.h" @@ -9,13 +10,13 @@ namespace Neon::set::container { GraphDependency::GraphDependency() { mHasStencilDependency = false; - mSource = GraphData::notSet; - mDestination = GraphData::notSet; + mSource = GraphInfo::notSet; + mDestination = GraphInfo::notSet; } GraphDependency::GraphDependency(GraphDependencyType type, - GraphData::Uid source, - GraphData::Uid destination) + GraphInfo::NodeUid source, + GraphInfo::NodeUid destination) { mHasStencilDependency = false; setType(type); @@ -55,32 +56,42 @@ auto GraphDependency::toString(std::function } auto GraphDependency::appendInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, - Neon::internal::dataDependency::DataUId dataUId, + Neon::internal::dataDependency::MdObjUid dataUId, Neon::Compute compute) -> void { - mInfo.push_back({dataDependencyType, dataUId, compute}); + mInfo.emplace_back(dataDependencyType, dataUId, compute); if (compute == Neon::Compute::STENCIL) { - mHasStencilDependency = true; + NEON_THROW_UNSUPPORTED_OPERATION("The appendStencilInfo method should be used instead.") } } -auto GraphDependency::getListStencilData() const -> std::vector +auto GraphDependency::appendStencilInfo(Neon::internal::dataDependency::DataDependencyType dataDependencyType, + Neon::internal::dataDependency::MdObjUid dataUId, + Neon::set::Container& haloUpdate) -> void { - std::vector output; - for (const auto i : mInfo) { + auto compute = Neon::Compute::STENCIL; + mInfo.emplace_back(dataDependencyType, dataUId, compute, haloUpdate); + mHasStencilDependency = true; +} + + +auto GraphDependency::getListStencilInfo() const -> std::vector +{ + std::vector output; + for (const auto& i : mInfo) { if (i.compute == Neon::Compute::STENCIL) { - output.push_back(i.dataUId); + output.push_back(&i); } } return output; } -auto GraphDependency::getSource() const -> GraphData::Uid +auto GraphDependency::getSource() const -> GraphInfo::NodeUid { return mSource; } -auto GraphDependency::getDestination() const -> GraphData::Uid +auto GraphDependency::getDestination() const -> GraphInfo::NodeUid { return mDestination; } diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 220b426d..0617f377 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -11,7 +11,7 @@ GraphNode::GraphNode() auto GraphNode::newBeginNode() -> GraphNode { GraphNode node; - node.mGraphNodeOrganization.setUid(GraphData::beginUid); + node.mGraphNodeOrganization.setUid(GraphInfo::beginUid); node.mContainer = Neon::set::Container::factoryAnchor("Begin"); return node; } @@ -19,17 +19,17 @@ auto GraphNode::newBeginNode() -> GraphNode auto GraphNode::newEndNode() -> GraphNode { GraphNode node; - node.mGraphNodeOrganization.setUid(GraphData::endUid); + node.mGraphNodeOrganization.setUid(GraphInfo::endUid); node.mContainer = Neon::set::Container::factoryAnchor("End"); return node; } -auto GraphNode::getGraphData() -> GraphData& +auto GraphNode::getGraphData() -> GraphInfo& { return mGraphNodeOrganization; } -auto GraphNode::getGraphData() const -> const GraphData& +auto GraphNode::getGraphData() const -> const GraphInfo& { return mGraphNodeOrganization; } @@ -54,7 +54,7 @@ auto GraphNode::getContainer() const -> const Container& return mContainer; } -GraphNode::GraphNode(const Container& container, GraphData::Uid uid) +GraphNode::GraphNode(const Container& container, GraphInfo::NodeUid uid) { mContainer = container; mGraphNodeOrganization.setUid(uid); diff --git a/libNeonSet/src/set/container/graph/GraphNodeOrganization.cpp b/libNeonSet/src/set/container/graph/GraphNodeOrganization.cpp index 3cac2bb2..c7b7f880 100644 --- a/libNeonSet/src/set/container/graph/GraphNodeOrganization.cpp +++ b/libNeonSet/src/set/container/graph/GraphNodeOrganization.cpp @@ -1,33 +1,33 @@ -#include "Neon/set/container/graph/GraphData.h" +#include "Neon/set/container/graph/GraphInfo.h" namespace Neon::set::container { -GraphData::GraphData() +GraphInfo::GraphInfo() { mUid = notSet; mIndex = notSet; } -GraphData::GraphData(int uid) +GraphInfo::GraphInfo(int uid) { mUid = uid; mIndex = notSet; } -auto GraphData::setUid(Uid uid) -> void +auto GraphInfo::setUid(NodeUid uid) -> void { mUid = uid; } -auto GraphData::setIndex(Index index) -> void +auto GraphInfo::setIndex(NodeIdx index) -> void { mIndex = index; } -auto GraphData::getUid() const -> Uid +auto GraphInfo::getUid() const -> NodeUid { return mUid; } -auto GraphData::getIndex() const -> Index +auto GraphInfo::getIndex() const -> NodeIdx { return mIndex; } diff --git a/libNeonSet/src/set/depencencyTools/Token.cpp b/libNeonSet/src/set/depencencyTools/Token.cpp index b330f249..c9726d00 100644 --- a/libNeonSet/src/set/depencencyTools/Token.cpp +++ b/libNeonSet/src/set/depencencyTools/Token.cpp @@ -2,14 +2,14 @@ namespace Neon::internal::dataDependency { -Token::Token(DataUId uid, +Token::Token(MdObjUid uid, AccessType access, Compute compute) { update(uid, access, compute); } -auto Token::update(DataUId uid, +auto Token::update(MdObjUid uid, AccessType access, Compute compute) -> void { @@ -38,7 +38,7 @@ auto Token::compute() const -> Compute return mCompute; } -auto Token::uid() const -> DataUId +auto Token::uid() const -> MdObjUid { return mUid; } @@ -74,4 +74,4 @@ auto Token::mergeAccess(AccessType tomerge) -> void mAccess = AccessTypeUtils::merge(mAccess, tomerge); } -} \ No newline at end of file +} // namespace Neon::internal::dataDependency \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h b/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h index f6b642d7..4a691090 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h @@ -150,7 +150,7 @@ struct MultiGpuGraph private: auto helpAddNewContainerToGraph(const Neon::set::Container& container) - -> Neon::set::container::GraphData::Uid; + -> Neon::set::container::GraphInfo::NodeUid; auto optimizeStandardOCC(const Neon::skeleton::Options&) -> void; diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h index 5e7e413d..2dfd3e75 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h @@ -10,10 +10,10 @@ namespace Neon::skeleton::internal { struct DataDependency { private: - Neon::set::container::GraphData::Uid mT0 = 0; - Neon::set::container::GraphData::Uid mT1 = 0; + Neon::set::container::GraphInfo::NodeUid mT0 = 0; + Neon::set::container::GraphInfo::NodeUid mT1 = 0; Neon::internal::dataDependency::DataDependencyType mType = Neon::internal::dataDependency::DataDependencyType::NONE; - Neon::internal::dataDependency::DataUId mDataUid = 0; + Neon::internal::dataDependency::MdObjUid mDataUid = 0; public: /** @@ -30,10 +30,10 @@ struct DataDependency * @param A * @param B */ - DataDependency(Neon::set::container::GraphData::Uid t1, + DataDependency(Neon::set::container::GraphInfo::NodeUid t1, Neon::internal::dataDependency::DataDependencyType type, - Neon::internal::dataDependency::DataUId m_uid, - Neon::set::container::GraphData::Uid t0); + Neon::internal::dataDependency::MdObjUid m_uid, + Neon::set::container::GraphInfo::NodeUid t0); /** * true the object has been initialized with a valid dependency @@ -57,13 +57,13 @@ struct DataDependency * Returns the "before" kernel id * @return */ - auto t0() -> Neon::set::container::GraphData::Uid; + auto t0() -> Neon::set::container::GraphInfo::NodeUid; /** * Returns the "after" kernel id * @return */ - auto t1() -> Neon::set::container::GraphData::Uid; + auto t1() -> Neon::set::container::GraphInfo::NodeUid; /** * Static method to build an empty dependency diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h index a009e726..3ea77fc3 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h @@ -12,18 +12,18 @@ namespace Neon::skeleton::internal { struct DependencyAnalyser { private: - std::vector mParsedR{}; - std::vector mParsedW{}; + std::vector mParsedR{}; + std::vector mParsedW{}; - Neon::internal::dataDependency::DataUId mUid; - Neon::internal::dataDependency::DataIdx mIdx; + Neon::internal::dataDependency::MdObjUid mUid; + Neon::internal::dataDependency::MdObjIdx mIdx; public: DependencyAnalyser() = delete; - DependencyAnalyser(Neon::internal::dataDependency::DataUId, - Neon::internal::dataDependency::DataIdx); + DependencyAnalyser(Neon::internal::dataDependency::MdObjUid, + Neon::internal::dataDependency::MdObjIdx); - auto update(Neon::set::container::GraphData::Uid newKernel, + auto update(Neon::set::container::GraphInfo::NodeUid newKernel, Neon::internal::dataDependency::AccessType newOp) -> std::vector; }; diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h index 9b55d3e7..cd354856 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h @@ -21,8 +21,8 @@ namespace Neon::skeleton::internal { struct UserDataManager { std::vector mDepAnalyserVec; - std::map + std::map mUid2Idx; private: @@ -31,8 +31,8 @@ struct UserDataManager * @param uid * @return */ - auto helpGetIdx(Neon::internal::dataDependency::DataUId uid) - -> Neon::internal::dataDependency::DataIdx; + auto helpGetIdx(Neon::internal::dataDependency::MdObjUid uid) + -> Neon::internal::dataDependency::MdObjIdx; public: /** @@ -44,9 +44,9 @@ struct UserDataManager * @param uid * @return */ - auto updateStatus(Neon::set::container::GraphData::Uid newKernel, + auto updateStatus(Neon::set::container::GraphInfo::NodeUid newKernel, Neon::internal::dataDependency::AccessType op, - Neon::internal::dataDependency::DataUId uid) -> std::vector; + Neon::internal::dataDependency::MdObjUid uid) -> std::vector; }; } // namespace Neon::skeleton::internal diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp index f6e5858b..0f5d3f66 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp @@ -2,10 +2,10 @@ namespace Neon::skeleton::internal { -DataDependency::DataDependency(Neon::set::container::GraphData::Uid t1, +DataDependency::DataDependency(Neon::set::container::GraphInfo::NodeUid t1, Neon::internal::dataDependency::DataDependencyType type, - Neon::internal::dataDependency::DataUId uid, - Neon::set::container::GraphData::Uid t0) + Neon::internal::dataDependency::MdObjUid uid, + Neon::set::container::GraphInfo::NodeUid t0) { mT1 = t1; mType = type; @@ -36,12 +36,12 @@ DataDependency DataDependency::getEmpty() return {}; } -auto DataDependency::t0() -> Neon::set::container::GraphData::Uid +auto DataDependency::t0() -> Neon::set::container::GraphInfo::NodeUid { return mT0; } -auto DataDependency::t1() -> Neon::set::container::GraphData::Uid +auto DataDependency::t1() -> Neon::set::container::GraphInfo::NodeUid { return mT1; } diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp index 68b2741f..7b3b7f4e 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp @@ -4,14 +4,14 @@ namespace Neon::skeleton::internal { -DependencyAnalyser::DependencyAnalyser(Neon::internal::dataDependency::DataUId uid, - Neon::internal::dataDependency::DataIdx idx) +DependencyAnalyser::DependencyAnalyser(Neon::internal::dataDependency::MdObjUid uid, + Neon::internal::dataDependency::MdObjIdx idx) { mUid = uid; mIdx = idx; } -auto DependencyAnalyser::update(Neon::set::container::GraphData::Uid newKernel, +auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid newKernel, Neon::internal::dataDependency::AccessType newOp) -> std::vector { @@ -95,7 +95,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphData::Uid newKe { // Executing b. mParsedR.clear(); - mParsedW = std::vector(1, newKernel); + mParsedW = std::vector(1, newKernel); } return output; @@ -129,7 +129,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphData::Uid newKe { // Executing c. mParsedR.clear(); - mParsedW = std::vector(1, newKernel); + mParsedW = std::vector(1, newKernel); } return output; } diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp index 7db5a629..a6db362b 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp @@ -2,12 +2,12 @@ namespace Neon::skeleton::internal { -auto UserDataManager::helpGetIdx(Neon::internal::dataDependency::DataUId uid) - -> Neon::internal::dataDependency::DataIdx +auto UserDataManager::helpGetIdx(Neon::internal::dataDependency::MdObjUid uid) + -> Neon::internal::dataDependency::MdObjIdx { auto count = mUid2Idx.count(uid); if (count == 0) { - Neon::internal::dataDependency::DataIdx idx = mDepAnalyserVec.size(); + Neon::internal::dataDependency::MdObjIdx idx = mDepAnalyserVec.size(); mDepAnalyserVec.emplace_back(uid, idx); mUid2Idx[uid] = idx; return idx; @@ -15,9 +15,9 @@ auto UserDataManager::helpGetIdx(Neon::internal::dataDependency::DataUId uid) return mUid2Idx[uid]; } -auto UserDataManager::updateStatus(Neon::set::container::GraphData::Uid nodeUid, +auto UserDataManager::updateStatus(Neon::set::container::GraphInfo::NodeUid nodeUid, Neon::internal::dataDependency::AccessType op, - Neon::internal::dataDependency::DataUId dataUid) + Neon::internal::dataDependency::MdObjUid dataUid) -> std::vector { auto idx = helpGetIdx(dataUid); diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index 1102f89b..513cd790 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -39,7 +39,7 @@ void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContaine // Register and retrieve the id for the new container // add a node - Neon::set::container::GraphData::Uid graphNodeUid = helpAddNewContainerToGraph(inContainer); + Neon::set::container::GraphInfo::NodeUid graphNodeUid = helpAddNewContainerToGraph(inContainer); // Parsing all the data toke used by the kernel container std::vector tokens = helpParseContainer(mGraph().getGraphNode(graphNodeUid).getContainer()); @@ -86,10 +86,10 @@ auto MultiGpuGraph::io2DotOriginalApp(const std::string& fname, const std::strin mGraph().ioToDot(fname, graphName, debug); } -auto MultiGpuGraph::helpAddNewContainerToGraph(const Neon::set::Container& container) -> Neon::set::container::GraphData::Uid +auto MultiGpuGraph::helpAddNewContainerToGraph(const Neon::set::Container& container) -> Neon::set::container::GraphInfo::NodeUid { const auto& graphNode = mGraph().addNode(container); - Neon::set::container::GraphData::Uid uid = graphNode.getGraphData().getUid(); + Neon::set::container::GraphInfo::NodeUid uid = graphNode.getGraphData().getUid(); return uid; } @@ -585,21 +585,24 @@ auto MultiGpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> } }); - for(auto depPtr : stencilDependencies){ + for (auto depPtr : stencilDependencies) { const auto& dep = *depPtr; - auto nodeA = mGraph().getGraphNode(dep.getSource()); - auto nodeB = mGraph().getGraphNode(dep.getDestination()); + auto nodeA = mGraph().getGraphNode(dep.getSource()); + auto nodeB = mGraph().getGraphNode(dep.getDestination()); - auto& newHaloContainer = Neon::set::Container::factoryHaloUpdate(); + auto stencilInfo = dep.getListStencilInfo(); - mGraph().addNodeInBetween() + for(auto& infoPrt : stencilInfo){ + mGraph().addNodeInBetween(dep.) + + } } // Detects all stencil nodes - std::vector stencilNodesUids; + std::vector stencilNodesUids; - mGraph().forEachNode([&](Neon::set::container::GraphData::Uid nodeUid) { + mGraph().forEachNode([&](Neon::set::container::GraphInfo::NodeUid nodeUid) { const auto& node = mGraph().getGraphNode(nodeUid); auto pattern = node.getContainer().getContainerInterface().getContainerPatternType(); if (pattern == Neon::set::ContainerPatternType::stencil) { From 7e08c1cfed4552f936faac215065437199c79451 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Fri, 21 Oct 2022 09:02:19 -0400 Subject: [PATCH 39/67] Fixing merging issues after merging develop. --- .../Neon/domain/interface/FieldBaseTemplate.h | 4 +- .../domain/interface/FieldBaseTemplate_imp.h | 2 +- .../Neon/domain/internal/dGrid/dFieldDev.h | 2 +- .../domain/internal/dGrid/dFieldDev_imp.h | 4 +- .../Neon/domain/internal/eGrid/eFieldDev.h | 4 +- .../Neon/domain/patterns/PatternScalar.h | 6 +-- .../Neon/domain/patterns/PatternScalar_imp.h | 4 +- libNeonSet/include/Neon/set/Containter_imp.h | 2 +- libNeonSet/include/Neon/set/DataSet.h | 12 +++-- .../include/Neon/set/MultiDeviceObjectUid.h | 7 --- ...ectInterface.h => MultiXpuDataInterface.h} | 24 +++++----- libNeonSet/include/Neon/set/MultiXpuDataUid.h | 7 +++ libNeonSet/include/Neon/set/Replica.h | 4 +- libNeonSet/include/Neon/set/SingletonSet.h | 8 ++-- .../Neon/set/container/AnchorContainer.h | 4 +- .../include/Neon/set/container/ContainerAPI.h | 15 +++--- .../set/container/ContainerExecutionType.h | 1 - .../set/container/ContainerOperationType.h | 1 - .../Neon/set/container/ContainerPatternType.h | 1 - .../Neon/set/container/DeviceContainer.h | 2 +- .../set/container/DeviceManagedContainer.h | 2 +- .../DeviceThenHostManagedContainer.h | 4 +- .../Neon/set/container/GraphContainer.h | 2 +- .../Neon/set/container/HostManagedContainer.h | 2 +- .../include/Neon/set/container/Loader.h | 40 ++++++++-------- .../set/container/OldDeviceManagedContainer.h | 2 +- .../include/Neon/set/dependency/AccessType.h | 2 +- .../include/Neon/set/dependency/Alias.h | 17 ------- .../Neon/set/dependency/DataDependencyType.h | 4 +- .../include/Neon/set/dependency/Token.h | 48 +++++++++++-------- libNeonSet/include/Neon/set/memory/memSet.h | 6 +-- .../src/set/container/AnchorContainer.cpp | 2 +- libNeonSet/src/set/container/ContainerAPI.cpp | 8 ++-- .../src/set/container/GraphContainer.cpp | 2 +- .../src/set/depencencyTools/AccessType.cpp | 2 +- .../depencencyTools/DataDependencyType.cpp | 4 +- libNeonSet/src/set/depencencyTools/Token.cpp | 18 +++---- .../Neon/skeleton/internal/MultiGpuGraph.h | 2 +- .../internal/dependencyTools/DataDependency.h | 10 ++-- .../dependencyTools/DependencyAnalyser.h | 10 ++-- .../dependencyTools/UserDataManager.h | 12 ++--- .../skeleton/depencencyTools/Dependency.cpp | 10 ++-- .../depencencyTools/DependencyAnalyser.cpp | 20 ++++---- .../depencencyTools/UserDataManager.cpp | 10 ++-- .../src/skeleton/internal/multiGpuGraph.cpp | 4 +- 45 files changed, 174 insertions(+), 183 deletions(-) delete mode 100644 libNeonSet/include/Neon/set/MultiDeviceObjectUid.h rename libNeonSet/include/Neon/set/{MultiDeviceObjectInterface.h => MultiXpuDataInterface.h} (69%) create mode 100644 libNeonSet/include/Neon/set/MultiXpuDataUid.h delete mode 100644 libNeonSet/include/Neon/set/dependency/Alias.h diff --git a/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate.h b/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate.h index 2ba43eca..fa913e2e 100644 --- a/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate.h +++ b/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate.h @@ -6,7 +6,7 @@ #include "Neon/set/DataConfig.h" #include "Neon/set/DevSet.h" -#include "Neon/set/MultiDeviceObjectInterface.h" +#include "Neon/set/MultiXpuDataInterface.h" #include "Neon/set/memory/memSet.h" #include "Neon/domain/interface/FieldBase.h" @@ -21,7 +21,7 @@ template class FieldBaseTemplate : public FieldBase, - public Neon::set::interface::MultiDeviceObjectInterface + public Neon::set::interface::MultiXpuDataInterface { public: using Partition = P; diff --git a/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate_imp.h b/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate_imp.h index 7156200d..870f859e 100644 --- a/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate_imp.h +++ b/libNeonDomain/include/Neon/domain/interface/FieldBaseTemplate_imp.h @@ -157,7 +157,7 @@ auto FieldBaseTemplate::swapUIDBeforeFullSwap(FieldBaseTemplate:: NEON_THROW(exp); } - Neon::set::interface::MultiDeviceObjectInterface::swapUIDs(A,B); + Neon::set::interface::MultiXpuDataInterface::swapUIDs(A,B); } diff --git a/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev.h b/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev.h index 9c4d8c9b..ad43f36a 100644 --- a/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev.h +++ b/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev.h @@ -87,7 +87,7 @@ class dFieldDev ~dFieldDev() = default; - auto uid() const -> Neon::set::MultiDeviceObjectUid; + auto uid() const -> Neon::set::dataDependency::MultiXpuDataUid; auto grid() -> grid_t&; diff --git a/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev_imp.h b/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev_imp.h index 04449e69..c9bfd809 100644 --- a/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev_imp.h +++ b/libNeonDomain/include/Neon/domain/internal/dGrid/dFieldDev_imp.h @@ -74,10 +74,10 @@ auto dFieldDev::operator=(dFieldDev&& other) -> dFieldDev& } template -auto dFieldDev::uid() const -> Neon::set::MultiDeviceObjectUid +auto dFieldDev::uid() const -> Neon::set::dataDependency::MultiXpuDataUid { void* addr = static_cast(m_data.get()); - Neon::set::MultiDeviceObjectUid uidRes = (size_t)addr; + Neon::set::dataDependency::MultiXpuDataUid uidRes = (size_t)addr; return uidRes; } diff --git a/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h b/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h index 2c9d8330..e4196d4a 100644 --- a/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h +++ b/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h @@ -200,10 +200,10 @@ class eFieldDevice_t * Returns a unique identifier for this type of DataSet * @return */ - auto uid() const -> Neon::set::MultiDeviceObjectUid + auto uid() const -> Neon::set::dataDependency::MultiXpuDataUid { void* addr = static_cast(m_data.get()); - Neon::set::MultiDeviceObjectUid uidRes = (size_t)addr; + Neon::set::dataDependency::MultiXpuDataUid uidRes = (size_t)addr; return uidRes; } diff --git a/libNeonDomain/include/Neon/domain/patterns/PatternScalar.h b/libNeonDomain/include/Neon/domain/patterns/PatternScalar.h index a4fdff78..a9f15853 100644 --- a/libNeonDomain/include/Neon/domain/patterns/PatternScalar.h +++ b/libNeonDomain/include/Neon/domain/patterns/PatternScalar.h @@ -1,13 +1,13 @@ #pragma once #include "Neon/set/Backend.h" -#include "Neon/set/MultiDeviceObjectInterface.h" +#include "Neon/set/MultiXpuDataInterface.h" #include "Neon/set/patterns/BlasSet.h" namespace Neon { template class PatternScalar - : public set::interface::MultiDeviceObjectInterface, int> + : public set::interface::MultiXpuDataInterface, int> { public: @@ -37,7 +37,7 @@ class PatternScalar /** * Returns a unique identifier to be used for the loading process */ - auto uid() const -> Neon::set::MultiDeviceObjectUid; + auto uid() const -> Neon::set::dataDependency::MultiXpuDataUid; auto getPartition(const Neon::DeviceType& devType, const Neon::SetIdx& idx, diff --git a/libNeonDomain/include/Neon/domain/patterns/PatternScalar_imp.h b/libNeonDomain/include/Neon/domain/patterns/PatternScalar_imp.h index 06d516b8..788bdd6c 100644 --- a/libNeonDomain/include/Neon/domain/patterns/PatternScalar_imp.h +++ b/libNeonDomain/include/Neon/domain/patterns/PatternScalar_imp.h @@ -45,10 +45,10 @@ auto PatternScalar::operator()() const -> const T& } template -auto PatternScalar::uid() const -> Neon::set::MultiDeviceObjectUid +auto PatternScalar::uid() const -> Neon::set::dataDependency::MultiXpuDataUid { void* addr = static_cast(mData.get()); - Neon::set::MultiDeviceObjectUid uidRes = (size_t)addr; + Neon::set::dataDependency::MultiXpuDataUid uidRes = (size_t)addr; return uidRes; } diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h index 3c401836..c412075d 100644 --- a/libNeonSet/include/Neon/set/Containter_imp.h +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" + #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/DataSet.h b/libNeonSet/include/Neon/set/DataSet.h index b729db7b..782b2d77 100644 --- a/libNeonSet/include/Neon/set/DataSet.h +++ b/libNeonSet/include/Neon/set/DataSet.h @@ -2,7 +2,7 @@ #include #include "Neon/core/types/DataView.h" -#include "Neon/set/MultiDeviceObjectUid.h" +#include "Neon/set/MultiXpuDataUid.h" #include "Neon/sys/devices/DevInterface.h" namespace Neon { @@ -103,10 +103,11 @@ struct DataSet * Returns a unique identifier for the data set. * @return */ - auto uid() -> MultiDeviceObjectUid + auto uid() + const -> Neon::set::dataDependency::MultiXpuDataUid { - T_ta* addr = m_data.get(); - MultiDeviceObjectUid uidRes = (size_t)addr; + T_ta* addr = m_data.get(); + auto uidRes = (Neon::set::dataDependency::MultiXpuDataUid)addr; return uidRes; } @@ -114,7 +115,8 @@ struct DataSet * * @return */ - auto local(Neon::DeviceType, SetIdx setIdx, const Neon::DataView& dataView = Neon::DataView::STANDARD) + auto local(Neon::DeviceType, SetIdx setIdx, + const Neon::DataView& dataView = Neon::DataView::STANDARD) -> T_ta& { (void)dataView; diff --git a/libNeonSet/include/Neon/set/MultiDeviceObjectUid.h b/libNeonSet/include/Neon/set/MultiDeviceObjectUid.h deleted file mode 100644 index d15fe9bc..00000000 --- a/libNeonSet/include/Neon/set/MultiDeviceObjectUid.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace Neon::set { - -using MultiDeviceObjectUid = size_t; - -} // namespace Neon::set diff --git a/libNeonSet/include/Neon/set/MultiDeviceObjectInterface.h b/libNeonSet/include/Neon/set/MultiXpuDataInterface.h similarity index 69% rename from libNeonSet/include/Neon/set/MultiDeviceObjectInterface.h rename to libNeonSet/include/Neon/set/MultiXpuDataInterface.h index f745f961..2eb64549 100644 --- a/libNeonSet/include/Neon/set/MultiDeviceObjectInterface.h +++ b/libNeonSet/include/Neon/set/MultiXpuDataInterface.h @@ -4,22 +4,22 @@ #include "Neon/core/core.h" #include "Neon/core/types/Execution.h" -#include "Neon/set/MultiDeviceObjectUid.h" +#include "Neon/set/MultiXpuDataUid.h" namespace Neon::set::interface { template -class MultiDeviceObjectInterface +class MultiXpuDataInterface { public: using Partition = P; using Storage = S; - using Self = MultiDeviceObjectInterface; + using Self = MultiXpuDataInterface; - virtual ~MultiDeviceObjectInterface() = default; + virtual ~MultiXpuDataInterface() = default; - MultiDeviceObjectInterface(); + MultiXpuDataInterface(); virtual auto updateIO(int streamId = 0) -> void = 0; @@ -44,7 +44,7 @@ class MultiDeviceObjectInterface auto getStorage() const -> const Storage&; - auto getUid() const -> Neon::set::MultiDeviceObjectUid; + auto getUid() const -> Neon::set::dataDependency::MultiXpuDataUid; protected: static auto swapUIDs(Self& A, Self& B) -> void; @@ -56,33 +56,33 @@ class MultiDeviceObjectInterface }; template -auto MultiDeviceObjectInterface::getStorage() -> Storage& +auto MultiXpuDataInterface::getStorage() -> Storage& { return *(mStorage.get()); } template -auto MultiDeviceObjectInterface::getStorage() const -> const Storage& +auto MultiXpuDataInterface::getStorage() const -> const Storage& { return *(mStorage.get()); } template -auto MultiDeviceObjectInterface::getUid() const -> Neon::set::MultiDeviceObjectUid +auto MultiXpuDataInterface::getUid() const -> Neon::set::dataDependency::MultiXpuDataUid { void* addr = static_cast(mUid.get()); - Neon::set::MultiDeviceObjectUid uidRes = (size_t)addr; + Neon::set::dataDependency::MultiXpuDataUid uidRes = (size_t)addr; return uidRes; } template -MultiDeviceObjectInterface::MultiDeviceObjectInterface() +MultiXpuDataInterface::MultiXpuDataInterface() { mStorage = std::make_shared(); mUid = std::make_shared(); } template -auto MultiDeviceObjectInterface::swapUIDs(MultiDeviceObjectInterface::Self& A, MultiDeviceObjectInterface::Self& B) -> void +auto MultiXpuDataInterface::swapUIDs(MultiXpuDataInterface::Self& A, MultiXpuDataInterface::Self& B) -> void { std::swap(A.mUid,B.mUid); } diff --git a/libNeonSet/include/Neon/set/MultiXpuDataUid.h b/libNeonSet/include/Neon/set/MultiXpuDataUid.h new file mode 100644 index 00000000..cd693611 --- /dev/null +++ b/libNeonSet/include/Neon/set/MultiXpuDataUid.h @@ -0,0 +1,7 @@ +#pragma once + +namespace Neon::set::dataDependency { + +using MultiXpuDataUid = size_t; + +} // namespace Neon::set::dataDependency diff --git a/libNeonSet/include/Neon/set/Replica.h b/libNeonSet/include/Neon/set/Replica.h index ee7bafa7..508b7944 100644 --- a/libNeonSet/include/Neon/set/Replica.h +++ b/libNeonSet/include/Neon/set/Replica.h @@ -3,7 +3,7 @@ #include #include "Neon/set/Containter.h" #include "Neon/set/DevSet.h" -#include "Neon/set/MultiDeviceObjectInterface.h" +#include "Neon/set/MultiXpuDataInterface.h" namespace Neon::set::internal::datum { @@ -69,7 +69,7 @@ namespace Neon::set { * @tparam Obj */ template -class Replica : public Neon::set::interface::MultiDeviceObjectInterface, +class Replica : public Neon::set::interface::MultiXpuDataInterface, Neon::set::internal::datum::Storage> { public: diff --git a/libNeonSet/include/Neon/set/SingletonSet.h b/libNeonSet/include/Neon/set/SingletonSet.h index 6cdc7d12..bd91a577 100644 --- a/libNeonSet/include/Neon/set/SingletonSet.h +++ b/libNeonSet/include/Neon/set/SingletonSet.h @@ -72,10 +72,10 @@ struct SingletonSet * Returns a unique identifier for the data set. * @return */ - auto uid() -> MultiDeviceObjectUid + auto uid() ->Neon::set::dataDependency::MultiXpuDataUid { T_ta* addr = m_data.get(); - MultiDeviceObjectUid uidRes = (size_t)addr; + Neon::set::dataDependency::MultiXpuDataUid uidRes = (size_t)addr; return uidRes; } @@ -83,10 +83,10 @@ struct SingletonSet * Returns a unique identifier for the data set. * @return */ - auto uid() const -> MultiDeviceObjectUid + auto uid() const ->Neon::set::dataDependency::MultiXpuDataUid { T_ta* addr = m_data.get(); - MultiDeviceObjectUid uidRes = (size_t)addr; + Neon::set::dataDependency::MultiXpuDataUid uidRes = (size_t)addr; return uidRes; } diff --git a/libNeonSet/include/Neon/set/container/AnchorContainer.h b/libNeonSet/include/Neon/set/container/AnchorContainer.h index 945885b3..0afb0bad 100644 --- a/libNeonSet/include/Neon/set/container/AnchorContainer.h +++ b/libNeonSet/include/Neon/set/container/AnchorContainer.h @@ -23,7 +23,7 @@ struct AnchorContainer : ContainerAPI public: AnchorContainer(const std::string& name); - auto parse() -> const std::vector& override; + auto parse() -> const std::vector& override; auto getHostContainer() -> std::shared_ptr final; @@ -44,7 +44,7 @@ struct AnchorContainer : ContainerAPI virtual auto run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void override; private: - std::vector mEmtpy; + std::vector mEmtpy; }; diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index 28805856..21e364fa 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -5,8 +5,9 @@ #include "Neon/set/DevSet.h" #include "Neon/set/container/ContainerExecutionType.h" -#include "Neon/set/dependencyTools/DataParsing.h" + +#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" @@ -75,7 +76,7 @@ struct ContainerAPI * @return */ virtual auto parse() - -> const std::vector& = 0; + -> const std::vector& = 0; /** @@ -88,13 +89,13 @@ struct ContainerAPI * Returns a list of tokens as result of parsing the Container loading lambda. */ auto getTokens() const - -> const std::vector&; + -> const std::vector&; /** * Returns a list of tokens as result of parsing the Container loading lambda. */ auto getTokenRef() - -> std::vector&; + -> std::vector&; /** * Get the execution type for the Container. @@ -129,7 +130,7 @@ struct ContainerAPI /** * Add a new token */ - auto addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) + auto addToken(Neon::set::dataDependency::Token& dataParsing) -> void; /** @@ -179,7 +180,7 @@ struct ContainerAPI * Set the patter for this Container based on a list of tokens. * @param tokens */ - auto setContainerPattern(const std::vector& tokens) + auto setContainerPattern(const std::vector& tokens) -> void; /** @@ -196,7 +197,7 @@ struct ContainerAPI -> void; private: - using TokenList = std::vector; + using TokenList = std::vector; std::string mName{"Anonymous"}; /**< Name of the Container */ bool mParsingDataUpdated = false; diff --git a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h index 2673c4e2..9ba63e3c 100644 --- a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h +++ b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h @@ -1,7 +1,6 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/container/ContainerOperationType.h b/libNeonSet/include/Neon/set/container/ContainerOperationType.h index edf9b061..9b2ddad4 100644 --- a/libNeonSet/include/Neon/set/container/ContainerOperationType.h +++ b/libNeonSet/include/Neon/set/container/ContainerOperationType.h @@ -1,7 +1,6 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/container/ContainerPatternType.h b/libNeonSet/include/Neon/set/container/ContainerPatternType.h index 93b16a21..19424520 100644 --- a/libNeonSet/include/Neon/set/container/ContainerPatternType.h +++ b/libNeonSet/include/Neon/set/container/ContainerPatternType.h @@ -1,7 +1,6 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" #include "functional" #include "type_traits" diff --git a/libNeonSet/include/Neon/set/container/DeviceContainer.h b/libNeonSet/include/Neon/set/container/DeviceContainer.h index 28b90294..2d0e8949 100644 --- a/libNeonSet/include/Neon/set/container/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceContainer.h @@ -78,7 +78,7 @@ struct DeviceContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { if (!this->isParsingDataUpdated()) { auto parser = newParser(); diff --git a/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h index f8e9cdec..76306d5b 100644 --- a/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceManagedContainer.h @@ -62,7 +62,7 @@ struct DeviceManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { Neon::SetIdx setIdx(0); if (!this->mParsingDataUpdated) { diff --git a/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h index 42b9aa6a..0f183a74 100644 --- a/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h @@ -64,7 +64,7 @@ struct DeviceThenHostManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { mHost->parse(); mDevice->parse(); @@ -75,7 +75,7 @@ struct DeviceThenHostManagedContainer : ContainerAPI for (auto const& token : devTokens) { getTokenRef().push_back(token); } - std::vector filtered; + std::vector filtered; for (auto const& token : hostTokens) { bool foundMatch = false; for (auto& acceptedTokens : getTokenRef()) { diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index 3630ce1a..caa68b04 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -28,7 +28,7 @@ struct GraphContainer : ContainerAPI auto newParser() -> Loader; - auto parse() -> const std::vector& override; + auto parse() -> const std::vector& override; auto getGraph() -> const Neon::set::container::Graph& override; diff --git a/libNeonSet/include/Neon/set/container/HostManagedContainer.h b/libNeonSet/include/Neon/set/container/HostManagedContainer.h index 20c1b306..a3127615 100644 --- a/libNeonSet/include/Neon/set/container/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/HostManagedContainer.h @@ -71,7 +71,7 @@ struct HostManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { auto parser = newParser(); Neon::SetIdx setIdx(0); diff --git a/libNeonSet/include/Neon/set/container/Loader.h b/libNeonSet/include/Neon/set/container/Loader.h index ff18e703..deabbcb1 100644 --- a/libNeonSet/include/Neon/set/container/Loader.h +++ b/libNeonSet/include/Neon/set/container/Loader.h @@ -1,7 +1,7 @@ #pragma once -//#include +// #include #include "Neon/set/DevSet.h" -#include "Neon/set/dependencyTools/DataParsing.h" + #include "Neon/set/container/ContainerAPI.h" #include "type_traits" @@ -151,10 +151,10 @@ struct Loader public: Loader(Neon::set::internal::ContainerAPI& container, - Neon::DeviceType devE, - Neon::SetIdx setIdx, - Neon::DataView dataView, - Neon::set::internal::LoadingMode_e::e loadingMode) + Neon::DeviceType devE, + Neon::SetIdx setIdx, + Neon::DataView dataView, + Neon::set::internal::LoadingMode_e::e loadingMode) : m_container(container), m_devE(devE), m_setIdx(setIdx), @@ -183,11 +183,11 @@ struct Loader switch (m_loadingMode) { case Neon::set::internal::LoadingMode_e::PARSE_AND_EXTRACT_LAMBDA: { - using namespace Neon::set::internal::dependencyTools; - DataUId_t uid = field.getUid(); - constexpr Access_et::e access = Access_et::WRITE; - Compute compute = computeE; - DataToken dataToken(uid, access, compute); + using namespace Neon::set::dataDependency; + Neon::set::dataDependency::MultiXpuDataUid uid = field.getUid(); + constexpr auto access = Neon::set::dataDependency::AccessType::WRITE; + Compute compute = computeE; + Token token(uid, access, compute); if (compute == Neon::Compute::STENCIL && (stencilOptions == StencilOptions::DEFAULT || stencilOptions == StencilOptions::LATTICE)) { @@ -196,7 +196,7 @@ struct Loader NEON_THROW(exp); } - m_container.addToken(dataToken); + m_container.addToken(token); return field.getPartition(m_devE, m_setIdx, m_dataView); } @@ -222,14 +222,14 @@ struct Loader { switch (m_loadingMode) { case Neon::set::internal::LoadingMode_e::PARSE_AND_EXTRACT_LAMBDA: { - using namespace Neon::set::internal::dependencyTools; - DataUId_t uid = field.getUid(); - constexpr Access_et::e access = Access_et::READ; - Neon::Compute compute = computeE; - DataToken dataToken(uid, access, compute); + using namespace Neon::set::dataDependency; + Neon::set::dataDependency::MultiXpuDataUid uid = field.getUid(); + constexpr auto access = Neon::set::dataDependency::AccessType::READ; + Neon::Compute compute = computeE; + Token token(uid, access, compute); if (compute == Neon::Compute::STENCIL) { - dataToken.setHaloUpdate( + token.setHaloUpdate( [&](Neon::set::HuOptions& opt) -> void { // TODO: add back following line with template metaprogramming // field.haloUpdate(bk, opt); @@ -245,7 +245,7 @@ struct Loader return; }); } - m_container.addToken(dataToken); + m_container.addToken(token); return field.getPartition(m_devE, m_setIdx, m_dataView); } @@ -257,4 +257,4 @@ struct Loader } }; -} // namespace Neon \ No newline at end of file +} // namespace Neon::set \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h b/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h index ba653e0d..5f444648 100644 --- a/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/OldDeviceManagedContainer.h @@ -59,7 +59,7 @@ struct OldDeviceManagedContainer : ContainerAPI return parser; } - auto parse() -> const std::vector& override + auto parse() -> const std::vector& override { auto parser = newParser(); this->mLoadingLambda(parser); diff --git a/libNeonSet/include/Neon/set/dependency/AccessType.h b/libNeonSet/include/Neon/set/dependency/AccessType.h index bd489f2d..dc7bdc88 100644 --- a/libNeonSet/include/Neon/set/dependency/AccessType.h +++ b/libNeonSet/include/Neon/set/dependency/AccessType.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/Backend.h" -namespace Neon::internal::dataDependency { +namespace Neon::set::dataDependency { /** diff --git a/libNeonSet/include/Neon/set/dependency/Alias.h b/libNeonSet/include/Neon/set/dependency/Alias.h deleted file mode 100644 index 055c92d0..00000000 --- a/libNeonSet/include/Neon/set/dependency/Alias.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "Neon/set/Backend.h" -#include "Neon/set/MultiDeviceObjectUid.h" - -namespace Neon::internal::dataDependency { - -/** - * Unique identifier for a kernel parameter - */ -using MdObjUid = Neon::set::MultiDeviceObjectUid; - -/** - * Unique identifier for a kernel parameter - */ -using MdObjIdx = Neon::set::MultiDeviceObjectUid; - -} // namespace Neon::internal::dataDependency diff --git a/libNeonSet/include/Neon/set/dependency/DataDependencyType.h b/libNeonSet/include/Neon/set/dependency/DataDependencyType.h index 386f7d15..378d1b93 100644 --- a/libNeonSet/include/Neon/set/dependency/DataDependencyType.h +++ b/libNeonSet/include/Neon/set/dependency/DataDependencyType.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/Backend.h" -namespace Neon::internal::dataDependency { +namespace Neon::set::dataDependency { /** * Classical definition of dependency types. @@ -26,5 +26,5 @@ struct DataDependencyTypeUtils static auto toString(DataDependencyType type) -> std::string; }; -std::ostream& operator<<(std::ostream& os, Neon::internal::dataDependency::DataDependencyType const& m); +std::ostream& operator<<(std::ostream& os, Neon::set::dataDependency::DataDependencyType const& m); } diff --git a/libNeonSet/include/Neon/set/dependency/Token.h b/libNeonSet/include/Neon/set/dependency/Token.h index febb09da..e215406e 100644 --- a/libNeonSet/include/Neon/set/dependency/Token.h +++ b/libNeonSet/include/Neon/set/dependency/Token.h @@ -2,11 +2,11 @@ #include "Neon/set/Backend.h" #include "Neon/set/HuOptions.h" +#include "Neon/set/MultiXpuDataUid.h" #include "Neon/set/dependency/AccessType.h" -#include "Neon/set/dependency/Alias.h" #include "Neon/set/dependency/ComputeType.h" -namespace Neon::internal::dataDependency { +namespace Neon::set::dataDependency { /** * Stores type of operations on data for each kernels while user code is "parsed" @@ -20,36 +20,39 @@ struct Token /** * Unique constructor */ - Token(MdObjUid m_uid, - AccessType m_access, - Neon::Compute m_compute); + Token(Neon::set::dataDependency::MultiXpuDataUid m_uid, + Neon::set::dataDependency::AccessType m_access, + Neon::Compute m_compute); /** * Method to update a token */ - auto update(MdObjUid m_uid, - AccessType m_access, - Neon::Compute m_compute) -> void; + auto update(Neon::set::dataDependency::MultiXpuDataUid m_uid, + Neon::set::dataDependency::AccessType m_access, + Neon::Compute m_compute) -> void; /** * It returns the multi-GPU data uid */ - auto uid() const -> MdObjUid; + auto uid() const -> Neon::set::dataDependency::MultiXpuDataUid; /** * It returns the type of data access */ - auto access() const -> AccessType; + auto access() + const -> Neon::set::dataDependency::AccessType; /** * Returns the compute pattern */ - auto compute() const -> Neon::Compute; + auto compute() + const -> Neon::Compute; /** * Converts the token into a string */ - auto toString() const -> std::string; + auto toString() + const -> std::string; /** * It sets the halo update container associated to the multi-GPU data. @@ -57,21 +60,26 @@ struct Token * @param huPerDevice */ auto setHaloUpdate(std::function hu, - std::function huPerDevice) -> void; + std::function huPerDevice) + -> void; - auto getHaloUpdate() const -> const std::function&; + auto getHaloUpdate() + const -> const std::function&; - auto getHaloUpdatePerDevice() const -> const std::function&; + auto getHaloUpdatePerDevice() + const -> const std::function&; - auto mergeAccess(AccessType) -> void; + auto mergeAccess(AccessType) + -> void; private: - MdObjUid mUid; - AccessType mAccess; - Compute mCompute; + Neon::set::dataDependency::MultiXpuDataUid mUid; + Neon::set::dataDependency::AccessType mAccess; + Neon::Compute mCompute; + std::function mHu; std::function mHuPerDevice; }; -} // namespace dependency +} // namespace Neon::set::dataDependency diff --git a/libNeonSet/include/Neon/set/memory/memSet.h b/libNeonSet/include/Neon/set/memory/memSet.h index 73d9e076..1255876a 100644 --- a/libNeonSet/include/Neon/set/memory/memSet.h +++ b/libNeonSet/include/Neon/set/memory/memSet.h @@ -115,10 +115,10 @@ class MemSet_t m_memSet_shp = std::make_shared(numEntries); } - auto uid() const -> Neon::set::MultiDeviceObjectUid + auto uid() const -> Neon::set::dataDependency::MultiXpuDataUid { - void* addr = static_cast(m_memSet_shp.get()); - Neon::set::MultiDeviceObjectUid uidRes = (size_t)addr; + void* addr = static_cast(m_memSet_shp.get()); + auto uidRes = (Neon::set::dataDependency::MultiXpuDataUid)addr; return uidRes; } diff --git a/libNeonSet/src/set/container/AnchorContainer.cpp b/libNeonSet/src/set/container/AnchorContainer.cpp index b100e679..c0e86509 100644 --- a/libNeonSet/src/set/container/AnchorContainer.cpp +++ b/libNeonSet/src/set/container/AnchorContainer.cpp @@ -13,7 +13,7 @@ AnchorContainer::AnchorContainer(const std::string& name) } -auto AnchorContainer::parse() -> const std::vector& +auto AnchorContainer::parse() -> const std::vector& { return mEmtpy; } diff --git a/libNeonSet/src/set/container/ContainerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp index c7e07f8d..c54e8fab 100644 --- a/libNeonSet/src/set/container/ContainerAPI.cpp +++ b/libNeonSet/src/set/container/ContainerAPI.cpp @@ -3,7 +3,7 @@ namespace Neon::set::internal { -auto ContainerAPI::addToken(Neon::set::internal::dependencyTools::DataToken& dataParsing) +auto ContainerAPI::addToken(Neon::set::dataDependency::Token& dataParsing) -> void { mParsed.push_back(dataParsing); @@ -16,13 +16,13 @@ auto ContainerAPI::getName() const } auto ContainerAPI::getTokens() const - -> const std::vector& + -> const std::vector& { return mParsed; } auto ContainerAPI::getTokenRef() - -> std::vector& + -> std::vector& { return mParsed; } @@ -62,7 +62,7 @@ auto ContainerAPI::setContainerPattern(Neon::set::ContainerPatternType patternTy this->mContainerPatternType = patternType; } -auto ContainerAPI::setContainerPattern(const std::vector& tokens) +auto ContainerAPI::setContainerPattern(const std::vector& tokens) -> void { Neon::set::ContainerPatternType patternType = Neon::set::ContainerPatternType::map; diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index e266ccb3..64278b3e 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -27,7 +27,7 @@ auto GraphContainer::newParser() -> Loader return parser; } -auto GraphContainer::parse() -> const std::vector& +auto GraphContainer::parse() -> const std::vector& { Neon::SetIdx setIdx(0); if (!this->isParsingDataUpdated()) { diff --git a/libNeonSet/src/set/depencencyTools/AccessType.cpp b/libNeonSet/src/set/depencencyTools/AccessType.cpp index 9cbdd823..59365819 100644 --- a/libNeonSet/src/set/depencencyTools/AccessType.cpp +++ b/libNeonSet/src/set/depencencyTools/AccessType.cpp @@ -1,6 +1,6 @@ #include "Neon/set/dependency/AccessType.h" -namespace Neon::internal::dataDependency { +namespace Neon::set::dataDependency { auto AccessTypeUtils::toString(AccessType val) -> std::string { diff --git a/libNeonSet/src/set/depencencyTools/DataDependencyType.cpp b/libNeonSet/src/set/depencencyTools/DataDependencyType.cpp index fefd3644..f5a8035a 100644 --- a/libNeonSet/src/set/depencencyTools/DataDependencyType.cpp +++ b/libNeonSet/src/set/depencencyTools/DataDependencyType.cpp @@ -1,6 +1,6 @@ #include "Neon/set/dependency/DataDependencyType.h" -namespace Neon::internal::dataDependency { +namespace Neon::set::dataDependency { auto DataDependencyTypeUtils::toString(DataDependencyType val) -> std::string { @@ -24,7 +24,7 @@ auto DataDependencyTypeUtils::toString(DataDependencyType val) -> std::string NEON_THROW_UNSUPPORTED_OPTION(); } -std::ostream& operator<<(std::ostream& os, Neon::internal::dataDependency::DataDependencyType const& m){ +std::ostream& operator<<(std::ostream& os, Neon::set::dataDependency::DataDependencyType const& m){ os << DataDependencyTypeUtils::toString(m); return os; } diff --git a/libNeonSet/src/set/depencencyTools/Token.cpp b/libNeonSet/src/set/depencencyTools/Token.cpp index c9726d00..adf35406 100644 --- a/libNeonSet/src/set/depencencyTools/Token.cpp +++ b/libNeonSet/src/set/depencencyTools/Token.cpp @@ -1,17 +1,17 @@ #include "Neon/set//dependency/Token.h" -namespace Neon::internal::dataDependency { +namespace Neon::set::dataDependency { -Token::Token(MdObjUid uid, - AccessType access, - Compute compute) +Token::Token(MultiXpuDataUid uid, + AccessType access, + Compute compute) { update(uid, access, compute); } -auto Token::update(MdObjUid uid, - AccessType access, - Compute compute) -> void +auto Token::update(MultiXpuDataUid uid, + AccessType access, + Compute compute) -> void { mUid = uid; mAccess = access; @@ -38,7 +38,7 @@ auto Token::compute() const -> Compute return mCompute; } -auto Token::uid() const -> MdObjUid +auto Token::uid() const -> MultiXpuDataUid { return mUid; } @@ -74,4 +74,4 @@ auto Token::mergeAccess(AccessType tomerge) -> void mAccess = AccessTypeUtils::merge(mAccess, tomerge); } -} // namespace Neon::internal::dataDependency \ No newline at end of file +} // namespace Neon::set::dataDependency \ No newline at end of file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h b/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h index 4a691090..fa55a7ec 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h @@ -137,7 +137,7 @@ struct MultiGpuGraph * @return */ auto helpParseContainer(Neon::set::Container& kernelContainerIdx) - -> std::vector; + -> std::vector; /** * helper function to export a dot file diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h index 2dfd3e75..ed8f4712 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h @@ -12,8 +12,8 @@ struct DataDependency private: Neon::set::container::GraphInfo::NodeUid mT0 = 0; Neon::set::container::GraphInfo::NodeUid mT1 = 0; - Neon::internal::dataDependency::DataDependencyType mType = Neon::internal::dataDependency::DataDependencyType::NONE; - Neon::internal::dataDependency::MdObjUid mDataUid = 0; + Neon::set::dataDependency::DataDependencyType mType = Neon::set::dataDependency::DataDependencyType::NONE; + Neon::set::dataDependency::MdObjUid mDataUid = 0; public: /** @@ -31,8 +31,8 @@ struct DataDependency * @param B */ DataDependency(Neon::set::container::GraphInfo::NodeUid t1, - Neon::internal::dataDependency::DataDependencyType type, - Neon::internal::dataDependency::MdObjUid m_uid, + Neon::set::dataDependency::DataDependencyType type, + Neon::set::dataDependency::MdObjUid m_uid, Neon::set::container::GraphInfo::NodeUid t0); /** @@ -51,7 +51,7 @@ struct DataDependency * Returns the dependency type * @return */ - auto type() -> Neon::internal::dataDependency::DataDependencyType; + auto type() -> Neon::set::dataDependency::DataDependencyType; /** * Returns the "before" kernel id diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h index 3ea77fc3..30d5fc44 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h @@ -15,16 +15,16 @@ struct DependencyAnalyser std::vector mParsedR{}; std::vector mParsedW{}; - Neon::internal::dataDependency::MdObjUid mUid; - Neon::internal::dataDependency::MdObjIdx mIdx; + Neon::set::dataDependency::MdObjUid mUid; + Neon::set::dataDependency::MdObjIdx mIdx; public: DependencyAnalyser() = delete; - DependencyAnalyser(Neon::internal::dataDependency::MdObjUid, - Neon::internal::dataDependency::MdObjIdx); + DependencyAnalyser(Neon::set::dataDependency::MdObjUid, + Neon::set::dataDependency::MdObjIdx); auto update(Neon::set::container::GraphInfo::NodeUid newKernel, - Neon::internal::dataDependency::AccessType newOp) + Neon::set::dataDependency::AccessType newOp) -> std::vector; }; diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h index cd354856..9ac177fe 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h @@ -21,8 +21,8 @@ namespace Neon::skeleton::internal { struct UserDataManager { std::vector mDepAnalyserVec; - std::map + std::map mUid2Idx; private: @@ -31,8 +31,8 @@ struct UserDataManager * @param uid * @return */ - auto helpGetIdx(Neon::internal::dataDependency::MdObjUid uid) - -> Neon::internal::dataDependency::MdObjIdx; + auto helpGetIdx(Neon::set::dataDependency::MdObjUid uid) + -> Neon::set::dataDependency::MdObjIdx; public: /** @@ -45,8 +45,8 @@ struct UserDataManager * @return */ auto updateStatus(Neon::set::container::GraphInfo::NodeUid newKernel, - Neon::internal::dataDependency::AccessType op, - Neon::internal::dataDependency::MdObjUid uid) -> std::vector; + Neon::set::dataDependency::AccessType op, + Neon::set::dataDependency::MdObjUid uid) -> std::vector; }; } // namespace Neon::skeleton::internal diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp index 0f5d3f66..7f9203d6 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp @@ -3,8 +3,8 @@ namespace Neon::skeleton::internal { DataDependency::DataDependency(Neon::set::container::GraphInfo::NodeUid t1, - Neon::internal::dataDependency::DataDependencyType type, - Neon::internal::dataDependency::MdObjUid uid, + Neon::set::dataDependency::DataDependencyType type, + Neon::set::dataDependency::MdObjUid uid, Neon::set::container::GraphInfo::NodeUid t0) { mT1 = t1; @@ -15,18 +15,18 @@ DataDependency::DataDependency(Neon::set::container::GraphInfo::NodeUid bool DataDependency::isValid() { - return mType != Neon::internal::dataDependency::DataDependencyType::NONE; + return mType != Neon::set::dataDependency::DataDependencyType::NONE; } auto DataDependency::toString() -> std::string { return std::to_string(mT1) + - " -> (" + Neon::internal::dataDependency::DataDependencyTypeUtils::toString(mType) + + " -> (" + Neon::set::dataDependency::DataDependencyTypeUtils::toString(mType) + " [" + std::to_string(mDataUid) + "]) -> " + std::to_string(mT0); } -auto DataDependency::type() -> Neon::internal::dataDependency::DataDependencyType +auto DataDependency::type() -> Neon::set::dataDependency::DataDependencyType { return mType; } diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp index 7b3b7f4e..ad782979 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp @@ -4,19 +4,19 @@ namespace Neon::skeleton::internal { -DependencyAnalyser::DependencyAnalyser(Neon::internal::dataDependency::MdObjUid uid, - Neon::internal::dataDependency::MdObjIdx idx) +DependencyAnalyser::DependencyAnalyser(Neon::set::dataDependency::MdObjUid uid, + Neon::set::dataDependency::MdObjIdx idx) { mUid = uid; mIdx = idx; } auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid newKernel, - Neon::internal::dataDependency::AccessType newOp) + Neon::set::dataDependency::AccessType newOp) -> std::vector { switch (newOp) { - case Neon::internal::dataDependency::AccessType::READ: { + case Neon::set::dataDependency::AccessType::READ: { if (mParsedW.size() == 0) { // We are parsing a READ with no previous WRITE // STEPS: @@ -41,7 +41,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid n auto t0W = mParsedW[0]; auto t1R = newKernel; if (t0W != t1R) { - DataDependency d(t1R, Neon::internal::dataDependency::DataDependencyType::RAW, mUid, t0W); + DataDependency d(t1R, Neon::set::dataDependency::DataDependencyType::RAW, mUid, t0W); output.push_back(d); } } @@ -56,7 +56,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid n } break; } - case Neon::internal::dataDependency::AccessType::WRITE: { + case Neon::set::dataDependency::AccessType::WRITE: { if (mParsedR.empty() && mParsedW.empty()) { // Parsing a WRITE as the first operation in the Container sequence. // @@ -87,7 +87,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid n for (const auto token_t0_READ : mParsedR) { const auto token_t1_WRITE = newKernel; if (token_t1_WRITE != token_t0_READ) { - DataDependency d(token_t1_WRITE, Neon::internal::dataDependency::DataDependencyType::WAR, mUid, token_t0_READ); + DataDependency d(token_t1_WRITE, Neon::set::dataDependency::DataDependencyType::WAR, mUid, token_t0_READ); output.push_back(d); } } @@ -113,7 +113,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid n auto token_t0_WRITE = mParsedW[0]; auto token_t1_WRITE = newKernel; if (token_t0_WRITE != token_t1_WRITE) { - DataDependency d(token_t1_WRITE, Neon::internal::dataDependency::DataDependencyType::WAW, mUid, token_t0_WRITE); + DataDependency d(token_t1_WRITE, Neon::set::dataDependency::DataDependencyType::WAW, mUid, token_t0_WRITE); output.push_back(d); } } @@ -121,7 +121,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid n for (const auto token_t0_READ : mParsedR) { const auto token_t1_WRITE = newKernel; if (token_t1_WRITE != token_t0_READ) { - DataDependency d(token_t1_WRITE, Neon::internal::dataDependency::DataDependencyType::WAR, mUid, token_t0_READ); + DataDependency d(token_t1_WRITE, Neon::set::dataDependency::DataDependencyType::WAR, mUid, token_t0_READ); output.push_back(d); } } @@ -135,7 +135,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid n } break; } - case Neon::internal::dataDependency::AccessType::NONE: { + case Neon::set::dataDependency::AccessType::NONE: { // Error NEON_THROW_UNSUPPORTED_OPTION(""); } diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp index a6db362b..a86ebd2b 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp @@ -2,12 +2,12 @@ namespace Neon::skeleton::internal { -auto UserDataManager::helpGetIdx(Neon::internal::dataDependency::MdObjUid uid) - -> Neon::internal::dataDependency::MdObjIdx +auto UserDataManager::helpGetIdx(Neon::set::dataDependency::MdObjUid uid) + -> Neon::set::dataDependency::MdObjIdx { auto count = mUid2Idx.count(uid); if (count == 0) { - Neon::internal::dataDependency::MdObjIdx idx = mDepAnalyserVec.size(); + Neon::set::dataDependency::MdObjIdx idx = mDepAnalyserVec.size(); mDepAnalyserVec.emplace_back(uid, idx); mUid2Idx[uid] = idx; return idx; @@ -16,8 +16,8 @@ auto UserDataManager::helpGetIdx(Neon::internal::dataDependency::MdObjUid uid) } auto UserDataManager::updateStatus(Neon::set::container::GraphInfo::NodeUid nodeUid, - Neon::internal::dataDependency::AccessType op, - Neon::internal::dataDependency::MdObjUid dataUid) + Neon::set::dataDependency::AccessType op, + Neon::set::dataDependency::MdObjUid dataUid) -> std::vector { auto idx = helpGetIdx(dataUid); diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index 513cd790..70e0ee6b 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -42,7 +42,7 @@ void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContaine Neon::set::container::GraphInfo::NodeUid graphNodeUid = helpAddNewContainerToGraph(inContainer); // Parsing all the data toke used by the kernel container - std::vector tokens = helpParseContainer(mGraph().getGraphNode(graphNodeUid).getContainer()); + std::vector tokens = helpParseContainer(mGraph().getGraphNode(graphNodeUid).getContainer()); // Tokens are based on the multi-GPU data loaded by Containers for (auto& token : tokens) { @@ -63,7 +63,7 @@ void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContaine } auto MultiGpuGraph::helpParseContainer(Neon::set::Container& container) - -> std::vector + -> std::vector { auto& kcInterface = container.getContainerInterface(); auto& tokens = kcInterface.parse(); From 2c4b9ca1a3f81280f721f18d5cabae713a7b658b Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Fri, 21 Oct 2022 09:20:19 -0400 Subject: [PATCH 40/67] Some clean up. --- libNeonSet/include/Neon/set/MultiXpuDataUid.h | 1 + libNeonSet/include/Neon/set/container/Graph.h | 8 +- .../include/Neon/set/dependency/Token.h | 12 +- libNeonSet/src/set/container/Graph.cpp | 186 +++++++++++------- .../include/Neon/skeleton/Skeleton.h | 4 +- .../{MultiGpuGraph.h => MultiXpuGraph.h} | 41 ++-- .../internal/dependencyTools/DataDependency.h | 16 +- .../dependencyTools/DependencyAnalyser.h | 8 +- .../dependencyTools/UserDataManager.h | 12 +- .../skeleton/depencencyTools/Dependency.cpp | 2 +- .../depencencyTools/DependencyAnalyser.cpp | 16 +- .../depencencyTools/UserDataManager.cpp | 8 +- .../src/skeleton/internal/multiGpuGraph.cpp | 36 ++-- 13 files changed, 201 insertions(+), 149 deletions(-) rename libNeonSkeleton/include/Neon/skeleton/internal/{MultiGpuGraph.h => MultiXpuGraph.h} (82%) diff --git a/libNeonSet/include/Neon/set/MultiXpuDataUid.h b/libNeonSet/include/Neon/set/MultiXpuDataUid.h index cd693611..490e9b99 100644 --- a/libNeonSet/include/Neon/set/MultiXpuDataUid.h +++ b/libNeonSet/include/Neon/set/MultiXpuDataUid.h @@ -3,5 +3,6 @@ namespace Neon::set::dataDependency { using MultiXpuDataUid = size_t; +using MultiXpuDataIdx = size_t; } // namespace Neon::set::dataDependency diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 5403fd02..af3e3161 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -7,6 +7,10 @@ #include "Neon/set/container/graph/GraphDependency.h" #include "Neon/set/container/graph/GraphNode.h" +namespace Neon::skeleton::internal { +struct MultiXpuGraph; +} + namespace Neon::set::container { /** @@ -15,13 +19,13 @@ namespace Neon::set::container { * directed edges of the graph are dependencies between the containers. * Dependencies my be data driven or user provided. * - * */ struct Graph { using Uid = GraphData::Uid; using Index = GraphData::Index; friend struct Bfs; + friend Neon::skeleton::internal::MultiXpuGraph; public: Graph(); @@ -146,7 +150,7 @@ struct Graph -> void; auto getNumberOfNodes() - ->int; + -> int; protected: /** diff --git a/libNeonSet/include/Neon/set/dependency/Token.h b/libNeonSet/include/Neon/set/dependency/Token.h index e215406e..b83a8cab 100644 --- a/libNeonSet/include/Neon/set/dependency/Token.h +++ b/libNeonSet/include/Neon/set/dependency/Token.h @@ -29,12 +29,14 @@ struct Token */ auto update(Neon::set::dataDependency::MultiXpuDataUid m_uid, Neon::set::dataDependency::AccessType m_access, - Neon::Compute m_compute) -> void; + Neon::Compute m_compute) + -> void; /** * It returns the multi-GPU data uid */ - auto uid() const -> Neon::set::dataDependency::MultiXpuDataUid; + auto uid() + const -> Neon::set::dataDependency::MultiXpuDataUid; /** * It returns the type of data access @@ -74,9 +76,9 @@ struct Token private: - Neon::set::dataDependency::MultiXpuDataUid mUid; - Neon::set::dataDependency::AccessType mAccess; - Neon::Compute mCompute; + Neon::set::dataDependency::MultiXpuDataUid mUid; + Neon::set::dataDependency::AccessType mAccess; + Neon::Compute mCompute; std::function mHu; std::function mHuPerDevice; diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index d9541cdb..888546e5 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -16,7 +16,8 @@ Graph::Graph() helpInvalidateScheduling(); } -auto Graph::getBeginNode() const -> const GraphNode& +auto Graph:: + getBeginNode() const -> const GraphNode& { return mRawGraph.getVertexProperty(GraphData::beginUid); } @@ -41,7 +42,9 @@ auto Graph::addNodeInBetween(const GraphNode& nodeA, return nodeB; } -auto Graph::addNode(const Container& container) -> GraphNode& +auto Graph:: + addNode(const Container& container) + -> GraphNode& { helpCheckBackendStatus(); helpInvalidateScheduling(); @@ -56,9 +59,11 @@ auto Graph::addNode(const Container& container) -> GraphNode& return mRawGraph.getVertexProperty(node.getGraphData().getUid()); } -auto Graph::addDependency(const GraphNode& nodeA, - const GraphNode& nodeB, - GraphDependencyType type) -> GraphDependency& +auto Graph:: + addDependency(const GraphNode& nodeA, + const GraphNode& nodeB, + GraphDependencyType type) + -> GraphDependency& { helpCheckBackendStatus(); if (nodeA.getGraphData().getUid() == nodeB.getGraphData().getUid()) { @@ -76,7 +81,9 @@ auto Graph::addDependency(const GraphNode& nodeA, nodeB.getGraphData().getUid()}); } -auto Graph::removeNode(GraphNode& gn) -> Container +auto Graph:: + removeNode(GraphNode& gn) + -> Container { helpInvalidateScheduling(); @@ -117,8 +124,9 @@ auto Graph::removeNode(GraphNode& gn) -> Container return gn.getContainer(); } -auto Graph::removeNodeAndItsDependencies(GraphNode& gn) - -> Container +auto Graph:: + removeNodeAndItsDependencies(GraphNode& gn) + -> Container { auto uidB = gn.getGraphData().getUid(); @@ -161,9 +169,10 @@ auto Graph::removeNodeAndItsDependencies(GraphNode& gn) return gn.getContainer(); } -auto Graph::getProceedingGraphNodes(const GraphNode& graphNode, - const std::vector& dependencyTypes) - -> std::vector +auto Graph:: + getProceedingGraphNodes(const GraphNode& graphNode, + const std::vector& dependencyTypes) + -> std::vector { std::vector nodes; @@ -191,9 +200,10 @@ auto Graph::getProceedingGraphNodes(const GraphNode& grap return nodes; } -auto Graph::getSubsequentGraphNodes(const GraphNode& graphNode, - const std::vector& dependencyTypes) - -> std::vector +auto Graph:: + getSubsequentGraphNodes(const GraphNode& graphNode, + const std::vector& dependencyTypes) + -> std::vector { std::vector nodes; @@ -220,8 +230,9 @@ auto Graph::getSubsequentGraphNodes(const GraphNode& grap return nodes; } -auto Graph::cloneNode(const GraphNode& graphNode) - -> GraphNode& +auto Graph:: + cloneNode(const GraphNode& graphNode) + -> GraphNode& { helpInvalidateScheduling(); @@ -243,9 +254,10 @@ auto Graph::cloneNode(const GraphNode& graphNode) return newNode; } -auto Graph::getDependencyType(const GraphNode& nodeA, - const GraphNode& nodeB) - -> GraphDependencyType +auto Graph:: + getDependencyType(const GraphNode& nodeA, + const GraphNode& nodeB) + -> GraphDependencyType { auto uidA = nodeA.getGraphData().getUid(); auto uidB = nodeB.getGraphData().getUid(); @@ -262,8 +274,9 @@ auto Graph::helpInvalidateScheduling() mSchedulingStatusIsValid = false; } -auto Graph::helpRemoveRedundantDependencies() - -> void +auto Graph:: + helpRemoveRedundantDependencies() + -> void { // Vectors of edges to be removed std::vector> edgesToBeRemoved; @@ -272,7 +285,7 @@ auto Graph::helpRemoveRedundantDependencies() // For each node do: // Check node's children - auto visitingNode = mRawGraph.getVertexProperty(diGraphNodeId).getGraphData().getUid(); + auto visitingNode = mRawGraph.getVertexProperty(diGraphNodeId).getGraphData().getUid(); const auto& children = helpGetOutNeighbors(visitingNode, false); if (children.size() <= 1) { // If no more than one, move to the next node @@ -332,10 +345,11 @@ auto Graph::helpRemoveRedundantDependencies() } } -auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, - bool filteredOut, - const std::vector& dependencyTypes) - -> std::set +auto Graph:: + helpGetOutNeighbors(GraphData::Uid nodeUid, + bool filteredOut, + const std::vector& dependencyTypes) + -> std::set { std::set outNgh; mRawGraph.forEachOutEdge( @@ -355,10 +369,11 @@ auto Graph::helpGetOutNeighbors(GraphData::Uid nodeUid, return outNgh; } -auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, - bool filterOutBegin, - const std::vector& dependencyTypes) - -> std::set +auto Graph:: + helpGetInNeighbors(GraphData::Uid nodeUid, + bool filterOutBegin, + const std::vector& dependencyTypes) + -> std::set { std::set inNgh; mRawGraph.forEachInEdge( @@ -377,10 +392,11 @@ auto Graph::helpGetInNeighbors(GraphData::Uid nodeUid, return inNgh; } -auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, - bool filterOutEnd, - const std::vector& dependencyTypes) - -> std::set> +auto Graph:: + helpGetOutEdges(GraphData::Uid nodeUid, + bool filterOutEnd, + const std::vector& dependencyTypes) + -> std::set> { std::set> outEdges; mRawGraph.forEachOutEdge( @@ -399,10 +415,11 @@ auto Graph::helpGetOutEdges(GraphData::Uid nodeUid, return outEdges; } -auto Graph::helpGetInEdges(GraphData::Uid nodeUid, - bool filterOutBegin, - const std::vector& dependencyTypes) - -> std::set> +auto Graph:: + helpGetInEdges(GraphData::Uid nodeUid, + bool filterOutBegin, + const std::vector& dependencyTypes) + -> std::set> { std::set> inEdges; mRawGraph.forEachInEdge( @@ -421,9 +438,10 @@ auto Graph::helpGetInEdges(GraphData::Uid nodeUid, return inEdges; } -auto Graph::helpGetBFS(bool filterOutBeginEnd, - const std::vector& dependencyTypes) - -> Bfs +auto Graph:: + helpGetBFS(bool filterOutBeginEnd, + const std::vector& dependencyTypes) + -> Bfs { using Frontier = std::unordered_map; @@ -481,8 +499,9 @@ auto Graph::helpGetBFS(bool filterOutBeginEnd return bfs; } -auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) - -> void +auto Graph:: + helpComputeScheduling(bool filterOutAnchors, int anchorStream) + -> void { helpComputeScheduling_00_resetData(); mBfs = helpComputeScheduling_01_generatingBFS(filterOutAnchors); @@ -491,8 +510,9 @@ auto Graph::helpComputeScheduling(bool filterOutAnchors, int anchorStream) helpComputeScheduling_04_ensureResources(maxStreamId, maxEventId); } -auto Graph::helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) - -> Bfs +auto Graph:: + helpComputeScheduling_01_generatingBFS(bool filterOutAnchors) + -> Bfs { return helpGetBFS(filterOutAnchors, {GraphDependencyType::data, GraphDependencyType::user}); @@ -510,16 +530,17 @@ auto Graph::helpGetGraphNode(GraphData::Uid uid) const -> const GraphNode& auto Graph::helpComputeScheduling_00_resetData() -> void { - mRawGraph.forEachVertex([&](const GraphData::Uid & graphNodeId) { + mRawGraph.forEachVertex([&](const GraphData::Uid& graphNodeId) { auto& targetNode = mRawGraph.getVertexProperty(graphNodeId); targetNode.getScheduling().reset(); }); } -auto Graph::helpComputeScheduling_02_mappingStreams(Bfs& bfs, - bool filterOutAnchors, - int anchorStream) - -> int +auto Graph:: + helpComputeScheduling_02_mappingStreams(Bfs& bfs, + bool filterOutAnchors, + int anchorStream) + -> int { mSchedulingStatusIsValid = true; mMaxNumberStreams = bfs.getMaxLevelWidth(); @@ -622,8 +643,9 @@ auto Graph::helpComputeScheduling_02_mappingStreams(Bfs& bfs, return mMaxNumberStreams - 1; } -auto Graph::helpComputeScheduling_03_events(Bfs& bfs) - -> int +auto Graph:: + helpComputeScheduling_03_events(Bfs& bfs) + -> int { int eventCount = 0; @@ -661,18 +683,21 @@ auto Graph::helpComputeScheduling_03_events(Bfs& bfs) return eventCount - 1; } -auto Graph::helpComputeScheduling_04_ensureResources(int maxStreamId, - int maxEventId) - -> void +auto Graph:: + helpComputeScheduling_04_ensureResources(int maxStreamId, + int maxEventId) + -> void { auto bk = getBackend(); bk.setAvailableStreamSet(maxStreamId + 1); bk.setAvailableUserEvents(maxEventId + 1); } -auto Graph::ioToDot(const std::string& fname, - const std::string& graphName, - bool debug) -> void +auto Graph:: + ioToDot(const std::string& fname, + const std::string& graphName, + bool debug) + -> void { this->helpRemoveRedundantDependencies(); @@ -706,7 +731,8 @@ auto Graph::ioToDot(const std::string& fname, vertexLabelProperty, edgeLabelProperty); } -Graph::Graph(const Backend& bk) +Graph:: + Graph(const Backend& bk) { mBackend = bk; mBackendIsSet = true; @@ -721,8 +747,9 @@ Graph::Graph(const Backend& bk) helpInvalidateScheduling(); } -auto Graph::getBackend() const - -> const Neon::Backend& +auto Graph:: + getBackend() + const -> const Neon::Backend& { if (mBackendIsSet) { return mBackend; @@ -732,10 +759,11 @@ auto Graph::getBackend() const NEON_THROW(ex); } -auto Graph::run(Neon::SetIdx setIdx, - int streamIdx, - Neon::DataView dataView) - -> void +auto Graph:: + run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) + -> void { if (dataView != Neon::DataView::STANDARD) { NEON_THROW_UNSUPPORTED_OPERATION(""); @@ -745,9 +773,10 @@ auto Graph::run(Neon::SetIdx setIdx, this->helpExecute(setIdx, streamIdx); } -auto Graph::run(int streamIdx, - Neon::DataView dataView) - -> void +auto Graph:: + run(int streamIdx, + Neon::DataView dataView) + -> void { if (dataView != Neon::DataView::STANDARD) { NEON_THROW_UNSUPPORTED_OPERATION(""); @@ -757,9 +786,10 @@ auto Graph::run(int streamIdx, this->helpExecute(streamIdx); } -auto Graph::helpExecute(Neon::SetIdx setIdx, - int anchorStream) - -> void +auto Graph:: + helpExecute(Neon::SetIdx setIdx, + int anchorStream) + -> void { if (anchorStream > -1 && (anchorStream != mAnchorStreamPreSet || mFilterOutAnchorsPreSet == true)) { Neon::NeonException ex(""); @@ -788,8 +818,9 @@ auto Graph::helpExecute(Neon::SetIdx setIdx, } } -auto Graph::helpExecute(int anchorStream) - -> void +auto Graph:: + helpExecute(int anchorStream) + -> void { if (anchorStream > -1 && (anchorStream != mAnchorStreamPreSet || mFilterOutAnchorsPreSet == true)) { Neon::NeonException ex(""); @@ -892,8 +923,9 @@ auto Graph::expandSubGraphs() -> void // this->ioToDot(std::to_string(i) + "_t_04", "kllkj", true); } } -auto Graph::helpCheckBackendStatus() - -> void +auto Graph:: + helpCheckBackendStatus() + -> void { if (!mBackendIsSet) { NeonException exception("Container Graph"); @@ -901,7 +933,9 @@ auto Graph::helpCheckBackendStatus() NEON_THROW(exception); } } -auto Graph::getNumberOfNodes() -> int +auto Graph:: + getNumberOfNodes() + -> int { // We remove 2 because of the head and tail holders. return int(mRawGraph.numVertices() - 2); diff --git a/libNeonSkeleton/include/Neon/skeleton/Skeleton.h b/libNeonSkeleton/include/Neon/skeleton/Skeleton.h index b3ff0004..e83ea145 100644 --- a/libNeonSkeleton/include/Neon/skeleton/Skeleton.h +++ b/libNeonSkeleton/include/Neon/skeleton/Skeleton.h @@ -2,7 +2,7 @@ #include "Neon/set/Backend.h" #include "Neon/set/Containter.h" #include "Neon/skeleton/Options.h" -#include "Neon/skeleton/internal/MultiGpuGraph.h" +#include "Neon/skeleton/internal/MultiXpuGraph.h" // #include "Neon/skeleton/internal/StreamScheduler.h" namespace Neon::skeleton { @@ -61,7 +61,7 @@ struct Skeleton private: Neon::Backend mBackend; Options mOptions; - Neon::skeleton::internal::MultiGpuGraph mMultiGraph; + Neon::skeleton::internal::MultiXpuGraph mMultiGraph; // Neon::skeleton::internal::StreamScheduler mStreamScheduler; bool m_inited = {false}; diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h b/libNeonSkeleton/include/Neon/skeleton/internal/MultiXpuGraph.h similarity index 82% rename from libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h rename to libNeonSkeleton/include/Neon/skeleton/internal/MultiXpuGraph.h index fa55a7ec..bee39835 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/MultiGpuGraph.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/MultiXpuGraph.h @@ -11,14 +11,14 @@ namespace Neon::skeleton::internal { /** * Graph storing dependency between user kernels */ -struct MultiGpuGraph +struct MultiXpuGraph { public: /** * Default empty constructor */ - MultiGpuGraph(); + MultiXpuGraph(); void init(Neon::Backend& bk, const std::vector& operations, @@ -32,7 +32,8 @@ struct MultiGpuGraph */ auto io2DotOriginalApp(const std::string& fname, const std::string& graphName, - bool debug = false) -> void; + bool debug = false) + -> void; /** * Export both the data dependency graph and the scheduling graph @@ -41,7 +42,8 @@ struct MultiGpuGraph */ auto io2Dot(const std::string& fname, const std::string& graphName, - bool debug = false) -> void; + bool debug = false) + -> void; private: @@ -70,8 +72,8 @@ struct MultiGpuGraph return m_storage->m_kContainers; } - inline auto m_kContainers() const - -> const std::vector& + inline auto m_kContainers() + const -> const std::vector& { return m_storage->m_kContainers; } @@ -80,7 +82,8 @@ struct MultiGpuGraph * Access methods to members * @return */ - inline auto m_dataRecords() -> UserDataManager& + inline auto m_dataRecords() + -> UserDataManager& { return m_storage->m_dataRecords; } @@ -95,7 +98,8 @@ struct MultiGpuGraph * Access methods to members * @return */ - inline auto m_setCardinality() -> int& + inline auto m_setCardinality() + -> int& { return m_storage->m_setCardinality; } @@ -128,7 +132,7 @@ struct MultiGpuGraph * The dependencies are extracted from the kernel container * @param container */ - auto helpParseNewContainer(const Neon::set::Container& inContainer) + auto helpParseNewContainer(const Neon::set::Container& inContainer) -> void; /** @@ -145,21 +149,26 @@ struct MultiGpuGraph * @param graphName */ auto h_io2Dot([[maybe_unused]] const std::string& fname, - [[maybe_unused]] const std::string& graphName) -> void; - + [[maybe_unused]] const std::string& graphName) + -> void; private: auto helpAddNewContainerToGraph(const Neon::set::Container& container) -> Neon::set::container::GraphInfo::NodeUid; - auto optimizeStandardOCC(const Neon::skeleton::Options&) -> void; + auto optimizeStandardOCC(const Neon::skeleton::Options&) + -> void; - auto optimizeExtendedOCC(const Neon::skeleton::Options&) -> void; + auto optimizeExtendedOCC(const Neon::skeleton::Options&) + -> void; - auto optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> void; + auto optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) + -> void; - auto addSyncAndMemoryTransfers(const Neon::skeleton::Options& options) -> void; + auto addSyncAndMemoryTransfers(const Neon::skeleton::Options& options) + -> void; - auto checkCoherency() -> void; + auto checkCoherency() + -> void; }; } // namespace Neon::skeleton::internal diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h index ed8f4712..cec6a086 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DataDependency.h @@ -1,7 +1,7 @@ #pragma once #include "Neon/set/Backend.h" #include "Neon/set/container/Graph.h" -#include "Neon/set/dependency/Alias.h" +#include "Neon/set/container/graph/GraphInfo.h" #include "Neon/set/dependency/DataDependencyType.h" namespace Neon::skeleton::internal { @@ -10,10 +10,10 @@ namespace Neon::skeleton::internal { struct DataDependency { private: - Neon::set::container::GraphInfo::NodeUid mT0 = 0; - Neon::set::container::GraphInfo::NodeUid mT1 = 0; + Neon::set::container::GraphInfo::NodeUid mT0 = 0; + Neon::set::container::GraphInfo::NodeUid mT1 = 0; Neon::set::dataDependency::DataDependencyType mType = Neon::set::dataDependency::DataDependencyType::NONE; - Neon::set::dataDependency::MdObjUid mDataUid = 0; + Neon::set::dataDependency::MultiXpuDataUid mDataUid = 0; public: /** @@ -30,10 +30,10 @@ struct DataDependency * @param A * @param B */ - DataDependency(Neon::set::container::GraphInfo::NodeUid t1, - Neon::set::dataDependency::DataDependencyType type, - Neon::set::dataDependency::MdObjUid m_uid, - Neon::set::container::GraphInfo::NodeUid t0); + DataDependency(Neon::set::container::GraphInfo::NodeUid t1, + Neon::set::dataDependency::DataDependencyType type, + Neon::set::dataDependency::MultiXpuDataUid m_uid, + Neon::set::container::GraphInfo::NodeUid t0); /** * true the object has been initialized with a valid dependency diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h index 30d5fc44..f51ff252 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h @@ -15,13 +15,13 @@ struct DependencyAnalyser std::vector mParsedR{}; std::vector mParsedW{}; - Neon::set::dataDependency::MdObjUid mUid; - Neon::set::dataDependency::MdObjIdx mIdx; + Neon::set::dataDependency::MultiXpuDataUid mUid; + Neon::set::dataDependency::MultiXpuDataIdx mIdx; public: DependencyAnalyser() = delete; - DependencyAnalyser(Neon::set::dataDependency::MdObjUid, - Neon::set::dataDependency::MdObjIdx); + DependencyAnalyser(Neon::set::dataDependency::MultiXpuDataUid, + Neon::set::dataDependency::MultiXpuDataIdx); auto update(Neon::set::container::GraphInfo::NodeUid newKernel, Neon::set::dataDependency::AccessType newOp) diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h index 9ac177fe..c4f97c14 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/dependencyTools/UserDataManager.h @@ -2,7 +2,7 @@ #include #include "Neon/set/Backend.h" #include "Neon/set/container/Graph.h" -#include "Neon/set/dependency/Alias.h" + #include "Neon/set/dependency/DataDependencyType.h" #include "Neon/skeleton/internal/dependencyTools/DependencyAnalyser.h" @@ -21,8 +21,8 @@ namespace Neon::skeleton::internal { struct UserDataManager { std::vector mDepAnalyserVec; - std::map + std::map mUid2Idx; private: @@ -31,8 +31,8 @@ struct UserDataManager * @param uid * @return */ - auto helpGetIdx(Neon::set::dataDependency::MdObjUid uid) - -> Neon::set::dataDependency::MdObjIdx; + auto helpGetIdx(Neon::set::dataDependency::MultiXpuDataUid uid) + -> Neon::set::dataDependency::MultiXpuDataIdx; public: /** @@ -46,7 +46,7 @@ struct UserDataManager */ auto updateStatus(Neon::set::container::GraphInfo::NodeUid newKernel, Neon::set::dataDependency::AccessType op, - Neon::set::dataDependency::MdObjUid uid) -> std::vector; + Neon::set::dataDependency::MultiXpuDataUid uid) -> std::vector; }; } // namespace Neon::skeleton::internal diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp index 7f9203d6..a11467ca 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/Dependency.cpp @@ -4,7 +4,7 @@ namespace Neon::skeleton::internal { DataDependency::DataDependency(Neon::set::container::GraphInfo::NodeUid t1, Neon::set::dataDependency::DataDependencyType type, - Neon::set::dataDependency::MdObjUid uid, + Neon::set::dataDependency::MultiXpuDataUid uid, Neon::set::container::GraphInfo::NodeUid t0) { mT1 = t1; diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp index ad782979..b13a224f 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/DependencyAnalyser.cpp @@ -4,19 +4,21 @@ namespace Neon::skeleton::internal { -DependencyAnalyser::DependencyAnalyser(Neon::set::dataDependency::MdObjUid uid, - Neon::set::dataDependency::MdObjIdx idx) +DependencyAnalyser:: + DependencyAnalyser(Neon::set::dataDependency::MultiXpuDataUid uid, + Neon::set::dataDependency::MultiXpuDataIdx idx) { mUid = uid; mIdx = idx; } -auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid newKernel, - Neon::set::dataDependency::AccessType newOp) - -> std::vector +auto DependencyAnalyser:: + update(Neon::set::container::GraphInfo::NodeUid newKernel, + Neon::set::dataDependency::AccessType newOp) + -> std::vector { switch (newOp) { - case Neon::set::dataDependency::AccessType::READ: { + case Neon::set::dataDependency::AccessType::READ: { if (mParsedW.size() == 0) { // We are parsing a READ with no previous WRITE // STEPS: @@ -56,7 +58,7 @@ auto DependencyAnalyser::update(Neon::set::container::GraphInfo::NodeUid n } break; } - case Neon::set::dataDependency::AccessType::WRITE: { + case Neon::set::dataDependency::AccessType::WRITE: { if (mParsedR.empty() && mParsedW.empty()) { // Parsing a WRITE as the first operation in the Container sequence. // diff --git a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp index a86ebd2b..1044af02 100644 --- a/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp +++ b/libNeonSkeleton/src/skeleton/depencencyTools/UserDataManager.cpp @@ -2,12 +2,12 @@ namespace Neon::skeleton::internal { -auto UserDataManager::helpGetIdx(Neon::set::dataDependency::MdObjUid uid) - -> Neon::set::dataDependency::MdObjIdx +auto UserDataManager::helpGetIdx(Neon::set::dataDependency::MultiXpuDataUid uid) + -> Neon::set::dataDependency::MultiXpuDataIdx { auto count = mUid2Idx.count(uid); if (count == 0) { - Neon::set::dataDependency::MdObjIdx idx = mDepAnalyserVec.size(); + Neon::set::dataDependency::MultiXpuDataIdx idx = mDepAnalyserVec.size(); mDepAnalyserVec.emplace_back(uid, idx); mUid2Idx[uid] = idx; return idx; @@ -17,7 +17,7 @@ auto UserDataManager::helpGetIdx(Neon::set::dataDependency::MdObjUid uid) auto UserDataManager::updateStatus(Neon::set::container::GraphInfo::NodeUid nodeUid, Neon::set::dataDependency::AccessType op, - Neon::set::dataDependency::MdObjUid dataUid) + Neon::set::dataDependency::MultiXpuDataUid dataUid) -> std::vector { auto idx = helpGetIdx(dataUid); diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index 70e0ee6b..411e2473 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -1,9 +1,9 @@ -#include "Neon/skeleton/internal/MultiGpuGraph.h" #include +#include "Neon/skeleton/internal/MultiXpuGraph.h" namespace Neon::skeleton::internal { -void MultiGpuGraph::init(Neon::Backend& bk, +void MultiXpuGraph::init(Neon::Backend& bk, const std::vector& operations, std::string name, Options options) @@ -11,20 +11,20 @@ void MultiGpuGraph::init(Neon::Backend& bk, mGraph() = Neon::set::container::Graph(bk); parse(bk.devSet().setCardinality(), std::forward&&>(operations)); - mGraph().removeRedundantDependencies(); + mGraph().helpRemoveRedundantDependencies(); h_io2Dot("t0_" + name + ".dot", "i"); optimizations(options); h_io2Dot("t1_" + name + ".dot", "i"); addSyncAndMemoryTransfers(options); - mGraph().removeRedundantDependencies(); + mGraph().helpRemoveRedundantDependencies(); checkCoherency(); h_io2Dot("t2_" + name + ".dot", "i"); } -void MultiGpuGraph::parse(int setCardinalty, +void MultiXpuGraph::parse(int setCardinalty, const std::vector&& operations) { m_setCardinality() = setCardinalty; @@ -34,7 +34,7 @@ void MultiGpuGraph::parse(int setCardinalt } } -void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContainer) +void MultiXpuGraph::helpParseNewContainer(const Neon::set::Container& inContainer) { // Register and retrieve the id for the new container @@ -62,7 +62,7 @@ void MultiGpuGraph::helpParseNewContainer(const Neon::set::Container& inContaine } } -auto MultiGpuGraph::helpParseContainer(Neon::set::Container& container) +auto MultiXpuGraph::helpParseContainer(Neon::set::Container& container) -> std::vector { auto& kcInterface = container.getContainerInterface(); @@ -70,23 +70,23 @@ auto MultiGpuGraph::helpParseContainer(Neon::set::Container& container) return tokens; } -auto MultiGpuGraph::h_io2Dot([[maybe_unused]] const std::string& fname, +auto MultiXpuGraph::h_io2Dot([[maybe_unused]] const std::string& fname, [[maybe_unused]] const std::string& graphName) -> void { io2Dot(fname, graphName, true); } -auto MultiGpuGraph::io2Dot(const std::string& fname, const std::string& graphName, bool debug) -> void +auto MultiXpuGraph::io2Dot(const std::string& fname, const std::string& graphName, bool debug) -> void { mGraph().ioToDot(fname, graphName, debug); } -auto MultiGpuGraph::io2DotOriginalApp(const std::string& fname, const std::string& graphName, bool debug) -> void +auto MultiXpuGraph::io2DotOriginalApp(const std::string& fname, const std::string& graphName, bool debug) -> void { mGraph().ioToDot(fname, graphName, debug); } -auto MultiGpuGraph::helpAddNewContainerToGraph(const Neon::set::Container& container) -> Neon::set::container::GraphInfo::NodeUid +auto MultiXpuGraph::helpAddNewContainerToGraph(const Neon::set::Container& container) -> Neon::set::container::GraphInfo::NodeUid { const auto& graphNode = mGraph().addNode(container); Neon::set::container::GraphInfo::NodeUid uid = graphNode.getGraphData().getUid(); @@ -94,7 +94,7 @@ auto MultiGpuGraph::helpAddNewContainerToGraph(const Neon::set::Container& conta } -auto MultiGpuGraph::optimizations(const Neon::skeleton::Options& options) -> void +auto MultiXpuGraph::optimizations(const Neon::skeleton::Options& options) -> void { switch (options.occ()) { case Neon::skeleton::Occ::none: @@ -108,7 +108,7 @@ auto MultiGpuGraph::optimizations(const Neon::skeleton::Options& options) -> voi } } -auto MultiGpuGraph::optimizeStandardOCC(const Neon::skeleton::Options&) -> void +auto MultiXpuGraph::optimizeStandardOCC(const Neon::skeleton::Options&) -> void { NEON_DEV_UNDER_CONSTRUCTION(""); @@ -184,7 +184,7 @@ auto MultiGpuGraph::optimizeStandardOCC(const Neon::skeleton::Options&) -> void // } } -auto MultiGpuGraph::optimizeExtendedOCC(const Neon::skeleton::Options&) -> void +auto MultiXpuGraph::optimizeExtendedOCC(const Neon::skeleton::Options&) -> void { NEON_DEV_UNDER_CONSTRUCTION(""); @@ -333,7 +333,7 @@ auto MultiGpuGraph::optimizeExtendedOCC(const Neon::skeleton::Options&) -> void // } } -auto MultiGpuGraph::optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> void +auto MultiXpuGraph::optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> void { NEON_DEV_UNDER_CONSTRUCTION(""); @@ -571,7 +571,7 @@ auto MultiGpuGraph::optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> } -auto MultiGpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> void +auto MultiXpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> void { if (m_setCardinality() == 1) { @@ -662,7 +662,7 @@ auto MultiGpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> NEON_DEV_UNDER_CONSTRUCTION(""); } -auto MultiGpuGraph::checkCoherency() -> void +auto MultiXpuGraph::checkCoherency() -> void { // // Detects all stencil nodes // std::vector stencilNodes; @@ -697,7 +697,7 @@ auto MultiGpuGraph::checkCoherency() -> void // } } -MultiGpuGraph::MultiGpuGraph() +MultiXpuGraph::MultiXpuGraph() { m_storage = std::make_shared(); } From f4072ff428ba500d6da5cbe744473fa5b24e7960 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Tue, 25 Oct 2022 11:44:15 -0400 Subject: [PATCH 41/67] WIP --- cmake/ManageCompilationFlags.cmake | 2 +- .../set/container/ContainerExecutionType.h | 20 +++++-- libNeonSet/include/Neon/set/container/Graph.h | 14 +++++ .../Neon/set/container/HaloUpdateContainer.h | 53 +++++++++++++++++ .../set/container/graph/GraphDependency.h | 30 ++++++++-- .../set/container/ContainerExecutionType.cpp | 6 +- libNeonSet/src/set/container/Graph.cpp | 51 ++++++++++++++++ .../src/set/container/HaloUpdateContainer.cpp | 42 ++++++++++++++ .../set/container/graph/GraphDependency.cpp | 58 +++++++++++++++++-- libNeonSet/src/set/depencencyTools/Token.cpp | 11 ++-- .../src/skeleton/internal/multiGpuGraph.cpp | 45 ++++++++------ 11 files changed, 293 insertions(+), 39 deletions(-) create mode 100644 libNeonSet/include/Neon/set/container/HaloUpdateContainer.h create mode 100644 libNeonSet/src/set/container/HaloUpdateContainer.cpp diff --git a/cmake/ManageCompilationFlags.cmake b/cmake/ManageCompilationFlags.cmake index dca53533..28d1f752 100644 --- a/cmake/ManageCompilationFlags.cmake +++ b/cmake/ManageCompilationFlags.cmake @@ -35,7 +35,7 @@ set(NeonCXXFlags #Add GCC specific compiler flags here #-Wno-class-memaccess for "writing to an object of type XXX with no trivial copy-assignment; use copy-assignment or copy-initialization instead" - $<$:-m64 -Wall -Wextra -Werror -Wno-unused-function -Wno-deprecated-declarations -Wno-class-memaccess> + $<$:-m64 -Wall -Wextra -Werror -Wno-unused-function -Wno-deprecated-declarations -Wno-class-memaccess -Wno-deprecated-declarations> #Add Clang specific compiler flags here $<$:-m64 -Wall -Wextra -Werror -Wno-unused-function -Wno-deprecated-declarations> diff --git a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h index 9ba63e3c..202296ef 100644 --- a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h +++ b/libNeonSet/include/Neon/set/container/ContainerExecutionType.h @@ -17,18 +17,26 @@ enum struct ContainerExecutionType deviceThenHostManaged = 2, /** a container that stores operation on both device and host. For this type of Container a getHostContainer method is enabled to retrieved a container with the host code */ hostManaged = 3 /** host managed container */, graph = 4 /** A complex container */, - none = 5 + communication = 5, + none = 6 }; struct ContainerExecutionTypeUtils { - static constexpr int nOptions = 5; + static constexpr int nOptions = 6; - static auto toString(ContainerExecutionType option) -> std::string; - static auto fromString(const std::string& option) -> ContainerExecutionType; - static auto getOptions() -> std::array; - static auto isExpandable(ContainerExecutionType option) -> bool; + static auto toString(ContainerExecutionType option) + -> std::string; + + static auto fromString(const std::string& option) + -> ContainerExecutionType; + + static auto getOptions() + -> std::array; + + static auto isExpandable(ContainerExecutionType option) + -> bool; }; /** diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index af3e3161..d30f0dbc 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -80,6 +80,14 @@ struct Graph GraphDependencyType type) -> GraphDependency&; + /** + * Adds a dependency between two node of the graph + */ + auto addDependency(const GraphNode& nodeA, + const GraphNode& nodeB, + const Neon::set::dataDependency::Token& token) + -> GraphDependency&; + /** * Returns the dependency type between two nodes. */ @@ -152,6 +160,12 @@ struct Graph auto getNumberOfNodes() -> int; + auto forEachDependency(const std::function &fun) + const -> void; + + auto forEachNode(const std::function &fun) + const -> void; + protected: /** * Invalidate all scheduling information that were computed diff --git a/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h b/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h new file mode 100644 index 00000000..103b3b15 --- /dev/null +++ b/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h @@ -0,0 +1,53 @@ +#pragma once +#include "Neon/core/core.h" + +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" + +namespace Neon { +namespace set { +namespace internal { + +/** + * Specialized implementation of KContainer_i + * + * + * @tparam DataIteratorContainerT + * @tparam UserComputeLambdaT + */ +struct HaloUpdateContainer : ContainerAPI +{ + public: + virtual ~HaloUpdateContainer() override = default; + + public: + HaloUpdateContainer(const std::string& name); + + auto parse() -> const std::vector& override; + + auto getHostContainer() -> std::shared_ptr final; + + virtual auto getDeviceContainer() -> std::shared_ptr final; + + /** + * Run container over streams + * @param streamIdx + * @param dataView + */ + virtual auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + + /** + * Run container over streams + * @param streamIdx + * @param dataView + */ + virtual auto run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void override; + + private: + std::vector mEmtpy; + +}; + +} // namespace internal +} // namespace set +} // namespace Neon diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index 58945e1b..2910f6f4 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -1,6 +1,7 @@ #pragma once #include "GraphDependencyType.h" +#include "Neon/set/dependency/Token.h" namespace Neon::set::container { @@ -8,15 +9,36 @@ struct GraphDependency { std::string getLabel(); + public: GraphDependency(); - GraphDependency(GraphDependencyType type); + explicit GraphDependency(GraphDependencyType type); + + explicit GraphDependency(const Neon::set::dataDependency::Token& type); + + explicit GraphDependency(const std::vector& type); + + auto setType(GraphDependencyType type) + -> void; + + auto getType() const + -> GraphDependencyType; + + auto addToken(const Neon::set::dataDependency::Token& token) + -> void; + + /** + * Returns the tokens generating this dependency + */ + auto getTokens() + const -> const std::vector&; - auto setType(GraphDependencyType type) -> void; - auto getType() const-> GraphDependencyType; + auto hasStencilDependency() + const -> bool; private: - GraphDependencyType mType; + GraphDependencyType mType; + std::vector mTokens /**< Tokens creating this dependency. */; // TODO - add information for data and Scheduling dependency }; diff --git a/libNeonSet/src/set/container/ContainerExecutionType.cpp b/libNeonSet/src/set/container/ContainerExecutionType.cpp index 60e701b1..31760fd4 100644 --- a/libNeonSet/src/set/container/ContainerExecutionType.cpp +++ b/libNeonSet/src/set/container/ContainerExecutionType.cpp @@ -24,6 +24,9 @@ auto ContainerExecutionTypeUtils::toString(ContainerExecutionType option) -> std case ContainerExecutionType::graph: { return "graph"; } + case ContainerExecutionType::communication: { + return "communication"; + } case ContainerExecutionType::none: { return "none"; } @@ -50,7 +53,8 @@ auto ContainerExecutionTypeUtils::getOptions() -> std::array GraphDependency& +{ + helpCheckBackendStatus(); + if (nodeA.getGraphData().getUid() == nodeB.getGraphData().getUid()) { + NEON_THROW_UNSUPPORTED_OPERATION(""); + } + helpInvalidateScheduling(); + + if (mRawGraph.hasEdge(nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid())) { + GraphDependency& graphDependency = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid()}); + graphDependency.addToken(token); + } else { + GraphDependency ab(token); + + mRawGraph.addEdge(nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid(), + ab); + } + + + return mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), + nodeB.getGraphData().getUid()}); +} + auto Graph:: removeNode(GraphNode& gn) -> Container @@ -933,6 +963,7 @@ auto Graph:: NEON_THROW(exception); } } + auto Graph:: getNumberOfNodes() -> int @@ -941,5 +972,25 @@ auto Graph:: return int(mRawGraph.numVertices() - 2); } +auto Graph:: + forEachDependency(const std::function& fun) + const -> void +{ + mRawGraph.forEachEdge([&](const auto& edge){ + const auto& dep = this->mRawGraph.getEdgeProperty(edge); + fun(dep); + }); +} + +auto Graph:: + forEachNode(const std::function& fun) + const -> void +{ + mRawGraph.forEachVertex([&](size_t nodeId){ + auto node = this->mRawGraph.getVertexProperty(nodeId); + fun(node); + }); +} + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/HaloUpdateContainer.cpp b/libNeonSet/src/set/container/HaloUpdateContainer.cpp new file mode 100644 index 00000000..057defe3 --- /dev/null +++ b/libNeonSet/src/set/container/HaloUpdateContainer.cpp @@ -0,0 +1,42 @@ +#include "Neon/core/core.h" + +#include "Neon/set/container/HaloUpdateContainer.h" + +namespace Neon::set::internal { + +HaloUpdateContainer:: + HaloUpdateContainer(const std::string& name) +{ + setName(name); + setContainerExecutionType(ContainerExecutionType::communication); + setContainerOperationType(ContainerOperationType::halo); + setDataViewSupport(ContainerAPI::DataViewSupport::off); +} + + +auto HaloUpdateContainer:: + parse() + -> const std::vector& +{ + return mEmtpy; +} + +auto HaloUpdateContainer::getHostContainer() -> std::shared_ptr +{ + NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); +} + +auto HaloUpdateContainer::getDeviceContainer() -> std::shared_ptr +{ + NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); +} + +auto HaloUpdateContainer::run(int /*streamIdx*/, Neon::DataView /*dataView*/) -> void +{ +} + +auto HaloUpdateContainer::run(Neon::SetIdx /*setIdx*/, int /*streamIdx*/, Neon::DataView /*dataView*/) -> void +{ +} + +} // namespace Neon::set::internal diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 5bfcc022..381e33c2 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -1,28 +1,76 @@ #include "Neon/set/container/graph/GraphDependency.h" #include + namespace Neon::set::container { -GraphDependency::GraphDependency() +GraphDependency:: + GraphDependency() { } -auto GraphDependency::setType(GraphDependencyType type) -> void +auto GraphDependency:: + setType(GraphDependencyType type) + -> void { mType = type; } -auto GraphDependency::getType() const -> GraphDependencyType +auto GraphDependency:: + getType() + const -> GraphDependencyType { return mType; } -GraphDependency::GraphDependency(GraphDependencyType type) +GraphDependency:: + GraphDependency(GraphDependencyType type) { setType(type); } -auto GraphDependency::getLabel() -> std::string +GraphDependency:: + GraphDependency(const dataDependency::Token& token) + : mType(GraphDependencyType::data) +{ + mTokens.push_back(token); +} + +GraphDependency:: + GraphDependency(const std::vector& tokens) + : mType(GraphDependencyType::data) +{ + mTokens = tokens; +} + +auto GraphDependency:: + getLabel() + -> std::string { return GraphDependencyTypeUtil::toString(getType()); } +auto GraphDependency:: + addToken(const Neon::set::dataDependency::Token& token) -> void +{ + mTokens.push_back(token); +} + + + +auto GraphDependency::getTokens() const -> const std::vector& +{ + return mTokens; +} + +auto GraphDependency::hasStencilDependency() + const -> bool +{ + bool isStencil = std::any_of(mTokens.begin(), + mTokens.end(), + [](const auto& token) { + return token.compute() == Neon::Compute::STENCIL; + }); + return isStencil; +} + + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/depencencyTools/Token.cpp b/libNeonSet/src/set/depencencyTools/Token.cpp index adf35406..a52fe8a5 100644 --- a/libNeonSet/src/set/depencencyTools/Token.cpp +++ b/libNeonSet/src/set/depencencyTools/Token.cpp @@ -1,3 +1,5 @@ +#include + #include "Neon/set//dependency/Token.h" namespace Neon::set::dataDependency { @@ -51,11 +53,12 @@ auto Token::toString() const -> std::string } -auto Token::setHaloUpdate(std::function hu, - std::function huPerDevice) -> void +auto Token:: + setHaloUpdate(std::function hu, + std::function huPerDevice) -> void { - mHu = hu; - mHuPerDevice = huPerDevice; + mHu = std::move(hu); + mHuPerDevice = std::move(huPerDevice); } auto Token::getHaloUpdate() const diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index 411e2473..a8f79bd0 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -34,36 +34,39 @@ void MultiXpuGraph::parse(int setCardinalt } } -void MultiXpuGraph::helpParseNewContainer(const Neon::set::Container& inContainer) +void MultiXpuGraph:: + helpParseNewContainer(const Neon::set::Container& inContainer) { // Register and retrieve the id for the new container // add a node - Neon::set::container::GraphInfo::NodeUid graphNodeUid = helpAddNewContainerToGraph(inContainer); + Neon::set::container::GraphInfo::NodeUid graphNodeUid; + graphNodeUid = helpAddNewContainerToGraph(inContainer); // Parsing all the data toke used by the kernel container - std::vector tokens = helpParseContainer(mGraph().getGraphNode(graphNodeUid).getContainer()); + std::vector tokens; + tokens = helpParseContainer(mGraph().helpGetGraphNode(graphNodeUid).getContainer()); // Tokens are based on the multi-GPU data loaded by Containers for (auto& token : tokens) { // update the dependency state machine with the new token. // newDependencies are the detected dependencies - auto newDependencies = m_dataRecords().updateStatus(graphNodeUid, token.access(), token.uid()); + auto newDependencies = m_dataRecords().updateStatus(graphNodeUid, + token.access(), + token.uid()); for (auto& dep : newDependencies) { - const auto& n0 = mGraph().getGraphNode(dep.t0()); - const auto& n1 = mGraph().getGraphNode(dep.t1()); - mGraph().appendDataDependency(n0, n1, - dep.type(), - token.uid(), - token.compute()); + const auto& n0 = mGraph().helpGetGraphNode(dep.t0()); + const auto& n1 = mGraph().helpGetGraphNode(dep.t1()); + mGraph().addDependency(n0, n1, token); } } } -auto MultiXpuGraph::helpParseContainer(Neon::set::Container& container) - -> std::vector +auto MultiXpuGraph:: + helpParseContainer(Neon::set::Container& container) + -> std::vector { auto& kcInterface = container.getContainerInterface(); auto& tokens = kcInterface.parse(); @@ -76,20 +79,27 @@ auto MultiXpuGraph::h_io2Dot([[maybe_unused]] const std::string& fname, io2Dot(fname, graphName, true); } -auto MultiXpuGraph::io2Dot(const std::string& fname, const std::string& graphName, bool debug) -> void +auto MultiXpuGraph:: + io2Dot(const std::string& fname, + const std::string& graphName, + bool debug) -> void { mGraph().ioToDot(fname, graphName, debug); } -auto MultiXpuGraph::io2DotOriginalApp(const std::string& fname, const std::string& graphName, bool debug) -> void +auto MultiXpuGraph:: + io2DotOriginalApp(const std::string& fname, + const std::string& graphName, + bool debug) -> void { mGraph().ioToDot(fname, graphName, debug); } auto MultiXpuGraph::helpAddNewContainerToGraph(const Neon::set::Container& container) -> Neon::set::container::GraphInfo::NodeUid { - const auto& graphNode = mGraph().addNode(container); - Neon::set::container::GraphInfo::NodeUid uid = graphNode.getGraphData().getUid(); + const auto& graphNode = mGraph().addNode(container); + Neon::set::container::GraphInfo::NodeUid uid; + uid = graphNode.getGraphData().getUid(); return uid; } @@ -592,9 +602,8 @@ auto MultiXpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> auto stencilInfo = dep.getListStencilInfo(); - for(auto& infoPrt : stencilInfo){ + for (auto& infoPrt : stencilInfo) { mGraph().addNodeInBetween(dep.) - } } From fe762b28b4e587b9396c8257a738fbd59a3b3b69 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Tue, 25 Oct 2022 16:22:47 -0400 Subject: [PATCH 42/67] New Container for data transfers. --- libNeonSet/include/Neon/set/Containter.h | 9 +- libNeonSet/include/Neon/set/Containter_imp.h | 21 ++- libNeonSet/include/Neon/set/HuOptions.h | 2 +- .../Neon/set/container/AnchorContainer.h | 12 +- .../include/Neon/set/container/ContainerAPI.h | 32 +++-- .../set/container/DataTransferContainer.h | 72 ++++++++++ .../Neon/set/container/DeviceContainer.h | 31 ++--- .../DeviceThenHostManagedContainer.h | 6 +- .../Neon/set/container/GraphContainer.h | 29 ++-- .../Neon/set/container/HaloUpdateContainer.h | 54 ++++---- .../Neon/set/container/HostManagedContainer.h | 2 +- .../{ => types}/ContainerExecutionType.h | 0 .../{ => types}/ContainerOperationType.h | 3 +- .../{ => types}/ContainerPatternType.h | 0 .../{ => types}/HostManagedSyncType.h | 0 libNeonSet/src/set/Containter.cpp | 1 + libNeonSet/src/set/HuOptions.cpp | 9 +- .../src/set/container/AnchorContainer.cpp | 25 ++-- libNeonSet/src/set/container/ContainerAPI.cpp | 131 ++++++++++++------ .../set/container/ContainerExecutionType.cpp | 2 +- .../set/container/ContainerOperationType.cpp | 6 +- .../set/container/ContainerPatternType.cpp | 2 +- .../src/set/container/GraphContainer.cpp | 10 -- .../src/set/container/graph/GraphNode.cpp | 2 +- 24 files changed, 287 insertions(+), 174 deletions(-) create mode 100644 libNeonSet/include/Neon/set/container/DataTransferContainer.h rename libNeonSet/include/Neon/set/container/{ => types}/ContainerExecutionType.h (100%) rename libNeonSet/include/Neon/set/container/{ => types}/ContainerOperationType.h (95%) rename libNeonSet/include/Neon/set/container/{ => types}/ContainerPatternType.h (100%) rename libNeonSet/include/Neon/set/container/{ => types}/HostManagedSyncType.h (100%) diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 8f95f950..547fdfe3 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -6,7 +6,8 @@ #include "type_traits" #include "Neon/set/container/ContainerAPI.h" -#include "Neon/set/container/HostManagedSyncType.h" +#include "Neon/set/container/types/HostManagedSyncType.h" + #include "Neon/set/container/Loader.h" namespace Neon::set { @@ -106,6 +107,12 @@ struct Container Container& host) -> Container; + template + static auto factoryDataTransfer(const MultiXpuDataT& multiXpuData, + Neon::set::TransferMode transferMode, + Neon::set::TransferSemantic transferSemantic) + -> Neon::set::Container; + static auto factoryAnchor(const std::string& name /**< A user's string to identify the computation done by the Container. */) -> Container; diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h index c412075d..6259693e 100644 --- a/libNeonSet/include/Neon/set/Containter_imp.h +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -10,6 +10,7 @@ #include "Neon/set/container/DeviceThenHostManagedContainer.h" #include "Neon/set/container/HostManagedContainer.h" #include "Neon/set/container/OldDeviceManagedContainer.h" +#include "Neon/set/container/DataTransferContainer.h" #include "Neon/set/container/GraphContainer.h" @@ -30,7 +31,7 @@ auto Container::factory(const std::string& name, blockSize, shMemSizeFun); std::shared_ptr tmp(k); - return Container(tmp); + return {tmp}; } template tmp(k); - return Container(tmp); + return {tmp}; } template tmp(k); - return Container(tmp); + return {tmp}; } template tmp(k); - return Container(tmp); + return {tmp}; } +template +auto Container::factoryDataTransfer(const MultiXpuDataT& multiXpuData, + Neon::set::TransferMode transferMode, + Neon::set::TransferSemantic transferSemantic) + -> Neon::set::Container{ + auto k = new Neon::set::internal::DataTransferContainer(multiXpuData, + transferMode, + transferSemantic ); + + std::shared_ptr tmp(k); + return {tmp}; +} } // namespace Neon::set diff --git a/libNeonSet/include/Neon/set/HuOptions.h b/libNeonSet/include/Neon/set/HuOptions.h index 779b79b8..7b28878d 100644 --- a/libNeonSet/include/Neon/set/HuOptions.h +++ b/libNeonSet/include/Neon/set/HuOptions.h @@ -30,7 +30,7 @@ struct HuOptions auto operationMode() const -> Neon::set::PeerTransferOption::operationMode_e; auto transferMode() const -> Neon::set::TransferMode; auto isExecuteMode() const -> bool; - auto structure() -> Neon::set::TransferSemantic; + auto getSemantic() const -> Neon::set::TransferSemantic; }; } // namespace set } // namespace Neon diff --git a/libNeonSet/include/Neon/set/container/AnchorContainer.h b/libNeonSet/include/Neon/set/container/AnchorContainer.h index 0afb0bad..68069bed 100644 --- a/libNeonSet/include/Neon/set/container/AnchorContainer.h +++ b/libNeonSet/include/Neon/set/container/AnchorContainer.h @@ -25,27 +25,25 @@ struct AnchorContainer : ContainerAPI auto parse() -> const std::vector& override; - auto getHostContainer() -> std::shared_ptr final; - - virtual auto getDeviceContainer() -> std::shared_ptr final; - /** * Run container over streams * @param streamIdx * @param dataView */ - virtual auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + virtual auto run(int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; /** * Run container over streams * @param streamIdx * @param dataView */ - virtual auto run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void override; + virtual auto run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void override; private: std::vector mEmtpy; - }; } // namespace internal diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index 21e364fa..4823bb22 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -1,10 +1,10 @@ #pragma once -#include "Neon/set/container/ContainerOperationType.h" -#include "Neon/set/container/ContainerPatternType.h" +#include "Neon/set/container/types/ContainerOperationType.h" +#include "Neon/set/container/types/ContainerPatternType.h" #include "Neon/set/DevSet.h" -#include "Neon/set/container/ContainerExecutionType.h" +#include "Neon/set/container/types/ContainerExecutionType.h" #include "Neon/set/dependency/Token.h" @@ -44,13 +44,16 @@ struct ContainerAPI /** * Run this Container over a stream. */ - virtual auto run(int streamIdx, Neon::DataView dataView = Neon::DataView::STANDARD) + virtual auto run(int streamIdx, + Neon::DataView dataView = Neon::DataView::STANDARD) -> void = 0; /** * Run this Container over a stream. */ - virtual auto run(Neon::SetIdx idx, int streamIdx, Neon::DataView dataView) + virtual auto run(Neon::SetIdx idx, + int streamIdx, + Neon::DataView dataView) -> void = 0; /** @@ -76,8 +79,10 @@ struct ContainerAPI * @return */ virtual auto parse() - -> const std::vector& = 0; + -> const std::vector&; + virtual auto getTransferMode()const + ->Neon::set::TransferMode ; /** * Returns a name associated to the container. @@ -91,12 +96,6 @@ struct ContainerAPI auto getTokens() const -> const std::vector&; - /** - * Returns a list of tokens as result of parsing the Container loading lambda. - */ - auto getTokenRef() - -> std::vector&; - /** * Get the execution type for the Container. */ @@ -127,6 +126,12 @@ struct ContainerAPI auto toLog(uint64_t ContainerUid) -> void; protected: + /** + * Returns a list of tokens as result of parsing the Container loading lambda. + */ + auto getTokensRef() + -> std::vector&; + /** * Add a new token */ @@ -155,7 +160,7 @@ struct ContainerAPI * Generate a string that will be printed in case or exceptions * @return */ - auto helpGetNameForError() + auto helpGetNameForError() const -> std::string; /** @@ -196,6 +201,7 @@ struct ContainerAPI auto setParsingDataUpdated(bool) -> void; + private: using TokenList = std::vector; diff --git a/libNeonSet/include/Neon/set/container/DataTransferContainer.h b/libNeonSet/include/Neon/set/container/DataTransferContainer.h new file mode 100644 index 00000000..18262849 --- /dev/null +++ b/libNeonSet/include/Neon/set/container/DataTransferContainer.h @@ -0,0 +1,72 @@ +#pragma once +#include "Neon/core/core.h" + +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/DeviceContainer.h" +#include "Neon/set/container/Graph.h" +#include "Neon/set/container/Loader.h" + +namespace Neon::set::internal { + +template +struct DataTransferContainer + : ContainerAPI +{ + virtual ~DataTransferContainer() override = default; + + DataTransferContainer(const MultiXpuDataT& multiXpuData, + Neon::set::TransferMode transferMode, + Neon::set::TransferSemantic transferSemantic) + : mMultiXpuData(multiXpuData), + mTransferMode(transferMode), + mTransferSemantic(transferSemantic) + { + setName("DataTransferContainer"); + + setContainerExecutionType(ContainerExecutionType::deviceManaged); + setContainerOperationType(ContainerOperationType::communication); + setDataViewSupport(DataViewSupport::off); + + mCompute = [&](Neon::SetIdx setIdx, + int streamIdx) { + Neon::set::HuOptions options(this->mTransferMode, + false, + streamIdx, + mTransferSemantic); + this->mMultiXpuData.haloUpdate(setIdx, options); + }; + } + + auto run(int streamIdx, + Neon::DataView dataView = Neon::DataView::STANDARD) -> void override + { + const Neon::Backend& bk = mMultiXpuData.getBackend(); + const int setCardinality = bk.devSet().setCardinality(); + +#pragma omp parallel for num_threads(setCardinality) + for (int i = 0; i < setCardinality; ++i) { + run(Neon::SetIdx(i), streamIdx, dataView); + } + } + + auto run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void override + { + if (ContainerExecutionType::deviceManaged == this->getContainerType()) { + mCompute(setIdx, streamIdx); + return; + } + NEON_THROW_UNSUPPORTED_OPTION(""); + } + + private: + std::function + mCompute; + MultiXpuDataT mMultiXpuData; + Neon::set::TransferMode mTransferMode; + Neon::set::TransferSemantic mTransferSemantic; +}; + +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/container/DeviceContainer.h b/libNeonSet/include/Neon/set/container/DeviceContainer.h index 2d0e8949..6d838298 100644 --- a/libNeonSet/include/Neon/set/container/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceContainer.h @@ -8,13 +8,6 @@ namespace Neon { namespace set { namespace internal { -/** - * Specialized implementation of KContainer_i - * - * - * @tparam DataIteratorContainerT - * @tparam UserComputeLambdaT - */ template struct DeviceContainer : ContainerAPI @@ -22,7 +15,6 @@ struct DeviceContainer : ContainerAPI public: virtual ~DeviceContainer() override = default; - public: DeviceContainer(const std::string& name, ContainerAPI::DataViewSupport dataViewSupport, const DataIteratorContainerT& dataIteratorContainer, @@ -90,23 +82,13 @@ struct DeviceContainer : ContainerAPI return getTokens(); } - - auto - getHostContainer() -> std::shared_ptr final - { - NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); - } - - virtual auto getDeviceContainer() -> std::shared_ptr final - { - NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); - } /** * Run container over streams * @param streamIdx * @param dataView */ - virtual auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override + virtual auto run(int streamIdx = 0, + Neon::DataView dataView = Neon::DataView::STANDARD) -> void override { const Neon::Backend& bk = m_dataIteratorContainer.getBackend(); @@ -132,7 +114,9 @@ struct DeviceContainer : ContainerAPI * @param streamIdx * @param dataView */ - virtual auto run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void override + virtual auto run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void override { const Neon::Backend& bk = m_dataIteratorContainer.getBackend(); @@ -143,7 +127,10 @@ struct DeviceContainer : ContainerAPI setIdx, kernelConfig, m_dataIteratorContainer, - [&](Neon::DeviceType devE, Neon::SetIdx setIdx, Neon::DataView dataView) -> UserComputeLambdaT { + [&](Neon::DeviceType devE, + Neon::SetIdx setIdx, + Neon::DataView dataView) + -> UserComputeLambdaT { Loader loader = this->newLoader(devE, setIdx, dataView, LoadingMode_e::EXTRACT_LAMBDA); UserComputeLambdaT userLambda = this->m_loadingLambda(loader); return userLambda; diff --git a/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h index 0f183a74..ae8ee3ff 100644 --- a/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceThenHostManagedContainer.h @@ -73,12 +73,12 @@ struct DeviceThenHostManagedContainer : ContainerAPI auto const& devTokens = mDevice->getTokens(); for (auto const& token : devTokens) { - getTokenRef().push_back(token); + getTokensRef().push_back(token); } std::vector filtered; for (auto const& token : hostTokens) { bool foundMatch = false; - for (auto& acceptedTokens : getTokenRef()) { + for (auto& acceptedTokens : getTokensRef()) { if (token.uid() == acceptedTokens.uid()) { acceptedTokens.mergeAccess(token.access()); foundMatch = true; @@ -90,7 +90,7 @@ struct DeviceThenHostManagedContainer : ContainerAPI } for (auto const& token : filtered) { - getTokenRef().push_back(token); + getTokensRef().push_back(token); } return getTokens(); diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index caa68b04..79051f93 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -17,39 +17,30 @@ struct GraphContainer : ContainerAPI public: ~GraphContainer() override = default; - /** - * User facing API to define a kernel - * @param data - * @param userLambda - */ GraphContainer(const std::string& name, const Neon::set::container::Graph& containerGraph, std::function loadingLambda); - auto newParser() -> Loader; + auto newParser() + -> Loader; - auto parse() -> const std::vector& override; + auto parse() + -> const std::vector& override; - auto getGraph() -> const Neon::set::container::Graph& override; + auto getGraph() + -> const Neon::set::container::Graph& override; - auto getHostContainer() -> std::shared_ptr override; - - auto getDeviceContainer() -> std::shared_ptr override; - /** - * Run container over streams - * @param streamIdx - * @param dataView - */ - auto run(int streamIdx = 0, + auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; auto run(Neon::SetIdx setIdx, int streamIdx = 0, - Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + Neon::DataView dataView = Neon::DataView::STANDARD) + -> void override; private: - std::function mLoadingLambda; + std::function mLoadingLambda; std::shared_ptr mGraph; }; diff --git a/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h b/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h index 103b3b15..e7030b17 100644 --- a/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h +++ b/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h @@ -2,50 +2,50 @@ #include "Neon/core/core.h" #include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Graph.h" +#include "Neon/set/container/GraphContainer.h" #include "Neon/set/container/Loader.h" namespace Neon { namespace set { namespace internal { -/** - * Specialized implementation of KContainer_i - * - * - * @tparam DataIteratorContainerT - * @tparam UserComputeLambdaT - */ -struct HaloUpdateContainer : ContainerAPI +template +struct HaloUpdateContainer + : public GraphContainer { + public: virtual ~HaloUpdateContainer() override = default; - public: - HaloUpdateContainer(const std::string& name); + HaloUpdateContainer(const Neon::Backend& bk, + const Neon::set::Container& dataTransferContainer, + const Neon::set::Container& syncContainer) + { + Neon::set::container::Graph graph(bk); - auto parse() -> const std::vector& override; + auto dataTranferNode = graph.addNode(dataTransferContainer); + auto syncNode = graph.addNode(syncContainer); - auto getHostContainer() -> std::shared_ptr final; + if (dataTransferContainer.getContainerInterface().getTransferMode() == + Neon::set::TransferMode::get) { + graph.addDependency(syncNode, dataTranferNode, GraphDependencyType::data); + } else { + graph.addDependency(dataTranferNode, syncNode, GraphDependencyType::data); + } - virtual auto getDeviceContainer() -> std::shared_ptr final; + auto name = std::string("HaloUpdate"); + GraphContainer graphContainer(graph, [&](Neon::set::Loader& loader) { + // Nothing to load + }); - /** - * Run container over streams - * @param streamIdx - * @param dataView - */ - virtual auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) -> void override; + this->GraphContainer = graphContainer; - /** - * Run container over streams - * @param streamIdx - * @param dataView - */ - virtual auto run(Neon::SetIdx setIdx, int streamIdx, Neon::DataView dataView) -> void override; + setContainerOperationType(ContainerOperationType::communication); + setDataViewSupport(DataViewSupport::off); + } private: - std::vector mEmtpy; - }; } // namespace internal diff --git a/libNeonSet/include/Neon/set/container/HostManagedContainer.h b/libNeonSet/include/Neon/set/container/HostManagedContainer.h index a3127615..99429d20 100644 --- a/libNeonSet/include/Neon/set/container/HostManagedContainer.h +++ b/libNeonSet/include/Neon/set/container/HostManagedContainer.h @@ -1,8 +1,8 @@ #pragma once #include "Neon/set/container/ContainerAPI.h" -#include "Neon/set/container/HostManagedSyncType.h" #include "Neon/set/container/Loader.h" +#include "Neon/set/container/types/HostManagedSyncType.h" namespace Neon::set::internal { diff --git a/libNeonSet/include/Neon/set/container/ContainerExecutionType.h b/libNeonSet/include/Neon/set/container/types/ContainerExecutionType.h similarity index 100% rename from libNeonSet/include/Neon/set/container/ContainerExecutionType.h rename to libNeonSet/include/Neon/set/container/types/ContainerExecutionType.h diff --git a/libNeonSet/include/Neon/set/container/ContainerOperationType.h b/libNeonSet/include/Neon/set/container/types/ContainerOperationType.h similarity index 95% rename from libNeonSet/include/Neon/set/container/ContainerOperationType.h rename to libNeonSet/include/Neon/set/container/types/ContainerOperationType.h index 9b2ddad4..08cadf6b 100644 --- a/libNeonSet/include/Neon/set/container/ContainerOperationType.h +++ b/libNeonSet/include/Neon/set/container/types/ContainerOperationType.h @@ -14,7 +14,7 @@ enum struct ContainerOperationType { compute = 0 /**< Compute container, can be on host or device */, graph = 1 /**< A graph based container */, - halo = 2 /**< Halo update container **/, + communication = 2 /**< Halo update container **/, sync = 3 /**< Synchronization Container */, anchor = 4 /**< Synchronization Container: begin or end */ }; @@ -46,4 +46,3 @@ struct ContainerOperationTypeUtils std::ostream& operator<<(std::ostream& os, Neon::set::ContainerOperationType const& m); } // namespace Neon::set - diff --git a/libNeonSet/include/Neon/set/container/ContainerPatternType.h b/libNeonSet/include/Neon/set/container/types/ContainerPatternType.h similarity index 100% rename from libNeonSet/include/Neon/set/container/ContainerPatternType.h rename to libNeonSet/include/Neon/set/container/types/ContainerPatternType.h diff --git a/libNeonSet/include/Neon/set/container/HostManagedSyncType.h b/libNeonSet/include/Neon/set/container/types/HostManagedSyncType.h similarity index 100% rename from libNeonSet/include/Neon/set/container/HostManagedSyncType.h rename to libNeonSet/include/Neon/set/container/types/HostManagedSyncType.h diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index a8e198cb..22ccb0d3 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -131,4 +131,5 @@ auto Container::factoryGraph(const std::string& name, } + } // namespace Neon::set diff --git a/libNeonSet/src/set/HuOptions.cpp b/libNeonSet/src/set/HuOptions.cpp index 978d9939..86fb6d6d 100644 --- a/libNeonSet/src/set/HuOptions.cpp +++ b/libNeonSet/src/set/HuOptions.cpp @@ -27,7 +27,8 @@ HuOptions::HuOptions(Neon::set::TransferMode transferMode, // EMPTY } -auto HuOptions::getPeerTransferOpt(const Neon::Backend& bk) -> Neon::set::PeerTransferOption& +auto HuOptions::getPeerTransferOpt(const Neon::Backend& bk) + -> Neon::set::PeerTransferOption& { if (m_peerTransferOpt.operationMode() == Neon::set::PeerTransferOption::operationMode_e::storeInfo) { @@ -52,7 +53,8 @@ auto HuOptions::streamSetIdx() const return m_streamSetIdx; } -auto HuOptions::transfers() -> std::vector& +auto HuOptions::transfers() + -> std::vector& { return m_peerTransferOpt.transfers(); } @@ -75,7 +77,8 @@ auto HuOptions::isExecuteMode() const return operationMode() == Neon::set::PeerTransferOption::operationMode_e::execute; } -auto HuOptions::structure() -> Neon::set::TransferSemantic +auto HuOptions::getSemantic() + const -> Neon::set::TransferSemantic { return m_structure; } diff --git a/libNeonSet/src/set/container/AnchorContainer.cpp b/libNeonSet/src/set/container/AnchorContainer.cpp index c0e86509..38667ee6 100644 --- a/libNeonSet/src/set/container/AnchorContainer.cpp +++ b/libNeonSet/src/set/container/AnchorContainer.cpp @@ -13,26 +13,25 @@ AnchorContainer::AnchorContainer(const std::string& name) } -auto AnchorContainer::parse() -> const std::vector& +auto AnchorContainer:: + parse() + -> const std::vector& { return mEmtpy; } -auto AnchorContainer::getHostContainer() -> std::shared_ptr +auto AnchorContainer:: + run(int /*streamIdx*/, + Neon::DataView /*dataView*/) + -> void { - NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); } -auto AnchorContainer::getDeviceContainer() -> std::shared_ptr -{ - NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); -} - -auto AnchorContainer::run(int /*streamIdx*/ , Neon::DataView /*dataView*/ ) -> void -{ -} - -auto AnchorContainer::run(Neon::SetIdx /*setIdx*/, int /*streamIdx*/, Neon::DataView /*dataView*/) -> void +auto AnchorContainer:: + run(Neon::SetIdx /*setIdx*/, + int /*streamIdx*/, + Neon::DataView /*dataView*/) + -> void { } diff --git a/libNeonSet/src/set/container/ContainerAPI.cpp b/libNeonSet/src/set/container/ContainerAPI.cpp index c54e8fab..db4490d6 100644 --- a/libNeonSet/src/set/container/ContainerAPI.cpp +++ b/libNeonSet/src/set/container/ContainerAPI.cpp @@ -3,67 +3,78 @@ namespace Neon::set::internal { -auto ContainerAPI::addToken(Neon::set::dataDependency::Token& dataParsing) - -> void +auto ContainerAPI:: + addToken(Neon::set::dataDependency::Token& dataParsing) + -> void { mParsed.push_back(dataParsing); } -auto ContainerAPI::getName() const +auto ContainerAPI:: + getName() const -> const std::string& { return mName; } -auto ContainerAPI::getTokens() const - -> const std::vector& +auto ContainerAPI:: + getTokens() + const -> const std::vector& { return mParsed; } -auto ContainerAPI::getTokenRef() - -> std::vector& +auto ContainerAPI:: + getTokensRef() + -> std::vector& { return mParsed; } -auto ContainerAPI::setName(const std::string& name) - -> void +auto ContainerAPI:: + setName(const std::string& name) + -> void { mName = name; } -auto ContainerAPI::setLaunchParameters(Neon::DataView dw) - -> Neon::set::LaunchParameters& +auto ContainerAPI:: + setLaunchParameters(Neon::DataView dw) + -> Neon::set::LaunchParameters& { return mLaunchParameters[DataViewUtil::toInt(dw)]; } -auto ContainerAPI::getLaunchParameters(Neon::DataView dw) const - -> const Neon::set::LaunchParameters& +auto ContainerAPI:: + getLaunchParameters(Neon::DataView dw) + const -> const Neon::set::LaunchParameters& { return mLaunchParameters[DataViewUtil::toInt(dw)]; } -auto ContainerAPI::getDataViewSupport() const -> ContainerAPI::DataViewSupport +auto ContainerAPI:: + getDataViewSupport() const -> ContainerAPI::DataViewSupport { return mDataViewSupport; } -auto ContainerAPI::setDataViewSupport(ContainerAPI::DataViewSupport dataViewSupport) - -> void +auto ContainerAPI:: + setDataViewSupport(ContainerAPI::DataViewSupport dataViewSupport) + -> void { mDataViewSupport = dataViewSupport; } -auto ContainerAPI::setContainerPattern(Neon::set::ContainerPatternType patternType) - -> void +auto ContainerAPI:: + setContainerPattern(Neon::set::ContainerPatternType patternType) + -> void { this->mContainerPatternType = patternType; } -auto ContainerAPI::setContainerPattern(const std::vector& tokens) - -> void +auto ContainerAPI:: + setContainerPattern(const std::vector& tokens) + -> void { Neon::set::ContainerPatternType patternType = Neon::set::ContainerPatternType::map; @@ -84,8 +95,9 @@ auto ContainerAPI::setContainerPattern(const std::vectormContainerPatternType = patternType; } -auto ContainerAPI::toLog(uint64_t uid) - -> void +auto ContainerAPI:: + toLog(uint64_t uid) + -> void { std::stringstream listOfTokes; for (auto& token : mParsed) { @@ -97,41 +109,47 @@ auto ContainerAPI::toLog(uint64_t uid) NEON_INFO("Container {}: tokens = [{}]", uid, listOfTokes.str()); } -auto ContainerAPI::getContainerExecutionType() - const +auto ContainerAPI:: + getContainerExecutionType() + const -> ContainerExecutionType { return mContainerExecutionType; } -auto ContainerAPI::getContainerOperationType() - const +auto ContainerAPI:: + getContainerOperationType() + const -> ContainerOperationType { return mContainerOperationType; } -auto ContainerAPI::getContainerPatternType() - const +auto ContainerAPI:: + getContainerPatternType() + const -> ContainerPatternType { return mContainerPatternType; } -auto ContainerAPI::setContainerExecutionType(ContainerExecutionType containerType) - -> void +auto ContainerAPI:: + setContainerExecutionType(ContainerExecutionType containerType) + -> void { mContainerExecutionType = containerType; } -auto ContainerAPI::setContainerOperationType(ContainerOperationType containerType) - -> void +auto ContainerAPI:: + setContainerOperationType(ContainerOperationType containerType) + -> void { mContainerOperationType = containerType; } -auto ContainerAPI::getGraph() - -> const Neon::set::container::Graph& +auto ContainerAPI:: + getGraph() + -> const Neon::set::container::Graph& { std::string description = helpGetNameForError(); Neon::NeonException exp("ContainerAPI"); @@ -141,8 +159,9 @@ auto ContainerAPI::getGraph() NEON_THROW(exp); } -auto ContainerAPI::getHostContainer() - -> std::shared_ptr +auto ContainerAPI:: + getHostContainer() + -> std::shared_ptr { std::string description = helpGetNameForError(); Neon::NeonException exp("ContainerAPI"); @@ -152,8 +171,9 @@ auto ContainerAPI::getHostContainer() NEON_THROW(exp); } -auto ContainerAPI::helpGetNameForError() - -> std::string +auto ContainerAPI:: + helpGetNameForError() + const -> std::string { std::stringstream s; s << getName() @@ -164,8 +184,9 @@ auto ContainerAPI::helpGetNameForError() return s.str(); } -auto ContainerAPI::getDeviceContainer() - -> std::shared_ptr +auto ContainerAPI:: + getDeviceContainer() + -> std::shared_ptr { std::string description = helpGetNameForError(); Neon::NeonException exp("ContainerAPI"); @@ -175,13 +196,39 @@ auto ContainerAPI::getDeviceContainer() NEON_THROW(exp); } -auto ContainerAPI::isParsingDataUpdated() -> bool +auto ContainerAPI:: + isParsingDataUpdated() -> bool { return mParsingDataUpdated; } -auto ContainerAPI::setParsingDataUpdated(bool status) -> void +auto ContainerAPI:: + setParsingDataUpdated(bool status) -> void { mParsingDataUpdated = status; } + +auto ContainerAPI:: + parse() + -> const std::vector& +{ + std::string description = helpGetNameForError(); + Neon::NeonException exp("ContainerAPI"); + exp << description << " " + << "parse" + << " is not supported."; + NEON_THROW(exp); +} + +auto ContainerAPI:: + getTransferMode() + const -> Neon::set::TransferMode +{ + std::string description = helpGetNameForError(); + Neon::NeonException exp("ContainerAPI"); + exp << description << " " + << "getTransferMode" + << " is not supported."; + NEON_THROW(exp); +} } // namespace Neon::set::internal diff --git a/libNeonSet/src/set/container/ContainerExecutionType.cpp b/libNeonSet/src/set/container/ContainerExecutionType.cpp index 31760fd4..93f6f0bf 100644 --- a/libNeonSet/src/set/container/ContainerExecutionType.cpp +++ b/libNeonSet/src/set/container/ContainerExecutionType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/container/ContainerExecutionType.h" +#include "Neon/set/container/types/ContainerExecutionType.h" /** * Abstract interface to hide diff --git a/libNeonSet/src/set/container/ContainerOperationType.cpp b/libNeonSet/src/set/container/ContainerOperationType.cpp index 2f9d00ed..405957bb 100644 --- a/libNeonSet/src/set/container/ContainerOperationType.cpp +++ b/libNeonSet/src/set/container/ContainerOperationType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/container/ContainerOperationType.h" +#include "Neon/set/container/types/ContainerOperationType.h" /** * Abstract interface to hide @@ -15,8 +15,8 @@ auto ContainerOperationTypeUtils::toString(ContainerOperationType option) -> std case ContainerOperationType::graph: { return "graph"; } - case ContainerOperationType::halo: { - return "halo"; + case ContainerOperationType::communication: { + return "communication"; } case ContainerOperationType::sync: { return "sync"; diff --git a/libNeonSet/src/set/container/ContainerPatternType.cpp b/libNeonSet/src/set/container/ContainerPatternType.cpp index 5c67aedc..b505a331 100644 --- a/libNeonSet/src/set/container/ContainerPatternType.cpp +++ b/libNeonSet/src/set/container/ContainerPatternType.cpp @@ -1,4 +1,4 @@ -#include "Neon/set/container/ContainerPatternType.h" +#include "Neon/set/container/types/ContainerPatternType.h" /** * Abstract interface to hide diff --git a/libNeonSet/src/set/container/GraphContainer.cpp b/libNeonSet/src/set/container/GraphContainer.cpp index 64278b3e..9d999d03 100644 --- a/libNeonSet/src/set/container/GraphContainer.cpp +++ b/libNeonSet/src/set/container/GraphContainer.cpp @@ -45,16 +45,6 @@ auto GraphContainer::getGraph() -> const Neon::set::container::Graph& return *mGraph; } -auto GraphContainer::getHostContainer() -> std::shared_ptr -{ - NEON_THROW_UNSUPPORTED_OPTION("A managed Container Container is not associated with any host operation."); -} - -auto GraphContainer::getDeviceContainer() -> std::shared_ptr -{ - NEON_THROW_UNSUPPORTED_OPTION("A managed Container Container is not associated with any host operation."); -} - /** * Run container over streams * @param streamIdx diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 220b426d..16ea22ad 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -1,6 +1,6 @@ #include "Neon/set/container/graph/GraphNode.h" #include "Neon/set/container/AnchorContainer.h" -#include "Neon/set/container/ContainerExecutionType.h" +#include "Neon/set/container/types/ContainerExecutionType.h" namespace Neon::set::container { From a8b3a03f285df655b1f588e28b28efcb4db08982 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Sun, 30 Oct 2022 19:03:42 -0400 Subject: [PATCH 43/67] Managing communication nodes. --- libNeonSet/include/Neon/set/Containter.h | 6 + libNeonSet/include/Neon/set/Containter_imp.h | 31 +++-- .../set/container/DataTransferContainer.h | 16 ++- libNeonSet/include/Neon/set/container/Graph.h | 26 ++++- .../Neon/set/container/HaloUpdateContainer.h | 43 ++----- .../set/container/HaloUpdateContainer_imp.h | 35 ++++++ .../set/container/SynchronizationContainer.h | 61 ++++++++++ .../set/container/graph/GraphDependency.h | 51 +++++++-- .../Neon/set/container/graph/GraphNode.h | 58 ++++++---- .../set/container/graph/GraphNodeScheduling.h | 25 ++-- .../container/types/ContainerOperationType.h | 2 +- .../types/SynchronizationContainerType.h | 38 +++++++ libNeonSet/src/set/Containter.cpp | 3 +- libNeonSet/src/set/container/Graph.cpp | 107 ++++++++++++++++-- .../src/set/container/HaloUpdateContainer.cpp | 42 ------- .../set/container/graph/GraphDependency.cpp | 46 ++++++-- .../src/set/container/graph/GraphNode.cpp | 78 ++++++++----- .../container/graph/GraphNodeScheduling.cpp | 7 ++ .../{ => types}/ContainerExecutionType.cpp | 0 .../{ => types}/ContainerOperationType.cpp | 8 +- .../{ => types}/ContainerPatternType.cpp | 0 .../types/SynchronizationContainerType.cpp | 46 ++++++++ .../Neon/skeleton/internal/MultiXpuGraph.h | 2 +- .../src/skeleton/internal/multiGpuGraph.cpp | 16 +-- 24 files changed, 555 insertions(+), 192 deletions(-) create mode 100644 libNeonSet/include/Neon/set/container/HaloUpdateContainer_imp.h create mode 100644 libNeonSet/include/Neon/set/container/SynchronizationContainer.h create mode 100644 libNeonSet/include/Neon/set/container/types/SynchronizationContainerType.h delete mode 100644 libNeonSet/src/set/container/HaloUpdateContainer.cpp rename libNeonSet/src/set/container/{ => types}/ContainerExecutionType.cpp (100%) rename libNeonSet/src/set/container/{ => types}/ContainerOperationType.cpp (91%) rename libNeonSet/src/set/container/{ => types}/ContainerPatternType.cpp (100%) create mode 100644 libNeonSet/src/set/container/types/SynchronizationContainerType.cpp diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 547fdfe3..abba3cab 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -7,6 +7,7 @@ #include "Neon/set/container/ContainerAPI.h" #include "Neon/set/container/types/HostManagedSyncType.h" +#include "Neon/set/container/types/SynchronizationContainerType.h" #include "Neon/set/container/Loader.h" @@ -113,6 +114,11 @@ struct Container Neon::set::TransferSemantic transferSemantic) -> Neon::set::Container; + template + static auto factorySynchronization(const MxpuDataT& multiXpuData, + SynchronizationContainerType syncType) + -> Container; + static auto factoryAnchor(const std::string& name /**< A user's string to identify the computation done by the Container. */) -> Container; diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h index 6259693e..2a08b5fc 100644 --- a/libNeonSet/include/Neon/set/Containter_imp.h +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -5,14 +5,15 @@ #include "functional" #include "type_traits" +#include "Neon/set/container/DataTransferContainer.h" #include "Neon/set/container/DeviceContainer.h" #include "Neon/set/container/DeviceManagedContainer.h" #include "Neon/set/container/DeviceThenHostManagedContainer.h" +#include "Neon/set/container/GraphContainer.h" #include "Neon/set/container/HostManagedContainer.h" #include "Neon/set/container/OldDeviceManagedContainer.h" -#include "Neon/set/container/DataTransferContainer.h" +#include "Neon/set/container/SynchronizationContainer.h" -#include "Neon/set/container/GraphContainer.h" namespace Neon::set { @@ -87,13 +88,27 @@ auto Container::factoryDeviceManaged(const std::string& } template -auto Container::factoryDataTransfer(const MultiXpuDataT& multiXpuData, - Neon::set::TransferMode transferMode, - Neon::set::TransferSemantic transferSemantic) - -> Neon::set::Container{ +auto Container:: + factoryDataTransfer(const MultiXpuDataT& multiXpuData, + Neon::set::TransferMode transferMode, + Neon::set::TransferSemantic transferSemantic) + -> Neon::set::Container +{ auto k = new Neon::set::internal::DataTransferContainer(multiXpuData, - transferMode, - transferSemantic ); + transferMode, + transferSemantic); + + std::shared_ptr tmp(k); + return {tmp}; +} + +template +auto Container:: + factorySynchronization(const MxpuDataT& multiXpuData, + SynchronizationContainerType syncType) -> Container +{ + auto k = new Neon::set::internal::SynchronizationContainer(multiXpuData, + syncType); std::shared_ptr tmp(k); return {tmp}; diff --git a/libNeonSet/include/Neon/set/container/DataTransferContainer.h b/libNeonSet/include/Neon/set/container/DataTransferContainer.h index 18262849..75228c8b 100644 --- a/libNeonSet/include/Neon/set/container/DataTransferContainer.h +++ b/libNeonSet/include/Neon/set/container/DataTransferContainer.h @@ -2,19 +2,17 @@ #include "Neon/core/core.h" #include "Neon/set/container/ContainerAPI.h" -#include "Neon/set/container/DeviceContainer.h" -#include "Neon/set/container/Graph.h" #include "Neon/set/container/Loader.h" namespace Neon::set::internal { -template +template struct DataTransferContainer : ContainerAPI { virtual ~DataTransferContainer() override = default; - DataTransferContainer(const MultiXpuDataT& multiXpuData, + DataTransferContainer(const MxpuDataT& multiXpuData, Neon::set::TransferMode transferMode, Neon::set::TransferSemantic transferSemantic) : mMultiXpuData(multiXpuData), @@ -27,7 +25,7 @@ struct DataTransferContainer setContainerOperationType(ContainerOperationType::communication); setDataViewSupport(DataViewSupport::off); - mCompute = [&](Neon::SetIdx setIdx, + mDataTransferFun = [&](Neon::SetIdx setIdx, int streamIdx) { Neon::set::HuOptions options(this->mTransferMode, false, @@ -38,7 +36,7 @@ struct DataTransferContainer } auto run(int streamIdx, - Neon::DataView dataView = Neon::DataView::STANDARD) -> void override + Neon::DataView dataView) -> void override { const Neon::Backend& bk = mMultiXpuData.getBackend(); const int setCardinality = bk.devSet().setCardinality(); @@ -54,7 +52,7 @@ struct DataTransferContainer Neon::DataView dataView) -> void override { if (ContainerExecutionType::deviceManaged == this->getContainerType()) { - mCompute(setIdx, streamIdx); + mDataTransferFun(setIdx, streamIdx); return; } NEON_THROW_UNSUPPORTED_OPTION(""); @@ -63,8 +61,8 @@ struct DataTransferContainer private: std::function - mCompute; - MultiXpuDataT mMultiXpuData; + mDataTransferFun; + MxpuDataT mMultiXpuData; Neon::set::TransferMode mTransferMode; Neon::set::TransferSemantic mTransferSemantic; }; diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index d30f0dbc..5d6047b5 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -5,12 +5,19 @@ #include "Neon/set/container/graph/Bfs.h" #include "Neon/set/container/graph/GraphDependency.h" +#include "Neon/set/container/graph/GraphDependencyType.h" #include "Neon/set/container/graph/GraphNode.h" + namespace Neon::skeleton::internal { struct MultiXpuGraph; } +namespace Neon::set::container { +struct GraphNode; +struct GraphDependency; +} // namespace Neon::set::container + namespace Neon::set::container { /** @@ -25,6 +32,8 @@ struct Graph using Uid = GraphData::Uid; using Index = GraphData::Index; friend struct Bfs; + friend Neon::set::container::GraphNode; + friend Neon::set::container::GraphDependency; friend Neon::skeleton::internal::MultiXpuGraph; public: @@ -95,6 +104,9 @@ struct Graph const GraphNode& nodeB) -> GraphDependencyType; + auto getDependency(const GraphNode& nodeA, + const GraphNode& nodeB) + const -> const GraphDependency&; /** * Clone a node and return a reference to the new clone. * The cloning process connects the clone the the same nodes of the original @@ -117,7 +129,9 @@ struct Graph */ auto getSubsequentGraphNodes(const GraphNode& graphNode, const std::vector& dependencyTypes = {GraphDependencyType::user, - GraphDependencyType::data}) -> std::vector; + GraphDependencyType::data}) + -> std::vector; + /** * Set the stream to run the graph. * We provide a preset function so that some initialization @@ -160,10 +174,10 @@ struct Graph auto getNumberOfNodes() -> int; - auto forEachDependency(const std::function &fun) + auto forEachDependency(const std::function& fun) const -> void; - auto forEachNode(const std::function &fun) + auto forEachNode(const std::function& fun) const -> void; protected: @@ -295,6 +309,12 @@ struct Graph auto helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) -> void; + /** + * Adding a graph between two nodes + */ + auto helpMergeGraphBetweenNodes(const Graph& graph, + const GraphNode& A, + const GraphNode& B); using RawGraph = DiGraph; diff --git a/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h b/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h index e7030b17..a5a48df7 100644 --- a/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h +++ b/libNeonSet/include/Neon/set/container/HaloUpdateContainer.h @@ -1,14 +1,18 @@ #pragma once + #include "Neon/core/core.h" #include "Neon/set/container/ContainerAPI.h" #include "Neon/set/container/Graph.h" #include "Neon/set/container/GraphContainer.h" #include "Neon/set/container/Loader.h" +#include "Neon/set/container/types/SynchronizationContainerType.h" + +namespace Neon::set { +struct Container; +} -namespace Neon { -namespace set { -namespace internal { +namespace Neon::set::internal { template struct HaloUpdateContainer @@ -16,38 +20,15 @@ struct HaloUpdateContainer { public: - virtual ~HaloUpdateContainer() override = default; + ~HaloUpdateContainer() override = default; HaloUpdateContainer(const Neon::Backend& bk, const Neon::set::Container& dataTransferContainer, - const Neon::set::Container& syncContainer) - { - Neon::set::container::Graph graph(bk); - - auto dataTranferNode = graph.addNode(dataTransferContainer); - auto syncNode = graph.addNode(syncContainer); - - if (dataTransferContainer.getContainerInterface().getTransferMode() == - Neon::set::TransferMode::get) { - graph.addDependency(syncNode, dataTranferNode, GraphDependencyType::data); - } else { - graph.addDependency(dataTranferNode, syncNode, GraphDependencyType::data); - } - - auto name = std::string("HaloUpdate"); - GraphContainer graphContainer(graph, [&](Neon::set::Loader& loader) { - // Nothing to load - }); - - this->GraphContainer = graphContainer; - - setContainerOperationType(ContainerOperationType::communication); - setDataViewSupport(DataViewSupport::off); - } + const Neon::set::Container& syncContainer); private: }; -} // namespace internal -} // namespace set -} // namespace Neon +} // namespace Neon::set::internal + +#include "Neon/set/container/HaloUpdateContainer_imp.h" \ No newline at end of file diff --git a/libNeonSet/include/Neon/set/container/HaloUpdateContainer_imp.h b/libNeonSet/include/Neon/set/container/HaloUpdateContainer_imp.h new file mode 100644 index 00000000..7746ee4e --- /dev/null +++ b/libNeonSet/include/Neon/set/container/HaloUpdateContainer_imp.h @@ -0,0 +1,35 @@ +#include "Neon/core/core.h" + +#include "Neon/set/container/HaloUpdateContainer.h" + +namespace Neon::set::internal { + +template +HaloUpdateContainer:: + HaloUpdateContainer(const Neon::Backend& bk, + const Neon::set::Container& dataTransferContainer, + const Neon::set::Container& syncContainer) +{ + Neon::set::container::Graph graph(bk); + + auto dataTranferNode = graph.addNode(dataTransferContainer); + auto syncNode = graph.addNode(syncContainer); + + if (dataTransferContainer.getContainerInterface().getTransferMode() == + Neon::set::TransferMode::get) { + graph.addDependency(syncNode, dataTranferNode, GraphDependencyType::data); + } else { + graph.addDependency(dataTranferNode, syncNode, GraphDependencyType::data); + } + + auto name = std::string("HaloUpdate"); + GraphContainer graphContainer(graph, [&](Neon::set::Loader& loader) { + // Nothing to load + }); + + this->GraphContainer = graphContainer; + + setContainerOperationType(ContainerOperationType::communication); + setDataViewSupport(DataViewSupport::off); +} +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/container/SynchronizationContainer.h b/libNeonSet/include/Neon/set/container/SynchronizationContainer.h new file mode 100644 index 00000000..65d790fa --- /dev/null +++ b/libNeonSet/include/Neon/set/container/SynchronizationContainer.h @@ -0,0 +1,61 @@ +#pragma once +#include "Neon/core/core.h" + +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/DeviceContainer.h" +#include "Neon/set/container/Graph.h" +#include "Neon/set/container/Loader.h" +#include "Neon/set/container/types/SynchronizationContainerType.h" + +#include + +namespace Neon::set::internal { + +template +struct SynchronizationContainer + : ContainerAPI +{ + ~SynchronizationContainer() override = default; + + explicit SynchronizationContainer(const MxpuDataT& multiXpuData, + SynchronizationContainerType syncType) + : mMultiXpuData(multiXpuData), + mSynchronizationType(syncType) + { + setName("SynchronizationContainer"); + + setContainerExecutionType(ContainerExecutionType::deviceManaged); + setContainerOperationType(ContainerOperationType::synchronization); + setDataViewSupport(DataViewSupport::off); + } + + auto run(int streamIdx, + Neon::DataView dataView) -> void override + { + const Neon::Backend& bk = mMultiXpuData.getBackend(); + const int setCardinality = bk.devSet().setCardinality(); + +#pragma omp parallel num_threads(setCardinality) + { + const int threadRank = omp_get_thread_num(); + run(Neon::SetIdx(threadRank), streamIdx, dataView); + } + } + + auto + run(Neon::SetIdx setIdx, + int streamIdx, + Neon::DataView dataView) -> void override + { + const auto& bk = mMultiXpuData.getBackend(); + bk.sync(setIdx, streamIdx); +#pragma omp barrier + } + + private: + MxpuDataT mMultiXpuData; + SynchronizationContainerType mSynchronizationType; + +}; // namespace Neon::set::internal + +} // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h index 2910f6f4..c079827c 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphDependency.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphDependency.h @@ -1,44 +1,73 @@ #pragma once -#include "GraphDependencyType.h" +#include "Neon/set/container/graph/GraphNode.h" #include "Neon/set/dependency/Token.h" +#include "GraphDependencyType.h" + +namespace Neon::skeleton::internal { +struct MultiXpuGraph; +} + namespace Neon::set::container { +struct GraphNode; +struct Graph; + struct GraphDependency { - std::string getLabel(); + using Tokens = std::vector; + using Token = Neon::set::dataDependency::Token; + using RawGraph = DiGraph; + friend Neon::skeleton::internal::MultiXpuGraph; + friend Graph; public: GraphDependency(); - explicit GraphDependency(GraphDependencyType type); + explicit GraphDependency(GraphDependencyType type, + const RawGraph::Edge& edge); - explicit GraphDependency(const Neon::set::dataDependency::Token& type); + explicit GraphDependency(const Token& type, + const RawGraph::Edge& edge); - explicit GraphDependency(const std::vector& type); + explicit GraphDependency(const Tokens& type, + const RawGraph::Edge& edge); - auto setType(GraphDependencyType type) + auto setType(GraphDependencyType type, + const RawGraph::Edge& edge) -> void; - auto getType() const - -> GraphDependencyType; + auto getType() + const -> GraphDependencyType; + + auto getLabel() const + -> std::string; auto addToken(const Neon::set::dataDependency::Token& token) -> void; + auto getSourceNode(const Graph& graph) + const -> const GraphNode&; + + auto getDestinationNode(const Graph& graph) + const -> const GraphNode&; /** * Returns the tokens generating this dependency */ auto getTokens() - const -> const std::vector&; + const -> const Tokens&; auto hasStencilDependency() const -> bool; private: - GraphDependencyType mType; - std::vector mTokens /**< Tokens creating this dependency. */; + auto getRawEdge() + const -> RawGraph::Edge; + + GraphDependencyType mType; + Tokens mTokens /**< Tokens creating this dependency. */; + RawGraph::Edge mEdge; // TODO - add information for data and Scheduling dependency }; diff --git a/libNeonSet/include/Neon/set/container/graph/GraphNode.h b/libNeonSet/include/Neon/set/container/graph/GraphNode.h index a0ad22d8..d310d985 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphNode.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphNode.h @@ -8,9 +8,6 @@ namespace Neon::set::container { struct GraphNode { - std::string getLabel(bool debug); - - std::string getLabelProperty(); public: GraphNode(); @@ -21,64 +18,85 @@ struct GraphNode /** * Factory method to generate a begin node */ - static auto newBeginNode() -> GraphNode; + static auto newBeginNode() + -> GraphNode; /** * Factory method to generate a end node */ - static auto newEndNode() -> GraphNode; + static auto newEndNode() + -> GraphNode; /** * Executes the scheduling operation associated to the node */ - auto execute() -> void; + auto execute() + -> void; /** * Returns a reference to graph information related to this node. * */ - auto getGraphData() -> GraphData&; + auto getGraphData() + -> GraphData&; /** * Returns a reference to some graph information related to this node. * */ - auto getGraphData() const -> const GraphData&; + auto getGraphData() + const -> const GraphData&; /** * Returns the scheduling information to run this node */ - auto getScheduling() -> GraphNodeScheduling&; + auto getScheduling() + -> GraphNodeScheduling&; /** * Returns the scheduling information to run this node */ - auto getScheduling() const -> const GraphNodeScheduling&; + auto getScheduling() + const -> const GraphNodeScheduling&; /** * Returns a reference to the container stored by this node. */ - auto getContainer() -> Container&; + auto getContainer() + -> Container&; /** * Returns a reference to the container stored by this node. */ - auto getContainer() const -> const Container&; + auto getContainer() + const -> const Container&; /** * Returns the operation type of the container associated to this node */ - auto getContainerOperationType() const -> Neon::set::ContainerOperationType; + auto getContainerOperationType() + const -> Neon::set::ContainerOperationType; + + auto toString() + const -> std::string; - auto toString() -> std::string; + auto getLabel(bool debug) + const -> std::string; + auto getLabelProperty() + const -> std::string; private: - auto helpGetDotProperties() -> std::string; - auto helpGetDotName() -> std::string; - auto helpGetDotInfo() -> std::string; + auto helpGetDotProperties() + const -> std::string; + + auto helpGetDotName() + const -> std::string; + + auto helpGetDotInfo() + const -> std::string; - Container mContainer /**< Any Neon container */; - GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; - GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; + Container mContainer /**< Any Neon container */; + GraphNodeScheduling mGraphNodeScheduling /**< Scheduling information for the node */; + GraphData mGraphNodeOrganization /**< Information to organize the node w.r.t. the rest of the graph */; ContainerPatternType getContainerpatternType() const; }; diff --git a/libNeonSet/include/Neon/set/container/graph/GraphNodeScheduling.h b/libNeonSet/include/Neon/set/container/graph/GraphNodeScheduling.h index caae61dc..79755af1 100644 --- a/libNeonSet/include/Neon/set/container/graph/GraphNodeScheduling.h +++ b/libNeonSet/include/Neon/set/container/graph/GraphNodeScheduling.h @@ -11,31 +11,38 @@ class GraphNodeScheduling /** * Get list of events to wait the completion of. */ - auto getDependentEvents() -> std::vector&; + auto getDependentEvents() + -> std::vector&; + + auto getDependentEvents() + const -> const std::vector&; /** * Set the data view for the node * @param dataView */ - auto setDataView(Neon::DataView dataView) -> void; + auto setDataView(Neon::DataView dataView) + -> void; GraphNodeScheduling(); /** * Returns data view associated to this node; */ - auto getDataView() const -> Neon::DataView; + auto getDataView() + const -> Neon::DataView; /** * Get the stream to execute the Container */ - auto getStream() const - -> int; + auto getStream() + const -> int; /** * Set the stream for the Container execution */ - auto setStream(int stream /**< stream for the Container execution */) -> void; + auto setStream(int stream /**< stream for the Container execution */) + -> void; /** * Get the event to asynchronously signal that the execution of the Container is completed. @@ -46,12 +53,14 @@ class GraphNodeScheduling /** * Set the event to asynchronously signal the completion of the Container. */ - auto setEvent(int event /**< Event to be used to signal the completion of the Container */) -> void; + auto setEvent(int event /**< Event to be used to signal the completion of the Container */) + -> void; /** * Reset all scheduling data */ - void reset(); + auto reset() + -> void; private: int mStream{-1} /**< Stream for each operation for the node */; diff --git a/libNeonSet/include/Neon/set/container/types/ContainerOperationType.h b/libNeonSet/include/Neon/set/container/types/ContainerOperationType.h index 08cadf6b..59fae9aa 100644 --- a/libNeonSet/include/Neon/set/container/types/ContainerOperationType.h +++ b/libNeonSet/include/Neon/set/container/types/ContainerOperationType.h @@ -15,7 +15,7 @@ enum struct ContainerOperationType compute = 0 /**< Compute container, can be on host or device */, graph = 1 /**< A graph based container */, communication = 2 /**< Halo update container **/, - sync = 3 /**< Synchronization Container */, + synchronization = 3 /**< Synchronization Container */, anchor = 4 /**< Synchronization Container: begin or end */ }; diff --git a/libNeonSet/include/Neon/set/container/types/SynchronizationContainerType.h b/libNeonSet/include/Neon/set/container/types/SynchronizationContainerType.h new file mode 100644 index 00000000..522bea21 --- /dev/null +++ b/libNeonSet/include/Neon/set/container/types/SynchronizationContainerType.h @@ -0,0 +1,38 @@ +#pragma once + +#include "Neon/set/DevSet.h" +#include "functional" +#include "type_traits" + +/** + * Abstract interface to hide + */ + +namespace Neon::set { + +enum struct SynchronizationContainerType +{ + hostOmpBarrier = 0, + none = 6 +}; + + +struct SynchronizationContainerTypeUtils +{ + static constexpr int nOptions = 1; + + static auto toString(SynchronizationContainerType option) + -> std::string; + + static auto fromString(const std::string& option) + -> SynchronizationContainerType; + + static auto getOptions() + -> std::array; +}; + +/** + * operator<< + */ +std::ostream& operator<<(std::ostream& os, Neon::set::SynchronizationContainerType const& m); +} // namespace Neon::set diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index 22ccb0d3..1e14e720 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -1,5 +1,6 @@ #include "Neon/set/Containter.h" #include "Neon/set/container/AnchorContainer.h" +#include "Neon/set/container/SynchronizationContainer.h" namespace Neon::set { @@ -130,6 +131,4 @@ auto Container::factoryGraph(const std::string& name, return Container(tmp); } - - } // namespace Neon::set diff --git a/libNeonSet/src/set/container/Graph.cpp b/libNeonSet/src/set/container/Graph.cpp index 0ad5dbc2..d07286c0 100644 --- a/libNeonSet/src/set/container/Graph.cpp +++ b/libNeonSet/src/set/container/Graph.cpp @@ -71,7 +71,10 @@ auto Graph:: } helpInvalidateScheduling(); - GraphDependency ab(type); + auto aUid = nodeA.getGraphData().getUid(); + auto bUid = nodeB.getGraphData().getUid(); + + GraphDependency ab(type, {aUid, bUid}); mRawGraph.addEdge(nodeA.getGraphData().getUid(), nodeB.getGraphData().getUid(), @@ -96,7 +99,7 @@ auto Graph:: if (mRawGraph.hasEdge(nodeA.getGraphData().getUid(), nodeB.getGraphData().getUid())) { GraphDependency& graphDependency = mRawGraph.getEdgeProperty({nodeA.getGraphData().getUid(), - nodeB.getGraphData().getUid()}); + nodeB.getGraphData().getUid()}); graphDependency.addToken(token); } else { GraphDependency ab(token); @@ -298,8 +301,22 @@ auto Graph:: return dependencyType; } -auto Graph::helpInvalidateScheduling() - -> void +auto Graph:: + getDependency(const GraphNode& nodeA, + const GraphNode& nodeB) + const -> const GraphDependency& +{ + auto uidA = nodeA.getGraphData().getUid(); + auto uidB = nodeB.getGraphData().getUid(); + + const auto& dependency = mRawGraph.getEdgeProperty({uidA, uidB}); + + return dependency; +} + +auto Graph:: + helpInvalidateScheduling() + -> void { mSchedulingStatusIsValid = false; } @@ -974,9 +991,9 @@ auto Graph:: auto Graph:: forEachDependency(const std::function& fun) - const -> void + const -> void { - mRawGraph.forEachEdge([&](const auto& edge){ + mRawGraph.forEachEdge([&](const auto& edge) { const auto& dep = this->mRawGraph.getEdgeProperty(edge); fun(dep); }); @@ -986,11 +1003,87 @@ auto Graph:: forEachNode(const std::function& fun) const -> void { - mRawGraph.forEachVertex([&](size_t nodeId){ + mRawGraph.forEachVertex([&](size_t nodeId) { auto node = this->mRawGraph.getVertexProperty(nodeId); fun(node); }); } +auto Graph::helpMergeGraphBetweenNodes(const Graph& graphOriginal, + const GraphNode& A, + const GraphNode& B) +{ + Graph inputGraph = graphOriginal; + inputGraph.expandSubGraphs(); + + std::unordered_map fromInputToLocal; + + auto isInternalNode = [&](const GraphNode& inputNode) { + if (&graphOriginal.getBeginNode() != &inputNode && + &graphOriginal.getEndNode() != &inputNode) { + return true; + } + return false; + }; + + auto isInternalDependency = [&](const GraphDependency& inputDependency) { + const auto& source = inputDependency.getSourceNode(graphOriginal); + const auto& dest = inputDependency.getDestinationNode(graphOriginal); + + if (isInternalNode(source) && + isInternalNode(dest)) { + return true; + } + return false; + }; + + // adding nodes to the graph + inputGraph.forEachNode([&](const GraphNode& inputNode) { + // discarding begin and end nodes + if (isInternalNode(inputNode)) { + auto& container = inputNode.getContainer(); + auto newGraphNode = this->addNode(container); + + fromInputToLocal[&inputNode] = &newGraphNode; + } + }); + + // adding dependency to the graph + inputGraph.forEachDependency([&](const GraphDependency& inputDependency) { + // discarding begin and end nodes + if (isInternalDependency(inputDependency)) { + const auto& sourceInput = inputDependency.getSourceNode(graphOriginal); + const auto& destInput = inputDependency.getDestinationNode(graphOriginal); + + auto source = fromInputToLocal[&sourceInput]; + auto dest = fromInputToLocal[&destInput]; + + this->addDependency(*source, *dest, inputDependency.getType()); + } + }); + + { // Connecting node A with all the child of the input graph begin node + const auto& inputBeginNode = inputGraph.getBeginNode(); + std::vector subsequentGraphNodes = inputGraph.getSubsequentGraphNodes(inputBeginNode); + for (auto inputGraphNodePtr : subsequentGraphNodes) { + auto source = &A; + auto dest = fromInputToLocal[inputGraphNodePtr]; + const auto& inputDependency = inputGraph.getDependency(inputBeginNode, *inputGraphNodePtr); + this->addDependency(*source, *dest, inputDependency.getType()); + } + } + + { // Connecting node B with all the parents of the input graph end node + const auto& inputEndNode = inputGraph.getEndNode(); + std::vector proceedingGraphNodes = inputGraph.getProceedingGraphNodes(inputEndNode); + for (auto inputGraphNodePtr : proceedingGraphNodes) { + auto source = fromInputToLocal[inputGraphNodePtr]; + auto dest = &B; + const auto& inputDependency = inputGraph.getDependency(*inputGraphNodePtr, inputEndNode); + this->addDependency(*source, *dest, inputDependency.getType()); + } + } +} + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/HaloUpdateContainer.cpp b/libNeonSet/src/set/container/HaloUpdateContainer.cpp deleted file mode 100644 index 057defe3..00000000 --- a/libNeonSet/src/set/container/HaloUpdateContainer.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "Neon/core/core.h" - -#include "Neon/set/container/HaloUpdateContainer.h" - -namespace Neon::set::internal { - -HaloUpdateContainer:: - HaloUpdateContainer(const std::string& name) -{ - setName(name); - setContainerExecutionType(ContainerExecutionType::communication); - setContainerOperationType(ContainerOperationType::halo); - setDataViewSupport(ContainerAPI::DataViewSupport::off); -} - - -auto HaloUpdateContainer:: - parse() - -> const std::vector& -{ - return mEmtpy; -} - -auto HaloUpdateContainer::getHostContainer() -> std::shared_ptr -{ - NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); -} - -auto HaloUpdateContainer::getDeviceContainer() -> std::shared_ptr -{ - NEON_THROW_UNSUPPORTED_OPTION("This Container type can not be decoupled."); -} - -auto HaloUpdateContainer::run(int /*streamIdx*/, Neon::DataView /*dataView*/) -> void -{ -} - -auto HaloUpdateContainer::run(Neon::SetIdx /*setIdx*/, int /*streamIdx*/, Neon::DataView /*dataView*/) -> void -{ -} - -} // namespace Neon::set::internal diff --git a/libNeonSet/src/set/container/graph/GraphDependency.cpp b/libNeonSet/src/set/container/graph/GraphDependency.cpp index 381e33c2..a722169b 100644 --- a/libNeonSet/src/set/container/graph/GraphDependency.cpp +++ b/libNeonSet/src/set/container/graph/GraphDependency.cpp @@ -9,10 +9,12 @@ GraphDependency:: } auto GraphDependency:: - setType(GraphDependencyType type) + setType(GraphDependencyType type, + const RawGraph::Edge& edge) -> void { mType = type; + mEdge = edge; } auto GraphDependency:: @@ -22,41 +24,45 @@ auto GraphDependency:: return mType; } GraphDependency:: - GraphDependency(GraphDependencyType type) + GraphDependency(GraphDependencyType type, + const RawGraph::Edge& edge) { - setType(type); + setType(type, edge); } GraphDependency:: - GraphDependency(const dataDependency::Token& token) - : mType(GraphDependencyType::data) + GraphDependency(const dataDependency::Token& token, + const RawGraph::Edge& edge) { + setType(GraphDependencyType::data, edge); mTokens.push_back(token); } GraphDependency:: - GraphDependency(const std::vector& tokens) - : mType(GraphDependencyType::data) + GraphDependency(const std::vector& tokens, + const RawGraph::Edge& edge) { + setType(GraphDependencyType::data, edge); mTokens = tokens; } auto GraphDependency:: getLabel() - -> std::string + const -> std::string { return GraphDependencyTypeUtil::toString(getType()); } auto GraphDependency:: - addToken(const Neon::set::dataDependency::Token& token) -> void + addToken(const Token& token) + -> void { mTokens.push_back(token); } - -auto GraphDependency::getTokens() const -> const std::vector& +auto GraphDependency::getTokens() + const -> const Tokens& { return mTokens; } @@ -72,5 +78,23 @@ auto GraphDependency::hasStencilDependency() return isStencil; } +auto GraphDependency::getRawEdge() + const -> RawGraph::Edge +{ + return mEdge; +} + +auto GraphDependency::getSourceNode(const Graph& graph) + const -> const GraphNode& +{ + return graph.helpGetGraphNode(mEdge.first); +} + +auto GraphDependency::getDestinationNode(const Graph& graph) + const -> const GraphNode& +{ + return graph.helpGetGraphNode(mEdge.second); +} + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/graph/GraphNode.cpp b/libNeonSet/src/set/container/graph/GraphNode.cpp index 16ea22ad..688ba6ee 100644 --- a/libNeonSet/src/set/container/graph/GraphNode.cpp +++ b/libNeonSet/src/set/container/graph/GraphNode.cpp @@ -8,7 +8,8 @@ GraphNode::GraphNode() { } -auto GraphNode::newBeginNode() -> GraphNode +auto GraphNode:: + newBeginNode() -> GraphNode { GraphNode node; node.mGraphNodeOrganization.setUid(GraphData::beginUid); @@ -16,7 +17,8 @@ auto GraphNode::newBeginNode() -> GraphNode return node; } -auto GraphNode::newEndNode() -> GraphNode +auto GraphNode:: + newEndNode() -> GraphNode { GraphNode node; node.mGraphNodeOrganization.setUid(GraphData::endUid); @@ -24,49 +26,62 @@ auto GraphNode::newEndNode() -> GraphNode return node; } -auto GraphNode::getGraphData() -> GraphData& +auto GraphNode:: + getGraphData() -> GraphData& { return mGraphNodeOrganization; } -auto GraphNode::getGraphData() const -> const GraphData& +auto GraphNode:: + getGraphData() + const -> const GraphData& { return mGraphNodeOrganization; } -auto GraphNode::getScheduling() -> GraphNodeScheduling& +auto GraphNode:: + getScheduling() -> GraphNodeScheduling& { return mGraphNodeScheduling; } -auto GraphNode::getScheduling() const -> const GraphNodeScheduling& +auto GraphNode:: + getScheduling() + const -> const GraphNodeScheduling& { return mGraphNodeScheduling; } -auto GraphNode::getContainer() -> Container& +auto GraphNode:: + getContainer() -> Container& { return mContainer; } -auto GraphNode::getContainer() const -> const Container& +auto GraphNode:: + getContainer() const -> const Container& { return mContainer; } -GraphNode::GraphNode(const Container& container, GraphData::Uid uid) +GraphNode:: + GraphNode(const Container& container, GraphData::Uid uid) { mContainer = container; mGraphNodeOrganization.setUid(uid); } -auto GraphNode::toString() -> std::string +auto GraphNode:: + toString() + const -> std::string { return std::string(); } -auto GraphNode::helpGetDotProperties() -> std::string +auto GraphNode:: + helpGetDotProperties() + const -> std::string { if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; @@ -74,22 +89,25 @@ auto GraphNode::helpGetDotProperties() -> std::string if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::communication) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::synchronization) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } NEON_DEV_UNDER_CONSTRUCTION(""); } -auto GraphNode::helpGetDotName() -> std::string +auto GraphNode:: + helpGetDotName() + const -> std::string { return getContainer().getName(); } -auto GraphNode::helpGetDotInfo() -> std::string +auto GraphNode::helpGetDotInfo() + const -> std::string { if (getContainerOperationType() == Neon::set::ContainerOperationType::anchor) { - return std::string(); + return {}; } if (getContainerOperationType() == Neon::set::ContainerOperationType::compute) { std::stringstream s; @@ -97,26 +115,30 @@ auto GraphNode::helpGetDotInfo() -> std::string s << "DataView = " << Neon::DataViewUtil::toString(getScheduling().getDataView()); return s.str(); } - if (getContainerOperationType() == Neon::set::ContainerOperationType::halo) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::communication) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (getContainerOperationType() == Neon::set::ContainerOperationType::sync) { + if (getContainerOperationType() == Neon::set::ContainerOperationType::synchronization) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } NEON_DEV_UNDER_CONSTRUCTION(""); } -auto GraphNode::getContainerOperationType() const -> Neon::set::ContainerOperationType +auto GraphNode:: + getContainerOperationType() const -> Neon::set::ContainerOperationType { return getContainer().getContainerInterface().getContainerOperationType(); } -auto GraphNode::getContainerpatternType() const -> Neon::set::ContainerPatternType +auto GraphNode:: + getContainerpatternType() const -> Neon::set::ContainerPatternType { return getContainer().getContainerInterface().getContainerPatternType(); } -auto GraphNode::getLabel(bool debug) -> std::string +auto GraphNode:: + getLabel(bool debug) + const -> std::string { auto containerOperationType = getContainerOperationType(); @@ -192,7 +214,7 @@ auto GraphNode::getLabel(bool debug) -> std::string } return s.str(); } - if (containerOperationType == Neon::set::ContainerOperationType::halo) { + if (containerOperationType == Neon::set::ContainerOperationType::communication) { std::stringstream s; s << "Halo Update " " - Name: " @@ -200,7 +222,7 @@ auto GraphNode::getLabel(bool debug) -> std::string s << " - UID: " << getContainer().getUid(); return s.str(); } - if (containerOperationType == Neon::set::ContainerOperationType::sync) { + if (containerOperationType == Neon::set::ContainerOperationType::synchronization) { std::stringstream s; s << "Sync " " - Name: " @@ -223,7 +245,9 @@ auto GraphNode::getLabel(bool debug) -> std::string } -auto GraphNode::getLabelProperty() -> std::string +auto GraphNode:: + getLabelProperty() + const -> std::string { auto containerOperationType = getContainerOperationType(); if (containerOperationType == Neon::set::ContainerOperationType::anchor) { @@ -233,7 +257,7 @@ auto GraphNode::getLabelProperty() -> std::string if (this->getGraphData().endUid == getGraphData().getUid()) { return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; } - //NEON_THROW_UNSUPPORTED_OPERATION(""); + // NEON_THROW_UNSUPPORTED_OPERATION(""); return R"(shape=doublecircle, style=filled, fillcolor="#d9d9d9", color="#6c6c6c")"; } if (containerOperationType == Neon::set::ContainerOperationType::compute) { @@ -253,11 +277,11 @@ auto GraphNode::getLabelProperty() -> std::string NEON_THROW_UNSUPPORTED_OPERATION(""); } - if (containerOperationType == Neon::set::ContainerOperationType::halo) { + if (containerOperationType == Neon::set::ContainerOperationType::communication) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } - if (containerOperationType == Neon::set::ContainerOperationType::sync) { + if (containerOperationType == Neon::set::ContainerOperationType::synchronization) { return R"(shape=octagon, style="rounded,filled", fillcolor="#fb8072", color="#b11605")"; } if (containerOperationType == Neon::set::ContainerOperationType::graph) { diff --git a/libNeonSet/src/set/container/graph/GraphNodeScheduling.cpp b/libNeonSet/src/set/container/graph/GraphNodeScheduling.cpp index d0fb662f..59f40d1f 100644 --- a/libNeonSet/src/set/container/graph/GraphNodeScheduling.cpp +++ b/libNeonSet/src/set/container/graph/GraphNodeScheduling.cpp @@ -25,6 +25,12 @@ auto GraphNodeScheduling::getDependentEvents() return mDependentEvents; } +auto GraphNodeScheduling::getDependentEvents() + const -> const std::vector& +{ + return mDependentEvents; +} + auto GraphNodeScheduling::setStream(int stream) -> void { @@ -55,4 +61,5 @@ auto GraphNodeScheduling::reset() -> void mDependentEvents.clear(); } + } // namespace Neon::set::container diff --git a/libNeonSet/src/set/container/ContainerExecutionType.cpp b/libNeonSet/src/set/container/types/ContainerExecutionType.cpp similarity index 100% rename from libNeonSet/src/set/container/ContainerExecutionType.cpp rename to libNeonSet/src/set/container/types/ContainerExecutionType.cpp diff --git a/libNeonSet/src/set/container/ContainerOperationType.cpp b/libNeonSet/src/set/container/types/ContainerOperationType.cpp similarity index 91% rename from libNeonSet/src/set/container/ContainerOperationType.cpp rename to libNeonSet/src/set/container/types/ContainerOperationType.cpp index 405957bb..6afce6c4 100644 --- a/libNeonSet/src/set/container/ContainerOperationType.cpp +++ b/libNeonSet/src/set/container/types/ContainerOperationType.cpp @@ -18,8 +18,8 @@ auto ContainerOperationTypeUtils::toString(ContainerOperationType option) -> std case ContainerOperationType::communication: { return "communication"; } - case ContainerOperationType::sync: { - return "sync"; + case ContainerOperationType::synchronization: { + return "synchronization"; } case ContainerOperationType::anchor: { return "anchor"; @@ -45,8 +45,8 @@ auto ContainerOperationTypeUtils::getOptions() -> std::array opts = {ContainerOperationType::compute, ContainerOperationType::graph, - ContainerOperationType::halo, - ContainerOperationType::sync, + ContainerOperationType::communication, + ContainerOperationType::synchronization, ContainerOperationType::anchor}; return opts; } diff --git a/libNeonSet/src/set/container/ContainerPatternType.cpp b/libNeonSet/src/set/container/types/ContainerPatternType.cpp similarity index 100% rename from libNeonSet/src/set/container/ContainerPatternType.cpp rename to libNeonSet/src/set/container/types/ContainerPatternType.cpp diff --git a/libNeonSet/src/set/container/types/SynchronizationContainerType.cpp b/libNeonSet/src/set/container/types/SynchronizationContainerType.cpp new file mode 100644 index 00000000..89610996 --- /dev/null +++ b/libNeonSet/src/set/container/types/SynchronizationContainerType.cpp @@ -0,0 +1,46 @@ +#include "Neon/set/container/types/SynchronizationContainerType.h" + +/** + * Abstract interface to hide + */ + +namespace Neon::set { + +auto SynchronizationContainerTypeUtils::toString(SynchronizationContainerType option) -> std::string +{ + switch (option) { + case SynchronizationContainerType::hostOmpBarrier: { + return "hostOmpBarrier"; + } + case SynchronizationContainerType::none: { + return "none"; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto SynchronizationContainerTypeUtils::fromString(const std::string& option) + -> SynchronizationContainerType +{ + auto const options = getOptions(); + + for (auto a : options) { + if (toString(a) == option) { + return a; + } + } + NEON_THROW_UNSUPPORTED_OPTION(""); +} + +auto SynchronizationContainerTypeUtils::getOptions() -> std::array +{ + std::array opts = {SynchronizationContainerType::hostOmpBarrier}; + return opts; +} + +std::ostream& operator<<(std::ostream& os, Neon::set::SynchronizationContainerType const& m) +{ + return os << Neon::set::SynchronizationContainerTypeUtils::toString(m); +} + +} // namespace Neon::set diff --git a/libNeonSkeleton/include/Neon/skeleton/internal/MultiXpuGraph.h b/libNeonSkeleton/include/Neon/skeleton/internal/MultiXpuGraph.h index bee39835..6f9f5838 100644 --- a/libNeonSkeleton/include/Neon/skeleton/internal/MultiXpuGraph.h +++ b/libNeonSkeleton/include/Neon/skeleton/internal/MultiXpuGraph.h @@ -165,7 +165,7 @@ struct MultiXpuGraph auto optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> void; - auto addSyncAndMemoryTransfers(const Neon::skeleton::Options& options) + auto addCommunications(const Neon::skeleton::Options&) -> void; auto checkCoherency() diff --git a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp index a8f79bd0..9581e179 100644 --- a/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp +++ b/libNeonSkeleton/src/skeleton/internal/multiGpuGraph.cpp @@ -16,7 +16,7 @@ void MultiXpuGraph::init(Neon::Backend& bk, h_io2Dot("t0_" + name + ".dot", "i"); optimizations(options); h_io2Dot("t1_" + name + ".dot", "i"); - addSyncAndMemoryTransfers(options); + addCommunications(options); mGraph().helpRemoveRedundantDependencies(); @@ -581,24 +581,26 @@ auto MultiXpuGraph::optimizeTwoWayExtendedOCC(const Neon::skeleton::Options&) -> } -auto MultiXpuGraph::addSyncAndMemoryTransfers(const Neon::skeleton::Options&) -> void +auto MultiXpuGraph::addCommunications(const Neon::skeleton::Options&) -> void { if (m_setCardinality() == 1) { return; } - std::vector stencilDependencies; + // List all dependencies related to stencil operations + std::vector stencilTypeDependencies; mGraph().forEachDependency([&](const Neon::set::container::GraphDependency& dep) { if (dep.hasStencilDependency()) { - stencilDependencies.push_back(&dep); + stencilTypeDependencies.push_back(&dep); } }); - for (auto depPtr : stencilDependencies) { + for (auto depPtr : stencilTypeDependencies) { const auto& dep = *depPtr; - auto nodeA = mGraph().getGraphNode(dep.getSource()); - auto nodeB = mGraph().getGraphNode(dep.getDestination()); + const auto rawEdge = dep.getRawEdge(); + auto nodeA = mGraph().helpGetGraphNode(rawEdge.first); + auto nodeB = mGraph().helpGetGraphNode(rawEdge.second); auto stencilInfo = dep.getListStencilInfo(); From e8f0218e143ab7fada802e75bb1a6517be7c8219 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Mon, 31 Oct 2022 19:12:16 -0400 Subject: [PATCH 44/67] Working on halo updates. --- .../Neon/domain/internal/eGrid/eFieldDev.h | 14 +- libNeonSet/include/Neon/set/Containter.h | 6 +- libNeonSet/include/Neon/set/Containter_imp.h | 4 +- libNeonSet/include/Neon/set/HuOptions.h | 8 +- libNeonSet/include/Neon/set/StencilSemantic.h | 41 ++++ libNeonSet/include/Neon/set/Transfer.h | 14 +- .../include/Neon/set/TransferSemantic.h | 42 ---- .../include/Neon/set/container/ContainerAPI.h | 18 +- .../set/container/DataTransferContainer.h | 4 +- .../Neon/set/container/DeviceContainer.h | 6 +- libNeonSet/include/Neon/set/container/Graph.h | 18 +- .../Neon/set/container/GraphContainer.h | 2 +- .../include/Neon/set/container/Loader.h | 217 ++---------------- .../include/Neon/set/container/Loader_imp.h | 212 +++++++++++++++++ .../set/container/graph/GraphDependency.h | 1 + .../include/Neon/set/dependency/Token.h | 21 +- libNeonSet/src/set/Containter.cpp | 1 + libNeonSet/src/set/HuOptions.cpp | 6 +- libNeonSet/src/set/StencilSemantic.cpp | 98 ++++++++ libNeonSet/src/set/TransferSemantic.cpp | 98 -------- libNeonSet/src/set/container/ContainerAPI.cpp | 3 +- libNeonSet/src/set/container/Graph.cpp | 96 +++++--- .../src/set/container/GraphContainer.cpp | 31 ++- libNeonSet/src/set/depencencyTools/Token.cpp | 39 ++-- .../internal/dependencyTools/DataDependency.h | 2 - .../src/skeleton/internal/multiGpuGraph.cpp | 144 ++++++------ 26 files changed, 620 insertions(+), 526 deletions(-) create mode 100644 libNeonSet/include/Neon/set/StencilSemantic.h delete mode 100644 libNeonSet/include/Neon/set/TransferSemantic.h create mode 100644 libNeonSet/include/Neon/set/container/Loader_imp.h create mode 100644 libNeonSet/src/set/StencilSemantic.cpp delete mode 100644 libNeonSet/src/set/TransferSemantic.cpp diff --git a/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h b/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h index e4196d4a..7cab1d6c 100644 --- a/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h +++ b/libNeonDomain/include/Neon/domain/internal/eGrid/eFieldDev.h @@ -67,7 +67,7 @@ class eFieldDevice_t std::array< std::array< std::vector, - Neon::set::TransferSemanticUtils::nOptions>, + Neon::set::StencilSemanticUtils::nOptions>, Neon::set::TransferModeUtils::nOptions> m_haloUpdateInfo; }; @@ -125,7 +125,7 @@ class eFieldDevice_t for (auto mode : {Neon::set::TransferMode::get, Neon::set::TransferMode::put}) { { // (GET,PUT), FORWARD, GRID - const auto structure = Neon::set::TransferSemantic::grid; + const auto structure = Neon::set::StencilSemantic::standard; auto& transfers = h_haloUpdateInfo(mode, structure); Neon::set::HuOptions huOptions(mode, transfers, structure); this->haloUpdate__(m_data->grid->getBackend(), huOptions); @@ -143,7 +143,7 @@ class eFieldDevice_t } auto h_haloUpdateInfo(Neon::set::TransferMode mode, - Neon::set::TransferSemantic structure) + Neon::set::StencilSemantic structure) -> std::vector& { return m_data->m_haloUpdateInfo[static_cast(mode)] @@ -491,7 +491,7 @@ class eFieldDevice_t #pragma omp parallel for num_threads(ompNDevs) default(shared) for (int setIdx = 0; setIdx < nDevs; setIdx++) { for (int cardIdx = 0; cardIdx < self().cardinality(); cardIdx++) { - constexpr auto structure = Neon::set::TransferSemantic::grid; + constexpr auto structure = Neon::set::StencilSemantic::standard; auto& peerTransferOpt = opt.getPeerTransferOpt(bk); h_huSoAByCardSingleDevFwd(peerTransferOpt, @@ -656,7 +656,7 @@ class eFieldDevice_t Neon::set::PeerTransferOption& peerTransferOpt = huOptions.getPeerTransferOpt(bk); // LATTICE + FORWARD - constexpr auto structure = Neon::set::TransferSemantic::lattice; + constexpr auto structure = Neon::set::StencilSemantic::streaming; h_huSoAByCardSingleDevFwd(peerTransferOpt, gpuIdx, cardIdx, @@ -808,7 +808,7 @@ class eFieldDevice_t auto h_huSoAByCardSingleDevFwd(Neon::set::PeerTransferOption opt, int devIdx, const int cardIdx, - Neon::set::TransferSemantic structure) const + Neon::set::StencilSemantic structure) const -> void { const Neon::Backend& bk = m_data->grid->getBackend(); @@ -846,7 +846,7 @@ class eFieldDevice_t } } - if (structure == Neon::set::TransferSemantic::lattice) { + if (structure == Neon::set::StencilSemantic::streaming) { index_3d dir = grid().getStencil().neighbours().at(cardIdx); switch (comDirection) { case ComDirection_e::COM_DW: { diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index abba3cab..019bdc8c 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -1,7 +1,6 @@ #pragma once #include "Neon/set/DevSet.h" -#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" @@ -9,10 +8,9 @@ #include "Neon/set/container/types/HostManagedSyncType.h" #include "Neon/set/container/types/SynchronizationContainerType.h" -#include "Neon/set/container/Loader.h" - namespace Neon::set { +struct Loader; struct Container { @@ -111,7 +109,7 @@ struct Container template static auto factoryDataTransfer(const MultiXpuDataT& multiXpuData, Neon::set::TransferMode transferMode, - Neon::set::TransferSemantic transferSemantic) + Neon::set::StencilSemantic transferSemantic) -> Neon::set::Container; template diff --git a/libNeonSet/include/Neon/set/Containter_imp.h b/libNeonSet/include/Neon/set/Containter_imp.h index 2a08b5fc..ea660298 100644 --- a/libNeonSet/include/Neon/set/Containter_imp.h +++ b/libNeonSet/include/Neon/set/Containter_imp.h @@ -5,6 +5,8 @@ #include "functional" #include "type_traits" +#include "Neon/set/container/Loader.h" + #include "Neon/set/container/DataTransferContainer.h" #include "Neon/set/container/DeviceContainer.h" #include "Neon/set/container/DeviceManagedContainer.h" @@ -91,7 +93,7 @@ template auto Container:: factoryDataTransfer(const MultiXpuDataT& multiXpuData, Neon::set::TransferMode transferMode, - Neon::set::TransferSemantic transferSemantic) + Neon::set::StencilSemantic transferSemantic) -> Neon::set::Container { auto k = new Neon::set::internal::DataTransferContainer(multiXpuData, diff --git a/libNeonSet/include/Neon/set/HuOptions.h b/libNeonSet/include/Neon/set/HuOptions.h index 7b28878d..5aff1a52 100644 --- a/libNeonSet/include/Neon/set/HuOptions.h +++ b/libNeonSet/include/Neon/set/HuOptions.h @@ -11,17 +11,17 @@ struct HuOptions bool m_startWithBarrier = true; int m_streamSetIdx = 0; Neon::set::PeerTransferOption m_peerTransferOpt; - Neon::set::TransferSemantic m_structure; + Neon::set::StencilSemantic m_structure; public: HuOptions(Neon::set::TransferMode transferMode /*< Mode of the transfer: put or get */, bool startWithBarrier /*< If true a barrier is executed before initiating the halo update */, int streamSetIdx = Neon::Backend::mainStreamIdx /*< Target stream for the halo update */, - Neon::set::TransferSemantic structure = Neon::set::TransferSemantic::grid /*< Structure on top of which the transfer is one: grid or lattice */); + Neon::set::StencilSemantic structure = Neon::set::StencilSemantic::standard /*< Structure on top of which the transfer is one: grid or lattice */); HuOptions(Neon::set::TransferMode transferMode, NEON_OUT std::vector& transfers, - Neon::set::TransferSemantic structure = Neon::set::TransferSemantic::grid); + Neon::set::StencilSemantic structure = Neon::set::StencilSemantic::standard); auto getPeerTransferOpt(const Neon::Backend& bk) -> Neon::set::PeerTransferOption&; auto startWithBarrier() const -> bool; @@ -30,7 +30,7 @@ struct HuOptions auto operationMode() const -> Neon::set::PeerTransferOption::operationMode_e; auto transferMode() const -> Neon::set::TransferMode; auto isExecuteMode() const -> bool; - auto getSemantic() const -> Neon::set::TransferSemantic; + auto getSemantic() const -> Neon::set::StencilSemantic; }; } // namespace set } // namespace Neon diff --git a/libNeonSet/include/Neon/set/StencilSemantic.h b/libNeonSet/include/Neon/set/StencilSemantic.h new file mode 100644 index 00000000..cd512ae7 --- /dev/null +++ b/libNeonSet/include/Neon/set/StencilSemantic.h @@ -0,0 +1,41 @@ +#pragma once +#include +#include + +#include "Neon/core/core.h" + +namespace Neon::set { + +enum struct StencilSemantic +{ + standard = 0 /*< Transfer for halo update on grid structure */, + streaming = 1 /*< Transfer for halo update on lattice structure */ +}; + + +struct StencilSemanticUtils +{ + static constexpr int nOptions = 2; + + static auto toString(StencilSemantic opt) -> std::string; + static auto fromString(const std::string& opt) -> StencilSemantic; + static auto getOptions() -> std::array; + + struct Cli + { + explicit Cli(std::string); + explicit Cli(StencilSemantic model); + Cli(); + + auto getOption() -> StencilSemantic; + auto set(const std::string& opt) -> void; + auto getStringOptions() -> std::string; + + private: + bool mSet = false; + StencilSemantic mOption; + }; +}; + + +} // namespace Neon::set diff --git a/libNeonSet/include/Neon/set/Transfer.h b/libNeonSet/include/Neon/set/Transfer.h index dbece3b9..1d2053b7 100644 --- a/libNeonSet/include/Neon/set/Transfer.h +++ b/libNeonSet/include/Neon/set/Transfer.h @@ -3,8 +3,8 @@ #include #include "Neon/core/core.h" +#include "Neon/set/StencilSemantic.h" #include "Neon/set/TransferMode.h" -#include "Neon/set/TransferSemantic.h" namespace Neon { namespace set { @@ -31,14 +31,14 @@ struct Transfer Endpoint_t m_dst; Endpoint_t m_src; size_t m_size{0}; - TransferSemantic m_structure; + StencilSemantic m_structure; public: Transfer(TransferMode mode, const Endpoint_t& dst, const Endpoint_t& src, size_t size, - TransferSemantic structure = TransferSemantic::grid) + StencilSemantic structure = StencilSemantic::standard) : m_mode(mode), m_dst(dst), m_src(src), m_size(size), m_structure(structure) { } @@ -96,14 +96,14 @@ struct PeerTransferOption operationMode_e m_operationMode = Neon::set::PeerTransferOption::execute; TransferMode m_transferMode = Neon::set::TransferMode::get; - Neon::set::TransferSemantic m_structure; + Neon::set::StencilSemantic m_structure; public: /** * Constructor with stream parameter */ explicit PeerTransferOption(TransferMode tranferMode, - Neon::set::TransferSemantic structure) + Neon::set::StencilSemantic structure) : m_transfers(nullptr), m_streamSet(nullptr), m_operationMode(operationMode_e::execute), @@ -120,7 +120,7 @@ struct PeerTransferOption */ PeerTransferOption(TransferMode tranferMode, std::vector& NEON_OUT transfers, - Neon::set::TransferSemantic structure) + Neon::set::StencilSemantic structure) : m_transfers(&transfers), m_streamSet(nullptr), m_operationMode(operationMode_e::storeInfo), @@ -180,7 +180,7 @@ struct PeerTransferOption return *m_transfers; } - auto structure() const -> const Neon::set::TransferSemantic& + auto structure() const -> const Neon::set::StencilSemantic& { return m_structure; } diff --git a/libNeonSet/include/Neon/set/TransferSemantic.h b/libNeonSet/include/Neon/set/TransferSemantic.h deleted file mode 100644 index ae347fac..00000000 --- a/libNeonSet/include/Neon/set/TransferSemantic.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include -#include - -#include "Neon/core/core.h" - -namespace Neon::set { - - -enum struct TransferSemantic -{ - grid = 0 /*< Transfer for halo update on grid structure */, - lattice = 1 /*< Transfer for halo update on lattice structure */ -}; - - -struct TransferSemanticUtils -{ - static constexpr int nOptions = 2; - - static auto toString(TransferSemantic opt) -> std::string; - static auto fromString(const std::string& opt) -> TransferSemantic; - static auto getOptions() -> std::array; - - struct Cli - { - explicit Cli(std::string); - explicit Cli(TransferSemantic model); - Cli(); - - auto getOption() -> TransferSemantic; - auto set(const std::string& opt) -> void; - auto getStringOptions() -> std::string; - - private: - bool mSet = false; - TransferSemantic mOption; - }; -}; - - -} // namespace Neon::set diff --git a/libNeonSet/include/Neon/set/container/ContainerAPI.h b/libNeonSet/include/Neon/set/container/ContainerAPI.h index 4823bb22..0a3d580c 100644 --- a/libNeonSet/include/Neon/set/container/ContainerAPI.h +++ b/libNeonSet/include/Neon/set/container/ContainerAPI.h @@ -1,13 +1,11 @@ #pragma once -#include "Neon/set/container/types/ContainerOperationType.h" -#include "Neon/set/container/types/ContainerPatternType.h" - #include "Neon/set/DevSet.h" #include "Neon/set/container/types/ContainerExecutionType.h" +#include "Neon/set/container/types/ContainerOperationType.h" +#include "Neon/set/container/types/ContainerPatternType.h" +//#include "Neon/set/dependency/Token.h" - -#include "Neon/set/dependency/Token.h" #include "functional" #include "type_traits" @@ -19,6 +17,10 @@ namespace Neon::set::container { struct Graph; } +namespace Neon::set::dataDependency { +struct Token; +} + namespace Neon::set::internal { /** @@ -71,7 +73,7 @@ struct ContainerAPI /** * Returns a handle to the internal graph of Containers. */ - virtual auto getGraph() + virtual auto getGraph() const -> const Neon::set::container::Graph&; /** @@ -81,8 +83,8 @@ struct ContainerAPI virtual auto parse() -> const std::vector&; - virtual auto getTransferMode()const - ->Neon::set::TransferMode ; + virtual auto getTransferMode() const + -> Neon::set::TransferMode; /** * Returns a name associated to the container. diff --git a/libNeonSet/include/Neon/set/container/DataTransferContainer.h b/libNeonSet/include/Neon/set/container/DataTransferContainer.h index 75228c8b..92fa12f6 100644 --- a/libNeonSet/include/Neon/set/container/DataTransferContainer.h +++ b/libNeonSet/include/Neon/set/container/DataTransferContainer.h @@ -14,7 +14,7 @@ struct DataTransferContainer DataTransferContainer(const MxpuDataT& multiXpuData, Neon::set::TransferMode transferMode, - Neon::set::TransferSemantic transferSemantic) + Neon::set::StencilSemantic transferSemantic) : mMultiXpuData(multiXpuData), mTransferMode(transferMode), mTransferSemantic(transferSemantic) @@ -64,7 +64,7 @@ struct DataTransferContainer mDataTransferFun; MxpuDataT mMultiXpuData; Neon::set::TransferMode mTransferMode; - Neon::set::TransferSemantic mTransferSemantic; + Neon::set::StencilSemantic mTransferSemantic; }; } // namespace Neon::set::internal diff --git a/libNeonSet/include/Neon/set/container/DeviceContainer.h b/libNeonSet/include/Neon/set/container/DeviceContainer.h index 6d838298..333bc097 100644 --- a/libNeonSet/include/Neon/set/container/DeviceContainer.h +++ b/libNeonSet/include/Neon/set/container/DeviceContainer.h @@ -4,9 +4,7 @@ #include "Neon/set/container/ContainerAPI.h" #include "Neon/set/container/Loader.h" -namespace Neon { -namespace set { -namespace internal { +namespace Neon::set::internal { template @@ -150,6 +148,4 @@ struct DeviceContainer : ContainerAPI DataIteratorContainerT m_dataIteratorContainer; }; -} // namespace internal -} // namespace set } // namespace Neon diff --git a/libNeonSet/include/Neon/set/container/Graph.h b/libNeonSet/include/Neon/set/container/Graph.h index 5d6047b5..9ada9f79 100644 --- a/libNeonSet/include/Neon/set/container/Graph.h +++ b/libNeonSet/include/Neon/set/container/Graph.h @@ -97,6 +97,8 @@ struct Graph const Neon::set::dataDependency::Token& token) -> GraphDependency&; + auto removeDependency(const GraphDependency&) + -> void; /** * Returns the dependency type between two nodes. */ @@ -180,6 +182,16 @@ struct Graph auto forEachNode(const std::function& fun) const -> void; + /** + * Adding a graph between two nodes A and B + * The method works only on Graph type containers. + * Finally, it returns the number of added nodes. + */ + auto expandAndMerge(const GraphNode& A, + const Container& graphOriginal, + const GraphNode& B) + -> int; + protected: /** * Invalidate all scheduling information that were computed @@ -309,12 +321,6 @@ struct Graph auto helpComputeScheduling_04_ensureResources(int maxStreamId, int maxEventId) -> void; - /** - * Adding a graph between two nodes - */ - auto helpMergeGraphBetweenNodes(const Graph& graph, - const GraphNode& A, - const GraphNode& B); using RawGraph = DiGraph; diff --git a/libNeonSet/include/Neon/set/container/GraphContainer.h b/libNeonSet/include/Neon/set/container/GraphContainer.h index 79051f93..f10ead04 100644 --- a/libNeonSet/include/Neon/set/container/GraphContainer.h +++ b/libNeonSet/include/Neon/set/container/GraphContainer.h @@ -28,7 +28,7 @@ struct GraphContainer : ContainerAPI -> const std::vector& override; auto getGraph() - -> const Neon::set::container::Graph& override; + const -> const Neon::set::container::Graph& override; auto run(int streamIdx = 0, Neon::DataView dataView = Neon::DataView::STANDARD) diff --git a/libNeonSet/include/Neon/set/container/Loader.h b/libNeonSet/include/Neon/set/container/Loader.h index a0f5a294..bb7180b7 100644 --- a/libNeonSet/include/Neon/set/container/Loader.h +++ b/libNeonSet/include/Neon/set/container/Loader.h @@ -1,10 +1,15 @@ #pragma once -// #include -#include "Neon/set/DevSet.h" +#include "type_traits" + +#include "Neon/set/DevSet.h" +#include "Neon/set/HuOptions.h" +#include "Neon/set/StencilSemantic.h" #include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/dependency/AccessType.h" +#include "Neon/set/dependency/ComputeType.h" +#include "Neon/set/dependency/Token.h" -#include "type_traits" namespace Neon::set { namespace internal { @@ -19,115 +24,6 @@ struct LoadingMode_e LoadingMode_e(const LoadingMode_e&) = delete; }; -namespace tmp { -// From: -// https://en.cppreference.com/w/cpp/experimental/is_detected -namespace detail { -template class Op, class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -} // namespace detail - -struct nonesuch -{ - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - void operator=(nonesuch const&) = delete; -}; - -template