Skip to content

Unable to do the difference between kind() and type() for dtype in numpy.h #2860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bemichel opened this issue Feb 12, 2021 · 5 comments
Open

Comments

@bemichel
Copy link
Contributor

Hi,
We are using pybind11 to give access to Python/C++ arrays in on a numerical project. For this, we are using the pybind11:array_t.

But, we would like to have access to type attribute in the PyArray_Descr in API C or the dtype.char on Python interface, but only the kind() method is available in the class pybin11::dtype in numpy.h.

The kind method gives only the "general" kind of the dtype, i.e.

    auto float32 = py::dtype::of<float>();
    std::cout << "float32.kind() = " << float32.kind() << std::endl; /// return 'f'
    auto float64 = py::dtype::of<double>();
    std::cout << "float64.kind() = " << float64.kind() << std::endl; /// return 'f'

So it is not possible to distinguish float from double, or int from long int.

Only by adding a new method in the pybind11::dtype::type() for exemple which returns the type attribute from PyArray_Descr, like the following

class dtype : public object {
  ....
    /// Single-character for dtype's kind (ex: float and double are 'f' or int and long int are 'i')
    char kind() const {
        return detail::array_descriptor_proxy(m_ptr)->kind;
    }

    /// Single-character for dtype's type (ex: float is 'f' and double 'd')
    char type() const {
        return detail::array_descriptor_proxy(m_ptr)->type;
    }
private:
  ....
};

It will be now possible to distinguish the effective type

    auto float32 = py::dtype::of<float>();
    std::cout << "float32.kind() = " << float32.kind() << std::endl; /// return 'f'
    std::cout << "float32.type() = " << float32.type() << std::endl; /// return 'f'
    auto float64 = py::dtype::of<double>();
    std::cout << "float64.kind() = " << float64.kind() << std::endl; /// return 'f'
    std::cout << "float64.type() = " << float64.type() << std::endl; /// return 'd'

Sorry, I am not sure if it is the good way to asking to add this little piece of code and/or if it is just possible ?
Should I create a merge request instead ?

Best regards,
Bertrand M.

@YannickJadoul
Copy link
Collaborator

YannickJadoul commented Feb 14, 2021

Hi, @bemichel. If you don't mind, a PR would indeed be easier. If not, let us know, and someone can do it.

By the way, in Python itself, it's dtype.char. So maybe we should adopt the same interface for py::dtype?

>>> np.dtype(np.float32).char
'f'
>>> np.dtype(np.float64).char
'd'

@bemichel
Copy link
Contributor Author

Hi @YannickJadoul,
Okay, I will try to open a PR !
I know that in python the interface is dtype.char but in C++ char is a reserved word, it is why I proposed type on the C++ side !
Do you validated my proposition py::dtype::type() ?
Best regards.
Bertrand M.

@YannickJadoul
Copy link
Collaborator

Oh, right. Of course, you're right...

One way pybind11 deals with this is by using an extra underscore. Like class_ or module_. So maybe we should do the same here and use char_. I'm a bit doubtful about using type, here, as maybe we would like to have the same kind as np.dtype.type thing here, returning a py::type?

@bstaletic, any thoughts?

@bemichel
Copy link
Contributor Author

Hi,
I can propose a PR with char_() !
I add some tests also to distinguish what is returned by kind() and char_().
All tests seems okay and pre-commit seems okay too.
Bertrand M.

@YannickJadoul
Copy link
Collaborator

I can propose a PR with char_() !

If that name also makes sense to you (does it?), then that would be perfect, yes :-) Thanks a lot :-)

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

No branches or pull requests

2 participants