Note
📝 We are in an early stage of development for hipDNN. This design is subject to change.
hipDNN is a graph-based deep learning library that enables multi-operation fusion for improved performance on AMD GPUs. It uses operation graphs as an intermediate representation to describe computations, allowing different backend engines to optimize and execute these graphs efficiently.
- Graph-based API: Operations are expressed as computational graphs rather than individual function calls, enabling optimization opportunities
- Plugin Architecture: Backend engines, heuristics, and benchmarking are implemented as plugins, allowing extensibility without modifying the core library
- Performance through Fusion: Multiple operations can be fused into single kernels for better performance
- Engine Selection: Heuristics and benchmarking will be implemented as plugins, allowing extensibility without modifying the core library
- Industry Standard API: Provides a familiar interface that matches established deep learning library conventions
hipDNN has a plugin-based architecture in order to allow contributors and users to extend hipDNN without modifying the core library. Currently, hipDNN has support for engine plugins which provide the kernels to solve graphs. In the future hipDNN will support both heuristic and benchmarking plugins to allow for improved engine selection. Benchmarking plugins will provide exhaustive tuning capabilities, but will require collecting samples from existing engines to do so. Heuristic plugins will provide better default engine selection given a graph, and shouldn't require collecting samples from existing engines to do so.
Frontend: A header-only C++ library that provides the industry standard API for interacting with hipDNN. The frontend wraps the backend C API to provide a more user-friendly C++ interface.
Backend: A shared library which provides a C API for hipDNN. The backend is the core component of hipDNN which acts as a plugin loader and manager, connecting problems to plugins that can solve them.
SDK: A header-only library that provides shared utilities and interfaces that plugins, frontend, and backend depend on to ensure compatibility and communication.
MIOpen Legacy Plugin: A plugin that wraps MIOpen and provides access to the existing API through hipDNN. In the future, the MIOpen Legacy Plugin will be its own separate project separate from hipDNN.
Other Plugins: Plugins will be added over time to provide additional operational support, or performance improvements. Plugins should be external projects to hipDNN.
The SDK is a header-only library that serves as the foundation for communication between different hipDNN components.
- Header-only: No compiled libraries, simplifying integration
- Dependencies: Flatbuffers and spdlog
- Purpose: Provides shared utilities and interfaces between Frontend, Backend, and Plugins
- Expected Usage: Consumed as a header-only dependency in user projects, and plugin projects
- Plugin APIs: Defines the interface that engine plugins must implement (e.g.,
hipdnnEnginePluginCreate,hipdnnEnginePluginExecuteOpGraph) - Data Objects: Flatbuffer-based data structures for graphs, tensors, and engine configurations
- Verification Utilities: Tools for validating solutions and ensuring correctness
- Logging Utilities: Consistent logging infrastructure across all components
- Type Helpers: Utilities for working with different data types (half, bfloat16, etc.)
For the SDK development roadmap and planned features, see the SDK section in the Roadmap.
The Frontend provides a user-friendly C++ interface to hipDNN, wrapping the lower-level C API provided by the Backend.
- Header-only C++ library: No compiled libraries, simplifying integration
- Dependencies: Backend, and SDK
- Purpose: Provides easy to use API for accessing hipDNN backend
- Expected Usage: Consumed as a header-only dependency in user projects
The central abstraction in the Frontend is the Graph class, which:
- Manages the construction of operation graphs
- Handles the creation and configuration of nodes
- Orchestrates the execution workflow
Nodes represent individual operations within a graph:
- Each node type (e.g.,
BatchnormNode,PointwiseNode) inherits fromINode - Nodes encapsulate their specific attributes and tensor connections
- Support serialization to Flatbuffer format for Backend consumption
Attributes configure the behavior of nodes:
- Each node type has corresponding attribute classes (e.g.,
Batchnorm_attributes) - Attributes include operation-specific parameters like epsilon, momentum, etc.
- Support builder pattern for easy configuration
// Create a graph
Graph graph;
graph.set_compute_data_type(DataType_t::FLOAT);
// Create tensors
auto x = Graph::tensor(/* tensor attributes */);
auto scale = Graph::tensor(/* tensor attributes */);
auto bias = Graph::tensor(/* tensor attributes */);
// Add operations
auto [y, mean, inv_var, _, _] = graph.batchnorm(x, scale, bias, bn_attributes);
// Build and execute
graph.build_operation_graph(handle);
graph.create_execution_plans();
graph.build_plans();
graph.execute(handle, variant_pack, workspace);For complete working examples, see the official samples.
The Backend is the core engine of hipDNN, responsible for managing plugins and orchestrating graph execution.
- Installable library: C API with ABI for language interoperability, dynamically loadable
- Dependencies: SDK
- Purpose: Provides a stable graph based API for describing kernel fusions
- Expected Usage: Library linked to the frontend API and expert user projects that provides access to the hipDNN backend API
The Backend uses descriptors as opaque handles to manage different aspects of graph execution:
- Represents the computational graph to be executed
- Contains nodes, tensors, and their connections
- Created from serialized Flatbuffer data
- Manages the selection of appropriate engines for a graph
- Queries plugins for applicable engines
- Extensible plugin design to control engine selection
- Represents a specific engine configuration
- Contains engine ID and configuration parameters
- Retrieved from heuristic results
- Represents a backend engine
- Contains engine ID, and a set of behavioral notes + configurable settings
- Retrieved from engine config Descriptor
- Combines an engine configuration with a graph
- Manages workspace requirements
- Prepares for actual execution
- Contains runtime data for execution
- Maps tensor UIDs to device memory pointers
- Includes workspace device memory pointer
- Create a Graph: Build an operation graph using Frontend
- Create Heuristic Descriptor: Initialize with the graph and desired heuristic mode
- Get Engine Configs: Query available engine configurations from the heuristic
- Create Execution Plan: Combine selected engine config with the graph
- Run Execution Plan: Execute with variant pack containing tensor data
// Simplified Backend workflow
hipdnnBackendDescriptor_t graph_desc, heuristic_desc, config_desc, plan_desc, variant_desc;
// 1. Create graph (from serialized data)
hipdnnBackendCreateAndDeserializeGraph_ext(&graph_desc, serialized_graph, size);
// 2. Create and configure heuristic
hipdnnBackendCreateDescriptor(HIPDNN_BACKEND_ENGINEHEUR_DESCRIPTOR, &heuristic_desc);
hipdnnBackendSetAttribute(heuristic_desc, HIPDNN_ATTR_ENGINEHEUR_OPERATION_GRAPH, ...);
hipdnnBackendFinalize(heuristic_desc);
// 3. Get engine configurations
hipdnnBackendGetAttribute(heuristic_desc, HIPDNN_ATTR_ENGINEHEUR_RESULTS, ...);
// 4. Create execution plan
hipdnnBackendCreateDescriptor(HIPDNN_BACKEND_EXECUTION_PLAN_DESCRIPTOR, &plan_desc);
hipdnnBackendSetAttribute(plan_desc, HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_CONFIG, ...);
hipdnnBackendFinalize(plan_desc);
// 5. Execute
hipdnnBackendExecute(handle, plan_desc, variant_desc);For the backend development roadmap and planned features, see the Backend section in the Roadmap.
Engine plugins provide the actual computational implementations for hipDNN graphs.
- Separate installable projects: Independent development and deployment
- Dependencies: hipDNN SDK, (and plugin specific dependencies as needed)
- Purpose: Provides engines which are capable of solving graphs
- Expected Usage: Loaded at runtime by hipDNN backend
- Backend discovers plugins at runtime via the default plugin path, or by using
hipdnnSetEnginePluginPaths_extto provide additional paths to load plugins from - Each plugin exports standard entry points defined in the SDK
- Each plugin can provide multiple engines
- Engines must have globally unique IDs that remain constant run to run
- Plugins determine which engines are applicable for a given graph
// Get all available engine IDs
hipdnnEnginePluginGetAllEngineIds(engine_ids, max_engines, num_engines);
// Check which engines can solve a graph
hipdnnEnginePluginGetApplicableEngineIds(handle, graph, engine_ids, max, num);
// Create execution context for a specific engine
hipdnnEnginePluginCreateExecutionContext(handle, config, graph, context);
// Execute the graph
hipdnnEnginePluginExecuteOpGraph(handle, context, workspace, buffers, num_buffers);- Provide pre-compiled kernels for specific operations
- Narrow support: Only handle specific configurations
- Example: MIOpen Legacy Plugin
- Advantages:
- Highly optimized for supported cases
- Predictable performance
- Lower compilation overhead
- Generate kernels at runtime based on graph structure
- Broad support: Handle general graph patterns
- Example: Future JIT-compilation plugins
- Advantages:
- Flexible operation fusion
- Support for novel graph patterns
- Adaptable to hardware capabilities
See Plugin Development for advanced information on developing and using plugins.
