Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Modular TensorFlow Graph C API #318

Merged
merged 11 commits into from
Dec 10, 2020

Conversation

Solaryee
Copy link
Contributor

@Solaryee Solaryee commented Oct 27, 2020

This RFC will be open for comment until Wednesday, Nov 18th, 2020.

Modular TensorFlow Graph C API

Status Proposed
RFC # 318
Author(s) Yang Sheng ([email protected]), Zhoulong Jiang ([email protected]), Yiqiang Li ([email protected]), Eric Lin ([email protected]), Jianhui Li ([email protected])
Sponsor Eugene Zhulenev ([email protected])
Updated 2020-10-27

Objective

TensorFlow currently provides a C++ API for registering a custom graph optimizer in Grappler. This project aims to create a modular/plugin-based TensorFlow implementation with C APIs. Plugins will be able to register custom graph optimizers. Users only need to install the plugin in a specified directory, and the mechanism is able to discover and plug in the capabilities offered by the plugin.

This RFC is based on the Modular TensorFlow RFC, which aims at extending the TensorFlow design to plug in capabilities like adding a new graph optimizer.

Copy link

@eric-haibin-lin eric-haibin-lin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the proposal. Would this RFC also enable custom XLA pass plugins, or is mainly targeting TF graph?

@ematejska ematejska added the RFC: Proposed RFC Design Document label Nov 2, 2020
@Solaryee
Copy link
Contributor Author

Solaryee commented Nov 3, 2020

Thanks for the proposal. Would this RFC also enable custom XLA pass plugins, or is mainly targeting TF graph?

Hi, @eric-haibin-lin , XLA pass is not included in this RFC, it is mainly targeting TF graph.

@eric-haibin-lin
Copy link

thanks for the reply!

@google-cla
Copy link

google-cla bot commented Nov 5, 2020

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added cla: no and removed cla: yes labels Nov 5, 2020
@penpornk
Copy link
Member

penpornk commented Nov 5, 2020

There will be a public design review meeting for this RFC.
Time: Thursday, November 19th, 2020 from 3:00-4:00pm PT
Meeting link: Google Meet

Meeting participants are expected to read the RFC ahead of time as the meeting will focus on the remaining issues/questions.

@Solaryee
Copy link
Contributor Author

Solaryee commented Nov 5, 2020

@googlebot I fixed it.

@google-cla
Copy link

google-cla bot commented Nov 5, 2020

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@Solaryee Solaryee force-pushed the yang/pluggable-graph branch from f12c89a to 639e1dc Compare November 5, 2020 00:52
@google-cla google-cla bot added cla: yes and removed cla: no labels Nov 5, 2020

### Struct/Function/Object Overview
- Struct
- Struct that should be filled by the plugin: `P_OptimizerConfigFns`, `P_RegistrationParams`, `TF_OptimizerBuilder`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does P_ prefix mean that the struct should be filled by the plugin? I am thinking if TP_ prefix would be better here (that might match what we do for StreamExecutor C API better where we have SP and SE prefixes).

Also, should TF_OptimizerBuilder be (T)P_OptimizerBuilder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I have already changed those names.


