Skip to content

Conversation

@PhilippvK
Copy link
Contributor

Motivation

I ran into the issue that I need to use C++ features in a BYOC generated kernel which is tricky to achieve because those are typically exported as .c files.

I am aware of the possibility to force gcc/g++ to threat all input files as C++ but this solves the issue only partially and is not really intuitive. Renaming the file names e.g. changing the file extension manually after the export via MLF is if also a workaround which does not work out for me.

Solution(s):

I came up with two rather simple solutions to solutions to solve the explained limitation in the ability to choose the correct file extension for kernel files written by a custom codegen and implemented the first one in this PR because it should add minimal complexity to the TVM codebase which might be desirable:

  1. Each CSourceModuleNode already has a format field which can be set in the constructor. Currently it can not be accessed by other classes but this can be easily solved by adding a getter and the respective python hooks for that property. This information can then be accessed by i.e. model_library_format.py to determine the file extension for the exported kernel. It would also be possible to use this interface for other types of modules in the future.

  2. Introduce a new class CppSourceModuleNode which is essentially a copy of CSourceModule with the only difference being the the the module_key which may then be used to choose a file extension in the aforementioned python functions. This sounds like much redundant code to me and also has less flexibility compared to option one as we would have to stick with either a .cc or a .cpp file extension for every modules of that type.

Open questions/thoughts:

I realized that the module format cc is currently already used by the CSourceCrtMetadataModuleNode declared in source_module.cc:

auto n = make_object<CSourceCrtMetadataModuleNode>(func_names, "cc", target, metadata);

This does not really make sense to me and especially makes some AoT and Model Library Format related pytests fail because the metadata module now being exported as .cc instead of .c as explaind the the previous paragraph. Let me know if I should add the fix these Makefiles to this PR and keep the module format for the CSourceCrtMetadataModuleNode defined as cc or if should work around this issue instead by changing the module format of that file to c?
I did not yet come up with new test cases which exercise the introduced changes to the MLF export as this would very likely result in a need to add a new dummy BYOC module which uses the cc format instead. During development I just patched the example codegen_c to export C++ kernels instead which worked fine,

I decided against an RFC for this discussion as only a couple of lines are added to the TVM codebase to realize this feature. Let me know if I should make this a (Pre-)RFC instead. Otherwise I would be happy for any feedback and answers to the remaining questions introduced in the last section.


CC @areusch @Mousius @giuseros @manupa-arm

…y fix failing tests

I realized that the module format `cc` is currently already used by the `CSourceCrtMetadataModuleNode` declared in `src/target/source/source_module.cc`.
This needs to be discussed first to decide if either the module_key should be changed or the test cases expecting the systemlib kernel (e.g. `default_lib0.c`) to have a `.c` extension.
…extensions

AOT: Add c++ support to aot_test.mk
AOT: Add c++ support to corstone300.mk
@PhilippvK
Copy link
Contributor Author

Ethosu and CMSIS-NN related builds seem to fail in CI, I will look into this and follow up with a fix for that.

Copy link
Contributor

@huajsj huajsj left a comment

Choose a reason for hiding this comment

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

Not see any UT logic, may need a test to explain the use case.

if fcompile is not None and hasattr(fcompile, "object_format"):
if module.type_key == "c":
object_format = "c"
assert module.format in ["c", "cc", "cpp"]
Copy link
Contributor

Choose a reason for hiding this comment

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

assert with error message?

@PhilippvK
Copy link
Contributor Author

Thank you for your review @huajsj. I will try to apply those patches soon.

Regarding unit tests, to did not want to introduce a new but otherwise useless BYOC codegen just for testing purposes. I will try to come up with something as simple as possible to test to changes to the SourceModule export. Eventuelly I will also figure out how include the special case nvcc -> cu into the tests.

@PhilippvK
Copy link
Contributor Author

To fix the CI run i will very likely need to rebase on top of main. This will eventually screw up open discussions in this PR. Please let me know if should just merge main into this branch instead to prevent that.

@areusch
Copy link
Contributor

areusch commented Oct 15, 2021

@PhilippvK yeah feel free to merge main. The github workflow is really confusing to me--basically what I do (mostly) is rebase and force-push until my PRs receive a comment; the minute they receive a comment, I merge instead. Then GitHub isn't allowed to garbage collect the old pushes.

@PhilippvK
Copy link
Contributor Author

Sorry for the CI bugs. I am working on them.

@PhilippvK
Copy link
Contributor Author

