pytorch - 💡(How to fix) Fix [privateuse1] Update the privateuse1 tutorial to mention registering HooksInterface [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
pytorch/pytorch#179008Fetched 2026-04-08 02:21:59
View on GitHub
Comments
0
Participants
1
Timeline
15
Reactions
0
Participants
Timeline (top)
mentioned ×7subscribed ×7labeled ×1

Error Message

""" Demonstrate what happens when PrivateUse1Hooks are NOT registered.

Registers everything EXCEPT hooks, then triggers the assert via backward(). """

import torch import torch._C

--- Setup: everything except hooks ---

torch.utils.rename_privateuse1_backend("new_device") torch.utils.generate_methods_for_privateuse1_backend()

class _DummyBackendModule: def is_available(self): return True def device_count(self): return 1 def current_device(self): return 0 def set_device(self, device): pass

torch._register_device_module("new_device", _DummyBackendModule())

class _DummyDeviceGuard(torch._C.acc.DeviceGuard): def type(self): return torch._C._autograd.DeviceType.PrivateUse1

torch._C._acc.register_python_privateuseone_device_guard(_DummyDeviceGuard())

--- Register minimal ops ---

def _make_tensor(size, dtype): return torch._C._acc.create_empty_tensor(list(size), dtype or torch.float32)

@torch.library.impl("aten::empty_strided", "PrivateUse1") def empty_strided(size, stride, *, dtype=None, layout=None, device=None, pin_memory=None): return _make_tensor(size, dtype)

@torch.library.impl("aten::empty.memory_format", "PrivateUse1") def empty_memory_format(size, *, dtype=None, layout=None, device=None, pin_memory=None, memory_format=None): return _make_tensor(size, dtype)

@torch.library.impl("aten::_copy_from", "PrivateUse1") def copy_from(src, dst): pass

@torch.library.impl("aten::mul.Tensor", "PrivateUse1") def mul_tensor(self, other): return _make_tensor(self.shape, self.dtype)

a = torch.randn(2, 3, requires_grad=True) a_new_device = a.to("new_device") b = a_new_device * a_new_device grad = torch.randn(2, 3).to("new_device")

RuntimeError: Please register PrivateUse1HooksInterface by RegisterPrivateUse1HooksInterface first.

b.backward(grad)

Code Example

"""
Demonstrate what happens when PrivateUse1Hooks are NOT registered.

Registers everything EXCEPT hooks, then triggers the assert via backward().
"""

import torch
import torch._C

# --- Setup: everything except hooks ---

torch.utils.rename_privateuse1_backend("new_device")
torch.utils.generate_methods_for_privateuse1_backend()


class _DummyBackendModule:
    def is_available(self):
        return True
    def device_count(self):
        return 1
    def current_device(self):
        return 0
    def set_device(self, device):
        pass

torch._register_device_module("new_device", _DummyBackendModule())


class _DummyDeviceGuard(torch._C._acc.DeviceGuard):
    def type_(self):
        return torch._C._autograd.DeviceType.PrivateUse1

torch._C._acc.register_python_privateuseone_device_guard(_DummyDeviceGuard())


# --- Register minimal ops ---

def _make_tensor(size, dtype):
    return torch._C._acc.create_empty_tensor(list(size), dtype or torch.float32)

@torch.library.impl("aten::empty_strided", "PrivateUse1")
def empty_strided(size, stride, *, dtype=None, layout=None, device=None, pin_memory=None):
    return _make_tensor(size, dtype)

@torch.library.impl("aten::empty.memory_format", "PrivateUse1")
def empty_memory_format(size, *, dtype=None, layout=None, device=None, pin_memory=None, memory_format=None):
    return _make_tensor(size, dtype)

@torch.library.impl("aten::_copy_from", "PrivateUse1")
def copy_from(src, dst):
    pass

@torch.library.impl("aten::mul.Tensor", "PrivateUse1")
def mul_tensor(self, other):
    return _make_tensor(self.shape, self.dtype)


a = torch.randn(2, 3, requires_grad=True)
a_new_device = a.to("new_device")
b = a_new_device * a_new_device
grad = torch.randn(2, 3).to("new_device")
# RuntimeError: Please register PrivateUse1HooksInterface by `RegisterPrivateUse1HooksInterface` first.
b.backward(grad)

---

File "/opt/pytorch/pytorch/torch/autograd/__init__.py", line 381, in backward
    _engine_run_backward(
  File "/opt/pytorch/pytorch/torch/autograd/graph.py", line 879, in _engine_run_backward
    return Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Please register PrivateUse1HooksInterface by `RegisterPrivateUse1HooksInterface` first.
RAW_BUFFERClick to expand / collapse

📚 The doc issue

Without using torch._C._acc.register_python_privateuseone_hook or C++ equivalent, one would see error on backward. The tutorial should mention this.

Repro

"""
Demonstrate what happens when PrivateUse1Hooks are NOT registered.

Registers everything EXCEPT hooks, then triggers the assert via backward().
"""

import torch
import torch._C

# --- Setup: everything except hooks ---

torch.utils.rename_privateuse1_backend("new_device")
torch.utils.generate_methods_for_privateuse1_backend()


class _DummyBackendModule:
    def is_available(self):
        return True
    def device_count(self):
        return 1
    def current_device(self):
        return 0
    def set_device(self, device):
        pass

torch._register_device_module("new_device", _DummyBackendModule())


class _DummyDeviceGuard(torch._C._acc.DeviceGuard):
    def type_(self):
        return torch._C._autograd.DeviceType.PrivateUse1

torch._C._acc.register_python_privateuseone_device_guard(_DummyDeviceGuard())


# --- Register minimal ops ---

def _make_tensor(size, dtype):
    return torch._C._acc.create_empty_tensor(list(size), dtype or torch.float32)

@torch.library.impl("aten::empty_strided", "PrivateUse1")
def empty_strided(size, stride, *, dtype=None, layout=None, device=None, pin_memory=None):
    return _make_tensor(size, dtype)

@torch.library.impl("aten::empty.memory_format", "PrivateUse1")
def empty_memory_format(size, *, dtype=None, layout=None, device=None, pin_memory=None, memory_format=None):
    return _make_tensor(size, dtype)

@torch.library.impl("aten::_copy_from", "PrivateUse1")
def copy_from(src, dst):
    pass

@torch.library.impl("aten::mul.Tensor", "PrivateUse1")
def mul_tensor(self, other):
    return _make_tensor(self.shape, self.dtype)


a = torch.randn(2, 3, requires_grad=True)
a_new_device = a.to("new_device")
b = a_new_device * a_new_device
grad = torch.randn(2, 3).to("new_device")
# RuntimeError: Please register PrivateUse1HooksInterface by `RegisterPrivateUse1HooksInterface` first.
b.backward(grad)

Error

  File "/opt/pytorch/pytorch/torch/autograd/__init__.py", line 381, in backward
    _engine_run_backward(
  File "/opt/pytorch/pytorch/torch/autograd/graph.py", line 879, in _engine_run_backward
    return Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Please register PrivateUse1HooksInterface by `RegisterPrivateUse1HooksInterface` first.

Tutorial - https://docs.pytorch.org/tutorials/advanced/privateuseone.html#generate-methods-and-properties-related-to-the-new-backend

Suggest a potential alternative/fix

N/A

cc @NmomoN @mengpenghui @fwenguang @cdzhan @1274085042 @PHLens @albanD

extent analysis

TL;DR

To fix the error, register the PrivateUse1HooksInterface using torch._C._acc.register_python_privateuseone_hook or its C++ equivalent.

Guidance

  • The error occurs because the PrivateUse1HooksInterface is not registered, which is required for the backward pass.
  • To verify the fix, run the code with the torch._C._acc.register_python_privateuseone_hook call added before the backward pass.
  • The tutorial should be updated to include this registration step to avoid similar errors.
  • The torch._C._acc.register_python_privateuseone_hook function should be called with the correct hook implementation to register the PrivateUse1HooksInterface.

Example

torch._C._acc.register_python_privateuseone_hook(my_hook_implementation)

Replace my_hook_implementation with the actual implementation of the PrivateUse1HooksInterface.

Notes

  • The exact implementation of the PrivateUse1HooksInterface is not provided in the issue, so the example code snippet is incomplete.
  • The fix assumes that the PrivateUse1HooksInterface implementation is available and can be registered using torch._C._acc.register_python_privateuseone_hook.

Recommendation

Apply workaround: Register the PrivateUse1HooksInterface using torch._C._acc.register_python_privateuseone_hook to fix the error. This is necessary to enable the backward pass for the custom device.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING