MCPcopy Create free account
hub / github.com/NVIDIA/DALI / TensorListFromListOfDLPackObjects

Function TensorListFromListOfDLPackObjects

dali/python/backend_impl.cc:1282–1420  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1280
1281template <typename Backend>
1282std::shared_ptr<TensorList<Backend>> TensorListFromListOfDLPackObjects(
1283 py::list &list_of_objects,
1284 const std::optional<std::string> &layout,
1285 py::object stream,
1286 bool contiguous) {
1287 constexpr uint32_t rangeColor = TensorListDLPackRangeColor<Backend>();
1288 DomainTimeRange range(TensorListDLPackRangeName<Backend>(), rangeColor);
1289
1290 if (list_of_objects.empty()) {
1291 auto ptr = std::make_shared<TensorList<Backend>>();
1292 if (layout.has_value()) {
1293 ptr->set_sample_dim(layout->length());
1294 ptr->SetLayout(*layout);
1295 }
1296 return ptr;
1297 }
1298
1299 AccessOrder copy_order = AccessOrder::host();
1300 if constexpr (std::is_same_v<Backend, GPUBackend>) {
1301 if (!stream.is_none())
1302 copy_order = AccessOrderFromPythonStreamObj(stream);
1303 }
1304
1305 // Preflight pass: validate device compatibility before consuming any capsule.
1306 // __dlpack__() is single-use, so mismatches must be caught before the handshake starts.
1307 int expected_device_id = -1;
1308 for (size_t i = 0; i < list_of_objects.size(); ++i) {
1309 py::object obj = list_of_objects[i];
1310 CheckDLPackDeviceBeforeCapsule<Backend>(obj, i, expected_device_id, copy_order);
1311 }
1312
1313 if constexpr (std::is_same_v<Backend, GPUBackend>) {
1314 // If no __dlpack_device__ was found and no explicit stream was provided, fall back to the
1315 // current CUDA device so every __dlpack__() call receives a concrete consumer stream.
1316 if (copy_order == AccessOrder::host()) {
1317 int current_dev = -1;
1318 CUDA_CALL(cudaGetDevice(&current_dev));
1319 copy_order = AccessOrder(UserStream::Get()->GetStream(static_cast<size_t>(current_dev)));
1320 }
1321 }
1322
1323 // Derive the DLPack consumer-stream handle from copy_order so the producer always
1324 // synchronizes with the exact same stream that DALI will use for the copy.
1325 py::object stream_handle = py::none();
1326 if constexpr (std::is_same_v<Backend, GPUBackend>) {
1327 if (copy_order.is_device()) {
1328 stream_handle = py::int_(reinterpret_cast<int64_t>(copy_order.stream()));
1329 }
1330 }
1331
1332 std::optional<TensorList<Backend>> non_contiguous_tmp;
1333 std::shared_ptr<TensorList<Backend>> non_contiguous_out;
1334
1335 if (contiguous)
1336 non_contiguous_tmp = TensorList<Backend>(list_of_objects.size());
1337 else
1338 non_contiguous_out = std::make_shared<TensorList<Backend>>(list_of_objects.size());
1339

Callers

nothing calls this directly

Calls 15

CUDA_CALLFunction · 0.85
AccessOrderFunction · 0.85
GetFunction · 0.85
int_Function · 0.85
ToDALITypeFunction · 0.85
FillTensorFromDlPackFunction · 0.85
lengthMethod · 0.80
SetSampleMethod · 0.80
set_orderMethod · 0.80
set_pinnedMethod · 0.80

Tested by

no test coverage detected