| 156 | } |
| 157 | |
| 158 | Maybe<Tensor> ConvertToIndexingTensor(PyObject* object) { |
| 159 | // NOTE: convert data to indexing will ensure in eager mode |
| 160 | LazyMode::Guard lazy_mode_disabled_guard(/*is_enabled*/ false); |
| 161 | const DataType dtype = InferScalarType(object); |
| 162 | const auto& device = JUST(Device::New("cpu")); |
| 163 | |
| 164 | // index type must be integers |
| 165 | if (!(IsIntegralDataType(dtype) || (IsBoolDataType(dtype)))) { |
| 166 | return Error::IndexError() << "only integers, slices (`:`), ellipsis (`...`), numpy.newaxis " |
| 167 | "(`None`) and integer or boolean arrays are valid indices"; |
| 168 | } |
| 169 | // In advanced indexing condition, index can be array object, need to handle it specially. |
| 170 | if (PyArray_Check(object)) { |
| 171 | return TensorWithData(object, NullOpt, device, /*requires_grad=*/false, /*pin_memory=*/false); |
| 172 | } |
| 173 | |
| 174 | const auto& sizes = InferArraySizes(object); |
| 175 | const auto& tensor = JUST(functional::Empty(sizes, CHECK_JUST(DType::Get(dtype)), device, |
| 176 | /*requires_grad=*/false, /*pin_memory=*/false)); |
| 177 | // Prevent the python object release until the callback is complete. |
| 178 | Py_INCREF(object); |
| 179 | auto handle = std::shared_ptr<PyObject>(PyObjectPtr(object)); |
| 180 | |
| 181 | JUST(PhysicalRun([&](InstructionsBuilder* builder) -> Maybe<void> { |
| 182 | return builder->AccessBlobByCallback( |
| 183 | JUST(tensor->AsLocalTensor()), |
| 184 | [handle](ep::Stream* stream, |
| 185 | const std::shared_ptr<vm::EagerBlobObject>& eager_blob_object) { |
| 186 | CHECK_JUST(Singleton<ForeignLockHelper>::Get()->WithScopedAcquire([&]() -> Maybe<void> { |
| 187 | ParseArrayToTensor(handle.get(), eager_blob_object); |
| 188 | return Maybe<void>::Ok(); |
| 189 | })); |
| 190 | }, |
| 191 | "mut"); |
| 192 | })); |
| 193 | return tensor; |
| 194 | } |
| 195 | |
| 196 | IndexItem UnpackIndexItem(PyObject* object) { |
| 197 | if (object == Py_Ellipsis) { |
no test coverage detected