Sample CodeReviewed 2026-07-21View on Apple Developer

Customizing a TensorFlow operation

At a glance

Item Summary
Purpose Implement a custom operation that uses Metal kernels to accelerate neural-network training performance.
App architecture C++, Python host code with Metal shaders; the Python HashEncoder layer invokes a registered TensorFlow operation whose C++ kernel dispatches the Metal hash-encoding functions.
Main patterns Custom operator bridge, Framework registration, Language boundary
Scope High-level review of 7 scanned source files and 10 detected declarations; build assets are omitted.

Project structure

Source bundle/
├── hash_encoder/
│   ├── hash_encoder_kernel.cc
│   ├── hash_encoder_kernel.metal
│   ├── hash_encoder.py
│   └── mtl_hash_encoder_kernel.cc
├── tiny_nerf_hash.py
├── tiny_nerf_mlp.py
└── render_utils.py

Structure observations

  • The entry/composition boundary and renderer or operation boundary are separate in the source; C++ TensorFlow op is the principal feature coordinator.
  • GPU-specific logic stays in Metal shader files; shared headers bridge host/shader layouts where present.
  • The tree above is intentionally pruned to composition, resource, and shader files.

Overall architecture

Reference code

hash_encoder/hash_encoder_kernel.cc:13 — feature handoff or setup anchor

REGISTER_OP("HashEncode")
    .Attr("T: {float}")
    // The input coordinates.
    .Input("inputs: float") 
    // The NGP embedding buffer.
    .Input("embeddings: T") 
    // The hashmap offsets of all levels.
    .Input("hashmap_offsets: int32")

Interpretation

The Python layer crosses TensorFlow’s custom-op ABI. C++ owns operation/kernel registration and the native dispatch path; the .metal file owns the parallel forward and backward algorithms.

Ownership and state

Ownership evidence

tiny_nerf_hash.py:313NGP creates and stores enc

        self.enc = HashEncoder(n_dim=ngp_n_dim, n_levels=ngp_levels, n_feature=ngp_feature,
                               resolution_coarsest=32, log2_hashmap_size=19, resolution_finest=256)

        # The output feature length.
        ngp_output_channel = ngp_feature * ngp_levels

        # The geometry feature vector length for the color net.
        geometry_feat = 3
Owner Object or state Relationship Mutation authority
NGP enc / HashEncoder Creates and stores; the diagram uses composition because construction is source-visible. The declaring scope performs setup and replacement.
C++ TensorFlow op Feature-specific framework and Metal resources Operation-local calls or stored state; exclusive lifetime is not assumed beyond cited evidence. Feature setup/encoding code controls mutation and command submission.

Class and protocol design

Type Responsibility Depends on or conforms to Source
HashEncoder encapsulates the feature operation and its framework/GPU resources. keras.Model hash_encoder/hash_encoder.py:70
_hash_encode binds the forward and backward custom operations through TensorFlow’s custom-gradient wrapper. concrete Metal/framework collaborators hash_encoder/hash_encoder.py:41
HashEncodeOp supplies the registered, intentionally unimplemented CPU forward-kernel fallback. OpKernel hash_encoder/hash_encoder_kernel.cc:67
HashEncodeGradOp supplies the registered, intentionally unimplemented CPU gradient-kernel fallback. OpKernel hash_encoder/hash_encoder_kernel.cc:80
KernelLibrarySingleton lazily loads and shares the compiled Metal kernel library. concrete Metal/framework collaborators hash_encoder/mtl_hash_encoder_kernel.cc:29
InitPlugin registers the forward and gradient GPU kernels when the plug-in library loads. concrete Metal/framework collaborators hash_encoder/mtl_hash_encoder_kernel.cc:484

No local protocol abstraction is present; the sample uses concrete framework, operation, or model types at this boundary.

Access control

Symbol Access Verified effect Design reason
hash_encoder_kernel C++ members C++ access specifier public/protected/private defines member reachability. Keep the usable surface no wider than the collaboration requires. (hash_encoder/hash_encoder_kernel.cc:68)
hash_encoder_kernel entry points Metal library boundary host code resolves named shader entry points; Swift access modifiers do not apply. Expose only named shader entry points needed by pipeline creation. (hash_encoder/hash_encoder_kernel.metal:184)
hash_encoder Python module boundary leading underscores are conventions; the compiled extension/registration layer defines the native export boundary. Keep the usable surface no wider than the collaboration requires. (hash_encoder/hash_encoder.py:1)

This sample does not use Swift private, fileprivate, or public for its native boundary. Objective-C/Objective-C++ use header versus implementation placement, C++ uses access specifiers/linkage, Python uses module conventions, and Metal entry points cross a compiled-library boundary; these are not Swift access levels.

Logic ownership and placement

Logic Owning type or file Why it lives there
Encapsulates the feature operation and its framework/GPU resources HashEncoderhash_encoder/hash_encoder.py:70 The type’s callbacks and stored state align with this responsibility.
Python layer and registered C++ custom operation C++ TensorFlow op / hash_encoder/hash_encoder_kernel.cc:13 Keeps Metal/framework setup and encoding out of entry or lifecycle code.
Metal hash-encoding kernel hash_encoder/hash_encoder_kernel.metal:184 GPU-parallel code remains in the Metal compilation boundary.

Shader boundary reference

hash_encoder/hash_encoder_kernel.metal:184 — representative GPU entry/helper

kernel void HashEncodeForward(
    // ...
    uint3 tid [[thread_position_in_grid]]) {
    // ...
}

Design patterns

Pattern Source evidence Purpose or tradeoff
Custom operator bridge hash_encoder/hash_encoder_kernel.cc:13 Makes the sample’s Python layer and registered C++ custom operation an explicit, reviewable boundary.
Framework registration hash_encoder/hash_encoder_kernel.cc:13 Makes the sample’s Python layer and registered C++ custom operation an explicit, reviewable boundary.
Language boundary hash_encoder/hash_encoder_kernel.cc:13 Python-facing APIs isolate compiled native/GPU implementation details.

Naming conventions

  • Role suffixes make ownership visible: HashEncoder.
  • Method names describe setup or encoding actions: forward, forward_with_tensors_only, grad, __init__, call, OK, queue.
  • Shader entry points use stage/operation names: HashEncodeForward, HashEncodeBackward.
  • Names favor concrete domain roles and target-local types; no broad public library namespace is introduced.

Architecture takeaways

  • Keep Python layer/model focused on composition; C++ TensorFlow op is the owner of Python layer and registered C++ custom operation.
  • Treat Metal hash-encoding kernel as a separate execution/compilation boundary with explicit resource and data-layout contracts.
  • The verified ownership edge is NGPenc; broader exclusive ownership is not inferred.
  • Access-control rationale follows concrete language boundaries rather than translating every header or shader symbol into Swift terms.

Source map

Source file Architectural role
hash_encoder/hash_encoder_kernel.cc HashEncodeOp, HashEncodeGradOp
tiny_nerf_hash.py NGP, TrainMonitor
hash_encoder/hash_encoder_kernel.metal entry point or feature implementation
hash_encoder/hash_encoder.py _hash_encode, HashEncoder
hash_encoder/mtl_hash_encoder_kernel.cc KernelLibrarySingleton, InitPlugin
tiny_nerf_mlp.py NeRF, TrainMonitor
render_utils.py entry point or feature implementation