Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

207 lines
8.2 KiB
C++

// Copyright Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#include <catch2/catch_test_macros.hpp>
#include <catch2/generators/catch_generators.hpp>
#include <rocRoller/Expression.hpp>
#include <rocRoller/KernelGraph/KernelGraph.hpp>
#include <rocRoller/KernelGraph/NodeSchedulingUtils.hpp>
#include <rocRoller/KernelGraph/Transforms/Simplify.hpp>
#include <rocRoller/KernelGraph/Utils.hpp>
using namespace rocRoller;
using namespace rocRoller::KernelGraph::ControlGraph;
using namespace rocRoller::KernelGraph::CoordinateGraph;
namespace NodeSchedulingUtilsTest
{
std::vector<int> addMultiplyNodes(KernelGraph::KernelGraph& graph, int parent, int count)
{
std::vector<int> rv;
for(int i = 0; i < count; ++i)
{
auto multiply = graph.control.addElement(Multiply{});
graph.control.addElement(Body(), {parent}, {multiply});
rv.push_back(multiply);
}
return rv;
}
TEST_CASE("getGroupedNodes", "[kernel-graph][utils][node-scheduling]")
{
KernelGraph::KernelGraph graph;
auto kernel = graph.control.addElement(Kernel());
auto forLoop = graph.control.addElement(ForLoopOp{Expression::literal(10), "Loop"});
auto multipliesInLoop = addMultiplyNodes(graph, forLoop, 10);
auto multipliesOutsideLoop = addMultiplyNodes(graph, kernel, 12);
SECTION("Groups nodes correctly")
{
auto expected = std::unordered_map<int, std::vector<int>>{
{forLoop, multipliesInLoop}, {kernel, multipliesOutsideLoop}};
CHECK(rocRoller::KernelGraph::NodeScheduling::getGroupedNodes<Multiply>(graph)
== expected);
SECTION("Sequence edges don't affect grouping")
{
for(int i = 0; i + 1 < multipliesInLoop.size(); ++i)
{
graph.control.chain<Sequence>(multipliesInLoop[i], multipliesInLoop[i + 1]);
}
for(int i = 0; i + 1 < multipliesOutsideLoop.size(); ++i)
{
graph.control.chain<Sequence>(multipliesOutsideLoop[i],
multipliesOutsideLoop[i + 1]);
}
CHECK(rocRoller::KernelGraph::NodeScheduling::getGroupedNodes<Multiply>(graph)
== expected);
SECTION("Simplify doesn't affect grouping")
{
auto simplifiedGraph = rocRoller::KernelGraph::Simplify().apply(graph);
CHECK(rocRoller::KernelGraph::NodeScheduling::getGroupedNodes<Multiply>(
simplifiedGraph)
== expected);
}
}
}
}
TEST_CASE("createSubGraph", "[kernel-graph][node-scheduling]")
{
KernelGraph::KernelGraph graph;
auto kernel = graph.control.addElement(Kernel());
auto forLoop = graph.control.addElement(ForLoopOp{Expression::literal(10), "Loop"});
graph.control.addElement(Body(), {kernel}, {forLoop});
auto multiplies = addMultiplyNodes(graph, forLoop, 10);
// 2 chains of 5 multiply nodes each
for(int i = 0; i < 4; i++)
{
graph.control.chain<Sequence>(multiplies.at(i), multiplies.at(i + 1));
graph.control.chain<Sequence>(multiplies.at(i + 5), multiplies.at(i + 6));
}
auto multipliesOutsideLoop = addMultiplyNodes(graph, kernel, 12);
for(int i = 0; i < 3; i++)
{
graph.control.chain<Sequence>(multipliesOutsideLoop.at(i),
multipliesOutsideLoop.at(i + 1));
graph.control.chain<Sequence>(multipliesOutsideLoop.at(i + 4),
multipliesOutsideLoop.at(i + 5));
graph.control.chain<Sequence>(multipliesOutsideLoop.at(i + 8),
multipliesOutsideLoop.at(i + 9));
}
bool simplify = GENERATE(true, false);
DYNAMIC_SECTION("simplify: " << simplify)
{
auto inputGraph = simplify ? rocRoller::KernelGraph::Simplify().apply(graph) : graph;
std::vector nodesToKeep = {forLoop,
multiplies[0],
multiplies[4],
multiplies[5],
multiplies[7],
multiplies[9],
multipliesOutsideLoop[0],
multipliesOutsideLoop[1],
multipliesOutsideLoop[4],
multipliesOutsideLoop[5],
multipliesOutsideLoop[8],
multipliesOutsideLoop[9]};
auto subGraph
= rocRoller::KernelGraph::NodeScheduling::createSubGraph(inputGraph, nodesToKeep);
CHECK(subGraph.getNodes().to<std::vector>() == nodesToKeep);
SECTION("Preserves ordering")
{
for(auto iterA = nodesToKeep.begin(); iterA != nodesToKeep.end(); ++iterA)
{
INFO(*iterA);
for(auto iterB = iterA + 1; iterB != nodesToKeep.end(); ++iterB)
{
INFO(*iterB);
auto origOrder = graph.control.compareNodes(UpdateCache, *iterA, *iterB);
auto subOrder = subGraph.compareNodes(UpdateCache, *iterA, *iterB);
CHECK(subOrder == origOrder);
}
}
}
}
}
TEST_CASE("orderNodes", "[kernel-graph][node-scheduling]")
{
KernelGraph::KernelGraph graph;
auto kernel = graph.control.addElement(Kernel());
auto forLoop = graph.control.addElement(ForLoopOp{Expression::literal(10), "Loop"});
graph.control.addElement(Body(), {kernel}, {forLoop});
auto multiplies = addMultiplyNodes(graph, forLoop, 10);
// 2 chains of 5 multiply nodes each
for(int i = 0; i < 4; i++)
{
graph.control.chain<Sequence>(multiplies.at(i), multiplies.at(i + 1));
graph.control.chain<Sequence>(multiplies.at(i + 5), multiplies.at(i + 6));
}
auto multipliesOutsideLoop = addMultiplyNodes(graph, kernel, 12);
for(int i = 0; i < 3; i++)
{
graph.control.chain<Sequence>(multipliesOutsideLoop.at(i),
multipliesOutsideLoop.at(i + 1));
graph.control.chain<Sequence>(multipliesOutsideLoop.at(i + 4),
multipliesOutsideLoop.at(i + 5));
graph.control.chain<Sequence>(multipliesOutsideLoop.at(i + 8),
multipliesOutsideLoop.at(i + 9));
}
bool simplify = GENERATE(true, false);
DYNAMIC_SECTION("simplify: " << simplify)
{
auto inputGraph = simplify ? rocRoller::KernelGraph::Simplify().apply(graph) : graph;
std::vector<int> nodesToOrder = multiplies;
nodesToOrder.insert(
nodesToOrder.end(), multipliesOutsideLoop.begin(), multipliesOutsideLoop.end());
auto comp = [](int a, int b) { return a > b; };
rocRoller::KernelGraph::NodeScheduling::orderNodes(inputGraph, nodesToOrder, comp);
for(auto iterA = nodesToOrder.begin(); iterA != nodesToOrder.end(); ++iterA)
{
for(auto iterB = iterA + 1; iterB != nodesToOrder.end(); ++iterB)
{
auto order = graph.control.compareNodes(UpdateCache, *iterA, *iterB);
CAPTURE(order);
CHECK((order == NodeOrdering::LeftFirst
|| order == NodeOrdering::RightInBodyOfLeft
|| order == NodeOrdering::Undefined));
if(order == NodeOrdering::Undefined)
{
CHECK(*iterA > *iterB);
}
}
}
}
}
}