[tf.data] Cleaning up mobile build target.
PiperOrigin-RevId: 333597626 Change-Id: I63be2d4b736d7d1423c93999a0ac2184257eadb4
This commit is contained in:
parent
37d1693ad1
commit
a6fa27882d
@ -173,6 +173,7 @@ tf_kernel_library(
|
||||
"//tensorflow/core:core_cpu_internal",
|
||||
"//tensorflow/core:dataset_ops_op_lib",
|
||||
"//tensorflow/core:framework",
|
||||
"//tensorflow/core:lib_internal",
|
||||
"//tensorflow/core:protos_all_cc",
|
||||
"//tensorflow/core/grappler:graph_topology_view",
|
||||
"//tensorflow/core/grappler/utils:traversal",
|
||||
@ -540,6 +541,7 @@ tf_cc_test(
|
||||
tf_kernel_library(
|
||||
name = "model_dataset_op",
|
||||
srcs = ["model_dataset_op.cc"],
|
||||
hdrs = ["model_dataset_op.h"],
|
||||
deps = [
|
||||
"//tensorflow/core:core_cpu_internal",
|
||||
"//tensorflow/core:dataset_ops_op_lib",
|
||||
@ -1444,15 +1446,11 @@ filegroup(
|
||||
"*.h",
|
||||
],
|
||||
exclude = [
|
||||
"dataset_ops*", # includes grappler dependency, which isn't supported on mobile.
|
||||
"optimize_dataset_op.*", # includes grappler dependency, which isn't supported on mobile.
|
||||
"model_dataset_op.*", # not supported on mobile.
|
||||
"rewrite_utils*", # includes grappler dependency, which isn't supported on mobile.
|
||||
"dataset_test_base.*",
|
||||
"*test.cc",
|
||||
"*test.h",
|
||||
"*_test_*",
|
||||
],
|
||||
),
|
||||
visibility = ["//tensorflow:__subpackages__"],
|
||||
)
|
||||
|
||||
tf_kernel_library(
|
||||
|
@ -12,9 +12,11 @@ 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.
|
||||
==============================================================================*/
|
||||
|
||||
#include "tensorflow/core/kernels/data/dataset_ops.h"
|
||||
|
||||
// On mobile we do not provide this functionality because not all of its
|
||||
// dependencies are available there.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include "tensorflow/core/common_runtime/graph_constructor.h"
|
||||
#include "tensorflow/core/common_runtime/graph_runner.h"
|
||||
#include "tensorflow/core/common_runtime/process_function_library_runtime.h"
|
||||
@ -168,3 +170,4 @@ REGISTER_KERNEL_BUILDER(Name("DatasetFromGraph").Device(DEVICE_CPU),
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
@ -12,10 +12,14 @@ 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.
|
||||
==============================================================================*/
|
||||
|
||||
#ifndef TENSORFLOW_CORE_KERNELS_DATA_DATASET_OPS_H_
|
||||
#define TENSORFLOW_CORE_KERNELS_DATA_DATASET_OPS_H_
|
||||
|
||||
#include "tensorflow/core/platform/platform.h"
|
||||
|
||||
// On mobile we do not provide this functionality because not all of its
|
||||
// dependencies are available there.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
#include "tensorflow/core/framework/op_kernel.h"
|
||||
|
||||
@ -61,5 +65,6 @@ class DatasetFromGraphOp : public OpKernel {
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
||||
#endif // TENSORFLOW_CORE_KERNELS_DATA_DATASET_OPS_H_
|
||||
|
@ -12,7 +12,11 @@ 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.
|
||||
==============================================================================*/
|
||||
#include "tensorflow/core/kernels/data/model_dataset_op.h"
|
||||
|
||||
// On mobile we do not provide model dataset op because not all of its
|
||||
// dependencies are available there. The op is replaced with a no-op.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include "absl/memory/memory.h"
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
#include "tensorflow/core/framework/metrics.h"
|
||||
@ -32,269 +36,283 @@ constexpr int64 kOptimizationPeriodThresholdMs = 60 * EnvTime::kSecondsToMillis;
|
||||
// Default share of available RAM that can be used by model's internal buffers.
|
||||
constexpr double kRamBudgetShare = 0.5;
|
||||
|
||||
class ModelDatasetOp : public UnaryDatasetOpKernel {
|
||||
public:
|
||||
static constexpr const char* const kAlgorithm = "algorithm";
|
||||
static constexpr const char* const kCpuBudget = "cpu_budget";
|
||||
static constexpr const char* const kRamBudget = "ram_budget";
|
||||
} // namespace
|
||||
|
||||
explicit ModelDatasetOp(OpKernelConstruction* ctx)
|
||||
: UnaryDatasetOpKernel(ctx) {
|
||||
if (ctx->HasAttr(kAlgorithm)) {
|
||||
int64 algorithm;
|
||||
OP_REQUIRES_OK(ctx, ctx->GetAttr(kAlgorithm, &algorithm));
|
||||
algorithm_ = model::AutotuneAlgorithm(algorithm);
|
||||
} else {
|
||||
algorithm_ = model::AutotuneAlgorithm::HILL_CLIMB;
|
||||
}
|
||||
OP_REQUIRES_OK(ctx, ctx->GetAttr(kCpuBudget, &cpu_budget_));
|
||||
OP_REQUIRES(ctx, cpu_budget_ >= 0,
|
||||
errors::InvalidArgument("CPU budget must be positive but is ",
|
||||
cpu_budget_, "."));
|
||||
if (ctx->HasAttr(kRamBudget)) {
|
||||
OP_REQUIRES_OK(ctx, ctx->GetAttr(kRamBudget, &ram_budget_));
|
||||
} else {
|
||||
ram_budget_ = 0;
|
||||
}
|
||||
OP_REQUIRES(ctx, ram_budget_ >= 0,
|
||||
errors::InvalidArgument("RAM budget must be positive but is ",
|
||||
ram_budget_, "."));
|
||||
/* static */ constexpr const char* const ModelDatasetOp::kAlgorithm;
|
||||
/* static */ constexpr const char* const ModelDatasetOp::kCpuBudget;
|
||||
/* static */ constexpr const char* const ModelDatasetOp::kRamBudget;
|
||||
|
||||
class ModelDatasetOp::Dataset : public DatasetBase {
|
||||
public:
|
||||
Dataset(OpKernelContext* ctx, const DatasetBase* input,
|
||||
model::AutotuneAlgorithm algorithm, int64 cpu_budget,
|
||||
int64 ram_budget)
|
||||
: DatasetBase(DatasetContext(ctx)),
|
||||
input_(input),
|
||||
algorithm_(algorithm),
|
||||
cpu_budget_(cpu_budget),
|
||||
ram_budget_(ram_budget) {
|
||||
input_->Ref();
|
||||
}
|
||||
|
||||
void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) override {
|
||||
*output = new Dataset(ctx, input, algorithm_, cpu_budget_, ram_budget_);
|
||||
~Dataset() override { input_->Unref(); }
|
||||
|
||||
std::unique_ptr<IteratorBase> MakeIteratorInternal(
|
||||
const string& prefix) const override {
|
||||
return absl::make_unique<Iterator>(
|
||||
Iterator::Params{this, strings::StrCat(prefix, "::Model")});
|
||||
}
|
||||
|
||||
const DataTypeVector& output_dtypes() const override {
|
||||
return input_->output_dtypes();
|
||||
}
|
||||
const std::vector<PartialTensorShape>& output_shapes() const override {
|
||||
return input_->output_shapes();
|
||||
}
|
||||
|
||||
string DebugString() const override { return "ModelDatasetOp::Dataset"; }
|
||||
|
||||
int64 Cardinality() const override { return input_->Cardinality(); }
|
||||
|
||||
Status InputDatasets(std::vector<const DatasetBase*>* inputs) const override {
|
||||
inputs->push_back(input_);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status CheckExternalState() const override {
|
||||
return input_->CheckExternalState();
|
||||
}
|
||||
|
||||
protected:
|
||||
Status AsGraphDefInternal(SerializationContext* ctx,
|
||||
DatasetGraphDefBuilder* b,
|
||||
Node** output) const override {
|
||||
Node* input_graph_node = nullptr;
|
||||
TF_RETURN_IF_ERROR(b->AddInputDataset(ctx, input_, &input_graph_node));
|
||||
TF_RETURN_IF_ERROR(b->AddDataset(this, {input_graph_node}, output));
|
||||
AttrValue algorithm_attr;
|
||||
b->BuildAttrValue(static_cast<int64>(algorithm_), &algorithm_attr);
|
||||
AttrValue cpu_budget_attr;
|
||||
b->BuildAttrValue(cpu_budget_, &cpu_budget_attr);
|
||||
AttrValue ram_budget_attr;
|
||||
b->BuildAttrValue(ram_budget_, &ram_budget_attr);
|
||||
|
||||
TF_RETURN_IF_ERROR(
|
||||
b->AddDataset(this, {input_graph_node},
|
||||
{std::make_pair(kAlgorithm, algorithm_attr),
|
||||
std::make_pair(kCpuBudget, cpu_budget_attr),
|
||||
std::make_pair(kRamBudget, ram_budget_attr)},
|
||||
output));
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
private:
|
||||
class Dataset : public DatasetBase {
|
||||
class Iterator : public DatasetIterator<Dataset> {
|
||||
public:
|
||||
Dataset(OpKernelContext* ctx, const DatasetBase* input,
|
||||
model::AutotuneAlgorithm algorithm, int64 cpu_budget,
|
||||
int64 ram_budget)
|
||||
: DatasetBase(DatasetContext(ctx)),
|
||||
input_(input),
|
||||
algorithm_(algorithm),
|
||||
cpu_budget_(cpu_budget),
|
||||
ram_budget_(ram_budget) {
|
||||
input_->Ref();
|
||||
explicit Iterator(const Params& params)
|
||||
: DatasetIterator<Dataset>(params),
|
||||
cpu_budget_(dataset()->cpu_budget_ == 0 ? port::NumSchedulableCPUs()
|
||||
: dataset()->cpu_budget_),
|
||||
ram_budget_(dataset()->ram_budget_ == 0
|
||||
? kRamBudgetShare * port::AvailableRam()
|
||||
: dataset()->ram_budget_) {
|
||||
model_ = std::make_shared<model::Model>();
|
||||
}
|
||||
|
||||
~Dataset() override { input_->Unref(); }
|
||||
|
||||
std::unique_ptr<IteratorBase> MakeIteratorInternal(
|
||||
const string& prefix) const override {
|
||||
return absl::make_unique<Iterator>(
|
||||
Iterator::Params{this, strings::StrCat(prefix, "::Model")});
|
||||
~Iterator() override {
|
||||
// Signal the optimize thread to terminate it. We will then join that
|
||||
// thread when we delete `this->optimize_thread_`.
|
||||
mutex_lock l(mu_);
|
||||
cancelled_ = true;
|
||||
cond_var_.notify_all();
|
||||
}
|
||||
|
||||
const DataTypeVector& output_dtypes() const override {
|
||||
return input_->output_dtypes();
|
||||
}
|
||||
const std::vector<PartialTensorShape>& output_shapes() const override {
|
||||
return input_->output_shapes();
|
||||
Status Initialize(IteratorContext* ctx) override {
|
||||
IteratorContext::Params params(ctx);
|
||||
params.model = model_;
|
||||
return dataset()->input_->MakeIterator(IteratorContext(std::move(params)),
|
||||
this, prefix(), &input_impl_);
|
||||
}
|
||||
|
||||
string DebugString() const override { return "ModelDatasetOp::Dataset"; }
|
||||
|
||||
int64 Cardinality() const override { return input_->Cardinality(); }
|
||||
|
||||
Status InputDatasets(
|
||||
std::vector<const DatasetBase*>* inputs) const override {
|
||||
inputs->push_back(input_);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status CheckExternalState() const override {
|
||||
return input_->CheckExternalState();
|
||||
Status GetNextInternal(IteratorContext* ctx,
|
||||
std::vector<Tensor>* out_tensors,
|
||||
bool* end_of_sequence) override {
|
||||
IteratorContext::Params params(ctx);
|
||||
{
|
||||
mutex_lock l(mu_);
|
||||
TF_RETURN_IF_ERROR(EnsureOptimizeThreadStarted(ctx));
|
||||
params.model = model_;
|
||||
int64 now_nanos = EnvTime::NowNanos();
|
||||
RecordInput(now_nanos);
|
||||
}
|
||||
Status s = input_impl_->GetNext(IteratorContext(std::move(params)),
|
||||
out_tensors, end_of_sequence);
|
||||
int64 now_nanos = EnvTime::NowNanos();
|
||||
mutex_lock l(mu_);
|
||||
RecordOutput(now_nanos);
|
||||
return s;
|
||||
}
|
||||
|
||||
protected:
|
||||
Status AsGraphDefInternal(SerializationContext* ctx,
|
||||
DatasetGraphDefBuilder* b,
|
||||
Node** output) const override {
|
||||
Node* input_graph_node = nullptr;
|
||||
TF_RETURN_IF_ERROR(b->AddInputDataset(ctx, input_, &input_graph_node));
|
||||
TF_RETURN_IF_ERROR(b->AddDataset(this, {input_graph_node}, output));
|
||||
AttrValue algorithm_attr;
|
||||
b->BuildAttrValue(static_cast<int64>(algorithm_), &algorithm_attr);
|
||||
AttrValue cpu_budget_attr;
|
||||
b->BuildAttrValue(cpu_budget_, &cpu_budget_attr);
|
||||
AttrValue ram_budget_attr;
|
||||
b->BuildAttrValue(ram_budget_, &ram_budget_attr);
|
||||
std::shared_ptr<model::Node> CreateNode(
|
||||
IteratorContext* ctx, model::Node::Args args) const override {
|
||||
return model::MakeKnownRatioNode(std::move(args),
|
||||
/*ratio=*/1);
|
||||
}
|
||||
|
||||
TF_RETURN_IF_ERROR(
|
||||
b->AddDataset(this, {input_graph_node},
|
||||
{std::make_pair(kAlgorithm, algorithm_attr),
|
||||
std::make_pair(kCpuBudget, cpu_budget_attr),
|
||||
std::make_pair(kRamBudget, ram_budget_attr)},
|
||||
output));
|
||||
Status SaveInternal(SerializationContext* ctx,
|
||||
IteratorStateWriter* writer) override {
|
||||
mutex_lock l(mu_);
|
||||
TF_RETURN_IF_ERROR(SaveInput(ctx, writer, input_impl_));
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status RestoreInternal(IteratorContext* ctx,
|
||||
IteratorStateReader* reader) override {
|
||||
mutex_lock l(mu_);
|
||||
TF_RETURN_IF_ERROR(RestoreInput(ctx, reader, input_impl_));
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
private:
|
||||
class Iterator : public DatasetIterator<Dataset> {
|
||||
public:
|
||||
explicit Iterator(const Params& params)
|
||||
: DatasetIterator<Dataset>(params),
|
||||
cpu_budget_(dataset()->cpu_budget_ == 0 ? port::NumSchedulableCPUs()
|
||||
: dataset()->cpu_budget_),
|
||||
ram_budget_(dataset()->ram_budget_ == 0
|
||||
? kRamBudgetShare * port::AvailableRam()
|
||||
: dataset()->ram_budget_) {
|
||||
model_ = std::make_shared<model::Model>();
|
||||
Status EnsureOptimizeThreadStarted(IteratorContext* ctx)
|
||||
TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
||||
if (!model_thread_) {
|
||||
std::shared_ptr<IteratorContext> new_ctx =
|
||||
std::make_shared<IteratorContext>(*ctx);
|
||||
model_thread_ = ctx->StartThread(
|
||||
"tf_data_model", [this, new_ctx]() { ModelThread(new_ctx); });
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
~Iterator() override {
|
||||
// Signal the optimize thread to terminate it. We will then join that
|
||||
// thread when we delete `this->optimize_thread_`.
|
||||
mutex_lock l(mu_);
|
||||
cancelled_ = true;
|
||||
cond_var_.notify_all();
|
||||
}
|
||||
|
||||
Status Initialize(IteratorContext* ctx) override {
|
||||
IteratorContext::Params params(ctx);
|
||||
params.model = model_;
|
||||
return dataset()->input_->MakeIterator(
|
||||
IteratorContext(std::move(params)), this, prefix(), &input_impl_);
|
||||
}
|
||||
|
||||
Status GetNextInternal(IteratorContext* ctx,
|
||||
std::vector<Tensor>* out_tensors,
|
||||
bool* end_of_sequence) override {
|
||||
IteratorContext::Params params(ctx);
|
||||
void ModelThread(const std::shared_ptr<IteratorContext>& ctx) {
|
||||
int64 last_optimization_ms = 0;
|
||||
int64 optimization_period_ms = 10;
|
||||
int64 current_time_ms = EnvTime::NowMicros() / EnvTime::kMillisToMicros;
|
||||
while (true) {
|
||||
{
|
||||
mutex_lock l(mu_);
|
||||
TF_RETURN_IF_ERROR(EnsureOptimizeThreadStarted(ctx));
|
||||
params.model = model_;
|
||||
int64 now_nanos = EnvTime::NowNanos();
|
||||
RecordInput(now_nanos);
|
||||
}
|
||||
Status s = input_impl_->GetNext(IteratorContext(std::move(params)),
|
||||
out_tensors, end_of_sequence);
|
||||
int64 now_nanos = EnvTime::NowNanos();
|
||||
mutex_lock l(mu_);
|
||||
RecordOutput(now_nanos);
|
||||
return s;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<model::Node> CreateNode(
|
||||
IteratorContext* ctx, model::Node::Args args) const override {
|
||||
return model::MakeKnownRatioNode(std::move(args),
|
||||
/*ratio=*/1);
|
||||
}
|
||||
|
||||
Status SaveInternal(SerializationContext* ctx,
|
||||
IteratorStateWriter* writer) override {
|
||||
mutex_lock l(mu_);
|
||||
TF_RETURN_IF_ERROR(SaveInput(ctx, writer, input_impl_));
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status RestoreInternal(IteratorContext* ctx,
|
||||
IteratorStateReader* reader) override {
|
||||
mutex_lock l(mu_);
|
||||
TF_RETURN_IF_ERROR(RestoreInput(ctx, reader, input_impl_));
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
private:
|
||||
Status EnsureOptimizeThreadStarted(IteratorContext* ctx)
|
||||
TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
||||
if (!model_thread_) {
|
||||
std::shared_ptr<IteratorContext> new_ctx =
|
||||
std::make_shared<IteratorContext>(*ctx);
|
||||
model_thread_ = ctx->StartThread(
|
||||
"tf_data_model", [this, new_ctx]() { ModelThread(new_ctx); });
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
void ModelThread(const std::shared_ptr<IteratorContext>& ctx) {
|
||||
int64 last_optimization_ms = 0;
|
||||
int64 optimization_period_ms = 10;
|
||||
int64 current_time_ms = EnvTime::NowMicros() / EnvTime::kMillisToMicros;
|
||||
while (true) {
|
||||
{
|
||||
mutex_lock l(mu_);
|
||||
while (!cancelled_ &&
|
||||
last_optimization_ms + optimization_period_ms >
|
||||
current_time_ms) {
|
||||
auto wait_ms = last_optimization_ms + optimization_period_ms -
|
||||
current_time_ms;
|
||||
VLOG(2) << "Waiting for " << wait_ms << " ms.";
|
||||
cond_var_.wait_for(l, std::chrono::milliseconds(wait_ms));
|
||||
current_time_ms = EnvTime::NowMicros() / EnvTime::kMillisToMicros;
|
||||
}
|
||||
if (cancelled_) return;
|
||||
while (!cancelled_ && last_optimization_ms + optimization_period_ms >
|
||||
current_time_ms) {
|
||||
auto wait_ms =
|
||||
last_optimization_ms + optimization_period_ms - current_time_ms;
|
||||
VLOG(2) << "Waiting for " << wait_ms << " ms.";
|
||||
cond_var_.wait_for(l, std::chrono::milliseconds(wait_ms));
|
||||
current_time_ms = EnvTime::NowMicros() / EnvTime::kMillisToMicros;
|
||||
}
|
||||
double model_input_time;
|
||||
{
|
||||
tf_shared_lock l(mu_);
|
||||
model_input_time = SelfInputTime();
|
||||
}
|
||||
model_->Optimize(dataset()->algorithm_, cpu_budget_, ram_budget_,
|
||||
/*model_input_time=*/0);
|
||||
// Exponentially increase the period of running the optimization
|
||||
// until a threshold is reached.
|
||||
if (optimization_period_ms != kOptimizationPeriodThresholdMs) {
|
||||
optimization_period_ms = std::min(optimization_period_ms << 1,
|
||||
kOptimizationPeriodThresholdMs);
|
||||
}
|
||||
current_time_ms = EnvTime::NowMicros() / EnvTime::kMillisToMicros;
|
||||
last_optimization_ms = current_time_ms;
|
||||
model_->FlushMetrics();
|
||||
if (cancelled_) return;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordInput(int64 time_nanos) TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
||||
if (last_output_time_ != 0) {
|
||||
DCHECK_LE(last_output_time_, time_nanos);
|
||||
input_time_ += time_nanos - last_output_time_;
|
||||
num_input_events_++;
|
||||
double model_input_time;
|
||||
{
|
||||
tf_shared_lock l(mu_);
|
||||
model_input_time = SelfInputTime();
|
||||
}
|
||||
}
|
||||
|
||||
void RecordOutput(int64 time_nanos) TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
||||
last_output_time_ = time_nanos;
|
||||
}
|
||||
|
||||
double SelfInputTime() const TF_SHARED_LOCKS_REQUIRED(mu_) {
|
||||
if (num_input_events_ == 0) {
|
||||
return 0;
|
||||
model_->Optimize(dataset()->algorithm_, cpu_budget_, ram_budget_,
|
||||
/*model_input_time=*/0);
|
||||
// Exponentially increase the period of running the optimization
|
||||
// until a threshold is reached.
|
||||
if (optimization_period_ms != kOptimizationPeriodThresholdMs) {
|
||||
optimization_period_ms = std::min(optimization_period_ms << 1,
|
||||
kOptimizationPeriodThresholdMs);
|
||||
}
|
||||
return static_cast<double>(input_time_) /
|
||||
static_cast<double>(num_input_events_);
|
||||
current_time_ms = EnvTime::NowMicros() / EnvTime::kMillisToMicros;
|
||||
last_optimization_ms = current_time_ms;
|
||||
model_->FlushMetrics();
|
||||
}
|
||||
}
|
||||
|
||||
mutex mu_;
|
||||
condition_variable cond_var_;
|
||||
std::shared_ptr<model::Model> model_;
|
||||
std::unique_ptr<Thread> model_thread_ TF_GUARDED_BY(mu_);
|
||||
bool cancelled_ TF_GUARDED_BY(mu_) = false;
|
||||
std::unique_ptr<IteratorBase> input_impl_;
|
||||
int64 num_input_events_ TF_GUARDED_BY(mu_) = 0;
|
||||
int64 input_time_ TF_GUARDED_BY(mu_) = 0;
|
||||
int64 last_output_time_ TF_GUARDED_BY(mu_) = 0;
|
||||
const int64 cpu_budget_;
|
||||
const int64 ram_budget_;
|
||||
};
|
||||
void RecordInput(int64 time_nanos) TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
||||
if (last_output_time_ != 0) {
|
||||
DCHECK_LE(last_output_time_, time_nanos);
|
||||
input_time_ += time_nanos - last_output_time_;
|
||||
num_input_events_++;
|
||||
}
|
||||
}
|
||||
|
||||
const DatasetBase* input_;
|
||||
const model::AutotuneAlgorithm algorithm_;
|
||||
void RecordOutput(int64 time_nanos) TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
|
||||
last_output_time_ = time_nanos;
|
||||
}
|
||||
|
||||
double SelfInputTime() const TF_SHARED_LOCKS_REQUIRED(mu_) {
|
||||
if (num_input_events_ == 0) {
|
||||
return 0;
|
||||
}
|
||||
return static_cast<double>(input_time_) /
|
||||
static_cast<double>(num_input_events_);
|
||||
}
|
||||
|
||||
mutex mu_;
|
||||
condition_variable cond_var_;
|
||||
std::shared_ptr<model::Model> model_;
|
||||
std::unique_ptr<Thread> model_thread_ TF_GUARDED_BY(mu_);
|
||||
bool cancelled_ TF_GUARDED_BY(mu_) = false;
|
||||
std::unique_ptr<IteratorBase> input_impl_;
|
||||
int64 num_input_events_ TF_GUARDED_BY(mu_) = 0;
|
||||
int64 input_time_ TF_GUARDED_BY(mu_) = 0;
|
||||
int64 last_output_time_ TF_GUARDED_BY(mu_) = 0;
|
||||
const int64 cpu_budget_;
|
||||
const int64 ram_budget_;
|
||||
};
|
||||
|
||||
model::AutotuneAlgorithm algorithm_;
|
||||
int64 cpu_budget_;
|
||||
int64 ram_budget_;
|
||||
const DatasetBase* input_;
|
||||
const model::AutotuneAlgorithm algorithm_;
|
||||
const int64 cpu_budget_;
|
||||
const int64 ram_budget_;
|
||||
};
|
||||
|
||||
ModelDatasetOp::ModelDatasetOp(OpKernelConstruction* ctx)
|
||||
: UnaryDatasetOpKernel(ctx) {
|
||||
if (ctx->HasAttr(kAlgorithm)) {
|
||||
int64 algorithm;
|
||||
OP_REQUIRES_OK(ctx, ctx->GetAttr(kAlgorithm, &algorithm));
|
||||
algorithm_ = model::AutotuneAlgorithm(algorithm);
|
||||
} else {
|
||||
algorithm_ = model::AutotuneAlgorithm::HILL_CLIMB;
|
||||
}
|
||||
OP_REQUIRES_OK(ctx, ctx->GetAttr(kCpuBudget, &cpu_budget_));
|
||||
OP_REQUIRES(ctx, cpu_budget_ >= 0,
|
||||
errors::InvalidArgument("CPU budget must be positive but is ",
|
||||
cpu_budget_, "."));
|
||||
if (ctx->HasAttr(kRamBudget)) {
|
||||
OP_REQUIRES_OK(ctx, ctx->GetAttr(kRamBudget, &ram_budget_));
|
||||
} else {
|
||||
ram_budget_ = 0;
|
||||
}
|
||||
OP_REQUIRES(ctx, ram_budget_ >= 0,
|
||||
errors::InvalidArgument("RAM budget must be positive but is ",
|
||||
ram_budget_, "."));
|
||||
}
|
||||
|
||||
void ModelDatasetOp::MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) {
|
||||
*output = new ModelDatasetOp::Dataset(ctx, input, algorithm_, cpu_budget_,
|
||||
ram_budget_);
|
||||
}
|
||||
|
||||
namespace {
|
||||
REGISTER_KERNEL_BUILDER(Name("ModelDataset").Device(DEVICE_CPU),
|
||||
ModelDatasetOp);
|
||||
} // namespace
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#else // !IS_MOBILE_PLATFORM
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
ModelDatasetOp::ModelDatasetOp(OpKernelConstruction* ctx)
|
||||
: UnaryDatasetOpKernel(ctx) {}
|
||||
|
||||
void ModelDatasetOp::MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) {
|
||||
input->Ref();
|
||||
*output = input;
|
||||
}
|
||||
|
||||
namespace {
|
||||
REGISTER_KERNEL_BUILDER(Name("ModelDataset").Device(DEVICE_CPU),
|
||||
ModelDatasetOp);
|
||||
} // namespace
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
70
tensorflow/core/kernels/data/model_dataset_op.h
Normal file
70
tensorflow/core/kernels/data/model_dataset_op.h
Normal file
@ -0,0 +1,70 @@
|
||||
/* Copyright 2020 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.
|
||||
==============================================================================*/
|
||||
#ifndef TENSORFLOW_CORE_KERNELS_DATA_MODEL_DATASET_OP_H_
|
||||
#define TENSORFLOW_CORE_KERNELS_DATA_MODEL_DATASET_OP_H_
|
||||
|
||||
#include "tensorflow/core/platform/platform.h"
|
||||
|
||||
// On mobile we do not provide model dataset op because not all of its
|
||||
// dependencies are available there. The op is replaced with a no-op.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
#include "tensorflow/core/framework/model.h"
|
||||
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
class ModelDatasetOp : public UnaryDatasetOpKernel {
|
||||
public:
|
||||
static constexpr const char* const kAlgorithm = "algorithm";
|
||||
static constexpr const char* const kCpuBudget = "cpu_budget";
|
||||
static constexpr const char* const kRamBudget = "ram_budget";
|
||||
|
||||
explicit ModelDatasetOp(OpKernelConstruction* ctx);
|
||||
|
||||
protected:
|
||||
void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) override;
|
||||
|
||||
private:
|
||||
class Dataset;
|
||||
|
||||
model::AutotuneAlgorithm algorithm_;
|
||||
int64 cpu_budget_;
|
||||
int64 ram_budget_;
|
||||
};
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#else // !IS_MOBILE_PLATFORM
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
class ModelDatasetOp : public UnaryDatasetOpKernel {
|
||||
public:
|
||||
explicit ModelDatasetOp(OpKernelConstruction* ctx);
|
||||
|
||||
protected:
|
||||
void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) override;
|
||||
};
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
||||
#endif // TENSORFLOW_CORE_KERNELS_DATA_MODEL_DATASET_OP_H_
|
@ -1,37 +0,0 @@
|
||||
/* Copyright 2018 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.
|
||||
==============================================================================*/
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
class ModelDatasetOp : public UnaryDatasetOpKernel {
|
||||
public:
|
||||
explicit ModelDatasetOp(OpKernelConstruction* ctx)
|
||||
: UnaryDatasetOpKernel(ctx) {}
|
||||
|
||||
void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) {
|
||||
input->Ref();
|
||||
*output = input;
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
REGISTER_KERNEL_BUILDER(Name("ModelDataset").Device(DEVICE_CPU),
|
||||
ModelDatasetOp);
|
||||
} // namespace
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
@ -14,6 +14,9 @@ limitations under the License.
|
||||
==============================================================================*/
|
||||
#include "tensorflow/core/kernels/data/optimize_dataset_op.h"
|
||||
|
||||
// On mobile we do not provide optimize dataset op because not all of its
|
||||
// dependencies are available there. The op is replaced with a no-op.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include <map>
|
||||
|
||||
#include "tensorflow/core/framework/partial_tensor_shape.h"
|
||||
@ -27,9 +30,6 @@ limitations under the License.
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
// See documentation in ../../ops/dataset_ops.cc for a high-level
|
||||
// description of the following op.
|
||||
|
||||
/* static */ constexpr const char* const OptimizeDatasetOp::kDatasetType;
|
||||
/* static */ constexpr const char* const OptimizeDatasetOp::kInputDataset;
|
||||
/* static */ constexpr const char* const OptimizeDatasetOp::kOptimizations;
|
||||
@ -178,3 +178,25 @@ REGISTER_KERNEL_BUILDER(Name("OptimizeDatasetV2").Device(DEVICE_CPU),
|
||||
} // namespace
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#else // !IS_MOBILE_PLATFORM
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
OptimizeDatasetOp::OptimizeDatasetOp(OpKernelConstruction* ctx)
|
||||
: UnaryDatasetOpKernel(ctx) {}
|
||||
|
||||
void OptimizeDatasetOp::MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) {
|
||||
input->Ref();
|
||||
*output = input;
|
||||
}
|
||||
|
||||
namespace {
|
||||
REGISTER_KERNEL_BUILDER(Name("OptimizeDataset").Device(DEVICE_CPU),
|
||||
OptimizeDatasetOp);
|
||||
REGISTER_KERNEL_BUILDER(Name("OptimizeDatasetV2").Device(DEVICE_CPU),
|
||||
OptimizeDatasetOp);
|
||||
} // namespace
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
@ -15,6 +15,11 @@ limitations under the License.
|
||||
#ifndef TENSORFLOW_CORE_KERNELS_DATA_OPTIMIZE_DATASET_OP_H_
|
||||
#define TENSORFLOW_CORE_KERNELS_DATA_OPTIMIZE_DATASET_OP_H_
|
||||
|
||||
#include "tensorflow/core/platform/platform.h"
|
||||
|
||||
// On mobile we do not provide optimize dataset op because not all of its
|
||||
// dependencies are available there. The op is replaced with a no-op.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
|
||||
namespace tensorflow {
|
||||
@ -54,5 +59,23 @@ class OptimizeDatasetOp : public UnaryDatasetOpKernel {
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#else // !IS_MOBILE_PLATFORM
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
class OptimizeDatasetOp : public UnaryDatasetOpKernel {
|
||||
public:
|
||||
explicit OptimizeDatasetOp(OpKernelConstruction* ctx);
|
||||
|
||||
protected:
|
||||
void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) override;
|
||||
};
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
||||
#endif // TENSORFLOW_CORE_KERNELS_DATA_OPTIMIZE_DATASET_OP_H_
|
||||
|
@ -1,39 +0,0 @@
|
||||
/* Copyright 2018 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.
|
||||
==============================================================================*/
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
|
||||
namespace tensorflow {
|
||||
namespace data {
|
||||
|
||||
class OptimizeDatasetOp : public UnaryDatasetOpKernel {
|
||||
public:
|
||||
explicit OptimizeDatasetOp(OpKernelConstruction* ctx)
|
||||
: UnaryDatasetOpKernel(ctx) {}
|
||||
|
||||
void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
|
||||
DatasetBase** output) {
|
||||
input->Ref();
|
||||
*output = input;
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
REGISTER_KERNEL_BUILDER(Name("OptimizeDataset").Device(DEVICE_CPU),
|
||||
OptimizeDatasetOp);
|
||||
REGISTER_KERNEL_BUILDER(Name("OptimizeDatasetV2").Device(DEVICE_CPU),
|
||||
OptimizeDatasetOp);
|
||||
} // namespace
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
@ -12,9 +12,11 @@ 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.
|
||||
==============================================================================*/
|
||||
|
||||
#include "tensorflow/core/kernels/data/rewrite_utils.h"
|
||||
|
||||
// On mobile we do not provide this functionality because not all of its
|
||||
// dependencies are available there.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include "tensorflow/core/common_runtime/graph_constructor.h"
|
||||
#include "tensorflow/core/common_runtime/graph_runner.h"
|
||||
#include "tensorflow/core/common_runtime/metrics.h"
|
||||
@ -222,3 +224,4 @@ Status RewriteDataset(OpKernelContext* ctx, const DatasetBase* input,
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
@ -15,6 +15,11 @@ limitations under the License.
|
||||
#ifndef TENSORFLOW_CORE_KERNELS_DATA_REWRITE_UTILS_H_
|
||||
#define TENSORFLOW_CORE_KERNELS_DATA_REWRITE_UTILS_H_
|
||||
|
||||
#include "tensorflow/core/platform/platform.h"
|
||||
|
||||
// On mobile we do not provide this functionality because not all of its
|
||||
// dependencies are available there.
|
||||
#if !defined(IS_MOBILE_PLATFORM)
|
||||
#include "tensorflow/core/common_runtime/function.h"
|
||||
#include "tensorflow/core/framework/dataset.h"
|
||||
#include "tensorflow/core/framework/function.h"
|
||||
@ -31,5 +36,6 @@ Status RewriteDataset(OpKernelContext* ctx, const DatasetBase* input,
|
||||
|
||||
} // namespace data
|
||||
} // namespace tensorflow
|
||||
#endif // !IS_MOBILE_PLATFORM
|
||||
|
||||
#endif // TENSORFLOW_CORE_KERNELS_DATA_REWRITE_UTILS_H_
|
||||
|
Loading…
x
Reference in New Issue
Block a user