tensorflow/compiler/xla/python/jax_jit.cc
// Returns nullptr if arg has no sticky device
Returns nullptr if arg has no sticky device
Returns nullptr if arg has no sticky device
static xla::StatusOr<xla::PjRtDevice*> GetJitArgumentStickyDevice(
    py::handle arg) {
  struct PythonTypes {
    py::object device_array;
  };
  static const auto& types = *[]() -> PythonTypes* {
    py::module xla_module(py::module::import("jax.interpreters.xla"));
    py::object device_array;
    if (py::hasattr(xla_module, "_DeviceArray")) {
      device_array = xla_module.attr("_DeviceArray");
    }
    return new PythonTypes{device_array};
  }();
  if (arg.get_type().ptr() == xla::PyBuffer::type()) {
    xla::PyBuffer* buffer = xla::PyBuffer::AsPyBufferUnchecked(arg);
    if (!buffer->sticky_device()) {
      return nullptr;
    }
    return buffer->sticky_device();
  }
  if (arg.get_type().ptr() == types.device_array.ptr()) {
    if (arg.attr("_device").is_none()) {
      return nullptr;
    }
    try {
      TF_ASSIGN_OR_RETURN(xla::PyBuffer * buffer,
                          xla::PyBuffer::AsPyBuffer(arg.attr("device_buffer")));
      return buffer->buffer()->device();
    } catch (const py::cast_error& e) {
      return xla::InvalidArgument(
          "%s", absl::StrCat("[jaxjit] Unsupported subclass of `DeviceArray`: "
                             "`device_buffer` field is of type ",
                             py::cast<std::string>(
                                 arg.attr("device_buffer").get_type().str()),
                             " while a `PyBuffer` was expected."));
    }
  }
  return nullptr;
}
static xla :: StatusOr < xla :: PjRtDevice * > GetJitArgumentStickyDevice ( py :: handle arg ) { struct PythonTypes { py :: object device_array ; } ; static const auto & types = * [ ] ( ) -> PythonTypes * { py :: module xla_module ( py :: module :: import ( " " ) ) ; py :: object device_array ; if ( py :: hasattr ( xla_module , " " ) ) { device_array = xla_module . attr ( " " ) ; } return new PythonTypes { device_array } ; } ( ) ; if ( arg . get_type ( ) . ptr ( ) == xla :: PyBuffer :: type ( ) ) { xla :: PyBuffer * buffer = xla :: PyBuffer :: AsPyBufferUnchecked ( arg ) ; if ( ! buffer -> sticky_device ( ) ) { return nullptr ; } return buffer -> sticky_device ( ) ; } if ( arg . get_type ( ) . ptr ( ) == types . device_array . ptr ( ) ) { if ( arg . attr ( " " ) . is_none ( ) ) { return nullptr ; } try { TF_ASSIGN_OR_RETURN ( xla :: PyBuffer * buffer , xla :: PyBuffer :: AsPyBuffer ( arg . attr ( " " ) ) ) ; return buffer -> buffer ( ) -> device ( ) ; } catch ( const py :: cast_error & e ) { return xla :: InvalidArgument ( " " , absl :: StrCat ( " " " " , py :: cast < std :: string > ( arg . attr ( " " ) . get_type ( ) . str ( ) ) , " " ) ) ; } } return nullptr ; }
Returns nullptr if arg has no sticky device
Returns nullptr if arg has no sticky device
// We specically only deal with DeviceArray (not ShardedDeviceArray). // (Can happen in jit(pmap), e.g. "test_jit_nested_donate_ignored"). // This can fail, e.g. for cloud TPU 2VM buffers.