Graph [Optimize](https://github.com/tensorflow/tensorflow/blob/r2.3/tensorflow/core/grappler/optimizers/graph_optimizer.h#L58) function is the main part that plugin authors need to implement. The C API looks like below. Both input and output graphs are represented by serialized `TF_Buffer` objects:
```cpp
void P_Optimize(void* optimizer, TF_Buffer* graph_buf, TF_Buffer* optimized_graph_buf, TF_Status* s);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have a struct for optimizer instead of void*? I am wondering if there would be some properties we would want to pass in the future.

Copy link
Contributor Author

@Solaryee Solaryee Nov 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mechanism is following Compute function in kernel C API. Here void* optimizer is a struct defined in plugin and created in P_Create function, it only contains some members that are used in plugin.

I am wondering if there would be some properties we would want to pass in the future.

I guess what you referred is TP_OptimizerBuilder. Previously it is a function call with fixed param, but just as you mentioned, making it as a struct would be more flexible. Currently only create/delete/optimize is included since these are most useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have already changed and updated the RFC.


Plugin:
```cpp
Status P_MessageToBuffer(const plugin::protobuf::MessageLite& in, TF_Buffer* out);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to make sure, P_MessageToBuffer and P_BufferToMessage are not a part of the API surface, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I think the name needs to be changed, they are confusing, maybe "plugin::MessageToBuffer" is more clear. I will clarify it in RFC.


void TF_InitGraphPlugin(P_RegistrationParams* params, TF_Status* status) {
// Plugin authors can turn on/off some optimizers.
params.config_fns.get_remapping = get_remapping;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these be TF_Bool fields instead of functions that return TF_Bool? Is there a reason that makes a function better in this case?

Copy link
Contributor Author

@Solaryee Solaryee Nov 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It optional for plugin users to set these configurations. It not set, function ptr here is a nullptr, then it will use default value defined in rewrite_config.proto. TF_Bool can not represent default value.


* **Configuring existing optimizers**

If pluggable graph optimizer is registered to a device type, e.g., GPU, its optional for plugin authors to provide a recommended configuration indicate whether some of existing optimizers in proper can be turned on/off, by populating flags in `P_RegistrationParams`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would existing optimizer configuration also be per-device-type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, plugin authors should register the optimizer along with device_type and configuration, and only one optimizer and configuration is allowed for each device type.

Making TP_OptimizerBuilder as a struct.
@Solaryee Solaryee force-pushed the yang/pluggable-graph branch 2 times, most recently from c0b0e7f to 0cfdfd7 Compare November 19, 2020 08:11
@Solaryee Solaryee force-pushed the yang/pluggable-graph branch from 0cfdfd7 to 302e0ac Compare November 19, 2020 08:37
@ezhulenev
Copy link
Member

only one optimizer is allowed to be registered per device type

What does it mean optimizer per device in practice? Grappler meta-optimizer runs on graphs that could be placed on multiple devices at the same time.

@ezhulenev
Copy link
Member

/cc @kulinseth and Alex, regarding TF dialect question raised during the meeting. I guess we can do something similar to https://github.com/tensorflow/mlir-hlo to pull TF dialect out of the TF repo, but this will be trickier because it unfortunately has dependencies (not much) on tensorflow core.

You probably can get a more informed answer in this group: https://groups.google.com/a/tensorflow.org/g/mlir

@penpornk
Copy link
Member

penpornk commented Nov 21, 2020

Design review meeting notes

@annarev: Should structs populated by plug-in be prefixed with TP_ instead of just P, to be consistent with StreamExecutor C API? (Original comment)
@ShengYang1: Yes. Changed the names.

@annarev: Should the void* optimizer parameter to P_Optimize be a struct? (Original comment)
@ShengYang1: Yes, it is a struct, following the Compute function in the kernel C API RFC.

// Struct for Optimizer. Plugin authors must provide an optimize function.
// Creation and deletion functions are optional.
typedef struct TP_Optimizer {
  size_t struct_size;
  void* ext;  // reserved for future use
  void* (*create_func)();
  void (*optimize_func)(void*, TF_Buffer*, TF_Buffer*);
  void (*destory_func)(void*);
} TP_Optimizer;

@kulinseth: Is the format for 'tf' dialect in the buffer TBD?
We have a graph optimizer pass that is already using MLIR. Do we have to go through GraphDef for this?
@aselle: MLIR is out of the scope of this RFC.
@rmlarsen: This is for GraphDef only. MLIR needs a separate effort.
@ematejska: How much migration effort would it take to move to MLIR-based graph optimizer?
@Jianhui-Li: Our optimizer mostly identifies a group of ops to fuse into one large op. We expect to make appropriate changes to match the new interface, but the optimizations should stay the same.
@ematejska: So we don’t know yet.
@aselle: Protobufs are ABI-compatible. In theory, it’s possible to create some abstractions on top of both GraphDef and tf dialect, but the benefits from doing so are dubious.
@rmlarsen: Could redefine TF_Buffer.
@sanjoy: If you only care about fusing small ops to a bigger op, we could create some other simpler representation as well.
@aselle: We could do this completely descriptively. But it often ended up messy in practice, with op attributes and other things.
@Jianhui-Li: We need a more flexible way. For example, depending on the accelerator type, we might want to offload a bigger chunk of ops.
@sanjoy: Rules should be able to handle attributes too, right?
@aselle: In principle, yes. This is similar to TFLite delegates where we write functions that take a graph, find a particular sequence of ops, and represent them in some other ways. The problem was when delegate writers assumed they could handle something, but did not cover it completely.
@ematejska: There could be a problem with new attributes too.
@aselle: Yes. Backward compatibility doesn’t prevent this from failing when there is a new attribute.
@penpornk: Optimizers could also want shape inferences too.

@aselle: Are there any version compatibility requirements for Grappler?
@rmlarsen: The C++ API surface has been stable for years. The graph optimization passes order changes over time. But these have never caused any churn so far.
@penpornk: The area that could have versioning problems is the ops themselves.
@rmlarsen: Yes, for example, op foo has a v2, causing Grappler and XLA to no longer work.
It’s up to the plug-in authors to track and handle this.

@annarev: P_MessageToBuffer and P_BufferToMessage are not a part of the API surface, correct? (Original comment)
@ShengYang1: Yes, they are not part of the API surface.

@annarev: Can the configurations in TP_OptimizerConfigFns be TF_Bools instead of functions that return TF_Bool?
@ShengYang1: There are three possible values: true, false, and default. TF_Bool cannot represent default value.
@sanjoy: Can we just use a tristate?
@rmlarsen: Agreed. Explicit tristates are nicer than functions.
@yiqianglee: We can try that.

@annarev: Would existing optimizer configuration also be per-device-type? (Original comment)
@ShengYang1: Yes.

@ezhulenev: What does it mean to have an optimizer per a device in practice? (Original comment)
@ShengYang1: Each PluggableDevice can register its own graph optimizer. We can also register a graph optimizer without registering a PluggableDevice with it. But a PluggableDevice cannot register multiple graph optimizers.
@ezhulenev: So if there are custom passes for “CPU”, “GPU”, and “XPU”, all three passes will be run after the main Grappler passes in a random order?
@yiqianglee: Yes.

@sanjoy: Why do you have to tie a graph optimization pass to a PluggableDevice?
@yiqianglee: Pairing each PluggableDevice with its own optimizer makes it easier to limit the scope of graph transformation to the device.
@sanjoy: Even with them tied together, we’d still need to trust the plug-in to some extent.
@ezhulenev: One benefit with this approach is that you can just skip the pass if you don’t have the corresponding PluggableDevice.
@sanjoy: You could also skip the serialization/deserialization if there are no PluggableDevices loaded.
@rmlarsen: In multiple session.run() calls where some don’t contain plug-in code, we can avoid the serialization.

@ezhulenev: What about optimizer plug-ins with conflicting configurations?
@yiqianglee: This is what we would like to get feedback from here.
@ezhulenev: Remapper only fuses ops placed on CPU and GPU. So it shouldn’t touch anything on those PluggableDevices in practice (unless they are registered as “GPU”).
@rmlarsen: We could do logical AND, i.e., don’t run a pass if at least one plug-in set enable=false for that pass.
@Jianhui-Li: We could also make plug-ins only able to turn a pass off (and not on). To turn on a pass that has previously been disabled, the user needs to make changes on the TensorFlow side.
@rmlarsen: Turning Grappler passes off could have negative performance implications.
@penpornk: How about plug-ins print warnings whenever a pass is disabled?
@Jianhui-Li: Printing could help.
@rmlarsen: Each plug-in should also run a set of performance benchmarks to verify that the pass(es) it is disabling wouldn’t have too much effect.
@penpornk: What if different plug-ins disable different passes? Each of them turns off only one pass and passes the performance benchmarks, but together, they disable too many passes and then everything is slow.
@ezhulenev: We could still run with remapper turned on for non-CPU/GPU device types.
@rmlarsen: Will need to add logic in the MetaOptimizer.

@kulinseth: Is the order of these plug-in passes towards the end of all Grappler passes?
@ShengYang1: Yes.

@annarev: Should max_values in TF_GetNodesToPreserveSize be num_values? (Original comment)
@ShengYang1: Yes.

@annarev: What does preserved nodes mean in the context of TF_GetNodesToPreserveSize? (Original comment)
@ShengYang1: It means nodes that cannot be transformed/removed. Will add more details.

@kulinseth: Quick question. For custom ops that are exposed through an op kernel library and are visible in the TensorFlow namespace, would they work with the plug-in passes?
@annarev: Yes. The plug-in should be able to see the op names in the GraphDef.

Alexandre Rames: Maybe this is not the right venue for the question. I’d like to learn more about the visibility of the tf dialect. Can plug-ins see it? Or is it only visible in TensorFlow?
For example, if plug-ins want to work on the MLIR tf dialect directly. We have partial lowerings to some other dialects.
@kulinseth: This is consistent with what we want.
@ezhulenev: We want to make tf dialect visible to plug-ins too. It’s just no one has looked at it yet. And, as of now, I don’t know how it will be done. Could you write an email explaining the requirements? We can start from there.

@ematejska: The RFC should be updated to reflect the conclusions on conflicting plug-in optimizer configurations. After that, we will see if we can conclude the RFC on the PR or if we will need another design review meeting.

@kulinseth
Copy link
Contributor

kulinseth commented Nov 21, 2020

/cc @kulinseth and Alex, regarding TF dialect question raised during the meeting. I guess we can do something similar to https://github.com/tensorflow/mlir-hlo to pull TF dialect out of the TF repo, but this will be trickier because it unfortunately has dependencies (not much) on tensorflow core.

@ezhulenev Thanks! for the pointer, much appreciated. Looks like this would be a good template to start with. Like you said as we dig into details we will know if the dependencies can be resolved.

You probably can get a more informed answer in this group: https://groups.google.com/a/tensorflow.org/g/mlir

@sanjoy
Copy link
Contributor

sanjoy commented Nov 21, 2020

CC @joker-eph @jpienaar

@Solaryee Solaryee force-pushed the yang/pluggable-graph branch 2 times, most recently from f20edd5 to d068e2f Compare November 23, 2020 09:02
@Solaryee Solaryee force-pushed the yang/pluggable-graph branch from d068e2f to 444b95f Compare November 23, 2020 09:20
@Solaryee
Copy link
Contributor Author

cc: @penpornk @ezhulenev @kulinseth @annarev @aselle @rmlarsen @ematejska @Jianhui-Li @ematejska @sanjoy
Hi all,
Here are some updates after the review meeting:

  • Update C API comments with more details. (Original comment)
  • Define a new enum TF_TriStates to represent true/false/default value.
  • Add some clarifications on conflicting optimizer configurations in a table.

Please review.

@mihaimaruseac
Copy link
Contributor

mihaimaruseac commented Dec 1, 2020

There will be a design meeting for this on 15th of December at 10 am Pacific.

If you want to join, here is the Meet link

Apologies: above comment should have been for a different RFC.

@mihaimaruseac
Copy link
Contributor

There will be a design meeting for this on 15th of December at 10 am Pacific.

If you want to join, here is the Meet link

The above should have been posted to a different RFC. Apologies for the confusion

Copy link
Member

@penpornk penpornk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ShengYang1 Thank you for the changes and sorry for the delay! I took a quick look and have minor comments. The rest seems fine to me.

void* ext; // reserved for future use
void* (*create_func)();
void (*optimize_func)(void*, TF_Buffer*, TF_Buffer*);
void (*destory_func)(void*);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo:

Suggested change
void (*destory_func)(void*);
void (*destroy_func)(void*);

Same as other places (there are a few other "destory"s).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review. All comments have been addressed.

|:-------------- |:-------------- |:-------------- |:-------------- |:-------------- |
| ON | ON/DEFAULT | ON/DEFAULT | **ON**| The optimizer is enabled. |
| ON | OFF | OFF | **OFF**| The optimizer is disabled, unless users manually unload the plugin. Grappler prints warnings to remind users that config has been changed based on plugin's config.|
| ON | ON/DEFAULT | OFF | **OFF**| The optimizer is disabled if at least one plugin turns off it. Grappler prints warnings to remind users that config has been changed based on plugin's config, and potention performance regression may happen due to the conflict configs.|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "turns off it" should be "turns it off". Same for other places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

| ON | OFF | OFF | **OFF**| The optimizer is disabled, unless users manually unload the plugin. Grappler prints warnings to remind users that config has been changed based on plugin's config.|
| ON | ON/DEFAULT | OFF | **OFF**| The optimizer is disabled if at least one plugin turns off it. Grappler prints warnings to remind users that config has been changed based on plugin's config, and potention performance regression may happen due to the conflict configs.|
| ON | OFF | ON/DEFAULT | **OFF**| Same as previous scenario.|
| OFF | ON/DEFAULT/OFF | ON/DEFAULT/OFF | **OFF**| The optimizer is always disabled when user turns off it. |

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add another paragraph (after the table) saying that plug-ins are responsible for benchmarking and ensuring that turning off the optimizer(s) doesn't cause nontrivial performance degradations? Thank you!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

```

When multiple plugins are registered and running for a graph, an error would be raised if their recommended configurations are different. Users should unload one of the plugins or disable plugin optimizers to resolve the conflict.
When multiple plugins are successfully registered and running for a graph, their recommended configurations may differ with each other. If any of the config has turned off the optimizer, the optimizer will be disabled. The following table lists all possible scenarios. In the table, plugin's config is represented by tristates, `ON` means turn on optimizer, `OFF` means turn off optimzier, and `DEFAULT` means uses proper's config.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo:

Suggested change
When multiple plugins are successfully registered and running for a graph, their recommended configurations may differ with each other. If any of the config has turned off the optimizer, the optimizer will be disabled. The following table lists all possible scenarios. In the table, plugin's config is represented by tristates, `ON` means turn on optimizer, `OFF` means turn off optimzier, and `DEFAULT` means uses proper's config.
When multiple plugins are successfully registered and running for a graph, their recommended configurations may differ with each other. If any of the config has turned off the optimizer, the optimizer will be disabled. The following table lists all possible scenarios. In the table, plugin's config is represented by tristates, `ON` means turn on optimizer, `OFF` means turn off optimizer, and `DEFAULT` means uses proper's config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@penpornk
Copy link
Member

penpornk commented Dec 2, 2020

Hi all,

To push this RFC forward, I'd like to set a deadline for responses. It has been nine days since the authors made the changes so I think another week is sufficient.

Please raise your concerns here by next Tuesday, December 8, 2020. If there are no outstanding concerns by then, I think we should wrap this up.


* **GraphDef**

The compatibility of `GraphDef` between plugin and proper is guaranteed by protobuf library.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The compatibility of `GraphDef` between plugin and proper is guaranteed by protobuf library.
The compatibility of `GraphDef` between plugin and proper follows the same compatibility [rules](https://developers.google.com/protocol-buffers/docs/cpptutorial?hl=en#extending-a-protocol-buffer) and [guarantees](https://developers.google.com/protocol-buffers/docs/proto3?hl=en#updating) as protobuf library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your suggestion. Updated.

@penpornk
Copy link
Member

penpornk commented Dec 9, 2020

@ematejska The deadline for additional feedback has passed. Since there is no outstanding concern, should we merge this?

@ematejska ematejska added RFC: Accepted RFC Design Document: Accepted by Review and removed RFC: Proposed RFC Design Document labels Dec 10, 2020
@ematejska ematejska merged commit ac2405f into tensorflow:master Dec 10, 2020
@Javier761227

This comment has been minimized.

@wchao1115
Copy link
Contributor

@PatriceVignola

@Mookel
Copy link

Mookel commented Dec 21, 2021

Hi, @ShengYang1 I am not sure whether this is the right place to ask question, but I will appreciate that if you can give me some advice:-).

In your RFC, you mentioned that:

Internal util functions
TensorFlow proper provides a series of functions to help modify graphs more conveniently in core/grappler/utils folder. Since creating C APIs for these functions is very messy, they would not be included in C APIs. Plugin authors can manually copy this part into plugin side, or they can write their own util functions.

I found that the utility classes in the core/grappler/utils are indeed quite useful, especially the functions provided in graph_view.h/.cc and pattern_util.h/.cc, but the implementation of these classes depends on components from other TensorFlow core libraries, which must also use C++ APIs. For instance:

So I think just copying these files into plugin side mabye not enough and my question is: If I want to modify the graph itself and do some pattern matches on the graph to support large set of operators fusion in the plugin side, are there any other better solutions?

Thanks very much!

@Solaryee
Copy link
Contributor Author

Hi, @ShengYang1 I am not sure whether this is the right place to ask question, but I will appreciate that if you can give me some advice:-).

In your RFC, you mentioned that:

Internal util functions
TensorFlow proper provides a series of functions to help modify graphs more conveniently in core/grappler/utils folder. Since creating C APIs for these functions is very messy, they would not be included in C APIs. Plugin authors can manually copy this part into plugin side, or they can write their own util functions.

I found that the utility classes in the core/grappler/utils are indeed quite useful, especially the functions provided in graph_view.h/.cc and pattern_util.h/.cc, but the implementation of these classes depends on components from other TensorFlow core libraries, which must also use C++ APIs. For instance:

So I think just copying these files into plugin side mabye not enough and my question is: If I want to modify the graph itself and do some pattern matches on the graph to support large set of operators fusion in the plugin side, are there any other better solutions?

Thanks very much!

Thanks for your question. Actually I prefer directly copying all those APIs(tensor_id.h, node_def_util.h,...) into plugin side, and naming them as plugin::TensorId, plugin::AddNodeAttr, since they only depends on protobuf objects and basic c++ objects. In such case, your code in plugin will be almost the same as those in proper, except for the namespace :)

@Mookel
Copy link

Mookel commented Dec 21, 2021

Thanks for your question. Actually I prefer directly copying all those APIs(tensor_id.h, node_def_util.h,...) into plugin side, and naming them as plugin::TensorId, plugin::AddNodeAttr, since they only depends on protobuf objects and basic c++ objects. In such case, your code in plugin will be almost the same as those in proper, except for the namespace :)

@ShengYang1 Thanks very much for your valuable suggestions , I will try:-).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes RFC: Accepted RFC Design Document: Accepted by Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.