Optimize (legacy, reference-typed) VariableOp::Compute().

The `cinfo_` member can be initialized at construction time, so there is no need to acquire a mutex in the `Compute()` method.

The changes in "ops_testutil.cc" update the test harness to use a non-deprecated method for creating kernels in C++ tests. The deprecated API did not set the resource manager in `OpKernelConstruction`.

Note that this op is still rather inefficient because it looks up the variable in the `ResourceMgr` every time it is invoked (for backwards compatibility reasons, relating to state invalidation via `Session::Reset()`). However, new code—and all TF2 code—should use resource variables, which avoid this codepath.

PiperOrigin-RevId: 303410876
Change-Id: I29e114bb863fe8a1f483d4ce1e034f5f13f1a116
This commit is contained in:
Derek Murray 2020-03-27 14:45:30 -07:00 committed by TensorFlower Gardener
parent 0a4a6893a8
commit 0c5bd2d4c7
3 changed files with 14 additions and 15 deletions

View File

@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/framework/node_properties.h"
#ifdef GOOGLE_CUDA
#define EIGEN_USE_GPU
#include "tensorflow/core/common_runtime/gpu/gpu_managed_allocator.h"
@ -137,11 +138,16 @@ Status OpsTestBase::InitOp() {
}
Status OpsTestBase::InitOpWithGraphVersion(int graph_def_version) {
Status status;
kernel_ = CreateOpKernel(device_type_, device_, allocator(), node_def_,
graph_def_version, &status);
if (kernel_ != nullptr) input_types_ = kernel_->input_types();
return status;
std::shared_ptr<const NodeProperties> props;
TF_RETURN_IF_ERROR(NodeProperties::CreateFromNodeDef(
node_def_, OpRegistry::Global(), &props));
OpKernel* kernel;
TF_RETURN_IF_ERROR(CreateOpKernel(
device_type_, device_, allocator(), /*flib=*/nullptr,
device_->resource_manager(), props, graph_def_version, &kernel));
kernel_.reset(kernel);
input_types_ = kernel_->input_types();
return Status::OK();
}
Status OpsTestBase::RunOpKernel() {

View File

@ -50,15 +50,11 @@ class LegacyVar : public ResourceBase {
VariableOp::VariableOp(OpKernelConstruction* context) : OpKernel(context) {
OP_REQUIRES_OK(context, context->GetAttr("shape", &shape_));
dtype_ = RemoveRefType(context->output_type(0));
OP_REQUIRES_OK(context, cinfo_.Init(context->resource_manager(), def(),
true /* use name() */));
}
void VariableOp::Compute(OpKernelContext* ctx) {
mutex_lock l(init_mu_);
if (!initialized_) {
OP_REQUIRES_OK(ctx, cinfo_.Init(ctx->resource_manager(), def(),
true /* use name() */));
initialized_ = true;
}
auto creator = [this](LegacyVar** var) {
*var = new LegacyVar(dtype_);
(*var)->tensor()->set_shape(shape_);

View File

@ -36,10 +36,7 @@ class VariableOp : public OpKernel {
private:
DataType dtype_;
TensorShape shape_;
mutex init_mu_;
ContainerInfo cinfo_ TF_GUARDED_BY(init_mu_);
bool initialized_ TF_GUARDED_BY(init_mu_){false};
ContainerInfo cinfo_;
TF_DISALLOW_COPY_AND_ASSIGN(VariableOp);
};