| 165 | |
| 166 | template<typename Backend> |
| 167 | py::dict ArrayInterfaceRepr(Tensor<Backend> &t) { |
| 168 | py::dict d; |
| 169 | py::tuple tup(2); |
| 170 | d["typestr"] = FormatStrFromType(t.type()); |
| 171 | // __array_interface__ expects shape to be a tuple |
| 172 | d["shape"] = py::tuple(py_shape<Backend>(t)); |
| 173 | // tuple of (raw_data_pointer, if_data_is_read_only) |
| 174 | tup[0] = PyLongFromVoidPtr(t.raw_mutable_data()); |
| 175 | // if we make it readonly, it prevents us from sharing memory with PyTorch tensor |
| 176 | tup[1] = false; |
| 177 | d["data"] = tup; |
| 178 | if constexpr (std::is_same<Backend, GPUBackend>::value) { |
| 179 | // see https://numba.pydata.org/numba-doc/dev/cuda/cuda_array_interface.html |
| 180 | // this set of atributes is tagged as version 2 |
| 181 | d["version"] = 2; |
| 182 | } else { |
| 183 | // see https://docs.scipy.org/doc/numpy/reference/arrays.interface.html |
| 184 | // this set of atributes is tagged as version 3 |
| 185 | d["version"] = 3; |
| 186 | if (t.is_pinned()) { |
| 187 | if (auto &event = t.ready_event()) |
| 188 | AccessOrder::host().wait(event); // more fine-grained synchronization |
| 189 | else |
| 190 | AccessOrder::host().wait(t.order()); |
| 191 | } |
| 192 | } |
| 193 | d["strides"] = py::none(); |
| 194 | return d; |
| 195 | } |
| 196 | |
| 197 | namespace { |
| 198 | const uint32_t kDynamicDefaultColor = 0x957DAD; |
nothing calls this directly
no test coverage detected