---
title: BIDS Meeting DType decisions space
tags: NumPy, dtypes
---
**Present:**
*Note: a table of contents can be found in the lower left corner*
Nomenclature
------------
Based on Matti's suggestion, if something is confusing maybe use these?:
* **dtype**: A class (type or not)
* **descriptor** (or **a dtype**): object tagged onto the array (an instance of dtype)
* **scalar type**: A type which, when instanciated, provides the scalar class
* a **scalar**: instance of scalar type.
API Brainstorming
=================
Python API code
---------------
```python
class mytype(dtype):
pass
```
<details><summary> Sebastian's take/start </summary>
```python
class dtype(object):
def __promote__(self, other):
"""Used by np.promote_types, identical to result_type
but without scalar logic.
"""
if isinstance(other, self):
# make sure to give priority to subclasses:
self, other = other, self
if self.__can_cast__(other):
return other
if other.__can_cast__(self):
return self
raise TypeError("cannot promote to common type.")
class unit(dtype):
itemsize = 8
type = pyunit
def __new__(self):
# what is specfically needed here?
pass
def __item_unpack__(self, val):
"""How to do this as low level loops?"""
return self.type.from_bytes(val)
def __item_pack__(self, obj):
if not isinstance(obj, self.type):
raise ValueError
return obj.to_bytes()
@classmethod # not sure?
def __promote__(cls, dt1, dt2):
"""By default, checks can_cast(self, other)"""
return np.result_type(self, other)
@classmethod
def __can_cast__(cls, dt1, dt2, casting="safe"):
return True or False # or unit["m"], loop?
@classmethod
def __get_loop__(self, ufunc, in_types, out_types):
"""
Alternatively, register loops and:
* check exact loops → promote → check loops again
* (loop could still refuse)
"""
if not_possible:
return NotImplemented
return UfuncLoop
class UfuncLoop:
# probably largely C-slots, but could fill from python
inner_loop
setup_loop = None # i.e. FloatClearErr
teardown_loop = None # i.e. FloatCheckErr
needs_api # Flag (or allow setup to set/override?)
identity = NotImplemented
# more flags to add
# Other or even extendable things?:
masked_inner_loop = None # already auto-wrapped if not there
specialized_inner_loops = None # contiguous (copy code), AVX?
```
</details>
Decisions and Discussion
========================
Scalars are dtype instances?
----------------------------
...
#### Decisions:
...
ArrFuncs and Subclassing
------------------------
...
#### Decisions:
...
Casting
-------
* Slot such as `__can_cast__`?
* Registration based system such as no?
#### Decisions:
...
Promotion
---------
Common type normally found with safe casting semantics (if `a` can safe cast to `b`, then `promote(a, b) is a`).
* `np.floating` may be tricky?
* Custom rules necessary?
* Promote scalars in `np.array`
#### Decisions:
...
UFuncs
------
**Need:**
* flexible dtype specialization
* setup/teardown
* Inner-loop metadata
* …
*Should thi*
#### Decisions:
...
#### Compatibility issues?
* How far can we go without creating compatibility issues e.g. for numba?
<details>
<summary> numba usage of ufunc struct </summary>
* iterates `ufunc->functions` to find its own and
edit `ufunc->data` for that function.
* Does manual loop adding modifying:
* `ntypes`
* `functions`
* `data`
* `ptr` (used also by `from_pyfunc`, is freed on `dealloc`)
* From numba code: `ptr == |<- functions ->|<- data ->|<- types ->|`
</details>
Random Notes
============
*Room for random notes/thoughts so they do not get lost?*
* Remember ufunc-inner-loops should have a return value.
* Ufuncs could have default args or parameter kwargs?