MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / Compute

Method Compute

tensorflow/python/lib/core/py_func.cc:308–371  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

306 bool IsExpensive() override { return true; }
307
308 void Compute(OpKernelContext* ctx) override {
309 PyCall call;
310 call.token = token_;
311 call.eager = eager_;
312 if (call.eager) {
313 // Eager's C API uses `Device`, whereas `OpKernelContext` stores a
314 // `DeviceBase`; attempt to downcast.
315 call.device = dynamic_cast<Device*>(ctx->device());
316 if (call.device == nullptr) {
317 ctx->CtxFailureWithWarning(errors::Internal(
318 "Unrecognized device class: ", ctx->device()->name()));
319 return;
320 }
321 call.eager_async = eager_async_;
322 }
323
324 for (int i = 0; i < ctx->num_inputs(); ++i) {
325 call.ins.push_back(ctx->input(i));
326 }
327
328 // NOTE(mrry): There is a potential time-of-check-to-time-of-use race here.
329 // because it is possible that `Py_Finalize()` could be called in another
330 // thread between this check and the call to `PyGILState_Ensure()`, which
331 // will abort the process if `Py_Finalize()` has been called. A more robust
332 // solution would be welcome, but it is not obvious how to make this work
333 // using the current Python C API.
334 OP_REQUIRES(ctx, Py_IsInitialized(),
335 errors::FailedPrecondition(
336 "Python interpreter state is not initialized. "
337 "The process may be terminated."));
338
339 PyGILState_STATE py_threadstate;
340 py_threadstate = PyGILState_Ensure();
341 bool log_on_error;
342 Status s = DoCallPyFunc(&call, &log_on_error);
343 // Sometimes py_funcs can be called without a session and leak memory. This
344 // ensures we clear the decref cache so this doesn't happen.
345 ClearDecrefCache();
346 PyGILState_Release(py_threadstate);
347
348 // Ensures that GIL is released even when !s.ok().
349 if (!s.ok()) {
350 if (log_on_error) {
351 ctx->CtxFailureWithWarning(s);
352 } else {
353 ctx->CtxFailure(s);
354 }
355 return;
356 }
357
358 OP_REQUIRES(ctx, static_cast<int32>(call.out.size()) == ctx->num_outputs(),
359 errors::InvalidArgument(token_, " returns ", call.out.size(),
360 " values, but expects to see ",
361 ctx->num_outputs(), " values."));
362 for (size_t i = 0; i < call.out.size(); ++i) {
363 const auto& t = call.out[i];
364 OP_REQUIRES(
365 ctx, t.dtype() == output_type(i),

Callers

nothing calls this directly

Calls 15

InternalFunction · 0.85
FailedPreconditionFunction · 0.85
DoCallPyFuncFunction · 0.85
ClearDecrefCacheFunction · 0.85
InvalidArgumentFunction · 0.85
output_typeFunction · 0.85
nameMethod · 0.65
DataTypeStringFunction · 0.50
deviceMethod · 0.45
CtxFailureWithWarningMethod · 0.45
num_inputsMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected