1 /* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #ifndef TENSORFLOW_CC_SAVED_MODEL_EXPERIMENTAL_PUBLIC_SIGNATURE_DEF_FUNCTION_H_
17 #define TENSORFLOW_CC_SAVED_MODEL_EXPERIMENTAL_PUBLIC_SIGNATURE_DEF_FUNCTION_H_
18
19 #include <vector>
20
21 #include "tensorflow/c/eager/c_api.h"
22 #include "tensorflow/c/experimental/saved_model/public/signature_def_function.h"
23 #include "tensorflow/cc/experimental/base/public/status.h"
24 #include "tensorflow/cc/saved_model/experimental/public/signature_def_function_metadata.h"
25
26 namespace tensorflow {
27 namespace experimental {
28 namespace cc {
29
30 // SignatureDefFunctions are functions that correspond to either:
31 // "signatures" saved from a TF2 SavedModel APIs:
32 // https://github.com/tensorflow/tensorflow/blob/8ce0600f58ed84a8c84a7bbdb014d1f09e44f4c8/tensorflow/python/saved_model/save.py#L830-L854
33 // Or the "SignatureDefMap" saved from TF1 SavedModel APIs:
34 // https://github.com/tensorflow/tensorflow/blob/8ce0600f58ed84a8c84a7bbdb014d1f09e44f4c8/tensorflow/python/saved_model/load_v1_in_v2_test.py#L170-L174
35 // In both cases, a SignatureDef is serialized as a SignatureDef protobuf:
36 // https://github.com/tensorflow/tensorflow/blob/8ce0600f58ed84a8c84a7bbdb014d1f09e44f4c8/tensorflow/core/protobuf/meta_graph.proto#L260-L330
37 // and represents a computation defined by a TF subgraph.
38 // These Signatures were primarily designed to be interoperable with the legacy
39 // TF 1 Session-based C++ SavedModelBundle loading APIs:
40 // https://github.com/tensorflow/tensorflow/blob/26c4ee0c833e74f94d0102d8b005c41a28b44445/tensorflow/cc/saved_model/loader.h#L96-L108
41 // SignatureDefFunctions have different semantics from regular TF2
42 // ConcreteFunctions, and are mainly intended provide a serving-friendly
43 // transition point from the TF1 Session API.
44 // First, SignatureDefFunctions have different calling conventions.
45 // SignatureDefFunctions' inputs and outputs are constrained to **flattened
46 // lists of TensorHandles only**. They do not support more exotic input/output
47 // types (like optionals, generators, etc). Additionally, this flattening means
48 // they will not preserve the exact interface of the original tf.function they
49 // were traced from, as things like composite tensors decay into their
50 // internal dense tensor representation.
51 // Second, all inputs and outputs are "named", and these names are load bearing
52 // (eg: they are part of the interface of tensorflow_serving):
53 // https://github.com/tensorflow/serving/blob/e0d247b2e4050713194b8fad0be24a0636df7209/tensorflow_serving/apis/predict.proto#L21
54 // https://github.com/tensorflow/serving/blob/e0d247b2e4050713194b8fad0be24a0636df7209/tensorflow_serving/apis/predict.proto#L39
55 // The name of each input/output is stored in the corresponding tf::Argument in
56 // SignatureDefFunctionMetadata::arguments(). Users must ensure the order of
57 // TensorHandles passed to the function matches with the order of named
58 // arguments. Similarly the name of the outputs is stored in
59 // SignatureDefFunctionMetadata::returns().
60 class SignatureDefFunction final {
61 public:
62 // Returns FunctionMetadata associated with this ConcreteFunction.
63 const SignatureDefFunctionMetadata* GetFunctionMetadata();
64
65 private:
66 friend class SavedModelAPI;
67 friend class ConcreteFunctionList;
68
69 // TODO(bmzhao): Consider adding a macro for wrapping/unwrapping
70 // when moving out of experimental.
wrap(TF_SignatureDefFunction * p)71 static SignatureDefFunction* wrap(TF_SignatureDefFunction* p) {
72 return reinterpret_cast<SignatureDefFunction*>(p);
73 }
unwrap(SignatureDefFunction * p)74 static TF_SignatureDefFunction* unwrap(SignatureDefFunction* p) {
75 return reinterpret_cast<TF_SignatureDefFunction*>(p);
76 }
77 };
78
79 inline const SignatureDefFunctionMetadata*
GetFunctionMetadata()80 SignatureDefFunction::GetFunctionMetadata() {
81 return SignatureDefFunctionMetadata::wrap(
82 TF_SignatureDefFunctionGetMetadata(unwrap(this)));
83 }
84
85 } // namespace cc
86 } // namespace experimental
87 } // namespace tensorflow
88
89 #endif // TENSORFLOW_CC_SAVED_MODEL_EXPERIMENTAL_PUBLIC_SIGNATURE_DEF_FUNCTION_H_
90