Skip to content

Add computeStructuralHash for shader graphs#2976

Draft
ashwinbhat wants to merge 2 commits into
AcademySoftwareFoundation:mainfrom
autodesk-forks:bhata/structural_hash_prototype
Draft

Add computeStructuralHash for shader graphs#2976
ashwinbhat wants to merge 2 commits into
AcademySoftwareFoundation:mainfrom
autodesk-forks:bhata/structural_hash_prototype

Conversation

@ashwinbhat

Copy link
Copy Markdown
Contributor

Introduce computeStructuralHash in MaterialXGenShader, a free function that produces a size_t hash of a finalized ShaderGraph capturing its topology and port types while ignoring instance-specific data (node/port names, parameter values, and texture paths). Two graphs that wire up the same node implementations in the same pattern hash identically even when their constants differ, enabling shader deduplication/caching and distinct-structure reporting across large material libraries.

The function is an external visitor over the public API of ShaderGraph, ShaderNode, and ShaderPort: it never mutates the graph and folds node implementation hashes, classifications, port structure (type, semantic, colorspace, unit, geomprop, uniform/bind-input flags), and connection topology into a Boost/Hydra-style hash combiner.

The hash is deterministic within a build but session-local: it relies on std::hash and implementation hashes, so it must not be persisted or compared across builds/versions, and it is a fast pre-filter rather than a collision-proof equivalence proof.

Also adds:

  • Python binding (computeStructuralHash) in PyMaterialXGenShader.
  • A --dumpHash flag to generateshader.py.
  • A GLSL structural-hash test exercising generation and determinism.

Introduce computeStructuralHash in MaterialXGenShader, a free function that
produces a size_t hash of a finalized ShaderGraph capturing its topology and
port types while ignoring instance-specific data (node/port names, parameter
values, and texture paths). Two graphs that wire up the same node
implementations in the same pattern hash identically even when their constants
differ, enabling shader deduplication/caching and distinct-structure reporting
across large material libraries.

The function is an external visitor over the public API of ShaderGraph,
ShaderNode, and ShaderPort: it never mutates the graph and folds node
implementation hashes, classifications, port structure (type, semantic,
colorspace, unit, geomprop, uniform/bind-input flags), and connection topology
into a Boost/Hydra-style hash combiner.

The hash is deterministic within a build but session-local: it relies on
std::hash and implementation hashes, so it must not be persisted or compared
across builds/versions, and it is a fast pre-filter rather than a
collision-proof equivalence proof.

Also adds:
- Python binding (computeStructuralHash) in PyMaterialXGenShader.
- A --dumpHash flag to generateshader.py.
- A GLSL structural-hash test exercising generation and determinism.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new structural hashing utility for MaterialXGenShader shader graphs to support shader deduplication/caching by hashing graph topology and port structure while ignoring instance-specific details (names, values, paths).

Changes:

  • Added computeStructuralHash(const ShaderGraph&) in MaterialXGenShader to hash finalized shader graph structure/topology.
  • Exposed the hash via Python (PyMaterialXGenShader.computeStructuralHash(shader)), and added a --dumpHash CLI flag to generateshader.py.
  • Added a GLSL-side Catch2 test to exercise structural hash determinism.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
source/PyMaterialX/PyMaterialXGenShader/PyUtil.cpp Adds Python binding for structural hashing via a Shader wrapper function.
source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp Adds a Catch2 test that computes/prints structural hashes and checks determinism.
source/MaterialXGenShader/ShaderGraphHash.h Declares the new public computeStructuralHash API.
source/MaterialXGenShader/ShaderGraphHash.cpp Implements the structural hash over graph sockets, nodes, ports, and connections.
python/Scripts/generateshader.py Adds --dumpHash to print the structural hash for generated shaders.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +281 to +286
std::string message;
bool docValid = doc->validate(&message);
if (!docValid)
{
continue;
}
Comment on lines +293 to +301
mx::ShaderPtr shader;
try
{
shader = context.getShaderGenerator().generate(element->getName(), element, context);
}
catch (const std::exception&)
{
continue;
}
Comment on lines +309 to +317
mx::ShaderPtr shader2;
try
{
shader2 = context.getShaderGenerator().generate(element->getName(), element, context);
}
catch (const std::exception&)
{
continue;
}
Comment on lines +331 to +334
// Output to Catch2 INFO so it appears with -s flag
INFO(hashLog.str());
SUCCEED();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants