Skip to content

Fix function number datatype from char to uint16_t - #10014

Merged
areusch merged 1 commit into
apache:mainfrom
A1245967:main
May 18, 2022
Merged

Fix function number datatype from char to uint16_t#10014
areusch merged 1 commit into
apache:mainfrom
A1245967:main

Conversation

@A1245967

Copy link
Copy Markdown
Contributor

Hi, @areusch
Here is the bug I mentioned before.
I cast the first two byte to uint16_t to store the function number.

@comaniac comaniac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Comment thread src/runtime/crt/common/func_registry.c Outdated
reg->registry.names = (const char*)buffer;
buffer[0] = 0; // number of functions present in buffer.
buffer[1] = 0; // end of names list marker.
buffer[1] = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Better to explicitly mention the purpose. Something like

Suggested change
buffer[1] = 0;
buffer[1] = 0; // note that we combine the first two elements to form a 16-bit function index.

@kparzysz-quic kparzysz-quic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are other places in this file that rely on the "one char for function count", that this patch does not update.

The approach of hiding the number of functions in the "names" buffer is dangerous---sooner or later somebody will forget it, or miss some cases, and it will result in hard-to-find bugs. I think it would be better to make it explicit in the data structures, or to create special functions that get/update the function count and get the actual beginning of the function names.

@comaniac

Copy link
Copy Markdown
Contributor

@kparzysz-quic thanks for pointing out the missing pieces. For the discussion about putting number in the name buffer, please refer to the discussion: https://discuss.tvm.apache.org/t/byoc-limited-function-numbers-on-crt-runtime/11952

@areusch

areusch commented Jan 23, 2022

Copy link
Copy Markdown
Contributor

@kparzysz-quic i agree it can be a bit misleading. if you feel strongly about it, i'm okay with us adopting the more explicit approach. it would waste a few bytes, but we do now provide a more compact solution for the standalone deployment workflow, so perhaps that's okay now. i am curious on your take on my rationale presented in the thread Cody links above. Regardless of the strategy taken around the C struct, it's going to be a bit dangerous since we generate this structure from LLVM and C source codegen, and then try to re-interpret the structure using a different compiler.

@A1245967 you'll also need to update the LLVM codegen and C source codegen to generate the proper structure.

@kparzysz-quic

kparzysz-quic commented Jan 24, 2022

Copy link
Copy Markdown
Contributor

I agree that accessing C structures via LLVM codegen may be tricky (due to pointer sizes in particular, and alignment rules), we're already running into a similar issue with enums in Device (IIRC). It should be ok to have the number of functions "hidden" in the buffer, but we should have separate functions to (1) read it from the buffer, (2) store it to the buffer, (3) get the beginning of the actual payload. This is what I meant in my first comment---this way we would avoid things like for (char *p = names + 1; ...), where it's not clear what that + 1 means, and instead have something like for (char *p = some_better_name_for_the_beginning_of_the_actual_names(); ...). This would localize the encoding and decoding of the function count to specialized function, where the situation can be explained in comments. This is all to make it harder for people to make an accidental mistake.

@areusch

areusch commented Apr 8, 2022

Copy link
Copy Markdown
Contributor

@kparzysz-quic ah i understand. sure, that's totally fine with me.

@A1245967 , if you're up for it, would you mind introducing a few helper functions e.g. TVMFuncRegistry_GetNumFuncs and TVMFuncRegistry_Get0thFunctionName and updating the remaining places to match? i think we can merge with that.

@A1245967

A1245967 commented Apr 9, 2022

Copy link
Copy Markdown
Contributor Author

@areusch okay, I try to use some helper functions instead of accessing the buffer directly.

@areusch

areusch commented Apr 11, 2022

Copy link
Copy Markdown
Contributor

@A1245967 that looks pretty good--i think you just need to update the C++ unit tests in tests/crt/func_registry_test.cc

@A1245967

Copy link
Copy Markdown
Contributor Author

@areusch I have updated the code. Do I need to modify anything else?

@areusch areusch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ahh--sorry @A1245967 i found one more problem. could you address this one, and then i think we're good to merge.

Comment thread src/runtime/crt/common/func_registry.c Outdated
return return_value;
}

uint16_t* TVMFuncRegistry_GetNumFuncs(const TVMFuncRegistry* reg) { return (uint16_t*)reg->names; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

for this function, i think we need to impl like this to avoid alignment problems:

Suggested change
uint16_t* TVMFuncRegistry_GetNumFuncs(const TVMFuncRegistry* reg) { return (uint16_t*)reg->names; }
uint16_t TVMFuncRegistry_GetNumFuncs(const TVMFuncRegistry* reg) {
uint16_t num_funcs;
memcpy(&num_funcs, reg->names, sizeof(num_funcs));
return num_funcs;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the following line also need to be changed if I choose to return the value instead of the address.

We update the value of num_funcs at this line .
If I choose to return the value in TVMFuncRegistry_GetNumFuncs, I should write a function to update num_funcs in buffer.
Do I need to write a function like TVMFuncRegistry_SetNumFuncs to set the value of num_funcs?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ah, yeah i think so. good catch.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@areusch I have implemented the functions TVMFuncRegistry_SetNumFuncs and TVMFuncRegistry_GetNumFuncs.
You can review these functions.

rewrite the modified part to pass lint check

Use 2 bytes for func num in fun_registry

Fix errors in linter

Add the declaration of the helper functions

set 2 bytes for func num in func_registry test units

pass num_func by value

This commit change the datatype of the number of the function from 1 Byte to 2 Bytes.
Besides, I use some helper functions to access the number of function and the first function name.

@areusch areusch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks @A1245967 !

@areusch
areusch merged commit f34bd22 into apache:main May 18, 2022
@areusch

areusch commented May 18, 2022

Copy link
Copy Markdown
Contributor

@kparzysz-quic merged this now

AndrewZhaoLuo pushed a commit that referenced this pull request May 18, 2022
…10014)" (#11363)

This reverts commit f34bd22.

Co-authored-by: driazati <driazati@users.noreply.github.com>
@driazati

Copy link
Copy Markdown
Member

Hey @A1245967 this PR's last CI run was a bit out of date so it broke things when it was merged with the main branch, so we had to revert it in c32224f. If you open another PR with the same changes (which you can do with something like

cd tvm
git fetch origin main
git reset --hard origin/main
curl -L https://github.com/apache/tvm/pull/10014.diff | patch -p1 -N -d .
# then git add, commit as usual

) and fix the CI bug we can get it merged back in ASAP

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.

5 participants