{"record":{"id":"23375c2eef5430ef","repo":"jax-ml/jax","slug":"specified-device-which-requires-a-copy-since-th-23375c","errorCode":null,"errorMessage":"Specified {device=} which requires a copy since the source device is {repr(dlpack_device)}, however copy=False. Set copy=True or copy=None to perform the requested operation.","messagePattern":"Specified (.+?) which requires a copy since the source device is (.+?), however copy=False\\. Set copy=True or copy=None to perform the requested operation\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/dlpack.py","lineNumber":180,"sourceCode":"    )\n  elif max_version >= MIN_DLPACK_VERSION:\n    # Oldest supported\n    return _to_dlpack(\n      x, stream=stream,\n      src_device=src_device,\n      device=device,\n      copy=copy\n    )\n  else:\n    raise BufferError(\n      f\"JAX does not support any version below {MIN_DLPACK_VERSION} but \"\n      f\"version ({max_version}) was requested.\"\n    )\n\ndef _check_device(device, dlpack_device, copy):\n  if device and dlpack_device != device:\n    if copy is not None and not copy:\n      raise ValueError(\n        f\"Specified {device=} which requires a copy since the source device \"\n        f\"is {repr(dlpack_device)}, however copy=False. Set copy=True or \"\n        \"copy=None to perform the requested operation.\"\n      )\n\ndef _place_array(_arr, device, dlpack_device, copy):\n  if device and dlpack_device != device:\n    return device_put(_arr, device)\n  if copy:\n    return jnp.array(_arr, copy=True)\n  return _arr\n\ndef _is_tensorflow_tensor(external_array):\n  t = type(external_array)\n  return (\n      t.__qualname__ == \"EagerTensor\"\n      and t.__module__.endswith(\"tensorflow.python.framework.ops\")\n  )","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/dlpack.py#L162-L198","documentation":"In from_dlpack, the caller specified a target device that differs from the DLPack buffer's device; producing the array there requires a copy, but copy=False forbids it.","triggerScenarios":"jax.dlpack.from_dlpack(external, device=dev, copy=False) where dev != the external buffer's device reported by __dlpack_device__.","commonSituations":"Moving torch tensors from GPU 0 to a JAX array on GPU 1, or CPU->GPU, with zero-copy assumed in a multi-GPU training pipeline.","solutions":["Set copy=True or copy=None to allow the transfer","Use the external library to move the buffer first (e.g. tensor.to(device)) then from_dlpack with matching device","Omit device to keep the array on the buffer's device and move later with jax.device_put"],"exampleFix":"# before\njax.dlpack.from_dlpack(t, device=jax.devices('gpu')[1], copy=False)\n\n# after\njax.dlpack.from_dlpack(t, device=jax.devices('gpu')[1], copy=True)","handlingStrategy":"validation","validationCode":"dl_dev = external.__dlpack_device__()  # compare via backend if needed\nif device is not None and copy is False:\n    # ensure device matches source, else allow copy\n    copy = None","typeGuard":null,"tryCatchPattern":"try:\n    jax.dlpack.from_dlpack(t, device=dev, copy=False)\nexcept ValueError:\n    jax.dlpack.from_dlpack(t, device=dev, copy=True)","preventionTips":["Default copy=None in wrappers","Move source tensors in the source framework before interop"],"tags":["jax","dlpack","device-mismatch","copy"],"backgroundTag":"cross-device-zero-copy","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}