Skip to content

[Bug] Invalid boolean negation of PyTorch Tensor in bfgsHessianInverse.py #64

Description

@dodowawa

I encountered an issue related to boolean operations on PyTorch tensors while running the tests with PyGRANSO 2.0.0.

My environment is approximately as follows:

  • PyGRANSO: 2.0.0
  • Python: 3.13.7
  • PyTorch: 2.8.0
  • OS: Windows 11

When running the tests, the following error occurred at line 188 of pygranso/private/bfgsHessianInverse.py:

RuntimeError: Boolean value of Tensor with more than one value is ambiguous

The corresponding code is:

notInf_flag = torch.all(not torch.isinf(H_vec))
notNan_flag = torch.all(not torch.isnan(H_vec))

Here, torch.isinf(H_vec) and torch.isnan(H_vec) return boolean tensors.

If H_vec contains multiple elements, Python's not operator attempts to convert the entire tensor into a single boolean value, which causes the error above.

I changed lines 188 and 189 to:

notInf_flag = torch.all(~torch.isinf(H_vec))
notNan_flag = torch.all(~torch.isnan(H_vec))

After this change, the relevant tests passed successfully.

For reference, the corresponding code in PyGRANSO 1.2.0 used element-wise comparisons:

notInf_flag = torch.all(torch.isinf(H_vec) == False)
notNan_flag = torch.all(torch.isnan(H_vec) == False)

Therefore, the change from PyGRANSO 1.2.0 to 2.0.0:

torch.isinf(H_vec) == False

to:

not torch.isinf(H_vec)

changes the actual semantics of the code.

For a regular Python bool, these two forms are essentially equivalent. However, for a PyTorch tensor, the former performs an element-wise comparison, while the latter attempts to evaluate the entire tensor as a Python boolean value.

I suggest changing the current implementation to something like:

notInf_flag = torch.all(~torch.isinf(H_vec))
notNan_flag = torch.all(~torch.isnan(H_vec))

or:

notInf_flag = torch.all(torch.logical_not(torch.isinf(H_vec)))
notNan_flag = torch.all(torch.logical_not(torch.isnan(H_vec)))

It may also be worth checking PyGRANSO 2.0.0 for similar changes where:

tensor == False

was mechanically replaced with:

not tensor

In particular, expressions such as the following may be worth reviewing:

not torch.isinf(...)
not torch.isnan(...)
not torch.isfinite(...)
not torch.any(...)
not torch.all(...)

If the expression returns a multi-element tensor, the same issue may occur.

Thank you for maintaining PyGRANSO. I hope this report and the proposed fix are helpful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions