{"record":{"id":"59b53dc2c39d4660","repo":"jax-ml/jax","slug":"specified-device-which-requires-a-copy-since-th","errorCode":null,"errorMessage":"Specified {device=} which requires a copy since the source device is {repr(src_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":70,"sourceCode":"\ndef is_supported_dtype(dtype: DTypeLike) -> bool:\n  \"\"\"Check if dtype is supported by jax.dlpack.\"\"\"\n  if dtype is None:\n    # NumPy will silently cast this to float64, which may be surprising.\n    raise TypeError(f\"Expected a string or dtype-like object; got {dtype=}\")\n  return np.dtype(dtype) in SUPPORTED_DTYPES_SET\n\n\ndef _to_dlpack(x: Array, stream: int | Any | None,\n               src_device: _jax.Device | None = None,\n               device: _jax.Device | None = None,\n               copy: bool | None = None):\n\n  if src_device is None:\n    src_device, = x.devices()\n  if device and (src_device is None or device != src_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(src_device)}, however copy=False. Set copy=True or \"\n        \"copy=None to perform the requested operation.\"\n      )\n    else:\n      arr = device_put(x, device)\n  else:\n    arr = _array_copy(x) if copy else x\n  return _jax.buffer_to_dlpack_managed_tensor(\n    arr.addressable_data(0), stream=stream\n  )\n\n\n_DL_DEVICE_TO_PLATFORM = {\n    DLDeviceType.kDLCPU: \"cpu\",\n    DLDeviceType.kDLCUDA: \"cuda\",\n    DLDeviceType.kDLCUDAHost: \"cuda\",\n    DLDeviceType.kDLROCM: \"rocm\",","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/dlpack.py#L52-L88","documentation":"to_dlpack was asked to place the resulting DLPack buffer on a device different from the array's source device, which requires a copy, but copy=False forbids copies.","triggerScenarios":"Calling jax.dlpack.to_dlpack(x, device=other_device, copy=False) where other_device != x.devices()[0].","commonSituations":"Zero-copy interop with PyTorch/TensorFlow where the target GPU differs from the JAX array's GPU; multi-GPU pipelines assuming cross-device zero-copy is possible.","solutions":["Set copy=True (or copy=None, the default, which copies only when needed)","First move the array with jax.device_put(x, device) and then to_dlpack with matching device","Omit the device argument if you want the buffer on the array's current device"],"exampleFix":"# before\njax.dlpack.to_dlpack(x, device=dev1, copy=False)\n\n# after\njax.dlpack.to_dlpack(x, device=dev1, copy=True)","handlingStrategy":"validation","validationCode":"src, = x.devices()\nif device is not None and device != src:\n    assert copy is not False, 'copy=False with cross-device target'","typeGuard":null,"tryCatchPattern":"try:\n    jax.dlpack.to_dlpack(x, device=dev, copy=copy)\nexcept ValueError:\n    jax.dlpack.to_dlpack(x, device=dev, copy=True)","preventionTips":["Use copy=None (default) unless zero-copy is proven","Move arrays with device_put 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"}