How to integrate a target specific library for codegen?

Dear All, I am quite lost on the flow of Codegen and lowering and not able to figure out way of integrating a target cross compiled external library to codegen to generate module (model) library?

I have a target specific cross compile library which contain the NN operator implementations optimized for the target and that to be integrate to the arm target.

Please help me…

You can try to follow this tutorial to build a codegen: https://docs.tvm.ai/dev/relay_bring_your_own_codegen.html

@comaniac Thank you for response. To achieve this codegen, the external library must be able to compile with GCC or the cross compiled library can do this?

This flow fits both cases. See the description of 2. You want to generate any other graph representations.

@comaniac, help me clarify one doubt, I have gone through the tutorial. in my understanding, it covers two part.

  1. We can integrate a GCC compiled external library for utilising an external operator implementation like rocblas.
  2. we can integrate a new runtime which basically have new graph representation like TensorRT. Please correct me if I missed anything.

But in my case, I have only the optimised operator implementation in the external library which is cross compiled for my target(not compatible to compile on GCC). It doesnot contain any runtime.

I tried the followings:

  1. I tried like ROCBLAS integration. If the library is GCC compiled, I can link the library to TVM and call the library API from operator as an external function as mentioned in src/runtime/contrib/rocblas But in my case, i have GCC incompatible library So the linking will not happen when TVM source code building.
  2. Basically I have to call operator implementation in my library (cross compiled) when the model is compiling for arm. But I am missing hook where and how to integrate this library to happen this interfacing internally at model compilation.

This case also can be covered in the flow https://docs.tvm.ai/dev/relay_bring_your_own_codegen.html ?

Regards, Albin

In this case you need a customized runtime. The flow would be like the following:

  • The codegen accepts a subgraph and generate the code that invokes functions in your library.
  • When exporting the TVM built model library, the SaveToBinary in your codegen will be called, and you need to cross-compile the generated code at this moment.
  • In runtime, TVM will invoke you customized runtime when seeing an external function call. Your customized runtime is not necessary to be a graph execution engine. It can be just a function dispatcher. For example, it first loads the binary compiled in the previous step and establishes a map such as subgraph1 -> function pointer. As a result, when TVM asks your runtime to run subgraph1, your runtime identifies the corresponding function pointer and invokes the function.

@comaniac Still the operator computes have to call the library functions right? at the TVM compilation
time, libtvm.so will not create dependency with the arm optimised library because the library is not GCC/linux compatible. Could you please help me to understand, How can we avoid this issue?

You can generate code and write it to a text file, so that you can leverage a system call to compile it. Since the compilation is a separate process, it doesn’t have to be built with TVM.

@comaniac I have analysed the code more and tried to prototype the solution. I followed the below process.

  1. I used a packed function registered with TVM_REGISTER_GLOBAL to call me library API. For this I created a temporary library which compatible with Linux and placed dummy API functions to make the libtvm.so build get success and symbols to be resolved.
  2. My plan is to link the model cross compiled library function symbol at runtime like with the actual arm compatible library.
  3. But I am acing one problem: in the model library, the symbol visible is the external function (arm library API is not visible in the symbol table) called from the operator but the arm library have normal API. So the direct linking is not possible, can you please suggest me a solution here?
  4. If I have to link the arm library at the model library cross compilation time(relay.build), is this possible?

When calling export library, the C code generated by your codegen will be compiled with the rest of parts. You can pass the library linking options like:

In this case, you need to build TVM with the ARM library, and you can achieve this by adding the dependency to the CMake configs. You can refer to the DNNL codegen example we put and see how the MKL-DNN dependency was added.

Alternatively, you can generate a graph representation (e.g., in JSON format) in your codegen instead of C code. In this case, you implement a customized runtime to accept the graph and call APIs in the ARM library. Of course, the runtime has to be compiled with the ARM library and you still need to add the dependency to the CMake configs.

Few queries,

  1. To build the TVM with ARM library, we have to build the entire TVM source code with ARM tool chain right?
  2. The DNNL support added in TVM for a cross compiled DNNL library? I have gone through the source code, the code is not using any TVM external function TVM_REGISTER_GLOBAL method. And the CMAKE dependency you are talking is cmake/modules/contrib/DNNL.cmake right?
  3. For the alternative solution you are suggesting, can you please give me an example for generating graph representation in codegen instead of C, if its available?
  1. To build the TVM with ARM library, we have to build the entire TVM source code with ARM tool chain right?

Simply speaking, yes.

  1. The DNNL support added in TVM for a cross compiled DNNL library? I have gone through the source code, the code is not using any TVM external function TVM_REGISTER_GLOBAL method.

DNNL support doesn’t use TVM_REGISTER_GLOBAL since we didn’t implement one-to-one op mapping like other contribs such as cBLAS/cuBLAS/cuDNN. Other contrib register their APIs to corresponding TVM ops and they will be directly invoked when a user specifies the target (e.g., -lib=cblas). DNNL codegen example, on the other hand, generates API calls by traversing subgraphs. In this case, we only need to include DNNL library when we need to compile the generated code:

And the CMAKE dependency you are talking is cmake/modules/contrib/DNNL.cmake right?

Yes.

  1. For the alternative solution you are suggesting, can you please give me an example for generating graph representation in codegen instead of C, if its available?

@zhiics and I are working on a general JSON codegen with a DNNL runtime engine as a more practical example. Hopefully we can file a PR next week.

In the DNNL solution, TVM expect to link the DNNL library at TVM load time (when we do “import tvm”) with the cmake change:

  find_library(EXTERN_LIBRARY_DNNL dnnl)
  list(APPEND TVM_RUNTIME_LINKER_LIBS ${EXTERN_LIBRARY_DNNL}) 

But in my case, I doesnot have this Linux compatible library to link with TVM at this place.

Is this possible by following DNNL flow and making below changes to overcome my situation?

  1. I create a dummy Linux library (all the Library APIs with dummy definitions) and use for TVM source code compilation and linking.
  2. At the time for “relay.build” and codegen, at the “export library”, as shown in “update_lib”, I will try to link original ARM library and map the Library API calls. Does this change need runtime modifications?
  3. With the above solution doesnot need TVM source code to be compiled with ARM tool chain.
  4. Just for confirmation, as of now there is no solution integrated in TVM with a dependency the entire TVM source code to be cross compiled, right?
  5. Will the above method or the alternative solution you suggested (make a TXT/JSON graph representation in codegen instead of C and a customised runtime to map the function with ARM Library API) more realistic?

If this library is Arm Compute Library, we in Arm are working on a proof of concept integration into the BYOC codegen pretty much with a json graph representation in codegen instead of using the C runtime.

Ramana

1 Like

@ramana-arm I am basically trying this for a research purpose. Could you please let me know, when this changes will be ready and uploaded?

@comaniac Could you please help me to clarify my queries.