Sorry for not following up on this. While the CI bugs have been fixed in the meantime, there are still 3 points open for discussion:

  1. Currently the function ModuleNode::GetFormat is defined in src/runtime/module.cc but each inherited class need to implement the trivial method by itself. The reason for this decision is, that not every module is supposed to have a format. I first thought only CSourceModuleNode and CSourceCrtMetadataModuleNode needs to be updated but it seems like runtime modules such as CMSISNNModuleNode and EthosUModuleNode are directly based on 'runtime::ModuleNode' instead of 'CSourceModuleNode' leading to a need to implement a 'GetFormat' function for them as well. Do you have an advice on how to avoid this?

  2. Coming up with proper unit tests for this feature: I think there are two parts which shall be tested individually:

    • The handling of the format argument in the runtime.CSourceModuleCreate function invoced by severel BYOC kernels as well as the 'GetFormat()' function which should return the specified value.
    • Export of C++ kernels with the required file extension i.e. via the Model Library Format. This should also include tests ensuring that special cases (e.g. nvcc which has the .cu extension hardcoded) do not break.
  3. As mentioned above, i was wondering, why the CSourceCrtMetadataModuleNode is using the format cc instead of c, which would result in a change of the file extension for this source file to tvmgen_default_lib0.cc instead of tvmgen_default_lib0.c and therefore likely break some Makefile-Setups where kernel filenames are hardcoded.

Copy link
Contributor

@areusch areusch left a comment

Choose a reason for hiding this comment

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

@PhilippvK sorry I missed this! one question on the approach here.

"""Get the format of the module."""
return _ffi_api.ModuleGetFormat(self)

def get_source(self, fmt=""):
Copy link
Contributor

Choose a reason for hiding this comment

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

i think Module can sometimes have multiple formats (e.g. CUDA modules do this I believe). what about leveraging this and modifying export_module to try with fmt="c" here and if not also try fmt="cc"?

@PhilippvK
Copy link
Contributor Author

@areusch Sorry but I do not really understand what you mean. Could you tell me how this helps solving my mentioned "issues"?

@masahi
Copy link
Member

masahi commented Jan 9, 2022

@PhilippvK please resolve the conflict.

@PhilippvK PhilippvK requested a review from icemelon as a code owner January 10, 2022 10:50
@masahi masahi merged commit cc5382e into apache:main Jan 19, 2022
yuanfz98 pushed a commit to yuanfz98/tvm that referenced this pull request Jan 24, 2022
…sources which require a .cpp/.cc file extension (apache#9243)

* Allow export of C++ kernels using correct file extension

* [WIP] Set module_key=c for CSourceCrtMetadataModuleNode to temporarily fix failing tests

I realized that the module format `cc` is currently already used by the `CSourceCrtMetadataModuleNode` declared in `src/target/source/source_module.cc`.
This needs to be discussed first to decide if either the module_key should be changed or the test cases expecting the systemlib kernel (e.g. `default_lib0.c`) to have a `.c` extension.

* Update Makefiles used by tests/python/relay/aot/ to support C++ file extensions

AOT: Add c++ support to aot_test.mk
AOT: Add c++ support to corstone300.mk

* Add missing definition of GetFormat to cmsisnn and ethosn codegens (WIP)

* Resolve PR comments

* lint python/tvm/runtime/module.py

* fix EthosUModuleNode for CI

* Fix: detect empty module.format

* Add error message to assertion

* Lint python/tvm/runtime/module.py
crazydemo pushed a commit to crazydemo/tvm that referenced this pull request Jan 27, 2022
…sources which require a .cpp/.cc file extension (apache#9243)

* Allow export of C++ kernels using correct file extension

* [WIP] Set module_key=c for CSourceCrtMetadataModuleNode to temporarily fix failing tests

I realized that the module format `cc` is currently already used by the `CSourceCrtMetadataModuleNode` declared in `src/target/source/source_module.cc`.
This needs to be discussed first to decide if either the module_key should be changed or the test cases expecting the systemlib kernel (e.g. `default_lib0.c`) to have a `.c` extension.

* Update Makefiles used by tests/python/relay/aot/ to support C++ file extensions

AOT: Add c++ support to aot_test.mk
AOT: Add c++ support to corstone300.mk

* Add missing definition of GetFormat to cmsisnn and ethosn codegens (WIP)

* Resolve PR comments

* lint python/tvm/runtime/module.py

* fix EthosUModuleNode for CI

* Fix: detect empty module.format

* Add error message to assertion

* Lint python/tvm/runtime/module.py
ylc pushed a commit to ylc/tvm that referenced this pull request Feb 16, 2022
…sources which require a .cpp/.cc file extension (apache#9243)

* Allow export of C++ kernels using correct file extension

* [WIP] Set module_key=c for CSourceCrtMetadataModuleNode to temporarily fix failing tests

I realized that the module format `cc` is currently already used by the `CSourceCrtMetadataModuleNode` declared in `src/target/source/source_module.cc`.
This needs to be discussed first to decide if either the module_key should be changed or the test cases expecting the systemlib kernel (e.g. `default_lib0.c`) to have a `.c` extension.

* Update Makefiles used by tests/python/relay/aot/ to support C++ file extensions

AOT: Add c++ support to aot_test.mk
AOT: Add c++ support to corstone300.mk

* Add missing definition of GetFormat to cmsisnn and ethosn codegens (WIP)

* Resolve PR comments

* lint python/tvm/runtime/module.py

* fix EthosUModuleNode for CI

* Fix: detect empty module.format

* Add error message to assertion

* Lint python/tvm/runtime/module.py
@PhilippvK PhilippvK deleted the export-cpp-sources branch January 23, 2024 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants