Add a SWIG wrapper for the tensorflow::CancellationManager
class.
This change is a step towards supporting user-driven cancellation for eager function calls. In a future change, I plan to add an experimental method for calling a `tf.function` and passing a `CancellationManager` argument, so that the caller can cancel execution asynchronously. PiperOrigin-RevId: 256369003
This commit is contained in:
parent
c346c4cfb6
commit
987046e078
@ -541,3 +541,22 @@ TFE_MonitoringSamplerCell* TFE_MonitoringGetCellSampler2(
|
|||||||
return static_cast<TFE_MonitoringSamplerCell*>(
|
return static_cast<TFE_MonitoringSamplerCell*>(
|
||||||
static_cast<void*>(sampler->sampler->GetCell(label1, label2)));
|
static_cast<void*>(sampler->sampler->GetCell(label1, label2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TFE_CancellationManager* TFE_NewCancellationManager() {
|
||||||
|
return new TFE_CancellationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFE_CancellationManagerStartCancel(
|
||||||
|
TFE_CancellationManager* cancellation_manager) {
|
||||||
|
cancellation_manager->cancellation_manager.StartCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TFE_CancellationManagerIsCancelled(
|
||||||
|
TFE_CancellationManager* cancellation_manager) {
|
||||||
|
return cancellation_manager->cancellation_manager.IsCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFE_DeleteCancellationManager(
|
||||||
|
TFE_CancellationManager* cancellation_manager) {
|
||||||
|
delete cancellation_manager;
|
||||||
|
}
|
||||||
|
@ -343,6 +343,19 @@ TF_CAPI_EXPORT extern void TFE_ContextSetThreadLocalMirroringPolicy(
|
|||||||
// thread.
|
// thread.
|
||||||
TF_CAPI_EXPORT extern TFE_ContextMirroringPolicy TFE_ContextGetMirroringPolicy(
|
TF_CAPI_EXPORT extern TFE_ContextMirroringPolicy TFE_ContextGetMirroringPolicy(
|
||||||
TFE_Context*);
|
TFE_Context*);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Cancellation APIs.
|
||||||
|
|
||||||
|
typedef struct TFE_CancellationManager TFE_CancellationManager;
|
||||||
|
TF_CAPI_EXPORT extern TFE_CancellationManager* TFE_NewCancellationManager();
|
||||||
|
TF_CAPI_EXPORT extern bool TFE_CancellationManagerIsCancelled(
|
||||||
|
TFE_CancellationManager*);
|
||||||
|
TF_CAPI_EXPORT extern void TFE_CancellationManagerStartCancel(
|
||||||
|
TFE_CancellationManager*);
|
||||||
|
TF_CAPI_EXPORT extern void TFE_DeleteCancellationManager(
|
||||||
|
TFE_CancellationManager*);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end extern "C" */
|
} /* end extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -295,5 +295,13 @@ TEST(CAPI, MonitoringMultipleSampler) {
|
|||||||
TF_DeleteStatus(status);
|
TF_DeleteStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CAPI, CancellationManager) {
|
||||||
|
TFE_CancellationManager* c_mgr = TFE_NewCancellationManager();
|
||||||
|
EXPECT_FALSE(TFE_CancellationManagerIsCancelled(c_mgr));
|
||||||
|
TFE_CancellationManagerStartCancel(c_mgr);
|
||||||
|
EXPECT_TRUE(TFE_CancellationManagerIsCancelled(c_mgr));
|
||||||
|
TFE_DeleteCancellationManager(c_mgr);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tensorflow
|
} // namespace tensorflow
|
||||||
|
@ -36,6 +36,7 @@ limitations under the License.
|
|||||||
#include "tensorflow/core/common_runtime/eager/tensor_handle.h"
|
#include "tensorflow/core/common_runtime/eager/tensor_handle.h"
|
||||||
#include "tensorflow/core/common_runtime/function.h"
|
#include "tensorflow/core/common_runtime/function.h"
|
||||||
#include "tensorflow/core/common_runtime/rendezvous_mgr.h"
|
#include "tensorflow/core/common_runtime/rendezvous_mgr.h"
|
||||||
|
#include "tensorflow/core/framework/cancellation.h"
|
||||||
#include "tensorflow/core/framework/rendezvous.h"
|
#include "tensorflow/core/framework/rendezvous.h"
|
||||||
#include "tensorflow/core/lib/core/errors.h"
|
#include "tensorflow/core/lib/core/errors.h"
|
||||||
#include "tensorflow/core/lib/core/stringpiece.h"
|
#include "tensorflow/core/lib/core/stringpiece.h"
|
||||||
@ -295,4 +296,8 @@ struct TFE_TraceContext {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TFE_CancellationManager {
|
||||||
|
tensorflow::CancellationManager cancellation_manager;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // TENSORFLOW_C_EAGER_C_API_INTERNAL_H_
|
#endif // TENSORFLOW_C_EAGER_C_API_INTERNAL_H_
|
||||||
|
@ -84,6 +84,27 @@ py_library(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
py_library(
|
||||||
|
name = "cancellation",
|
||||||
|
srcs = ["cancellation.py"],
|
||||||
|
srcs_version = "PY2AND3",
|
||||||
|
visibility = ["//tensorflow:internal"],
|
||||||
|
deps = [
|
||||||
|
"//tensorflow/python:pywrap_tensorflow",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cuda_py_test(
|
||||||
|
name = "cancellation_test",
|
||||||
|
size = "small",
|
||||||
|
srcs = ["cancellation_test.py"],
|
||||||
|
additional_deps = [
|
||||||
|
":cancellation",
|
||||||
|
":test",
|
||||||
|
],
|
||||||
|
tags = ["no_pip"],
|
||||||
|
)
|
||||||
|
|
||||||
py_library(
|
py_library(
|
||||||
name = "context",
|
name = "context",
|
||||||
srcs = ["context.py"],
|
srcs = ["context.py"],
|
||||||
|
40
tensorflow/python/eager/cancellation.py
Normal file
40
tensorflow/python/eager/cancellation.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ==============================================================================
|
||||||
|
"""Cancellation support for eager execution."""
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from tensorflow.python import pywrap_tensorflow
|
||||||
|
|
||||||
|
|
||||||
|
class CancellationManager(object):
|
||||||
|
"""A mechanism for cancelling blocking computation."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._impl = pywrap_tensorflow.TFE_NewCancellationManager()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_cancelled(self):
|
||||||
|
"""Returns `True` if `CancellationManager.start_cancel` has been called."""
|
||||||
|
return pywrap_tensorflow.TFE_CancellationManagerIsCancelled(self._impl)
|
||||||
|
|
||||||
|
def start_cancel(self):
|
||||||
|
"""Cancels blocking operations that have been registered with this object."""
|
||||||
|
pywrap_tensorflow.TFE_CancellationManagerStartCancel(self._impl)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
pywrap_tensorflow.TFE_DeleteCancellationManager(self._impl)
|
34
tensorflow/python/eager/cancellation_test.py
Normal file
34
tensorflow/python/eager/cancellation_test.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from tensorflow.python.eager import cancellation
|
||||||
|
from tensorflow.python.platform import test
|
||||||
|
|
||||||
|
|
||||||
|
class CancellationTest(test.TestCase):
|
||||||
|
|
||||||
|
def testStartCancel(self):
|
||||||
|
manager = cancellation.CancellationManager()
|
||||||
|
self.assertFalse(manager.is_cancelled)
|
||||||
|
manager.start_cancel()
|
||||||
|
self.assertTrue(manager.is_cancelled)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test.main()
|
@ -159,6 +159,10 @@ limitations under the License.
|
|||||||
%rename("%s") TFE_MonitoringNewSampler2;
|
%rename("%s") TFE_MonitoringNewSampler2;
|
||||||
%rename("%s") TFE_MonitoringDeleteSampler2;
|
%rename("%s") TFE_MonitoringDeleteSampler2;
|
||||||
%rename("%s") TFE_MonitoringGetCellSampler2;
|
%rename("%s") TFE_MonitoringGetCellSampler2;
|
||||||
|
%rename("%s") TFE_NewCancellationManager;
|
||||||
|
%rename("%s") TFE_CancellationManagerIsCancelled;
|
||||||
|
%rename("%s") TFE_CancellationManagerStartCancel;
|
||||||
|
%rename("%s") TFE_DeleteCancellationManager;
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include "tensorflow/python/eager/pywrap_tfe.h"
|
#include "tensorflow/python/eager/pywrap_tfe.h"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user