Files
TheRock/rocm-systems/projects/hip-tests/catch/unit/graph/hipGraphCycle.cc
T
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

258 lines
11 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
/**
Testcase Scenarios :
1) Purpose is to check for topology of graph
2) Basic tests with manually added nodes, make graph cyclic
3) Basic tests with manually added nodes, remove edges from graph making sure
node levels are correct if graph is not cyclic in a previously cyclic graph.
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Cyclic graph, cycle formation first, then adding more nodes
*/
HIP_TEST_CASE(Unit_hipGraph_BasicCyclic1) {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
hipGraphNode_t emptyNode1, emptyNode2, emptyNode3, emptyNode4, emptyNode5, emptyNode6;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode4, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode5, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode6, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode4, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode6, 1));
HIP_CHECK(hipStreamCreate(&streamForGraph));
REQUIRE(hipErrorInvalidValue == hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipStreamDestroy(streamForGraph));
HIP_CHECK(hipGraphDestroy(graph));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Cyclic graph, cycle formation first, Remove edge to resolve cycle
*/
HIP_TEST_CASE(Unit_hipGraph_BasicCyclic2) {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
hipGraphNode_t emptyNode1, emptyNode2, emptyNode3, emptyNode4, emptyNode5;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode4, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode5, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode4, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Cyclic graph, cycle formation first, Remove edge causes disconnected graph which is still
* cyclic
*/
HIP_TEST_CASE(Unit_hipGraph_BasicCyclic3) {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
hipGraphNode_t emptyNode1, emptyNode2, emptyNode3, emptyNode4, emptyNode5, emptyNode6;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode4, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode5, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode6, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode4, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode6, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipStreamCreate(&streamForGraph));
REQUIRE(hipErrorInvalidValue == hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipStreamDestroy(streamForGraph));
HIP_CHECK(hipGraphDestroy(graph));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Uncyclic graph, removing edge from middle of linear graph
*/
HIP_TEST_CASE(Unit_hipGraph_BasicCyclic4) {
int N = 1024 * 1024;
int Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
hipStream_t stream;
int *X_d, *Y_d, *X_h, *Y_h;
HipTest::initArrays<int>(&X_d, &Y_d, nullptr, &X_h, &Y_h, nullptr, N, false);
hipGraphNode_t kMemCpyH2D_X, memcpyD2D, memcpyD2H_RC, emptyNode1;
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipGraphAddMemcpyNode1D(&kMemCpyH2D_X, graph, nullptr, 0, X_d, X_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2D, graph, nullptr, 0, Y_d, X_d, Nbytes,
hipMemcpyDeviceToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_RC, graph, nullptr, 0, Y_h, Y_d, Nbytes,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2D, &memcpyD2H_RC, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphDestroyNode(emptyNode1));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &memcpyD2D, 1));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Verify graph result as X_h == Y_h
for (size_t i = 0; i < N; i++) {
if (Y_h[i] != X_h[i]) {
INFO("Validation failed for graph at index " << i << " Y_h[i] " << Y_h[i] << " X_h[i] "
<< X_h[i]);
REQUIRE(false);
}
}
HipTest::freeArrays<int>(X_d, Y_d, nullptr, X_h, Y_h, nullptr, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(stream));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* cyclic graph, removing edge to resolve cycle and remove edge from middle of graph
*/
HIP_TEST_CASE(Unit_hipGraph_BasicCyclic5) {
int N = 1024 * 1024;
int Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
hipStream_t stream;
int *X_d, *Y_d, *X_h, *Y_h;
HipTest::initArrays<int>(&X_d, &Y_d, nullptr, &X_h, &Y_h, nullptr, N, false);
hipGraphNode_t kMemCpyH2D_X, memcpyD2D, memcpyD2H_RC, emptyNode1, emptyNode2, emptyNode3;
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipGraphAddMemcpyNode1D(&kMemCpyH2D_X, graph, nullptr, 0, X_d, X_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2D, graph, nullptr, 0, Y_d, X_d, Nbytes,
hipMemcpyDeviceToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_RC, graph, nullptr, 0, Y_h, Y_d, Nbytes,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2D, &memcpyD2H_RC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_RC, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &memcpyD2H_RC, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphDestroyNode(emptyNode1));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &memcpyD2D, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode3, &memcpyD2H_RC, 1));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Verify graph result as X_h == Y_h
for (size_t i = 0; i < N; i++) {
if (Y_h[i] != X_h[i]) {
INFO("Validation failed for graph at index " << i << " Y_h[i] " << Y_h[i] << " X_h[i] "
<< X_h[i]);
REQUIRE(false);
}
}
HipTest::freeArrays<int>(X_d, Y_d, nullptr, X_h, Y_h, nullptr, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(stream));
}
HIP_TEST_CASE(Unit_hipGraph_CyclicChildInstantiation) {
hipGraph_t parent_graph = nullptr;
hipGraph_t child_graph = nullptr;
hipGraphExec_t graph_exec = nullptr;
hipGraphNode_t child_node = nullptr;
hipGraphNode_t first_node = nullptr;
hipGraphNode_t second_node = nullptr;
hipGraphNode_t third_node = nullptr;
HIP_CHECK(hipGraphCreate(&parent_graph, 0));
HIP_CHECK(hipGraphCreate(&child_graph, 0));
HIP_CHECK(hipGraphAddEmptyNode(&first_node, child_graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&second_node, child_graph, &first_node, 1));
HIP_CHECK(hipGraphAddEmptyNode(&third_node, child_graph, &second_node, 1));
HIP_CHECK(hipGraphAddDependencies(child_graph, &third_node, &second_node, 1));
HIP_CHECK(hipGraphAddChildGraphNode(&child_node, parent_graph, nullptr, 0, child_graph));
REQUIRE(hipGraphInstantiate(&graph_exec, parent_graph, nullptr, nullptr, 0) ==
hipErrorInvalidValue);
HIP_CHECK(hipGraphDestroy(parent_graph));
HIP_CHECK(hipGraphDestroy(child_graph));
}