Skip to content

dpt.astype returns wrong result on boolean view of numpy.ndarray #2121

Closed

Description

@antonwolfy

Here is example with unexpected behavior:

import dpctl, dpctl.tensor as dpt, numpy

dpctl.__version__
# Out: '0.21.0dev0+49.g5be8ef909c'

a = numpy.array([0, 3, 1, 2, 0, 1], dtype='u1')
a_view = a.view('?')

# create a view from numpy.ndarray
b = numpy.array(a_view)
b
# Out: array([False,  True,  True,  True, False,  True])

dpt_b = dpt.asarray(a_view)
dpt_b  # the same as b
# Out: usm_ndarray([False,  True,  True,  True, False,  True])

# cast to integer dtype
numpy.astype(b, int)
# Out: array([0, 1, 1, 1, 0, 1])

# the result is unexpected, since True and False have to casted to 0 and 1 only
dpt.astype(dpt_b, int)
# Out: usm_ndarray([0, 3, 1, 2, 0, 1])

Activity

  1. added 2 commits that reference this issue on Jul 9, 2025
    f791949
    8e952d1
  2. added a commit that references this issue on Jul 15, 2025
  3. sycloid commented on Sep 26, 2025

    @sycloid
    Contributor

    @ndgrigorian @antonwolfy

    Notice that C++ also disagrees with NumPy here:

    // clang++ gh_2121.cpp -o tmp
    #include <iostream>
    #include <cstdint>
    
    #include <string>
    #include <vector>
    
    int main(void) {
      std::vector<std::uint8_t> orig{{0, 3, 1, 2, 0, 1}};
      std::vector<std::uint8_t> conv(orig.size());
    
      std::cout << "Original : ";
      for(std::size_t i = 0; i < orig.size(); ++i) {
         std::cout << std::to_string(orig[i]) << " ";
      }
      std::cout << "\n";
    
      bool *p = reinterpret_cast<bool *>(orig.data());
    
      for(std::size_t i=0; i < orig.size(); ++i) {
          conv[i] = (p[i]) ? 1 : 0;
      }
    
      std::cout << "Converted: ";
      for(std::size_t i = 0; i < orig.size(); ++i) {
            std::cout << std::to_string(conv[i]) << " ";
      }
      std::cout << "\n";
    
      return 0;
    }
    $ clang++ gh_2121.cpp -o tmp
    $ ./tmp
    Original : 0 3 1 2 0 1
    Converted: 0 1 1 0 0 1
    

    To implement NumPy's behavior in C++ one needs to always work with bool by reference (otherwise a copy is made standardizing the underlying bit-set), bit-cast bool to std::uint8_t and convert as needed.

  4. added 4 commits that reference this issue on Sep 26, 2025
    2911601
    c3a147f
    a6dd869
    cc0756f
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