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

279 lines
9.3 KiB
C++

// Copyright © Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_map>
#include <variant>
#include <hipdnn_data_sdk/utilities/Constants.hpp>
#include <hipdnn_data_sdk/utilities/EngineNames.hpp>
#include <hipdnn_data_sdk/utilities/Tensor.hpp>
#include <hipdnn_frontend.hpp>
#include <hipdnn_test_sdk/utilities/CpuFpReferenceBatchnorm.hpp>
#include <hipdnn_test_sdk/utilities/CpuFpReferenceValidation.hpp>
#include <hipdnn_test_sdk/utilities/TestTolerances.hpp>
#include "../utils/Helpers.hpp"
using namespace hipdnn_frontend;
using namespace hipdnn_data_sdk;
namespace
{
std::string knobValueToString(const KnobValueVariant& value)
{
std::string ret;
if(std::holds_alternative<int64_t>(value))
{
ret = std::to_string(std::get<int64_t>(value));
}
else if(std::holds_alternative<double>(value))
{
std::ostringstream oss;
oss << std::fixed << std::setprecision(2) << std::get<double>(value);
ret = oss.str();
}
else if(std::holds_alternative<std::string>(value))
{
ret = "\"" + std::get<std::string>(value) + "\"";
}
return ret;
}
void demonstrateKnobQuery(int64_t engineId, graph::Graph& graph)
{
std::cout << "Querying Knobs (vector):\n";
std::vector<Knob> knobs;
auto error = graph.get_knobs_for_engine(engineId, knobs);
if(!error.is_good())
{
std::cerr << " Error: " << error.get_message() << "\n";
return;
}
std::cout << " Engine " << hipdnn_data_sdk::utilities::getEngineNameFromId(engineId)
<< " has " << knobs.size() << " knob(s):\n";
for(const auto& knob : knobs)
{
std::cout << " " << knob.knobId() << " (" << hipdnn_frontend::to_string(knob.valueType())
<< ", default=" << knobValueToString(knob.defaultValue()) << ")";
if(const auto* constraint = knob.constraint())
{
std::cout << " [" << constraint->toString() << "]";
}
std::cout << "\n";
}
std::cout << "Querying Knobs (map):\n";
std::unordered_map<std::string, Knob> knobMap;
error = graph.get_knob_lookup_for_engine(engineId, knobMap);
if(error.is_good())
{
auto it = knobMap.find("global.benchmarking");
if(it != knobMap.end())
{
std::cout << " Found 'global.benchmarking': " << it->second.description() << "\n";
}
else
{
std::cout << " 'global.benchmarking' not found\n";
}
}
}
void demonstrateSettingKnobs(int64_t engineId, graph::Graph& graph)
{
std::cout << "Setting KnobSettings:\n";
std::vector<KnobSetting> settings;
settings.emplace_back("global.benchmarking", static_cast<int64_t>(1));
settings.emplace_back("global.workspace_size_limit", static_cast<int64_t>(64 * 1024 * 1024));
std::cout << " Settings: global.benchmarking=1, global.workspace_size_limit=64MB\n";
auto error = graph.create_execution_plan_ext(engineId, settings);
std::cout << " Execution plan: " << (error.is_good() ? "OK" : error.get_message()) << "\n";
}
void demonstrateKnobValidation(int64_t engineId, graph::Graph& graph)
{
std::cout << "Validating KnobSettings:\n";
std::vector<Knob> knobs;
auto error = graph.get_knobs_for_engine(engineId, knobs);
if(!error.is_good())
{
std::cerr << " Error: " << error.get_message() << "\n";
return;
}
for(const auto& knob : knobs)
{
if(knob.knobId() == "global.benchmarking")
{
const KnobSetting validSetting("global.benchmarking", static_cast<int64_t>(1));
auto validationError = knob.validate(validSetting);
std::cout << " global.benchmarking=1: "
<< (validationError.is_good() ? "VALID" : "INVALID") << "\n";
const KnobSetting invalidSetting("global.benchmarking", static_cast<int64_t>(5));
validationError = knob.validate(invalidSetting);
std::cout << " global.benchmarking=5: "
<< (validationError.is_good()
? "VALID"
: "INVALID (" + validationError.get_message() + ")")
<< "\n";
break;
}
}
}
} // namespace
int main(int argc, char* argv[])
{
try
{
RETURN_SUCCESS_IF_NO_DEVICE();
bool useBenchmarking = false;
for(int i = 1; i < argc; ++i)
{
const std::string arg(argv[i]);
if(arg == "--help" || arg == "-h")
{
std::cout << "Usage: " << argv[0] << " [OPTIONS]\n"
<< " --benchmark Use the benchmarking knob\n"
<< " --help, -h Show this help\n";
return 0;
}
if(arg == "--benchmark")
{
useBenchmarking = true;
}
else
{
std::cerr << "Unknown argument: " << arg << " (use --help)\n";
return 1;
}
}
std::cout << "hipDNN Knobs Usage Sample\n";
initializeFrontendLogging();
hipdnnHandle_t handle = nullptr;
HIPDNN_CHECK(hipdnnCreate(&handle));
auto graph = std::make_shared<graph::Graph>();
graph->set_io_data_type(hipdnn_frontend::DataType::FLOAT)
.set_intermediate_data_type(hipdnn_frontend::DataType::FLOAT)
.set_compute_data_type(hipdnn_frontend::DataType::FLOAT);
const int64_t n = 16; // BATCH SIZE
const int64_t c = 16; // CHANNELS (FEATURES)
const int64_t h = 16; // HEIGHT (SPATIAL DIMENSION)
const int64_t w = 16; // WIDTH (SPATIAL DIMENSION)
const auto inputType = hipdnn_frontend::DataType::FLOAT;
const auto intermediateType = hipdnn_frontend::DataType::FLOAT;
const auto layout = utilities::TensorLayout::NCHW;
auto x = createTensor({n, c, h, w}, inputType, layout);
auto scale = createTensor({1, c, 1, 1}, intermediateType, layout);
auto bias = createTensor({1, c, 1, 1}, intermediateType, layout);
auto mean = createTensor({1, c, 1, 1}, intermediateType, layout);
auto invVariance = createTensor({1, c, 1, 1}, intermediateType, layout);
auto bnAttributes = graph::BatchnormInferenceAttributes();
auto y = graph->batchnorm_inference(x, mean, invVariance, scale, bias, bnAttributes);
y->set_output(true);
HIPDNN_FE_CHECK(graph->validate());
HIPDNN_FE_CHECK(graph->build_operation_graph(handle));
std::vector<int64_t> rankedEngineIds;
HIPDNN_FE_CHECK(graph->get_ranked_engine_ids(rankedEngineIds));
if(rankedEngineIds.empty())
{
std::cerr << "No engines available\n";
HIPDNN_CHECK(hipdnnDestroy(handle));
return 1;
}
const int64_t engineId = rankedEngineIds[0];
demonstrateKnobQuery(engineId, *graph);
demonstrateSettingKnobs(engineId, *graph);
demonstrateKnobValidation(engineId, *graph);
const std::vector<KnobSetting> defaultSettings;
std::vector<KnobSetting> benchmarkingSettings;
benchmarkingSettings.emplace_back("global.benchmarking", static_cast<int64_t>(1));
HIPDNN_FE_CHECK(graph->create_execution_plan_ext(
engineId, useBenchmarking ? benchmarkingSettings : defaultSettings));
HIPDNN_FE_CHECK(graph->check_support());
HIPDNN_FE_CHECK(graph->build_plans());
utilities::Tensor<float> xTensor(x->get_dim(), utilities::TensorLayout::NCHW);
utilities::Tensor<float> scaleTensor(scale->get_dim());
utilities::Tensor<float> biasTensor(bias->get_dim());
utilities::Tensor<float> meanTensor(mean->get_dim());
utilities::Tensor<float> invVarianceTensor(invVariance->get_dim());
utilities::Tensor<float> yTensor(y->get_dim(), utilities::TensorLayout::NCHW);
xTensor.fillWithRandomValues(0.0f, 1.0f);
scaleTensor.fillWithRandomValues(0.0f, 1.0f);
biasTensor.fillWithRandomValues(0.0f, 1.0f);
meanTensor.fillWithRandomValues(0.0f, 1.0f);
invVarianceTensor.fillWithRandomValues(0.1f, 1.0f);
std::unordered_map<int64_t, void*> variantPack;
variantPack[x->get_uid()] = xTensor.memory().deviceData();
variantPack[scale->get_uid()] = scaleTensor.memory().deviceData();
variantPack[bias->get_uid()] = biasTensor.memory().deviceData();
variantPack[mean->get_uid()] = meanTensor.memory().deviceData();
variantPack[invVariance->get_uid()] = invVarianceTensor.memory().deviceData();
variantPack[y->get_uid()] = yTensor.memory().deviceData();
HIPDNN_FE_CHECK(graph->execute(handle, variantPack, nullptr));
yTensor.memory().markDeviceModified();
auto yHostPtr = yTensor.memory().hostData();
std::cout << "Execution OK, output[0..4]: ";
for(int i = 0; i < 5; ++i)
{
std::cout << yHostPtr[i] << " ";
}
std::cout << "\n";
HIPDNN_CHECK(hipdnnDestroy(handle));
std::cout << "\nDone. See docs/Knobs.md for details.\n";
return 0;
}
catch(const std::exception& e)
{
std::fprintf(stderr, "Unhandled exception: %s\n", e.what());
return 1;
}
}