2
0

SWDEV-366390 - [catch2][dtest] Adding additional functional tests for hipGraphAddEmptyNode() (#106)

Change-Id: Ibc2f72280a0c4f50c7d28acd5e5de4b6e835a3d6
Este cometimento está contido em:
ROCm CI Service Account
2023-06-21 11:52:37 +05:30
cometido por GitHub
ascendente 973109fec0
cometimento cbf80dda94
+156 -3
Ver ficheiro
@@ -1,5 +1,5 @@
/*
Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
@@ -21,10 +21,18 @@ THE SOFTWARE.
Testcase Scenarios :
1) Create and add empty node to graph and verify addition is successful.
2) Negative Scenarios
3) Functional Test to use empty node as barrier to wait for multiple nodes.
In a graph add 3 independent memcpy_h2d nodes, add an empty node with
dependencies on the 3 memcpy_h2d nodes, add 3 independent kernel nodes,
add another empty node with dependencies on the 3 kernel nodes and
add 3 independent memcpy_d2h nodes with dependencies on previous empty
node. Execute the graph and validate the results.
*/
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#include <hip_test_kernels.hh>
#define TEST_LOOP_SIZE 50
/**
* Functional Test to add empty node with dependencies
*/
@@ -90,7 +98,7 @@ TEST_CASE("Unit_hipGraphAddEmptyNode_NegTest") {
dependencies.data(), dependencies.size()));
}
// pDependencies is nullptr
SECTION("Null Graph") {
SECTION("Dependencies is null") {
REQUIRE(hipErrorInvalidValue == hipGraphAddEmptyNode(&emptyNode, graph,
nullptr, dependencies.size()));
}
@@ -98,3 +106,148 @@ TEST_CASE("Unit_hipGraphAddEmptyNode_NegTest") {
HIP_CHECK(hipFree(pOutBuff_d));
HIP_CHECK(hipGraphDestroy(graph));
}
// Function to fill input data
static void fillRandInpData(int *A1_h, int *A2_h, int *A3_h, size_t N) {
unsigned int seed = time(nullptr);
for (size_t i = 0; i < N; i++) {
A1_h[i] = (HipTest::RAND_R(&seed) & 0xFF);
A2_h[i] = (HipTest::RAND_R(&seed) & 0xFF);
A3_h[i] = (HipTest::RAND_R(&seed) & 0xFF);
}
}
// Function to validate result
static void validateOutData(int *A1_h, int *A2_h, size_t N) {
for (size_t i = 0; i < N; i++) {
int result = (A1_h[i]*A1_h[i]);
REQUIRE(result == A2_h[i]);
}
}
/**
* Functional Test to use empty node as barrier to wait for multiple nodes.
*/
TEST_CASE("Unit_hipGraphAddEmptyNode_BarrierFunc") {
size_t size = 1024;
constexpr auto blocksPerCU = 6;
constexpr auto threadsPerBlock = 256;
unsigned blocks = HipTest::setNumBlocks(blocksPerCU,
threadsPerBlock, size);
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
HIP_CHECK(hipGraphCreate(&graph, 0));
int *inputVec_d1{nullptr}, *inputVec_h1{nullptr}, *outputVec_h1{nullptr},
*outputVec_d1{nullptr};
int *inputVec_d2{nullptr}, *inputVec_h2{nullptr}, *outputVec_h2{nullptr},
*outputVec_d2{nullptr};
int *inputVec_d3{nullptr}, *inputVec_h3{nullptr}, *outputVec_h3{nullptr},
*outputVec_d3{nullptr};
// host and device allocation
HipTest::initArrays<int>(&inputVec_d1, &outputVec_d1, nullptr,
&inputVec_h1, &outputVec_h1, nullptr, size, false);
HipTest::initArrays<int>(&inputVec_d2, &outputVec_d2, nullptr,
&inputVec_h2, &outputVec_h2, nullptr, size, false);
HipTest::initArrays<int>(&inputVec_d3, &outputVec_d3, nullptr,
&inputVec_h3, &outputVec_h3, nullptr, size, false);
// add nodes to graph
hipGraphNode_t memcpyH2D_1, memcpyH2D_2, memcpyH2D_3;
hipGraphNode_t vecSqr1, vecSqr2, vecSqr3;
hipGraphNode_t memcpyD2H_1, memcpyD2H_2, memcpyD2H_3;
hipGraphNode_t emptyNode1, emptyNode2;
// Create memcpy h2d nodes
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_1, graph, nullptr,
0, inputVec_d1, inputVec_h1, (sizeof(int)*size), hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_2, graph, nullptr,
0, inputVec_d2, inputVec_h2, (sizeof(int)*size), hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_3, graph, nullptr,
0, inputVec_d3, inputVec_h3, (sizeof(int)*size), hipMemcpyHostToDevice));
// Create dependency list
nodeDependencies.push_back(memcpyH2D_1);
nodeDependencies.push_back(memcpyH2D_2);
nodeDependencies.push_back(memcpyH2D_3);
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nodeDependencies.data(),
nodeDependencies.size()));
nodeDependencies.clear();
nodeDependencies.push_back(emptyNode1);
// Creating kernel nodes
hipKernelNodeParams kerNodeParams1{}, kerNodeParams2{}, kerNodeParams3{};
void* kernelArgs1[] = {reinterpret_cast<void*>(&inputVec_d1),
reinterpret_cast<void*>(&outputVec_d1),
reinterpret_cast<void*>(&size)};
kerNodeParams1.func = reinterpret_cast<void*>(HipTest::vector_square<int>);
kerNodeParams1.gridDim = dim3(blocks);
kerNodeParams1.blockDim = dim3(threadsPerBlock);
kerNodeParams1.sharedMemBytes = 0;
kerNodeParams1.kernelParams = reinterpret_cast<void**>(kernelArgs1);
kerNodeParams1.extra = nullptr;
HIP_CHECK(hipGraphAddKernelNode(&vecSqr1, graph, nodeDependencies.data(),
nodeDependencies.size(), &kerNodeParams1));
void* kernelArgs2[] = {reinterpret_cast<void*>(&inputVec_d2),
reinterpret_cast<void*>(&outputVec_d2),
reinterpret_cast<void*>(&size)};
kerNodeParams2.func = reinterpret_cast<void*>(HipTest::vector_square<int>);
kerNodeParams2.gridDim = dim3(blocks);
kerNodeParams2.blockDim = dim3(threadsPerBlock);
kerNodeParams2.sharedMemBytes = 0;
kerNodeParams2.kernelParams = reinterpret_cast<void**>(kernelArgs2);
kerNodeParams2.extra = nullptr;
HIP_CHECK(hipGraphAddKernelNode(&vecSqr2, graph, nodeDependencies.data(),
nodeDependencies.size(), &kerNodeParams2));
void* kernelArgs3[] = {reinterpret_cast<void*>(&inputVec_d3),
reinterpret_cast<void*>(&outputVec_d3),
reinterpret_cast<void*>(&size)};
kerNodeParams3.func = reinterpret_cast<void*>(HipTest::vector_square<int>);
kerNodeParams3.gridDim = dim3(blocks);
kerNodeParams3.blockDim = dim3(threadsPerBlock);
kerNodeParams3.sharedMemBytes = 0;
kerNodeParams3.kernelParams = reinterpret_cast<void**>(kernelArgs3);
kerNodeParams3.extra = nullptr;
HIP_CHECK(hipGraphAddKernelNode(&vecSqr3, graph, nodeDependencies.data(),
nodeDependencies.size(), &kerNodeParams3));
nodeDependencies.clear();
nodeDependencies.push_back(vecSqr1);
nodeDependencies.push_back(vecSqr2);
nodeDependencies.push_back(vecSqr3);
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nodeDependencies.data(),
nodeDependencies.size()));
nodeDependencies.clear();
nodeDependencies.push_back(emptyNode2);
// Create memcpy d2h nodes
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_1, graph,
nodeDependencies.data(), nodeDependencies.size(), outputVec_h1,
outputVec_d1, (sizeof(int)*size), hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_2, graph,
nodeDependencies.data(), nodeDependencies.size(), outputVec_h2,
outputVec_d2, (sizeof(int)*size), hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_3, graph,
nodeDependencies.data(), nodeDependencies.size(), outputVec_h3,
outputVec_d3, (sizeof(int)*size), hipMemcpyDeviceToHost));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec{nullptr};
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr,
nullptr, 0));
// Execute graph
for (int iter = 0; iter < TEST_LOOP_SIZE; iter++) {
fillRandInpData(inputVec_h1, inputVec_h2, inputVec_h3, size);
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
validateOutData(inputVec_h1, outputVec_h1, size);
validateOutData(inputVec_h2, outputVec_h2, size);
validateOutData(inputVec_h3, outputVec_h3, size);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipStreamDestroy(streamForGraph));
// Free
HipTest::freeArrays<int>(inputVec_d1, outputVec_d1, nullptr,
inputVec_h1, outputVec_h1, nullptr, false);
HipTest::freeArrays<int>(inputVec_d2, outputVec_d2, nullptr,
inputVec_h2, outputVec_h2, nullptr, false);
HipTest::freeArrays<int>(inputVec_d3, outputVec_d3, nullptr,
inputVec_h3, outputVec_h3, nullptr, false);
HIP_CHECK(hipGraphDestroy(graph));
}